From fbd74b2e504283240d93321f9102c949136b631c Mon Sep 17 00:00:00 2001 From: Git User Date: Sun, 31 May 2020 21:10:53 -0700 Subject: [PATCH 001/317] Initial empty repository From 387d008122959223472b83bf4a25a4a3aa803cfb Mon Sep 17 00:00:00 2001 From: George Shen Date: Sun, 28 Jun 2020 15:40:33 -0700 Subject: [PATCH 002/317] msm: eva: Initial eva driver For Waipio. Change-Id: I2fa0eeadcbf9252190a6febbe0f890f1dc7b1524 Signed-off-by: George Shen --- Makefile | 11 + config/waipioeva.conf | 5 + config/waipioevaconf.h | 6 + msm/Makefile | 24 + msm/eva/cvp.c | 604 +++++ msm/eva/cvp_comm_def.h | 24 + msm/eva/cvp_core_hfi.c | 52 + msm/eva/cvp_core_hfi.h | 271 ++ msm/eva/cvp_hfi.c | 4680 ++++++++++++++++++++++++++++++++ msm/eva/cvp_hfi.h | 216 ++ msm/eva/cvp_hfi_api.h | 379 +++ msm/eva/cvp_hfi_helper.h | 453 ++++ msm/eva/cvp_hfi_io.h | 223 ++ msm/eva/cvp_private.h | 18 + msm/eva/hfi_packetization.c | 462 ++++ msm/eva/hfi_packetization.h | 75 + msm/eva/hfi_response_handler.c | 676 +++++ msm/eva/msm_cvp.c | 1646 +++++++++++ msm/eva/msm_cvp.h | 36 + msm/eva/msm_cvp_buf.c | 936 +++++++ msm/eva/msm_cvp_buf.h | 198 ++ msm/eva/msm_cvp_clocks.c | 25 + msm/eva/msm_cvp_clocks.h | 12 + msm/eva/msm_cvp_common.c | 1610 +++++++++++ msm/eva/msm_cvp_common.h | 34 + msm/eva/msm_cvp_core.c | 394 +++ msm/eva/msm_cvp_core.h | 40 + msm/eva/msm_cvp_debug.c | 540 ++++ msm/eva/msm_cvp_debug.h | 181 ++ msm/eva/msm_cvp_dsp.c | 599 ++++ msm/eva/msm_cvp_dsp.h | 145 + msm/eva/msm_cvp_internal.h | 315 +++ msm/eva/msm_cvp_ioctl.c | 650 +++++ msm/eva/msm_cvp_platform.c | 233 ++ msm/eva/msm_cvp_res_parse.c | 1073 ++++++++ msm/eva/msm_cvp_res_parse.h | 30 + msm/eva/msm_cvp_resources.h | 185 ++ msm/eva/msm_cvp_synx.c | 240 ++ msm/eva/msm_cvp_synx.h | 55 + msm/eva/msm_smem.c | 473 ++++ 40 files changed, 17829 insertions(+) create mode 100644 Makefile create mode 100644 config/waipioeva.conf create mode 100644 config/waipioevaconf.h create mode 100644 msm/Makefile create mode 100644 msm/eva/cvp.c create mode 100644 msm/eva/cvp_comm_def.h create mode 100644 msm/eva/cvp_core_hfi.c create mode 100644 msm/eva/cvp_core_hfi.h create mode 100644 msm/eva/cvp_hfi.c create mode 100644 msm/eva/cvp_hfi.h create mode 100644 msm/eva/cvp_hfi_api.h create mode 100644 msm/eva/cvp_hfi_helper.h create mode 100644 msm/eva/cvp_hfi_io.h create mode 100644 msm/eva/cvp_private.h create mode 100644 msm/eva/hfi_packetization.c create mode 100644 msm/eva/hfi_packetization.h create mode 100644 msm/eva/hfi_response_handler.c create mode 100644 msm/eva/msm_cvp.c create mode 100644 msm/eva/msm_cvp.h create mode 100644 msm/eva/msm_cvp_buf.c create mode 100644 msm/eva/msm_cvp_buf.h create mode 100644 msm/eva/msm_cvp_clocks.c create mode 100644 msm/eva/msm_cvp_clocks.h create mode 100644 msm/eva/msm_cvp_common.c create mode 100644 msm/eva/msm_cvp_common.h create mode 100644 msm/eva/msm_cvp_core.c create mode 100644 msm/eva/msm_cvp_core.h create mode 100644 msm/eva/msm_cvp_debug.c create mode 100644 msm/eva/msm_cvp_debug.h create mode 100644 msm/eva/msm_cvp_dsp.c create mode 100644 msm/eva/msm_cvp_dsp.h create mode 100644 msm/eva/msm_cvp_internal.h create mode 100644 msm/eva/msm_cvp_ioctl.c create mode 100644 msm/eva/msm_cvp_platform.c create mode 100644 msm/eva/msm_cvp_res_parse.c create mode 100644 msm/eva/msm_cvp_res_parse.h create mode 100644 msm/eva/msm_cvp_resources.h create mode 100644 msm/eva/msm_cvp_synx.c create mode 100644 msm/eva/msm_cvp_synx.h create mode 100644 msm/eva/msm_smem.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..3e80127286 --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0-only + +# auto-detect subdirs +ifneq ($(CONFIG_ARCH_QTI_VM), y) +ifeq ($(CONFIG_ARCH_LAHAINA), y) +include $(srctree)/techpack/eva/config/waipioeva.conf +LINUXINCLUDE += -include $(srctree)/techpack/eva/config/waipioevaconf.h +endif +endif + +obj-y +=msm/ diff --git a/config/waipioeva.conf b/config/waipioeva.conf new file mode 100644 index 0000000000..1bfda5e8aa --- /dev/null +++ b/config/waipioeva.conf @@ -0,0 +1,5 @@ +ifeq ($(CONFIG_QGKI),y) +export CONFIG_MSM_EVA=n +else +export CONFIG_MSM_EVA=n +endif diff --git a/config/waipioevaconf.h b/config/waipioevaconf.h new file mode 100644 index 0000000000..2ec1e53ade --- /dev/null +++ b/config/waipioevaconf.h @@ -0,0 +1,6 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#define CONFIG_MSM_EVA 0 diff --git a/msm/Makefile b/msm/Makefile new file mode 100644 index 0000000000..bffc386392 --- /dev/null +++ b/msm/Makefile @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: GPL-2.0-only +ccflags-y += -I$(srctree)/techpack/eva/msm/eva/ \ + -I$(srctree)/drivers/media/platform/msm/synx/ + +msm-eva-objs := eva/cvp.o \ + eva/msm_cvp_ioctl.o \ + eva/msm_cvp_platform.o \ + eva/msm_cvp_common.o \ + eva/msm_cvp_core.o \ + eva/msm_cvp.o \ + eva/msm_smem.o \ + eva/msm_cvp_debug.o \ + eva/msm_cvp_res_parse.o \ + eva/cvp_hfi.o \ + eva/hfi_response_handler.o \ + eva/hfi_packetization.o \ + eva/cvp_core_hfi.o \ + eva/msm_cvp_clocks.o\ + eva/msm_cvp_dsp.o \ + eva/msm_cvp_buf.o \ + eva/msm_cvp_synx.o + +obj-$(CONFIG_MSM_EVA) := msm-eva.o + diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c new file mode 100644 index 0000000000..2802932c17 --- /dev/null +++ b/msm/eva/cvp.c @@ -0,0 +1,604 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm_cvp_core.h" +#include "msm_cvp_common.h" +#include "msm_cvp_debug.h" +#include "msm_cvp_internal.h" +#include "msm_cvp_res_parse.h" +#include "msm_cvp_resources.h" +#include "cvp_hfi_api.h" +#include "cvp_private.h" +#include "msm_cvp_clocks.h" +#include "msm_cvp_dsp.h" + +#define CLASS_NAME "cvp" +#define DRIVER_NAME "cvp" + +struct msm_cvp_drv *cvp_driver; + +static int cvp_open(struct inode *inode, struct file *filp) +{ + struct msm_cvp_core *core = container_of(inode->i_cdev, + struct msm_cvp_core, cdev); + struct msm_cvp_inst *inst; + + dprintk(CVP_SESS, "%s: Enter\n", __func__); + + inst = msm_cvp_open(core->id, MSM_CVP_USER); + if (!inst) { + dprintk(CVP_ERR, "Failed to create cvp instance\n"); + return -ENOMEM; + } + filp->private_data = inst; + return 0; +} + +static int cvp_close(struct inode *inode, struct file *filp) +{ + int rc = 0; + struct msm_cvp_inst *inst = filp->private_data; + + rc = msm_cvp_close(inst); + filp->private_data = NULL; + return rc; +} + +static unsigned int cvp_poll(struct file *filp, struct poll_table_struct *p) +{ + int rc = 0; + struct msm_cvp_inst *inst = filp->private_data; + unsigned long flags = 0; + + poll_wait(filp, &inst->event_handler.wq, p); + + spin_lock_irqsave(&inst->event_handler.lock, flags); + if (inst->event_handler.event == CVP_SSR_EVENT) + rc |= POLLPRI; + spin_unlock_irqrestore(&inst->event_handler.lock, flags); + + return rc; +} + +static const struct file_operations cvp_fops = { + .owner = THIS_MODULE, + .open = cvp_open, + .release = cvp_close, + .unlocked_ioctl = cvp_unblocked_ioctl, + .compat_ioctl = cvp_compat_ioctl, + .poll = cvp_poll, +}; + +static int read_platform_resources(struct msm_cvp_core *core, + struct platform_device *pdev) +{ + int rc = 0; + + if (!core || !pdev) { + dprintk(CVP_ERR, "%s: Invalid params %pK %pK\n", + __func__, core, pdev); + return -EINVAL; + } + + core->hfi_type = CVP_HFI_IRIS; + core->resources.pdev = pdev; + if (pdev->dev.of_node) { + /* Target supports DT, parse from it */ + rc = cvp_read_platform_resources_from_drv_data(core); + rc = cvp_read_platform_resources_from_dt(&core->resources); + } else { + dprintk(CVP_ERR, "pdev node is NULL\n"); + rc = -EINVAL; + } + return rc; +} + +static int msm_cvp_initialize_core(struct platform_device *pdev, + struct msm_cvp_core *core) +{ + int i = 0; + int rc = 0; + + if (!core) + return -EINVAL; + rc = read_platform_resources(core, pdev); + if (rc) { + dprintk(CVP_ERR, "Failed to get platform resources\n"); + return rc; + } + + INIT_LIST_HEAD(&core->instances); + mutex_init(&core->lock); + + core->state = CVP_CORE_UNINIT; + for (i = SYS_MSG_INDEX(SYS_MSG_START); + i <= SYS_MSG_INDEX(SYS_MSG_END); i++) { + init_completion(&core->completions[i]); + } + + INIT_DELAYED_WORK(&core->fw_unload_work, msm_cvp_fw_unload_handler); + INIT_WORK(&core->ssr_work, msm_cvp_ssr_handler); + + return rc; +} + +static ssize_t link_name_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct msm_cvp_core *core = dev_get_drvdata(dev); + + if (core) + if (dev == core->dev) + return snprintf(buf, PAGE_SIZE, "msm_cvp\n"); + else + return 0; + else + return 0; +} + +static DEVICE_ATTR_RO(link_name); + +static ssize_t pwr_collapse_delay_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + unsigned long val = 0; + int rc = 0; + struct msm_cvp_core *core = NULL; + + rc = kstrtoul(buf, 0, &val); + if (rc) + return rc; + else if (!val) + return -EINVAL; + + core = get_cvp_core(MSM_CORE_CVP); + if (!core) + return -EINVAL; + core->resources.msm_cvp_pwr_collapse_delay = val; + return count; +} + +static ssize_t pwr_collapse_delay_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct msm_cvp_core *core = NULL; + + core = get_cvp_core(MSM_CORE_CVP); + if (!core) + return -EINVAL; + + return snprintf(buf, PAGE_SIZE, "%u\n", + core->resources.msm_cvp_pwr_collapse_delay); +} + +static DEVICE_ATTR_RW(pwr_collapse_delay); + +static ssize_t thermal_level_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return snprintf(buf, PAGE_SIZE, "%d\n", cvp_driver->thermal_level); +} + +static ssize_t thermal_level_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int rc = 0, val = 0; + + rc = kstrtoint(buf, 0, &val); + if (rc || val < 0) { + dprintk(CVP_WARN, + "Invalid thermal level value: %s\n", buf); + return -EINVAL; + } + dprintk(CVP_PWR, "Thermal level old %d new %d\n", + cvp_driver->thermal_level, val); + + if (val == cvp_driver->thermal_level) + return count; + cvp_driver->thermal_level = val; + + msm_cvp_comm_handle_thermal_event(); + return count; +} + +static DEVICE_ATTR_RW(thermal_level); + +static ssize_t sku_version_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return scnprintf(buf, PAGE_SIZE, "%d", + cvp_driver->sku_version); +} + +static DEVICE_ATTR_RO(sku_version); + +static ssize_t boot_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int rc = 0, val = 0; + static int booted; + + rc = kstrtoint(buf, 0, &val); + if (rc || val < 0) { + dprintk(CVP_WARN, + "Invalid boot value: %s\n", buf); + return -EINVAL; + } + + if (val > 0 && booted == 0) { + struct msm_cvp_inst *inst; + + inst = msm_cvp_open(MSM_CORE_CVP, MSM_CVP_BOOT); + if (!inst) { + dprintk(CVP_ERR, + "Failed to create cvp instance\n"); + return -ENOMEM; + } + rc = msm_cvp_close(inst); + if (rc) { + dprintk(CVP_ERR, + "Failed to close cvp instance\n"); + return rc; + } + } + booted = 1; + return count; +} + +static DEVICE_ATTR_WO(boot); + +static struct attribute *msm_cvp_core_attrs[] = { + &dev_attr_pwr_collapse_delay.attr, + &dev_attr_thermal_level.attr, + &dev_attr_sku_version.attr, + &dev_attr_link_name.attr, + &dev_attr_boot.attr, + NULL +}; + +static struct attribute_group msm_cvp_core_attr_group = { + .attrs = msm_cvp_core_attrs, +}; + +static const struct of_device_id msm_cvp_plat_match[] = { + {.compatible = "qcom,msm-cvp"}, + {.compatible = "qcom,msm-cvp,context-bank"}, + {.compatible = "qcom,msm-cvp,bus"}, + {.compatible = "qcom,msm-cvp,mem-cdsp"}, + {} +}; + +static int msm_probe_cvp_device(struct platform_device *pdev) +{ + int rc = 0; + struct msm_cvp_core *core; + + if (!cvp_driver) { + dprintk(CVP_ERR, "Invalid cvp driver\n"); + return -EINVAL; + } + + core = kzalloc(sizeof(*core), GFP_KERNEL); + if (!core) + return -ENOMEM; + + core->platform_data = cvp_get_drv_data(&pdev->dev); + dev_set_drvdata(&pdev->dev, core); + rc = msm_cvp_initialize_core(pdev, core); + if (rc) { + dprintk(CVP_ERR, "Failed to init core\n"); + goto err_core_init; + } + + core->id = MSM_CORE_CVP; + + rc = alloc_chrdev_region(&core->dev_num, 0, 1, DRIVER_NAME); + if (rc < 0) { + dprintk(CVP_ERR, "alloc_chrdev_region failed: %d\n", + rc); + goto err_alloc_chrdev; + } + + core->class = class_create(THIS_MODULE, CLASS_NAME); + if (IS_ERR(core->class)) { + rc = PTR_ERR(core->class); + dprintk(CVP_ERR, "class_create failed: %d\n", + rc); + goto err_class_create; + } + + core->dev = device_create(core->class, NULL, + core->dev_num, NULL, DRIVER_NAME); + if (IS_ERR(core->dev)) { + rc = PTR_ERR(core->dev); + dprintk(CVP_ERR, "device_create failed: %d\n", + rc); + goto err_device_create; + } + dev_set_drvdata(core->dev, core); + + cdev_init(&core->cdev, &cvp_fops); + rc = cdev_add(&core->cdev, + MKDEV(MAJOR(core->dev_num), 0), 1); + if (rc < 0) { + dprintk(CVP_ERR, "cdev_add failed: %d\n", + rc); + goto error_cdev_add; + } + + /* finish setting up the 'core' */ + mutex_lock(&cvp_driver->lock); + if (cvp_driver->num_cores + 1 > MSM_CVP_CORES_MAX) { + mutex_unlock(&cvp_driver->lock); + dprintk(CVP_ERR, "Maximum cores already exist, core_no = %d\n", + cvp_driver->num_cores); + goto err_cores_exceeded; + } + cvp_driver->num_cores++; + mutex_unlock(&cvp_driver->lock); + + rc = sysfs_create_group(&core->dev->kobj, &msm_cvp_core_attr_group); + if (rc) { + dprintk(CVP_ERR, + "Failed to create attributes\n"); + goto err_cores_exceeded; + } + + core->device = cvp_hfi_initialize(core->hfi_type, core->id, + &core->resources, &cvp_handle_cmd_response); + if (IS_ERR_OR_NULL(core->device)) { + mutex_lock(&cvp_driver->lock); + cvp_driver->num_cores--; + mutex_unlock(&cvp_driver->lock); + + rc = PTR_ERR(core->device) ?: -EBADHANDLE; + if (rc != -EPROBE_DEFER) + dprintk(CVP_ERR, "Failed to create HFI device\n"); + else + dprintk(CVP_CORE, "msm_cvp: request probe defer\n"); + goto err_hfi_initialize; + } + + mutex_lock(&cvp_driver->lock); + list_add_tail(&core->list, &cvp_driver->cores); + mutex_unlock(&cvp_driver->lock); + + core->debugfs_root = msm_cvp_debugfs_init_core( + core, cvp_driver->debugfs_root); + + cvp_driver->sku_version = core->resources.sku_version; + + dprintk(CVP_CORE, "populating sub devices\n"); + /* + * Trigger probe for each sub-device i.e. qcom,msm-cvp,context-bank. + * When msm_cvp_probe is called for each sub-device, parse the + * context-bank details and store it in core->resources.context_banks + * list. + */ + rc = of_platform_populate(pdev->dev.of_node, msm_cvp_plat_match, NULL, + &pdev->dev); + if (rc) { + dprintk(CVP_ERR, "Failed to trigger probe for sub-devices\n"); + goto err_fail_sub_device_probe; + } + + atomic64_set(&core->kernel_trans_id, 0); + + rc = cvp_dsp_device_init(); + if (rc) + dprintk(CVP_WARN, "Failed to initialize DSP driver\n"); + + return rc; + +err_fail_sub_device_probe: + cvp_hfi_deinitialize(core->hfi_type, core->device); +err_hfi_initialize: +err_cores_exceeded: + cdev_del(&core->cdev); +error_cdev_add: + device_destroy(core->class, core->dev_num); +err_device_create: + class_destroy(core->class); +err_class_create: + unregister_chrdev_region(core->dev_num, 1); +err_alloc_chrdev: + sysfs_remove_group(&pdev->dev.kobj, &msm_cvp_core_attr_group); +err_core_init: + dev_set_drvdata(&pdev->dev, NULL); + kfree(core); + return rc; +} + +static int msm_cvp_probe_mem_cdsp(struct platform_device *pdev) +{ + return cvp_read_mem_cdsp_resources_from_dt(pdev); +} + +static int msm_cvp_probe_context_bank(struct platform_device *pdev) +{ + return cvp_read_context_bank_resources_from_dt(pdev); +} + +static int msm_cvp_probe_bus(struct platform_device *pdev) +{ + return cvp_read_bus_resources_from_dt(pdev); +} + +static int msm_cvp_probe(struct platform_device *pdev) +{ + /* + * Sub devices probe will be triggered by of_platform_populate() towards + * the end of the probe function after msm-cvp device probe is + * completed. Return immediately after completing sub-device probe. + */ + if (of_device_is_compatible(pdev->dev.of_node, "qcom,msm-cvp")) { + return msm_probe_cvp_device(pdev); + } else if (of_device_is_compatible(pdev->dev.of_node, + "qcom,msm-cvp,bus")) { + return msm_cvp_probe_bus(pdev); + } else if (of_device_is_compatible(pdev->dev.of_node, + "qcom,msm-cvp,context-bank")) { + return msm_cvp_probe_context_bank(pdev); + } else if (of_device_is_compatible(pdev->dev.of_node, + "qcom,msm-cvp,mem-cdsp")) { + return msm_cvp_probe_mem_cdsp(pdev); + } + + /* How did we end up here? */ + MSM_CVP_ERROR(1); + return -EINVAL; +} + +static int msm_cvp_remove(struct platform_device *pdev) +{ + int rc = 0; + struct msm_cvp_core *core; + + if (!pdev) { + dprintk(CVP_ERR, "%s invalid input %pK", __func__, pdev); + return -EINVAL; + } + + core = dev_get_drvdata(&pdev->dev); + if (!core) { + dprintk(CVP_ERR, "%s invalid core", __func__); + return -EINVAL; + } + + cvp_hfi_deinitialize(core->hfi_type, core->device); + msm_cvp_free_platform_resources(&core->resources); + sysfs_remove_group(&pdev->dev.kobj, &msm_cvp_core_attr_group); + dev_set_drvdata(&pdev->dev, NULL); + mutex_destroy(&core->lock); + kfree(core); + return rc; +} + +static int msm_cvp_pm_suspend(struct device *dev) +{ + int rc = 0; + struct msm_cvp_core *core; + + /* + * Bail out if + * - driver possibly not probed yet + * - not the main device. We don't support power management on + * subdevices (e.g. context banks) + */ + if (!dev || !dev->driver || + !of_device_is_compatible(dev->of_node, "qcom,msm-cvp")) + return 0; + + core = dev_get_drvdata(dev); + if (!core) { + dprintk(CVP_ERR, "%s invalid core\n", __func__); + return -EINVAL; + } + + rc = msm_cvp_suspend(core->id); + if (rc == -ENOTSUPP) + rc = 0; + else if (rc) + dprintk(CVP_WARN, "Failed to suspend: %d\n", rc); + + + return rc; +} + +static int msm_cvp_pm_resume(struct device *dev) +{ + dprintk(CVP_INFO, "%s\n", __func__); + return 0; +} + +static const struct dev_pm_ops msm_cvp_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(msm_cvp_pm_suspend, msm_cvp_pm_resume) +}; + +MODULE_DEVICE_TABLE(of, msm_cvp_plat_match); + +static struct platform_driver msm_cvp_driver = { + .probe = msm_cvp_probe, + .remove = msm_cvp_remove, + .driver = { + .name = "msm_cvp", + .of_match_table = msm_cvp_plat_match, + .pm = &msm_cvp_pm_ops, + }, +}; + +static int __init msm_cvp_init(void) +{ + int rc = 0; + + cvp_driver = kzalloc(sizeof(*cvp_driver), GFP_KERNEL); + if (!cvp_driver) { + dprintk(CVP_ERR, + "Failed to allocate memroy for msm_cvp_drv\n"); + return -ENOMEM; + } + + INIT_LIST_HEAD(&cvp_driver->cores); + mutex_init(&cvp_driver->lock); + cvp_driver->debugfs_root = msm_cvp_debugfs_init_drv(); + if (!cvp_driver->debugfs_root) + dprintk(CVP_ERR, + "Failed to create debugfs for msm_cvp\n"); + + rc = platform_driver_register(&msm_cvp_driver); + if (rc) { + dprintk(CVP_ERR, + "Failed to register platform driver\n"); + debugfs_remove_recursive(cvp_driver->debugfs_root); + kfree(cvp_driver); + cvp_driver = NULL; + return rc; + } + + cvp_driver->msg_cache = KMEM_CACHE(cvp_session_msg, 0); + cvp_driver->frame_cache = KMEM_CACHE(msm_cvp_frame, 0); + cvp_driver->buf_cache = KMEM_CACHE(cvp_internal_buf, 0); + cvp_driver->smem_cache = KMEM_CACHE(msm_cvp_smem, 0); + + return rc; +} + +static void __exit msm_cvp_exit(void) +{ + cvp_dsp_device_exit(); + kmem_cache_destroy(cvp_driver->msg_cache); + kmem_cache_destroy(cvp_driver->frame_cache); + kmem_cache_destroy(cvp_driver->buf_cache); + kmem_cache_destroy(cvp_driver->smem_cache); + + platform_driver_unregister(&msm_cvp_driver); + debugfs_remove_recursive(cvp_driver->debugfs_root); + mutex_destroy(&cvp_driver->lock); + kfree(cvp_driver); + cvp_driver = NULL; +} + +module_init(msm_cvp_init); +module_exit(msm_cvp_exit); + +MODULE_LICENSE("GPL v2"); diff --git a/msm/eva/cvp_comm_def.h b/msm/eva/cvp_comm_def.h new file mode 100644 index 0000000000..1e590fdc6e --- /dev/null +++ b/msm/eva/cvp_comm_def.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _MSM_COMM_DEF_H_ +#define _MSM_COMM_DEF_H_ + +#include + +enum op_mode { + OP_NORMAL, + OP_DRAINING, + OP_FLUSH, + OP_INVALID, +}; + +enum queue_state { + QUEUE_INIT, + QUEUE_ACTIVE = 1, + QUEUE_STOP = 2, + QUEUE_INVALID, +}; +#endif diff --git a/msm/eva/cvp_core_hfi.c b/msm/eva/cvp_core_hfi.c new file mode 100644 index 0000000000..d6fae2f105 --- /dev/null +++ b/msm/eva/cvp_core_hfi.c @@ -0,0 +1,52 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#include +#include "msm_cvp_debug.h" +#include "cvp_hfi_api.h" +#include "cvp_core_hfi.h" + +struct cvp_hfi_device *cvp_hfi_initialize(enum msm_cvp_hfi_type hfi_type, + u32 device_id, struct msm_cvp_platform_resources *res, + hfi_cmd_response_callback callback) +{ + struct cvp_hfi_device *hdev = NULL; + int rc = 0; + + hdev = kzalloc(sizeof(struct cvp_hfi_device), GFP_KERNEL); + if (!hdev) { + dprintk(CVP_ERR, "%s: failed to allocate hdev\n", __func__); + return NULL; + } + + rc = cvp_iris_hfi_initialize(hdev, device_id, res, callback); + + if (rc) { + if (rc != -EPROBE_DEFER) + dprintk(CVP_ERR, "%s device init failed rc = %d", + __func__, rc); + goto err_hfi_init; + } + + return hdev; + +err_hfi_init: + kfree(hdev); + return ERR_PTR(rc); +} + +void cvp_hfi_deinitialize(enum msm_cvp_hfi_type hfi_type, + struct cvp_hfi_device *hdev) +{ + if (!hdev) { + dprintk(CVP_ERR, "%s invalid device %pK", __func__, hdev); + return; + } + + cvp_iris_hfi_delete_device(hdev->hfi_device_data); + + kfree(hdev); +} + diff --git a/msm/eva/cvp_core_hfi.h b/msm/eva/cvp_core_hfi.h new file mode 100644 index 0000000000..427f063503 --- /dev/null +++ b/msm/eva/cvp_core_hfi.h @@ -0,0 +1,271 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#ifndef __H_CVP_CORE_HFI_H__ +#define __H_CVP_CORE_HFI_H__ + +#include +#include +#include +#include +#include +#include "cvp_hfi_api.h" +#include "cvp_hfi_helper.h" +#include "cvp_hfi_api.h" +#include "cvp_hfi.h" +#include "msm_cvp_resources.h" +#include "hfi_packetization.h" + +#define HFI_MASK_QHDR_TX_TYPE 0xFF000000 +#define HFI_MASK_QHDR_RX_TYPE 0x00FF0000 +#define HFI_MASK_QHDR_PRI_TYPE 0x0000FF00 +#define HFI_MASK_QHDR_Q_ID_TYPE 0x000000FF +#define HFI_Q_ID_HOST_TO_CTRL_CMD_Q 0x00 +#define HFI_Q_ID_CTRL_TO_HOST_MSG_Q 0x01 +#define HFI_Q_ID_CTRL_TO_HOST_DEBUG_Q 0x02 +#define HFI_MASK_QHDR_STATUS 0x000000FF + +#define CVP_IFACEQ_NUMQ 3 +#define CVP_IFACEQ_CMDQ_IDX 0 +#define CVP_IFACEQ_MSGQ_IDX 1 +#define CVP_IFACEQ_DBGQ_IDX 2 +#define CVP_IFACEQ_MAX_BUF_COUNT 50 +#define CVP_IFACE_MAX_PARALLEL_CLNTS 16 +#define CVP_IFACEQ_DFLT_QHDR 0x01010000 + +#define CVP_MAX_NAME_LENGTH 64 +#define CVP_MAX_PC_SKIP_COUNT 10 +#define CVP_MAX_SUBCACHES 4 +#define CVP_MAX_SUBCACHE_SIZE 52 + +struct cvp_hfi_queue_table_header { + u32 qtbl_version; + u32 qtbl_size; + u32 qtbl_qhdr0_offset; + u32 qtbl_qhdr_size; + u32 qtbl_num_q; + u32 qtbl_num_active_q; + void *device_addr; + char name[256]; +}; + +struct cvp_hfi_queue_header { + u32 qhdr_status; + u32 qhdr_start_addr; + u32 qhdr_type; + u32 qhdr_q_size; + u32 qhdr_pkt_size; + u32 qhdr_pkt_drop_cnt; + u32 qhdr_rx_wm; + u32 qhdr_tx_wm; + u32 qhdr_rx_req; + u32 qhdr_tx_req; + u32 qhdr_rx_irq_status; + u32 qhdr_tx_irq_status; + u32 qhdr_read_idx; + u32 qhdr_write_idx; +}; + +struct cvp_hfi_mem_map_table { + u32 mem_map_num_entries; + u32 mem_map_table_base_addr; +}; + +struct cvp_hfi_mem_map { + u32 virtual_addr; + u32 physical_addr; + u32 size; + u32 attr; +}; + +#define CVP_IFACEQ_TABLE_SIZE (sizeof(struct cvp_hfi_queue_table_header) \ + + sizeof(struct cvp_hfi_queue_header) * CVP_IFACEQ_NUMQ) + +#define CVP_IFACEQ_QUEUE_SIZE (CVP_IFACEQ_MAX_PKT_SIZE * \ + CVP_IFACEQ_MAX_BUF_COUNT * CVP_IFACE_MAX_PARALLEL_CLNTS) + +#define CVP_IFACEQ_GET_QHDR_START_ADDR(ptr, i) \ + (void *)((ptr + sizeof(struct cvp_hfi_queue_table_header)) + \ + (i * sizeof(struct cvp_hfi_queue_header))) + +#define QDSS_SIZE 4096 +#define SFR_SIZE 4096 + +#define QUEUE_SIZE (CVP_IFACEQ_TABLE_SIZE + \ + (CVP_IFACEQ_QUEUE_SIZE * CVP_IFACEQ_NUMQ)) + +#define ALIGNED_QDSS_SIZE ALIGN(QDSS_SIZE, SZ_4K) +#define ALIGNED_SFR_SIZE ALIGN(SFR_SIZE, SZ_4K) +#define ALIGNED_QUEUE_SIZE ALIGN(QUEUE_SIZE, SZ_4K) +#define SHARED_QSIZE ALIGN(ALIGNED_SFR_SIZE + ALIGNED_QUEUE_SIZE + \ + ALIGNED_QDSS_SIZE, SZ_1M) + +struct cvp_mem_addr { + u32 align_device_addr; + u8 *align_virtual_addr; + u32 mem_size; + struct msm_cvp_smem mem_data; +}; + +struct cvp_iface_q_info { + spinlock_t hfi_lock; + void *q_hdr; + struct cvp_mem_addr q_array; +}; + +/* + * These are helper macros to iterate over various lists within + * iris_hfi_device->res. The intention is to cut down on a lot of boiler-plate + * code + */ + +/* Read as "for each 'thing' in a set of 'thingies'" */ +#define iris_hfi_for_each_thing(__device, __thing, __thingy) \ + iris_hfi_for_each_thing_continue(__device, __thing, __thingy, 0) + +#define iris_hfi_for_each_thing_reverse(__device, __thing, __thingy) \ + iris_hfi_for_each_thing_reverse_continue(__device, __thing, __thingy, \ + (__device)->res->__thingy##_set.count - 1) + +/* TODO: the __from parameter technically not required since we can figure it + * out with some pointer magic (i.e. __thing - __thing##_tbl[0]). If this macro + * sees extensive use, probably worth cleaning it up but for now omitting it + * since it introduces unnecessary complexity. + */ +#define iris_hfi_for_each_thing_continue(__device, __thing, __thingy, __from) \ + for (__thing = &(__device)->res->\ + __thingy##_set.__thingy##_tbl[__from]; \ + __thing < &(__device)->res->__thingy##_set.__thingy##_tbl[0] + \ + ((__device)->res->__thingy##_set.count - __from); \ + ++__thing) + +#define iris_hfi_for_each_thing_reverse_continue(__device, __thing, __thingy, \ + __from) \ + for (__thing = &(__device)->res->\ + __thingy##_set.__thingy##_tbl[__from]; \ + __thing >= &(__device)->res->__thingy##_set.__thingy##_tbl[0]; \ + --__thing) + +/* Regular set helpers */ +#define iris_hfi_for_each_regulator(__device, __rinfo) \ + iris_hfi_for_each_thing(__device, __rinfo, regulator) + +#define iris_hfi_for_each_regulator_reverse(__device, __rinfo) \ + iris_hfi_for_each_thing_reverse(__device, __rinfo, regulator) + +#define iris_hfi_for_each_regulator_reverse_continue(__device, __rinfo, \ + __from) \ + iris_hfi_for_each_thing_reverse_continue(__device, __rinfo, \ + regulator, __from) + +/* Clock set helpers */ +#define iris_hfi_for_each_clock(__device, __cinfo) \ + iris_hfi_for_each_thing(__device, __cinfo, clock) + +#define iris_hfi_for_each_clock_reverse(__device, __cinfo) \ + iris_hfi_for_each_thing_reverse(__device, __cinfo, clock) + +#define iris_hfi_for_each_clock_reverse_continue(__device, __rinfo, \ + __from) \ + iris_hfi_for_each_thing_reverse_continue(__device, __rinfo, \ + clock, __from) + +/* Bus set helpers */ +#define iris_hfi_for_each_bus(__device, __binfo) \ + iris_hfi_for_each_thing(__device, __binfo, bus) +#define iris_hfi_for_each_bus_reverse(__device, __binfo) \ + iris_hfi_for_each_thing_reverse(__device, __binfo, bus) + +/* Subcache set helpers */ +#define iris_hfi_for_each_subcache(__device, __sinfo) \ + iris_hfi_for_each_thing(__device, __sinfo, subcache) +#define iris_hfi_for_each_subcache_reverse(__device, __sinfo) \ + iris_hfi_for_each_thing_reverse(__device, __sinfo, subcache) + +#define call_iris_op(d, op, args...) \ + (((d) && (d)->vpu_ops && (d)->vpu_ops->op) ? \ + ((d)->vpu_ops->op(args)):0) + +struct cvp_hal_data { + u32 irq; + phys_addr_t firmware_base; + u8 __iomem *register_base; + u8 __iomem *gcc_reg_base; + u32 register_size; + u32 gcc_reg_size; +}; + +struct iris_resources { + struct msm_cvp_fw fw; +}; + +enum iris_hfi_state { + IRIS_STATE_DEINIT = 1, + IRIS_STATE_INIT, +}; + +enum reset_state { + INIT = 1, + ASSERT, + DEASSERT, +}; + +struct iris_hfi_device; + +struct iris_hfi_vpu_ops { + void (*interrupt_init)(struct iris_hfi_device *ptr); + void (*setup_dsp_uc_memmap)(struct iris_hfi_device *device); + void (*clock_config_on_enable)(struct iris_hfi_device *device); + int (*reset_ahb2axi_bridge)(struct iris_hfi_device *device); + void (*power_off)(struct iris_hfi_device *device); + void (*noc_error_info)(struct iris_hfi_device *device); +}; + +struct iris_hfi_device { + struct list_head sess_head; + u32 version; + u32 intr_status; + u32 device_id; + u32 clk_freq; + u32 last_packet_type; + unsigned long clk_bitrate; + unsigned long scaled_rate; + struct msm_cvp_gov_data bus_vote; + bool power_enabled; + bool reg_dumped; + struct mutex lock; + msm_cvp_callback callback; + struct cvp_mem_addr iface_q_table; + struct cvp_mem_addr dsp_iface_q_table; + struct cvp_mem_addr qdss; + struct cvp_mem_addr sfr; + struct cvp_mem_addr mem_addr; + struct cvp_iface_q_info iface_queues[CVP_IFACEQ_NUMQ]; + struct cvp_iface_q_info dsp_iface_queues[CVP_IFACEQ_NUMQ]; + struct cvp_hal_data *cvp_hal_data; + struct workqueue_struct *cvp_workq; + struct workqueue_struct *iris_pm_workq; + int spur_count; + int reg_count; + struct iris_resources resources; + struct msm_cvp_platform_resources *res; + enum iris_hfi_state state; + struct cvp_hfi_packetization_ops *pkt_ops; + enum hfi_packetization_type packetization_type; + struct msm_cvp_cb_info *response_pkt; + u8 *raw_packet; + struct pm_qos_request qos; + unsigned int skip_pc_count; + struct msm_cvp_capability *sys_init_capabilities; + struct iris_hfi_vpu_ops *vpu_ops; +}; + +void cvp_iris_hfi_delete_device(void *device); + +int cvp_iris_hfi_initialize(struct cvp_hfi_device *hdev, u32 device_id, + struct msm_cvp_platform_resources *res, + hfi_cmd_response_callback callback); + +#endif diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c new file mode 100644 index 0000000000..10cd7b23c4 --- /dev/null +++ b/msm/eva/cvp_hfi.c @@ -0,0 +1,4680 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hfi_packetization.h" +#include "msm_cvp_debug.h" +#include "cvp_core_hfi.h" +#include "cvp_hfi_helper.h" +#include "cvp_hfi_io.h" +#include "msm_cvp_dsp.h" + +#define FIRMWARE_SIZE 0X00A00000 +#define REG_ADDR_OFFSET_BITMASK 0x000FFFFF +#define QDSS_IOVA_START 0x80001000 +#define MIN_PAYLOAD_SIZE 3 + +const struct msm_cvp_hfi_defs cvp_hfi_defs[] = { + { + .size = HFI_DFS_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DFS_CONFIG, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_SESSION_DFS_CONFIG_CMD_DONE, + }, + { + .size = HFI_DFS_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DFS_FRAME, + .buf_offset = HFI_DFS_FRAME_BUFFERS_OFFSET, + .buf_num = HFI_DFS_BUF_NUM, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_DME_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DME_CONFIG, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_SESSION_DME_CONFIG_CMD_DONE, + }, + { + .size = HFI_DME_BASIC_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DME_BASIC_CONFIG, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_SESSION_DME_BASIC_CONFIG_CMD_DONE, + }, + { + .size = HFI_DME_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DME_FRAME, + .buf_offset = HFI_DME_FRAME_BUFFERS_OFFSET, + .buf_num = HFI_DME_BUF_NUM, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_PERSIST_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS, + .buf_offset = HFI_PERSIST_BUFFERS_OFFSET, + .buf_num = HFI_PERSIST_BUF_NUM, + .resp = HAL_SESSION_PERSIST_SET_DONE, + }, + { + .size = 0xffffffff, + .type = HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_SESSION_PERSIST_REL_DONE, + }, + { + .size = HFI_DS_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DS, + .buf_offset = HFI_DS_BUFFERS_OFFSET, + .buf_num = HFI_DS_BUF_NUM, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_OF_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_CV_TME_CONFIG, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_SESSION_TME_CONFIG_CMD_DONE, + }, + { + .size = HFI_OF_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_CV_TME_FRAME, + .buf_offset = HFI_OF_BUFFERS_OFFSET, + .buf_num = HFI_OF_BUF_NUM, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_ODT_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_CV_ODT_CONFIG, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_SESSION_ODT_CONFIG_CMD_DONE, + }, + { + .size = HFI_ODT_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_CV_ODT_FRAME, + .buf_offset = HFI_ODT_BUFFERS_OFFSET, + .buf_num = HFI_ODT_BUF_NUM, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_OD_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_CV_OD_CONFIG, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_SESSION_OD_CONFIG_CMD_DONE, + }, + { + .size = HFI_OD_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_CV_OD_FRAME, + .buf_offset = HFI_OD_BUFFERS_OFFSET, + .buf_num = HFI_OD_BUF_NUM, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_NCC_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_NCC_CONFIG, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_SESSION_NCC_CONFIG_CMD_DONE, + }, + { + .size = HFI_NCC_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_NCC_FRAME, + .buf_offset = HFI_NCC_BUFFERS_OFFSET, + .buf_num = HFI_NCC_BUF_NUM, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_ICA_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_ICA_CONFIG, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_SESSION_ICA_CONFIG_CMD_DONE, + }, + { + .size = HFI_ICA_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_ICA_FRAME, + .buf_offset = HFI_ICA_BUFFERS_OFFSET, + .buf_num = HFI_ICA_BUF_NUM, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_HCD_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_HCD_CONFIG, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_SESSION_HCD_CONFIG_CMD_DONE, + }, + { + .size = HFI_HCD_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_HCD_FRAME, + .buf_offset = HFI_HCD_BUFFERS_OFFSET, + .buf_num = HFI_HCD_BUF_NUM, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_DCM_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DC_CONFIG, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_SESSION_DC_CONFIG_CMD_DONE, + }, + { + .size = HFI_DCM_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DC_FRAME, + .buf_offset = HFI_DCM_BUFFERS_OFFSET, + .buf_num = HFI_DCM_BUF_NUM, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_DCM_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DCM_CONFIG, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_SESSION_DCM_CONFIG_CMD_DONE, + }, + { + .size = HFI_DCM_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DCM_FRAME, + .buf_offset = HFI_DCM_BUFFERS_OFFSET, + .buf_num = HFI_DCM_BUF_NUM, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_PYS_HCD_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_PYS_HCD_CONFIG, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_SESSION_PYS_HCD_CONFIG_CMD_DONE, + }, + { + .size = HFI_PYS_HCD_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_PYS_HCD_FRAME, + .buf_offset = HFI_PYS_HCD_BUFFERS_OFFSET, + .buf_num = HFI_PYS_HCD_BUF_NUM, + .resp = HAL_NO_RESP, + }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_SESSION_MODEL_BUF_CMD_DONE, + }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_FD_CONFIG, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_SESSION_FD_CONFIG_CMD_DONE, + }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_FD_FRAME, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_NO_RESP, + }, + +}; + +struct cvp_tzbsp_memprot { + u32 cp_start; + u32 cp_size; + u32 cp_nonpixel_start; + u32 cp_nonpixel_size; +}; + +#define TZBSP_PIL_SET_STATE 0xA +#define TZBSP_CVP_PAS_ID 26 + +/* Poll interval in uS */ +#define POLL_INTERVAL_US 50 + +enum tzbsp_subsys_state { + TZ_SUBSYS_STATE_SUSPEND = 0, + TZ_SUBSYS_STATE_RESUME = 1, + TZ_SUBSYS_STATE_RESTORE_THRESHOLD = 2, +}; + +const struct msm_cvp_gov_data CVP_DEFAULT_BUS_VOTE = { + .data = NULL, + .data_count = 0, +}; + +const int cvp_max_packets = 32; + +static void iris_hfi_pm_handler(struct work_struct *work); +static DECLARE_DELAYED_WORK(iris_hfi_pm_work, iris_hfi_pm_handler); +static inline int __resume(struct iris_hfi_device *device); +static inline int __suspend(struct iris_hfi_device *device); +static int __disable_regulators(struct iris_hfi_device *device); +static int __enable_regulators(struct iris_hfi_device *device); +static inline int __prepare_enable_clks(struct iris_hfi_device *device); +static inline void __disable_unprepare_clks(struct iris_hfi_device *device); +static void __flush_debug_queue(struct iris_hfi_device *device, u8 *packet); +static int __initialize_packetization(struct iris_hfi_device *device); +static struct cvp_hal_session *__get_session(struct iris_hfi_device *device, + u32 session_id); +static bool __is_session_valid(struct iris_hfi_device *device, + struct cvp_hal_session *session, const char *func); +static int __set_clocks(struct iris_hfi_device *device, u32 freq); +static int __iface_cmdq_write(struct iris_hfi_device *device, + void *pkt); +static int __load_fw(struct iris_hfi_device *device); +static void __unload_fw(struct iris_hfi_device *device); +static int __tzbsp_set_cvp_state(enum tzbsp_subsys_state state); +static int __enable_subcaches(struct iris_hfi_device *device); +static int __set_subcaches(struct iris_hfi_device *device); +static int __release_subcaches(struct iris_hfi_device *device); +static int __disable_subcaches(struct iris_hfi_device *device); +static int __power_collapse(struct iris_hfi_device *device, bool force); +static int iris_hfi_noc_error_info(void *dev); + +static void interrupt_init_iris2(struct iris_hfi_device *device); +static void setup_dsp_uc_memmap_vpu5(struct iris_hfi_device *device); +static void clock_config_on_enable_vpu5(struct iris_hfi_device *device); +static int reset_ahb2axi_bridge(struct iris_hfi_device *device); +static void power_off_iris2(struct iris_hfi_device *device); + +static int __set_ubwc_config(struct iris_hfi_device *device); +static void __noc_error_info_iris2(struct iris_hfi_device *device); + +static struct iris_hfi_vpu_ops iris2_ops = { + .interrupt_init = interrupt_init_iris2, + .setup_dsp_uc_memmap = setup_dsp_uc_memmap_vpu5, + .clock_config_on_enable = clock_config_on_enable_vpu5, + .reset_ahb2axi_bridge = reset_ahb2axi_bridge, + .power_off = power_off_iris2, + .noc_error_info = __noc_error_info_iris2, +}; + +/** + * Utility function to enforce some of our assumptions. Spam calls to this + * in hotspots in code to double check some of the assumptions that we hold. + */ +static inline void __strict_check(struct iris_hfi_device *device) +{ + msm_cvp_res_handle_fatal_hw_error(device->res, + !mutex_is_locked(&device->lock)); +} + +static inline void __set_state(struct iris_hfi_device *device, + enum iris_hfi_state state) +{ + device->state = state; +} + +static inline bool __core_in_valid_state(struct iris_hfi_device *device) +{ + return device->state != IRIS_STATE_DEINIT; +} + +static inline bool is_sys_cache_present(struct iris_hfi_device *device) +{ + return device->res->sys_cache_present; +} + +#define ROW_SIZE 32 + +int get_pkt_index(struct cvp_hal_session_cmd_pkt *hdr) +{ + int i, pkt_num = ARRAY_SIZE(cvp_hfi_defs); + + for (i = 0; i < pkt_num; i++) + if (cvp_hfi_defs[i].type == hdr->packet_type) + return i; + + return -EINVAL; +} + +int get_hfi_version(void) +{ + struct msm_cvp_core *core; + struct iris_hfi_device *hfi; + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + hfi = (struct iris_hfi_device *)core->device->hfi_device_data; + + return hfi->version; +} + +unsigned int get_msg_size(void) +{ + return sizeof(struct cvp_hfi_msg_session_hdr); +} + +unsigned int get_msg_session_id(void *msg) +{ + struct cvp_hfi_msg_session_hdr *hdr = + (struct cvp_hfi_msg_session_hdr *)msg; + + return hdr->session_id; +} + +unsigned int get_msg_errorcode(void *msg) +{ + struct cvp_hfi_msg_session_hdr *hdr = + (struct cvp_hfi_msg_session_hdr *)msg; + + return hdr->error_type; +} + +int get_msg_opconfigs(void *msg, unsigned int *session_id, + unsigned int *error_type, unsigned int *config_id) +{ + struct cvp_hfi_msg_session_op_cfg_packet *cfg = + (struct cvp_hfi_msg_session_op_cfg_packet *)msg; + + *session_id = cfg->session_id; + *error_type = cfg->error_type; + *config_id = cfg->op_conf_id; + return 0; +} + +int get_signal_from_pkt_type(unsigned int type) +{ + int i, pkt_num = ARRAY_SIZE(cvp_hfi_defs); + + for (i = 0; i < pkt_num; i++) + if (cvp_hfi_defs[i].type == type) + return cvp_hfi_defs[i].resp; + + return -EINVAL; +} + +static void __dump_packet(u8 *packet, enum cvp_msg_prio log_level) +{ + u32 c = 0, packet_size = *(u32 *)packet; + /* + * row must contain enough for 0xdeadbaad * 8 to be converted into + * "de ad ba ab " * 8 + '\0' + */ + char row[3 * ROW_SIZE]; + + for (c = 0; c * ROW_SIZE < packet_size; ++c) { + int bytes_to_read = ((c + 1) * ROW_SIZE > packet_size) ? + packet_size % ROW_SIZE : ROW_SIZE; + hex_dump_to_buffer(packet + c * ROW_SIZE, bytes_to_read, + ROW_SIZE, 4, row, sizeof(row), false); + dprintk(log_level, "%s\n", row); + } +} + +static int __dsp_suspend(struct iris_hfi_device *device, bool force, u32 flags) +{ + int rc; + struct cvp_hal_session *temp; + + if (msm_cvp_dsp_disable) + return 0; + + list_for_each_entry(temp, &device->sess_head, list) { + /* if forceful suspend, don't check session pause info */ + if (force) + continue; + + /* don't suspend if cvp session is not paused */ + if (!(temp->flags & SESSION_PAUSE)) { + dprintk(CVP_DSP, + "%s: cvp session %x not paused\n", + __func__, hash32_ptr(temp)); + return -EBUSY; + } + } + + dprintk(CVP_DSP, "%s: suspend dsp\n", __func__); + rc = cvp_dsp_suspend(flags); + if (rc) { + dprintk(CVP_ERR, "%s: dsp suspend failed with error %d\n", + __func__, rc); + return -EINVAL; + } + + dprintk(CVP_DSP, "%s: dsp suspended\n", __func__); + return 0; +} + +static int __dsp_resume(struct iris_hfi_device *device, u32 flags) +{ + int rc; + + if (msm_cvp_dsp_disable) + return 0; + + dprintk(CVP_DSP, "%s: resume dsp\n", __func__); + rc = cvp_dsp_resume(flags); + if (rc) { + dprintk(CVP_ERR, + "%s: dsp resume failed with error %d\n", + __func__, rc); + return rc; + } + + dprintk(CVP_DSP, "%s: dsp resumed\n", __func__); + return rc; +} + +static int __dsp_shutdown(struct iris_hfi_device *device, u32 flags) +{ + int rc; + + if (msm_cvp_dsp_disable) + return 0; + + dprintk(CVP_DSP, "%s: shutdown dsp\n", __func__); + rc = cvp_dsp_shutdown(flags); + if (rc) { + dprintk(CVP_ERR, + "%s: dsp shutdown failed with error %d\n", + __func__, rc); + WARN_ON(1); + } + + dprintk(CVP_DSP, "%s: dsp shutdown successful\n", __func__); + return rc; +} + +static int __acquire_regulator(struct regulator_info *rinfo, + struct iris_hfi_device *device) +{ + int rc = 0; + + if (rinfo->has_hw_power_collapse) { + rc = regulator_set_mode(rinfo->regulator, + REGULATOR_MODE_NORMAL); + if (rc) { + /* + * This is somewhat fatal, but nothing we can do + * about it. We can't disable the regulator w/o + * getting it back under s/w control + */ + dprintk(CVP_WARN, + "Failed to acquire regulator control: %s\n", + rinfo->name); + } else { + + dprintk(CVP_PWR, + "Acquire regulator control from HW: %s\n", + rinfo->name); + + } + } + + if (!regulator_is_enabled(rinfo->regulator)) { + dprintk(CVP_WARN, "Regulator is not enabled %s\n", + rinfo->name); + msm_cvp_res_handle_fatal_hw_error(device->res, true); + } + + return rc; +} + +static int __hand_off_regulator(struct regulator_info *rinfo) +{ + int rc = 0; + + if (rinfo->has_hw_power_collapse) { + rc = regulator_set_mode(rinfo->regulator, + REGULATOR_MODE_FAST); + if (rc) { + dprintk(CVP_WARN, + "Failed to hand off regulator control: %s\n", + rinfo->name); + } else { + dprintk(CVP_PWR, + "Hand off regulator control to HW: %s\n", + rinfo->name); + } + } + + return rc; +} + +static int __hand_off_regulators(struct iris_hfi_device *device) +{ + struct regulator_info *rinfo; + int rc = 0, c = 0; + + iris_hfi_for_each_regulator(device, rinfo) { + rc = __hand_off_regulator(rinfo); + /* + * If one regulator hand off failed, driver should take + * the control for other regulators back. + */ + if (rc) + goto err_reg_handoff_failed; + c++; + } + + return rc; +err_reg_handoff_failed: + iris_hfi_for_each_regulator_reverse_continue(device, rinfo, c) + __acquire_regulator(rinfo, device); + + return rc; +} + +static int __write_queue(struct cvp_iface_q_info *qinfo, u8 *packet, + bool *rx_req_is_set) +{ + struct cvp_hfi_queue_header *queue; + u32 packet_size_in_words, new_write_idx; + u32 empty_space, read_idx, write_idx; + u32 *write_ptr; + + if (!qinfo || !packet) { + dprintk(CVP_ERR, "Invalid Params\n"); + return -EINVAL; + } else if (!qinfo->q_array.align_virtual_addr) { + dprintk(CVP_WARN, "Queues have already been freed\n"); + return -EINVAL; + } + + queue = (struct cvp_hfi_queue_header *) qinfo->q_hdr; + if (!queue) { + dprintk(CVP_ERR, "queue not present\n"); + return -ENOENT; + } + + if (msm_cvp_debug & CVP_PKT) { + dprintk(CVP_PKT, "%s: %pK\n", __func__, qinfo); + __dump_packet(packet, CVP_PKT); + } + + packet_size_in_words = (*(u32 *)packet) >> 2; + if (!packet_size_in_words || packet_size_in_words > + qinfo->q_array.mem_size>>2) { + dprintk(CVP_ERR, "Invalid packet size\n"); + return -ENODATA; + } + + spin_lock(&qinfo->hfi_lock); + read_idx = queue->qhdr_read_idx; + write_idx = queue->qhdr_write_idx; + + empty_space = (write_idx >= read_idx) ? + ((qinfo->q_array.mem_size>>2) - (write_idx - read_idx)) : + (read_idx - write_idx); + if (empty_space <= packet_size_in_words) { + queue->qhdr_tx_req = 1; + spin_unlock(&qinfo->hfi_lock); + dprintk(CVP_ERR, "Insufficient size (%d) to write (%d)\n", + empty_space, packet_size_in_words); + return -ENOTEMPTY; + } + + queue->qhdr_tx_req = 0; + + new_write_idx = write_idx + packet_size_in_words; + write_ptr = (u32 *)((qinfo->q_array.align_virtual_addr) + + (write_idx << 2)); + if (write_ptr < (u32 *)qinfo->q_array.align_virtual_addr || + write_ptr > (u32 *)(qinfo->q_array.align_virtual_addr + + qinfo->q_array.mem_size)) { + spin_unlock(&qinfo->hfi_lock); + dprintk(CVP_ERR, "Invalid write index\n"); + return -ENODATA; + } + + if (new_write_idx < (qinfo->q_array.mem_size >> 2)) { + memcpy(write_ptr, packet, packet_size_in_words << 2); + } else { + new_write_idx -= qinfo->q_array.mem_size >> 2; + memcpy(write_ptr, packet, (packet_size_in_words - + new_write_idx) << 2); + memcpy((void *)qinfo->q_array.align_virtual_addr, + packet + ((packet_size_in_words - new_write_idx) << 2), + new_write_idx << 2); + } + + /* + * Memory barrier to make sure packet is written before updating the + * write index + */ + mb(); + queue->qhdr_write_idx = new_write_idx; + if (rx_req_is_set) + *rx_req_is_set = queue->qhdr_rx_req == 1; + /* + * Memory barrier to make sure write index is updated before an + * interrupt is raised. + */ + mb(); + spin_unlock(&qinfo->hfi_lock); + return 0; +} + +static int __read_queue(struct cvp_iface_q_info *qinfo, u8 *packet, + u32 *pb_tx_req_is_set) +{ + struct cvp_hfi_queue_header *queue; + u32 packet_size_in_words, new_read_idx; + u32 *read_ptr; + u32 receive_request = 0; + u32 read_idx, write_idx; + int rc = 0; + + if (!qinfo || !packet || !pb_tx_req_is_set) { + dprintk(CVP_ERR, "Invalid Params\n"); + return -EINVAL; + } else if (!qinfo->q_array.align_virtual_addr) { + dprintk(CVP_WARN, "Queues have already been freed\n"); + return -EINVAL; + } + + /* + * Memory barrier to make sure data is valid before + *reading it + */ + mb(); + queue = (struct cvp_hfi_queue_header *) qinfo->q_hdr; + + if (!queue) { + dprintk(CVP_ERR, "Queue memory is not allocated\n"); + return -ENOMEM; + } + + /* + * Do not set receive request for debug queue, if set, + * Iris generates interrupt for debug messages even + * when there is no response message available. + * In general debug queue will not become full as it + * is being emptied out for every interrupt from Iris. + * Iris will anyway generates interrupt if it is full. + */ + spin_lock(&qinfo->hfi_lock); + if (queue->qhdr_type & HFI_Q_ID_CTRL_TO_HOST_MSG_Q) + receive_request = 1; + + read_idx = queue->qhdr_read_idx; + write_idx = queue->qhdr_write_idx; + + if (read_idx == write_idx) { + queue->qhdr_rx_req = receive_request; + /* + * mb() to ensure qhdr is updated in main memory + * so that iris reads the updated header values + */ + mb(); + *pb_tx_req_is_set = 0; + if (write_idx != queue->qhdr_write_idx) { + queue->qhdr_rx_req = 0; + } else { + spin_unlock(&qinfo->hfi_lock); + dprintk(CVP_HFI, + "%s queue is empty, rx_req = %u, tx_req = %u, read_idx = %u\n", + receive_request ? "message" : "debug", + queue->qhdr_rx_req, queue->qhdr_tx_req, + queue->qhdr_read_idx); + return -ENODATA; + } + } + + read_ptr = (u32 *)((qinfo->q_array.align_virtual_addr) + + (read_idx << 2)); + if (read_ptr < (u32 *)qinfo->q_array.align_virtual_addr || + read_ptr > (u32 *)(qinfo->q_array.align_virtual_addr + + qinfo->q_array.mem_size - sizeof(*read_ptr))) { + spin_unlock(&qinfo->hfi_lock); + dprintk(CVP_ERR, "Invalid read index\n"); + return -ENODATA; + } + + packet_size_in_words = (*read_ptr) >> 2; + if (!packet_size_in_words) { + spin_unlock(&qinfo->hfi_lock); + dprintk(CVP_ERR, "Zero packet size\n"); + return -ENODATA; + } + + new_read_idx = read_idx + packet_size_in_words; + if (((packet_size_in_words << 2) <= CVP_IFACEQ_VAR_HUGE_PKT_SIZE) + && read_idx <= (qinfo->q_array.mem_size >> 2)) { + if (new_read_idx < (qinfo->q_array.mem_size >> 2)) { + memcpy(packet, read_ptr, + packet_size_in_words << 2); + } else { + new_read_idx -= (qinfo->q_array.mem_size >> 2); + memcpy(packet, read_ptr, + (packet_size_in_words - new_read_idx) << 2); + memcpy(packet + ((packet_size_in_words - + new_read_idx) << 2), + (u8 *)qinfo->q_array.align_virtual_addr, + new_read_idx << 2); + } + } else { + dprintk(CVP_WARN, + "BAD packet received, read_idx: %#x, pkt_size: %d\n", + read_idx, packet_size_in_words << 2); + dprintk(CVP_WARN, "Dropping this packet\n"); + new_read_idx = write_idx; + rc = -ENODATA; + } + + if (new_read_idx != queue->qhdr_write_idx) + queue->qhdr_rx_req = 0; + else + queue->qhdr_rx_req = receive_request; + queue->qhdr_read_idx = new_read_idx; + /* + * mb() to ensure qhdr is updated in main memory + * so that iris reads the updated header values + */ + mb(); + + *pb_tx_req_is_set = (queue->qhdr_tx_req == 1) ? 1 : 0; + + spin_unlock(&qinfo->hfi_lock); + + if ((msm_cvp_debug & CVP_PKT) && + !(queue->qhdr_type & HFI_Q_ID_CTRL_TO_HOST_DEBUG_Q)) { + dprintk(CVP_PKT, "%s: %pK\n", __func__, qinfo); + __dump_packet(packet, CVP_PKT); + } + + return rc; +} + +static int __smem_alloc(struct iris_hfi_device *dev, struct cvp_mem_addr *mem, + u32 size, u32 align, u32 flags) +{ + struct msm_cvp_smem *alloc = &mem->mem_data; + int rc = 0; + + if (!dev || !mem || !size) { + dprintk(CVP_ERR, "Invalid Params\n"); + return -EINVAL; + } + + dprintk(CVP_INFO, "start to alloc size: %d, flags: %d\n", size, flags); + rc = msm_cvp_smem_alloc(size, align, flags, 1, (void *)dev->res, alloc); + if (rc) { + dprintk(CVP_ERR, "Alloc failed\n"); + rc = -ENOMEM; + goto fail_smem_alloc; + } + + dprintk(CVP_MEM, "%s: ptr = %pK, size = %d\n", __func__, + alloc->kvaddr, size); + + mem->mem_size = alloc->size; + mem->align_virtual_addr = alloc->kvaddr; + mem->align_device_addr = alloc->device_addr; + + return rc; +fail_smem_alloc: + return rc; +} + +static void __smem_free(struct iris_hfi_device *dev, struct msm_cvp_smem *mem) +{ + if (!dev || !mem) { + dprintk(CVP_ERR, "invalid param %pK %pK\n", dev, mem); + return; + } + + msm_cvp_smem_free(mem); +} + +static void __write_register(struct iris_hfi_device *device, + u32 reg, u32 value) +{ + u32 hwiosymaddr = reg; + u8 *base_addr; + + if (!device) { + dprintk(CVP_ERR, "Invalid params: %pK\n", device); + return; + } + + __strict_check(device); + + if (!device->power_enabled) { + dprintk(CVP_WARN, + "HFI Write register failed : Power is OFF\n"); + msm_cvp_res_handle_fatal_hw_error(device->res, true); + return; + } + + base_addr = device->cvp_hal_data->register_base; + dprintk(CVP_REG, "Base addr: %pK, written to: %#x, Value: %#x...\n", + base_addr, hwiosymaddr, value); + base_addr += hwiosymaddr; + writel_relaxed(value, base_addr); + + /* + * Memory barrier to make sure value is written into the register. + */ + wmb(); +} + +static int __read_register(struct iris_hfi_device *device, u32 reg) +{ + int rc = 0; + u8 *base_addr; + + if (!device) { + dprintk(CVP_ERR, "Invalid params: %pK\n", device); + return -EINVAL; + } + + __strict_check(device); + + if (!device->power_enabled) { + dprintk(CVP_WARN, + "HFI Read register failed : Power is OFF\n"); + msm_cvp_res_handle_fatal_hw_error(device->res, true); + return -EINVAL; + } + + base_addr = device->cvp_hal_data->register_base; + + rc = readl_relaxed(base_addr + reg); + /* + * Memory barrier to make sure value is read correctly from the + * register. + */ + rmb(); + dprintk(CVP_REG, "Base addr: %pK, read from: %#x, value: %#x...\n", + base_addr, reg, rc); + + return rc; +} + +static void __set_registers(struct iris_hfi_device *device) +{ + struct reg_set *reg_set; + int i; + + if (!device->res) { + dprintk(CVP_ERR, + "device resources null, cannot set registers\n"); + return; + } + + reg_set = &device->res->reg_set; + for (i = 0; i < reg_set->count; i++) { + __write_register(device, reg_set->reg_tbl[i].reg, + reg_set->reg_tbl[i].value); + dprintk(CVP_REG, "write_reg offset=%x, val=%x\n", + reg_set->reg_tbl[i].reg, + reg_set->reg_tbl[i].value); + } +} + +/* + * The existence of this function is a hack for 8996 (or certain Iris versions) + * to overcome a hardware bug. Whenever the GDSCs momentarily power collapse + * (after calling __hand_off_regulators()), the values of the threshold + * registers (typically programmed by TZ) are incorrectly reset. As a result + * reprogram these registers at certain agreed upon points. + */ +static void __set_threshold_registers(struct iris_hfi_device *device) +{ + u32 version = __read_register(device, CVP_WRAPPER_HW_VERSION); + + version &= ~GENMASK(15, 0); + if (version != (0x3 << 28 | 0x43 << 16)) + return; + + if (__tzbsp_set_cvp_state(TZ_SUBSYS_STATE_RESTORE_THRESHOLD)) + dprintk(CVP_ERR, "Failed to restore threshold values\n"); +} + +static int __unvote_buses(struct iris_hfi_device *device) +{ + int rc = 0; + struct bus_info *bus = NULL; + + kfree(device->bus_vote.data); + device->bus_vote.data = NULL; + device->bus_vote.data_count = 0; + + iris_hfi_for_each_bus(device, bus) { + rc = icc_set_bw(bus->client, 0, 0); + if (rc) { + dprintk(CVP_ERR, + "%s: Failed unvoting bus\n", __func__); + goto err_unknown_device; + } + } + +err_unknown_device: + return rc; +} + +static int __vote_buses(struct iris_hfi_device *device, + struct cvp_bus_vote_data *data, int num_data) +{ + int rc = 0; + struct bus_info *bus = NULL; + struct cvp_bus_vote_data *new_data = NULL; + + if (!num_data) { + dprintk(CVP_PWR, "No vote data available\n"); + goto no_data_count; + } else if (!data) { + dprintk(CVP_ERR, "Invalid voting data\n"); + return -EINVAL; + } + + new_data = kmemdup(data, num_data * sizeof(*new_data), GFP_KERNEL); + if (!new_data) { + dprintk(CVP_ERR, "Can't alloc memory to cache bus votes\n"); + rc = -ENOMEM; + goto err_no_mem; + } + +no_data_count: + kfree(device->bus_vote.data); + device->bus_vote.data = new_data; + device->bus_vote.data_count = num_data; + + iris_hfi_for_each_bus(device, bus) { + if (bus) { + rc = icc_set_bw(bus->client, bus->range[1], 0); + if (rc) + dprintk(CVP_ERR, + "Failed voting bus %s to ab %u\n", + bus->name, bus->range[1]*1000); + } + } + +err_no_mem: + return rc; +} + +static int iris_hfi_vote_buses(void *dev, struct cvp_bus_vote_data *d, int n) +{ + int rc = 0; + struct iris_hfi_device *device = dev; + + if (!device) + return -EINVAL; + + mutex_lock(&device->lock); + rc = __vote_buses(device, d, n); + mutex_unlock(&device->lock); + + return rc; + +} + +static int __core_set_resource(struct iris_hfi_device *device, + struct cvp_resource_hdr *resource_hdr, void *resource_value) +{ + struct cvp_hfi_cmd_sys_set_resource_packet *pkt; + u8 packet[CVP_IFACEQ_VAR_SMALL_PKT_SIZE]; + int rc = 0; + + if (!device || !resource_hdr || !resource_value) { + dprintk(CVP_ERR, "set_res: Invalid Params\n"); + return -EINVAL; + } + + pkt = (struct cvp_hfi_cmd_sys_set_resource_packet *) packet; + + rc = call_hfi_pkt_op(device, sys_set_resource, + pkt, resource_hdr, resource_value); + if (rc) { + dprintk(CVP_ERR, "set_res: failed to create packet\n"); + goto err_create_pkt; + } + + rc = __iface_cmdq_write(device, pkt); + if (rc) + rc = -ENOTEMPTY; + +err_create_pkt: + return rc; +} + +static int __core_release_resource(struct iris_hfi_device *device, + struct cvp_resource_hdr *resource_hdr) +{ + struct cvp_hfi_cmd_sys_release_resource_packet *pkt; + u8 packet[CVP_IFACEQ_VAR_SMALL_PKT_SIZE]; + int rc = 0; + + if (!device || !resource_hdr) { + dprintk(CVP_ERR, "release_res: Invalid Params\n"); + return -EINVAL; + } + + pkt = (struct cvp_hfi_cmd_sys_release_resource_packet *) packet; + + rc = call_hfi_pkt_op(device, sys_release_resource, + pkt, resource_hdr); + + if (rc) { + dprintk(CVP_ERR, "release_res: failed to create packet\n"); + goto err_create_pkt; + } + + rc = __iface_cmdq_write(device, pkt); + if (rc) + rc = -ENOTEMPTY; + +err_create_pkt: + return rc; +} + +static int __tzbsp_set_cvp_state(enum tzbsp_subsys_state state) +{ + int rc = 0; + + rc = qcom_scm_set_remote_state(state, TZBSP_CVP_PAS_ID); + dprintk(CVP_CORE, "Set state %d, resp %d\n", state, rc); + + if (rc) { + dprintk(CVP_ERR, "Failed qcom_scm_set_remote_state %d\n", rc); + return rc; + } + + return 0; +} + +static inline int __boot_firmware(struct iris_hfi_device *device) +{ + int rc = 0; + u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 1000; + + ctrl_init_val = BIT(0); + __write_register(device, CVP_CTRL_INIT, ctrl_init_val); + while (!ctrl_status && count < max_tries) { + ctrl_status = __read_register(device, CVP_CTRL_STATUS); + if ((ctrl_status & CVP_CTRL_ERROR_STATUS__M) == 0x4) { + dprintk(CVP_ERR, "invalid setting for UC_REGION\n"); + rc = -ENODATA; + break; + } + + /* Reduce to 1/100th and x100 of max_tries */ + usleep_range(500, 1000); + count++; + } + + if (!(ctrl_status & CVP_CTRL_INIT_STATUS__M)) { + dprintk(CVP_ERR, "Failed to boot FW status: %x\n", + ctrl_status); + rc = -ENODEV; + } + + /* Enable interrupt before sending commands to tensilica */ + __write_register(device, CVP_CPU_CS_H2XSOFTINTEN, 0x1); + __write_register(device, CVP_CPU_CS_X2RPMh, 0x0); + + return rc; +} + +static int iris_hfi_resume(void *dev) +{ + int rc = 0; + struct iris_hfi_device *device = (struct iris_hfi_device *) dev; + + if (!device) { + dprintk(CVP_ERR, "%s invalid device\n", __func__); + return -EINVAL; + } + + dprintk(CVP_CORE, "Resuming Iris\n"); + + mutex_lock(&device->lock); + rc = __resume(device); + mutex_unlock(&device->lock); + + return rc; +} + + +static int iris_hfi_suspend(void *dev) +{ + int rc = 0; + struct iris_hfi_device *device = (struct iris_hfi_device *) dev; + + if (!device) { + dprintk(CVP_ERR, "%s invalid device\n", __func__); + return -EINVAL; + } else if (!device->res->sw_power_collapsible) { + return -ENOTSUPP; + } + + dprintk(CVP_CORE, "Suspending Iris\n"); + mutex_lock(&device->lock); + rc = __power_collapse(device, true); + if (rc) { + dprintk(CVP_WARN, "%s: Iris is busy\n", __func__); + rc = -EBUSY; + } + mutex_unlock(&device->lock); + + /* Cancel pending delayed works if any */ + if (!rc) + cancel_delayed_work(&iris_hfi_pm_work); + + return rc; +} + +static void cvp_dump_csr(struct iris_hfi_device *dev) +{ + u32 reg; + + if (!dev) + return; + if (!dev->power_enabled || dev->reg_dumped) + return; + reg = __read_register(dev, CVP_WRAPPER_CPU_STATUS); + dprintk(CVP_ERR, "CVP_WRAPPER_CPU_STATUS: %x\n", reg); + reg = __read_register(dev, CVP_CPU_CS_SCIACMDARG0); + dprintk(CVP_ERR, "CVP_CPU_CS_SCIACMDARG0: %x\n", reg); + reg = __read_register(dev, CVP_WRAPPER_CPU_CLOCK_CONFIG); + dprintk(CVP_ERR, "CVP_WRAPPER_CPU_CLOCK_CONFIG: %x\n", reg); + reg = __read_register(dev, CVP_WRAPPER_CORE_CLOCK_CONFIG); + dprintk(CVP_ERR, "CVP_WRAPPER_CORE_CLOCK_CONFIG: %x\n", reg); + reg = __read_register(dev, CVP_WRAPPER_INTR_STATUS); + dprintk(CVP_ERR, "CVP_WRAPPER_INTR_STATUS: %x\n", reg); + reg = __read_register(dev, CVP_CPU_CS_H2ASOFTINT); + dprintk(CVP_ERR, "CVP_CPU_CS_H2ASOFTINT: %x\n", reg); + reg = __read_register(dev, CVP_CPU_CS_A2HSOFTINT); + dprintk(CVP_ERR, "CVP_CPU_CS_A2HSOFTINT: %x\n", reg); + reg = __read_register(dev, CVP_CC_MVS1C_GDSCR); + dprintk(CVP_ERR, "CVP_CC_MVS1C_GDSCR: %x\n", reg); + reg = __read_register(dev, CVP_CC_MVS1C_CBCR); + dprintk(CVP_ERR, "CVP_CC_MVS1C_CBCR: %x\n", reg); + dev->reg_dumped = true; +} + +static int iris_hfi_flush_debug_queue(void *dev) +{ + int rc = 0; + struct iris_hfi_device *device = (struct iris_hfi_device *) dev; + + if (!device) { + dprintk(CVP_ERR, "%s invalid device\n", __func__); + return -EINVAL; + } + + cvp_dump_csr(device); + mutex_lock(&device->lock); + + if (!device->power_enabled) { + dprintk(CVP_WARN, "%s: iris power off\n", __func__); + rc = -EINVAL; + goto exit; + } + __flush_debug_queue(device, NULL); +exit: + mutex_unlock(&device->lock); + return rc; +} + +static int __set_clocks(struct iris_hfi_device *device, u32 freq) +{ + struct clock_info *cl; + int rc = 0; + + iris_hfi_for_each_clock(device, cl) { + if (cl->has_scaling) {/* has_scaling */ + device->clk_freq = freq; + if (msm_cvp_clock_voting) + freq = msm_cvp_clock_voting; + + rc = clk_set_rate(cl->clk, freq); + if (rc) { + dprintk(CVP_ERR, + "Failed to set clock rate %u %s: %d %s\n", + freq, cl->name, rc, __func__); + return rc; + } + + dprintk(CVP_PWR, "Scaling clock %s to %u\n", + cl->name, freq); + } + } + + return 0; +} + +static int iris_hfi_scale_clocks(void *dev, u32 freq) +{ + int rc = 0; + struct iris_hfi_device *device = dev; + + if (!device) { + dprintk(CVP_ERR, "Invalid args: %pK\n", device); + return -EINVAL; + } + + mutex_lock(&device->lock); + + if (__resume(device)) { + dprintk(CVP_ERR, "Resume from power collapse failed\n"); + rc = -ENODEV; + goto exit; + } + + rc = __set_clocks(device, freq); +exit: + mutex_unlock(&device->lock); + + return rc; +} + +static int __scale_clocks(struct iris_hfi_device *device) +{ + int rc = 0; + struct allowed_clock_rates_table *allowed_clks_tbl = NULL; + u32 rate = 0; + + allowed_clks_tbl = device->res->allowed_clks_tbl; + + rate = device->clk_freq ? device->clk_freq : + allowed_clks_tbl[0].clock_rate; + + dprintk(CVP_PWR, "%s: scale clock rate %d\n", __func__, rate); + rc = __set_clocks(device, rate); + return rc; +} + +/* Writes into cmdq without raising an interrupt */ +static int __iface_cmdq_write_relaxed(struct iris_hfi_device *device, + void *pkt, bool *requires_interrupt) +{ + struct cvp_iface_q_info *q_info; + struct cvp_hal_cmd_pkt_hdr *cmd_packet; + int result = -E2BIG; + + if (!device || !pkt) { + dprintk(CVP_ERR, "Invalid Params\n"); + return -EINVAL; + } + + __strict_check(device); + + if (!__core_in_valid_state(device)) { + dprintk(CVP_ERR, "%s - fw not in init state\n", __func__); + result = -EINVAL; + goto err_q_null; + } + + cmd_packet = (struct cvp_hal_cmd_pkt_hdr *)pkt; + device->last_packet_type = cmd_packet->packet_type; + + q_info = &device->iface_queues[CVP_IFACEQ_CMDQ_IDX]; + if (!q_info) { + dprintk(CVP_ERR, "cannot write to shared Q's\n"); + goto err_q_null; + } + + if (!q_info->q_array.align_virtual_addr) { + dprintk(CVP_ERR, "cannot write to shared CMD Q's\n"); + result = -ENODATA; + goto err_q_null; + } + + if (__resume(device)) { + dprintk(CVP_ERR, "%s: Power on failed\n", __func__); + goto err_q_write; + } + + if (!__write_queue(q_info, (u8 *)pkt, requires_interrupt)) { + if (device->res->sw_power_collapsible) { + cancel_delayed_work(&iris_hfi_pm_work); + if (!queue_delayed_work(device->iris_pm_workq, + &iris_hfi_pm_work, + msecs_to_jiffies( + device->res->msm_cvp_pwr_collapse_delay))) { + dprintk(CVP_PWR, + "PM work already scheduled\n"); + } + } + + result = 0; + } else { + dprintk(CVP_ERR, "__iface_cmdq_write: queue full\n"); + } + +err_q_write: +err_q_null: + return result; +} + +static int __iface_cmdq_write(struct iris_hfi_device *device, void *pkt) +{ + bool needs_interrupt = false; + int rc = __iface_cmdq_write_relaxed(device, pkt, &needs_interrupt); + + if (!rc && needs_interrupt) { + /* Consumer of cmdq prefers that we raise an interrupt */ + rc = 0; + __write_register(device, CVP_CPU_CS_H2ASOFTINT, 1); + } + + return rc; +} + +static int __iface_msgq_read(struct iris_hfi_device *device, void *pkt) +{ + u32 tx_req_is_set = 0; + int rc = 0; + struct cvp_iface_q_info *q_info; + + if (!pkt) { + dprintk(CVP_ERR, "Invalid Params\n"); + return -EINVAL; + } + + __strict_check(device); + + if (!__core_in_valid_state(device)) { + dprintk(CVP_WARN, "%s - fw not in init state\n", __func__); + rc = -EINVAL; + goto read_error_null; + } + + q_info = &device->iface_queues[CVP_IFACEQ_MSGQ_IDX]; + if (q_info->q_array.align_virtual_addr == NULL) { + dprintk(CVP_ERR, "cannot read from shared MSG Q's\n"); + rc = -ENODATA; + goto read_error_null; + } + + if (!__read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) { + if (tx_req_is_set) + __write_register(device, CVP_CPU_CS_H2ASOFTINT, 1); + rc = 0; + } else + rc = -ENODATA; + +read_error_null: + return rc; +} + +static int __iface_dbgq_read(struct iris_hfi_device *device, void *pkt) +{ + u32 tx_req_is_set = 0; + int rc = 0; + struct cvp_iface_q_info *q_info; + + if (!pkt) { + dprintk(CVP_ERR, "Invalid Params\n"); + return -EINVAL; + } + + __strict_check(device); + + q_info = &device->iface_queues[CVP_IFACEQ_DBGQ_IDX]; + if (q_info->q_array.align_virtual_addr == NULL) { + dprintk(CVP_ERR, "cannot read from shared DBG Q's\n"); + rc = -ENODATA; + goto dbg_error_null; + } + + if (!__read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) { + if (tx_req_is_set) + __write_register(device, CVP_CPU_CS_H2ASOFTINT, 1); + rc = 0; + } else + rc = -ENODATA; + +dbg_error_null: + return rc; +} + +static void __set_queue_hdr_defaults(struct cvp_hfi_queue_header *q_hdr) +{ + q_hdr->qhdr_status = 0x1; + q_hdr->qhdr_type = CVP_IFACEQ_DFLT_QHDR; + q_hdr->qhdr_q_size = CVP_IFACEQ_QUEUE_SIZE / 4; + q_hdr->qhdr_pkt_size = 0; + q_hdr->qhdr_rx_wm = 0x1; + q_hdr->qhdr_tx_wm = 0x1; + q_hdr->qhdr_rx_req = 0x1; + q_hdr->qhdr_tx_req = 0x0; + q_hdr->qhdr_rx_irq_status = 0x0; + q_hdr->qhdr_tx_irq_status = 0x0; + q_hdr->qhdr_read_idx = 0x0; + q_hdr->qhdr_write_idx = 0x0; +} + +static void __interface_dsp_queues_release(struct iris_hfi_device *device) +{ + int i; + struct msm_cvp_smem *mem_data = &device->dsp_iface_q_table.mem_data; + struct context_bank_info *cb = mem_data->mapping_info.cb_info; + + if (!device->dsp_iface_q_table.align_virtual_addr) { + dprintk(CVP_ERR, "%s: already released\n", __func__); + return; + } + + dma_unmap_single_attrs(cb->dev, mem_data->device_addr, + mem_data->size, DMA_BIDIRECTIONAL, 0); + dma_free_coherent(device->res->mem_cdsp.dev, mem_data->size, + mem_data->kvaddr, mem_data->dma_handle); + + for (i = 0; i < CVP_IFACEQ_NUMQ; i++) { + device->dsp_iface_queues[i].q_hdr = NULL; + device->dsp_iface_queues[i].q_array.align_virtual_addr = NULL; + device->dsp_iface_queues[i].q_array.align_device_addr = 0; + } + device->dsp_iface_q_table.align_virtual_addr = NULL; + device->dsp_iface_q_table.align_device_addr = 0; +} + +static int __interface_dsp_queues_init(struct iris_hfi_device *dev) +{ + int rc = 0; + u32 i; + struct cvp_hfi_queue_table_header *q_tbl_hdr; + struct cvp_hfi_queue_header *q_hdr; + struct cvp_iface_q_info *iface_q; + int offset = 0; + phys_addr_t fw_bias = 0; + size_t q_size; + struct msm_cvp_smem *mem_data; + void *kvaddr; + dma_addr_t dma_handle; + dma_addr_t iova; + struct context_bank_info *cb; + + q_size = ALIGN(QUEUE_SIZE, SZ_1M); + mem_data = &dev->dsp_iface_q_table.mem_data; + + /* Allocate dsp queues from CDSP device memory */ + kvaddr = dma_alloc_coherent(dev->res->mem_cdsp.dev, q_size, + &dma_handle, GFP_KERNEL); + if (IS_ERR_OR_NULL(kvaddr)) { + dprintk(CVP_ERR, "%s: failed dma allocation\n", __func__); + goto fail_dma_alloc; + } + cb = msm_cvp_smem_get_context_bank(0, dev->res, 0); + if (!cb) { + dprintk(CVP_ERR, + "%s: failed to get context bank\n", __func__); + goto fail_dma_map; + } + iova = dma_map_single_attrs(cb->dev, phys_to_virt(dma_handle), + q_size, DMA_BIDIRECTIONAL, 0); + if (dma_mapping_error(cb->dev, iova)) { + dprintk(CVP_ERR, "%s: failed dma mapping\n", __func__); + goto fail_dma_map; + } + dprintk(CVP_DSP, + "%s: kvaddr %pK dma_handle %#llx iova %#llx size %zd\n", + __func__, kvaddr, dma_handle, iova, q_size); + + memset(mem_data, 0, sizeof(struct msm_cvp_smem)); + mem_data->kvaddr = kvaddr; + mem_data->device_addr = iova; + mem_data->dma_handle = dma_handle; + mem_data->size = q_size; + mem_data->ion_flags = 0; + mem_data->mapping_info.cb_info = cb; + + if (!is_iommu_present(dev->res)) + fw_bias = dev->cvp_hal_data->firmware_base; + + dev->dsp_iface_q_table.align_virtual_addr = kvaddr; + dev->dsp_iface_q_table.align_device_addr = iova - fw_bias; + dev->dsp_iface_q_table.mem_size = CVP_IFACEQ_TABLE_SIZE; + offset = dev->dsp_iface_q_table.mem_size; + + for (i = 0; i < CVP_IFACEQ_NUMQ; i++) { + iface_q = &dev->dsp_iface_queues[i]; + iface_q->q_array.align_device_addr = iova + offset - fw_bias; + iface_q->q_array.align_virtual_addr = kvaddr + offset; + iface_q->q_array.mem_size = CVP_IFACEQ_QUEUE_SIZE; + offset += iface_q->q_array.mem_size; + iface_q->q_hdr = CVP_IFACEQ_GET_QHDR_START_ADDR( + dev->dsp_iface_q_table.align_virtual_addr, i); + __set_queue_hdr_defaults(iface_q->q_hdr); + spin_lock_init(&iface_q->hfi_lock); + } + + q_tbl_hdr = (struct cvp_hfi_queue_table_header *) + dev->dsp_iface_q_table.align_virtual_addr; + q_tbl_hdr->qtbl_version = 0; + q_tbl_hdr->device_addr = (void *)dev; + strlcpy(q_tbl_hdr->name, "msm_cvp", sizeof(q_tbl_hdr->name)); + q_tbl_hdr->qtbl_size = CVP_IFACEQ_TABLE_SIZE; + q_tbl_hdr->qtbl_qhdr0_offset = + sizeof(struct cvp_hfi_queue_table_header); + q_tbl_hdr->qtbl_qhdr_size = sizeof(struct cvp_hfi_queue_header); + q_tbl_hdr->qtbl_num_q = CVP_IFACEQ_NUMQ; + q_tbl_hdr->qtbl_num_active_q = CVP_IFACEQ_NUMQ; + + iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_CMDQ_IDX]; + q_hdr = iface_q->q_hdr; + q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; + q_hdr->qhdr_type |= HFI_Q_ID_HOST_TO_CTRL_CMD_Q; + + iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_MSGQ_IDX]; + q_hdr = iface_q->q_hdr; + q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; + q_hdr->qhdr_type |= HFI_Q_ID_CTRL_TO_HOST_MSG_Q; + + iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_DBGQ_IDX]; + q_hdr = iface_q->q_hdr; + q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; + q_hdr->qhdr_type |= HFI_Q_ID_CTRL_TO_HOST_DEBUG_Q; + /* + * Set receive request to zero on debug queue as there is no + * need of interrupt from cvp hardware for debug messages + */ + q_hdr->qhdr_rx_req = 0; + return rc; + +fail_dma_map: + dma_free_coherent(dev->res->mem_cdsp.dev, q_size, kvaddr, dma_handle); +fail_dma_alloc: + return -ENOMEM; +} + +static void __interface_queues_release(struct iris_hfi_device *device) +{ + int i; + struct cvp_hfi_mem_map_table *qdss; + struct cvp_hfi_mem_map *mem_map; + int num_entries = device->res->qdss_addr_set.count; + unsigned long mem_map_table_base_addr; + struct context_bank_info *cb; + + if (device->qdss.align_virtual_addr) { + qdss = (struct cvp_hfi_mem_map_table *) + device->qdss.align_virtual_addr; + qdss->mem_map_num_entries = num_entries; + mem_map_table_base_addr = + device->qdss.align_device_addr + + sizeof(struct cvp_hfi_mem_map_table); + qdss->mem_map_table_base_addr = + (u32)mem_map_table_base_addr; + if ((unsigned long)qdss->mem_map_table_base_addr != + mem_map_table_base_addr) { + dprintk(CVP_ERR, + "Invalid mem_map_table_base_addr %#lx", + mem_map_table_base_addr); + } + + mem_map = (struct cvp_hfi_mem_map *)(qdss + 1); + cb = msm_cvp_smem_get_context_bank(false, device->res, 0); + + for (i = 0; cb && i < num_entries; i++) { + iommu_unmap(cb->domain, + mem_map[i].virtual_addr, + mem_map[i].size); + } + + __smem_free(device, &device->qdss.mem_data); + } + + __smem_free(device, &device->iface_q_table.mem_data); + __smem_free(device, &device->sfr.mem_data); + + for (i = 0; i < CVP_IFACEQ_NUMQ; i++) { + device->iface_queues[i].q_hdr = NULL; + device->iface_queues[i].q_array.align_virtual_addr = NULL; + device->iface_queues[i].q_array.align_device_addr = 0; + } + + device->iface_q_table.align_virtual_addr = NULL; + device->iface_q_table.align_device_addr = 0; + + device->qdss.align_virtual_addr = NULL; + device->qdss.align_device_addr = 0; + + device->sfr.align_virtual_addr = NULL; + device->sfr.align_device_addr = 0; + + device->mem_addr.align_virtual_addr = NULL; + device->mem_addr.align_device_addr = 0; + + __interface_dsp_queues_release(device); +} + +static int __get_qdss_iommu_virtual_addr(struct iris_hfi_device *dev, + struct cvp_hfi_mem_map *mem_map, + struct iommu_domain *domain) +{ + int i; + int rc = 0; + dma_addr_t iova = QDSS_IOVA_START; + int num_entries = dev->res->qdss_addr_set.count; + struct addr_range *qdss_addr_tbl = dev->res->qdss_addr_set.addr_tbl; + + if (!num_entries) + return -ENODATA; + + for (i = 0; i < num_entries; i++) { + if (domain) { + rc = iommu_map(domain, iova, + qdss_addr_tbl[i].start, + qdss_addr_tbl[i].size, + IOMMU_READ | IOMMU_WRITE); + + if (rc) { + dprintk(CVP_ERR, + "IOMMU QDSS mapping failed for addr %#x\n", + qdss_addr_tbl[i].start); + rc = -ENOMEM; + break; + } + } else { + iova = qdss_addr_tbl[i].start; + } + + mem_map[i].virtual_addr = (u32)iova; + mem_map[i].physical_addr = qdss_addr_tbl[i].start; + mem_map[i].size = qdss_addr_tbl[i].size; + mem_map[i].attr = 0x0; + + iova += mem_map[i].size; + } + + if (i < num_entries) { + dprintk(CVP_ERR, + "QDSS mapping failed, Freeing other entries %d\n", i); + + for (--i; domain && i >= 0; i--) { + iommu_unmap(domain, + mem_map[i].virtual_addr, + mem_map[i].size); + } + } + + return rc; +} + +static void __setup_ucregion_memory_map(struct iris_hfi_device *device) +{ + __write_register(device, CVP_UC_REGION_ADDR, + (u32)device->iface_q_table.align_device_addr); + __write_register(device, CVP_UC_REGION_SIZE, SHARED_QSIZE); + __write_register(device, CVP_QTBL_ADDR, + (u32)device->iface_q_table.align_device_addr); + __write_register(device, CVP_QTBL_INFO, 0x01); + if (device->sfr.align_device_addr) + __write_register(device, CVP_SFR_ADDR, + (u32)device->sfr.align_device_addr); + if (device->qdss.align_device_addr) + __write_register(device, CVP_MMAP_ADDR, + (u32)device->qdss.align_device_addr); + call_iris_op(device, setup_dsp_uc_memmap, device); +} + +static int __interface_queues_init(struct iris_hfi_device *dev) +{ + struct cvp_hfi_queue_table_header *q_tbl_hdr; + struct cvp_hfi_queue_header *q_hdr; + u32 i; + int rc = 0; + struct cvp_hfi_mem_map_table *qdss; + struct cvp_hfi_mem_map *mem_map; + struct cvp_iface_q_info *iface_q; + struct cvp_hfi_sfr_struct *vsfr; + struct cvp_mem_addr *mem_addr; + int offset = 0; + int num_entries = dev->res->qdss_addr_set.count; + phys_addr_t fw_bias = 0; + size_t q_size; + unsigned long mem_map_table_base_addr; + struct context_bank_info *cb; + + q_size = SHARED_QSIZE - ALIGNED_SFR_SIZE - ALIGNED_QDSS_SIZE; + mem_addr = &dev->mem_addr; + if (!is_iommu_present(dev->res)) + fw_bias = dev->cvp_hal_data->firmware_base; + rc = __smem_alloc(dev, mem_addr, q_size, 1, SMEM_UNCACHED); + if (rc) { + dprintk(CVP_ERR, "iface_q_table_alloc_fail\n"); + goto fail_alloc_queue; + } + + dev->iface_q_table.align_virtual_addr = mem_addr->align_virtual_addr; + dev->iface_q_table.align_device_addr = mem_addr->align_device_addr - + fw_bias; + dev->iface_q_table.mem_size = CVP_IFACEQ_TABLE_SIZE; + dev->iface_q_table.mem_data = mem_addr->mem_data; + offset += dev->iface_q_table.mem_size; + + for (i = 0; i < CVP_IFACEQ_NUMQ; i++) { + iface_q = &dev->iface_queues[i]; + iface_q->q_array.align_device_addr = mem_addr->align_device_addr + + offset - fw_bias; + iface_q->q_array.align_virtual_addr = + mem_addr->align_virtual_addr + offset; + iface_q->q_array.mem_size = CVP_IFACEQ_QUEUE_SIZE; + offset += iface_q->q_array.mem_size; + iface_q->q_hdr = CVP_IFACEQ_GET_QHDR_START_ADDR( + dev->iface_q_table.align_virtual_addr, i); + __set_queue_hdr_defaults(iface_q->q_hdr); + spin_lock_init(&iface_q->hfi_lock); + } + + if ((msm_cvp_fw_debug_mode & HFI_DEBUG_MODE_QDSS) && num_entries) { + rc = __smem_alloc(dev, mem_addr, ALIGNED_QDSS_SIZE, 1, + SMEM_UNCACHED); + if (rc) { + dprintk(CVP_WARN, + "qdss_alloc_fail: QDSS messages logging will not work\n"); + dev->qdss.align_device_addr = 0; + } else { + dev->qdss.align_device_addr = + mem_addr->align_device_addr - fw_bias; + dev->qdss.align_virtual_addr = + mem_addr->align_virtual_addr; + dev->qdss.mem_size = ALIGNED_QDSS_SIZE; + dev->qdss.mem_data = mem_addr->mem_data; + } + } + + rc = __smem_alloc(dev, mem_addr, ALIGNED_SFR_SIZE, 1, SMEM_UNCACHED); + if (rc) { + dprintk(CVP_WARN, "sfr_alloc_fail: SFR not will work\n"); + dev->sfr.align_device_addr = 0; + } else { + dev->sfr.align_device_addr = mem_addr->align_device_addr - + fw_bias; + dev->sfr.align_virtual_addr = mem_addr->align_virtual_addr; + dev->sfr.mem_size = ALIGNED_SFR_SIZE; + dev->sfr.mem_data = mem_addr->mem_data; + } + + q_tbl_hdr = (struct cvp_hfi_queue_table_header *) + dev->iface_q_table.align_virtual_addr; + q_tbl_hdr->qtbl_version = 0; + q_tbl_hdr->device_addr = (void *)dev; + strlcpy(q_tbl_hdr->name, "msm_cvp", sizeof(q_tbl_hdr->name)); + q_tbl_hdr->qtbl_size = CVP_IFACEQ_TABLE_SIZE; + q_tbl_hdr->qtbl_qhdr0_offset = + sizeof(struct cvp_hfi_queue_table_header); + q_tbl_hdr->qtbl_qhdr_size = sizeof(struct cvp_hfi_queue_header); + q_tbl_hdr->qtbl_num_q = CVP_IFACEQ_NUMQ; + q_tbl_hdr->qtbl_num_active_q = CVP_IFACEQ_NUMQ; + + iface_q = &dev->iface_queues[CVP_IFACEQ_CMDQ_IDX]; + q_hdr = iface_q->q_hdr; + q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; + q_hdr->qhdr_type |= HFI_Q_ID_HOST_TO_CTRL_CMD_Q; + + iface_q = &dev->iface_queues[CVP_IFACEQ_MSGQ_IDX]; + q_hdr = iface_q->q_hdr; + q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; + q_hdr->qhdr_type |= HFI_Q_ID_CTRL_TO_HOST_MSG_Q; + + iface_q = &dev->iface_queues[CVP_IFACEQ_DBGQ_IDX]; + q_hdr = iface_q->q_hdr; + q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; + q_hdr->qhdr_type |= HFI_Q_ID_CTRL_TO_HOST_DEBUG_Q; + /* + * Set receive request to zero on debug queue as there is no + * need of interrupt from cvp hardware for debug messages + */ + q_hdr->qhdr_rx_req = 0; + + if (dev->qdss.align_virtual_addr) { + qdss = + (struct cvp_hfi_mem_map_table *)dev->qdss.align_virtual_addr; + qdss->mem_map_num_entries = num_entries; + mem_map_table_base_addr = dev->qdss.align_device_addr + + sizeof(struct cvp_hfi_mem_map_table); + qdss->mem_map_table_base_addr = mem_map_table_base_addr; + + mem_map = (struct cvp_hfi_mem_map *)(qdss + 1); + cb = msm_cvp_smem_get_context_bank(false, dev->res, 0); + if (!cb) { + dprintk(CVP_ERR, + "%s: failed to get context bank\n", __func__); + return -EINVAL; + } + + rc = __get_qdss_iommu_virtual_addr(dev, mem_map, cb->domain); + if (rc) { + dprintk(CVP_ERR, + "IOMMU mapping failed, Freeing qdss memdata\n"); + __smem_free(dev, &dev->qdss.mem_data); + dev->qdss.align_virtual_addr = NULL; + dev->qdss.align_device_addr = 0; + } + } + + vsfr = (struct cvp_hfi_sfr_struct *) dev->sfr.align_virtual_addr; + if (vsfr) + vsfr->bufSize = ALIGNED_SFR_SIZE; + + rc = __interface_dsp_queues_init(dev); + if (rc) { + dprintk(CVP_ERR, "dsp_queues_init failed\n"); + goto fail_alloc_queue; + } + + __setup_ucregion_memory_map(dev); + return 0; +fail_alloc_queue: + return -ENOMEM; +} + +static int __sys_set_debug(struct iris_hfi_device *device, u32 debug) +{ + u8 packet[CVP_IFACEQ_VAR_SMALL_PKT_SIZE]; + int rc = 0; + struct cvp_hfi_cmd_sys_set_property_packet *pkt = + (struct cvp_hfi_cmd_sys_set_property_packet *) &packet; + + rc = call_hfi_pkt_op(device, sys_debug_config, pkt, debug); + if (rc) { + dprintk(CVP_WARN, + "Debug mode setting to FW failed\n"); + return -ENOTEMPTY; + } + + if (__iface_cmdq_write(device, pkt)) + return -ENOTEMPTY; + return 0; +} + +static int __sys_set_idle_indicator(struct iris_hfi_device *device, + bool enable) +{ + u8 packet[CVP_IFACEQ_VAR_SMALL_PKT_SIZE]; + int rc = 0; + struct cvp_hfi_cmd_sys_set_property_packet *pkt = + (struct cvp_hfi_cmd_sys_set_property_packet *) &packet; + + rc = call_hfi_pkt_op(device, sys_set_idle_indicator, pkt, enable); + if (__iface_cmdq_write(device, pkt)) + return -ENOTEMPTY; + return 0; +} + +static int __sys_set_coverage(struct iris_hfi_device *device, u32 mode) +{ + u8 packet[CVP_IFACEQ_VAR_SMALL_PKT_SIZE]; + int rc = 0; + struct cvp_hfi_cmd_sys_set_property_packet *pkt = + (struct cvp_hfi_cmd_sys_set_property_packet *) &packet; + + rc = call_hfi_pkt_op(device, sys_coverage_config, + pkt, mode); + if (rc) { + dprintk(CVP_WARN, + "Coverage mode setting to FW failed\n"); + return -ENOTEMPTY; + } + + if (__iface_cmdq_write(device, pkt)) { + dprintk(CVP_WARN, "Failed to send coverage pkt to f/w\n"); + return -ENOTEMPTY; + } + + return 0; +} + +static int __sys_set_power_control(struct iris_hfi_device *device, + bool enable) +{ + struct regulator_info *rinfo; + bool supported = false; + u8 packet[CVP_IFACEQ_VAR_SMALL_PKT_SIZE]; + struct cvp_hfi_cmd_sys_set_property_packet *pkt = + (struct cvp_hfi_cmd_sys_set_property_packet *) &packet; + + iris_hfi_for_each_regulator(device, rinfo) { + if (rinfo->has_hw_power_collapse) { + supported = true; + break; + } + } + + if (!supported) + return 0; + + call_hfi_pkt_op(device, sys_power_control, pkt, enable); + if (__iface_cmdq_write(device, pkt)) + return -ENOTEMPTY; + return 0; +} + +static int iris_hfi_core_init(void *device) +{ + int rc = 0; + struct cvp_hfi_cmd_sys_init_packet pkt; + struct cvp_hfi_cmd_sys_get_property_packet version_pkt; + struct iris_hfi_device *dev; + + if (!device) { + dprintk(CVP_ERR, "Invalid device\n"); + return -ENODEV; + } + + dev = device; + + dprintk(CVP_CORE, "Core initializing\n"); + + mutex_lock(&dev->lock); + + dev->bus_vote.data = + kzalloc(sizeof(struct cvp_bus_vote_data), GFP_KERNEL); + if (!dev->bus_vote.data) { + dprintk(CVP_ERR, "Bus vote data memory is not allocated\n"); + rc = -ENOMEM; + goto err_no_mem; + } + + dev->bus_vote.data_count = 1; + dev->bus_vote.data->power_mode = CVP_POWER_TURBO; + + rc = __load_fw(dev); + if (rc) { + dprintk(CVP_ERR, "Failed to load Iris FW\n"); + goto err_load_fw; + } + + __set_state(dev, IRIS_STATE_INIT); + dev->reg_dumped = false; + + dprintk(CVP_CORE, "Dev_Virt: %pa, Reg_Virt: %pK\n", + &dev->cvp_hal_data->firmware_base, + dev->cvp_hal_data->register_base); + + + rc = __interface_queues_init(dev); + if (rc) { + dprintk(CVP_ERR, "failed to init queues\n"); + rc = -ENOMEM; + goto err_core_init; + } + + rc = __boot_firmware(dev); + if (rc) { + dprintk(CVP_ERR, "Failed to start core\n"); + rc = -ENODEV; + goto err_core_init; + } + + dev->version = __read_register(dev, CVP_VERSION_INFO); + + rc = call_hfi_pkt_op(dev, sys_init, &pkt, 0); + if (rc) { + dprintk(CVP_ERR, "Failed to create sys init pkt\n"); + goto err_core_init; + } + + if (__iface_cmdq_write(dev, &pkt)) { + rc = -ENOTEMPTY; + goto err_core_init; + } + + rc = call_hfi_pkt_op(dev, sys_image_version, &version_pkt); + if (rc || __iface_cmdq_write(dev, &version_pkt)) + dprintk(CVP_WARN, "Failed to send image version pkt to f/w\n"); + + __sys_set_debug(device, msm_cvp_fw_debug); + + __enable_subcaches(device); + __set_subcaches(device); + + __set_ubwc_config(device); + __sys_set_idle_indicator(device, true); + + if (dev->res->pm_qos_latency_us) + pm_qos_add_request(&dev->qos, PM_QOS_CPU_DMA_LATENCY, + dev->res->pm_qos_latency_us); + + mutex_unlock(&dev->lock); + + cvp_dsp_send_hfi_queue(); + + dprintk(CVP_CORE, "Core inited successfully\n"); + + return 0; +err_core_init: + __set_state(dev, IRIS_STATE_DEINIT); + __unload_fw(dev); +err_load_fw: +err_no_mem: + dprintk(CVP_ERR, "Core init failed\n"); + mutex_unlock(&dev->lock); + return rc; +} + +static int iris_hfi_core_release(void *dev) +{ + int rc = 0; + struct iris_hfi_device *device = dev; + struct cvp_hal_session *session, *next; + + if (!device) { + dprintk(CVP_ERR, "invalid device\n"); + return -ENODEV; + } + + mutex_lock(&device->lock); + dprintk(CVP_WARN, "Core releasing\n"); + if (device->res->pm_qos_latency_us && + pm_qos_request_active(&device->qos)) + pm_qos_remove_request(&device->qos); + + __resume(device); + __set_state(device, IRIS_STATE_DEINIT); + + __dsp_shutdown(device, 0); + + __unload_fw(device); + + /* unlink all sessions from device */ + list_for_each_entry_safe(session, next, &device->sess_head, list) { + list_del(&session->list); + session->device = NULL; + } + + dprintk(CVP_CORE, "Core released successfully\n"); + mutex_unlock(&device->lock); + + return rc; +} + +static void __core_clear_interrupt(struct iris_hfi_device *device) +{ + u32 intr_status = 0, mask = 0; + + if (!device) { + dprintk(CVP_ERR, "%s: NULL device\n", __func__); + return; + } + + intr_status = __read_register(device, CVP_WRAPPER_INTR_STATUS); + mask = (CVP_WRAPPER_INTR_MASK_A2HCPU_BMSK | CVP_FATAL_INTR_BMSK); + + if (intr_status & mask) { + device->intr_status |= intr_status; + device->reg_count++; + dprintk(CVP_CORE, + "INTERRUPT for device: %pK: times: %d status: %d\n", + device, device->reg_count, intr_status); + } else { + device->spur_count++; + } + + __write_register(device, CVP_CPU_CS_A2HSOFTINTCLR, 1); +} + +static int iris_hfi_core_trigger_ssr(void *device, + enum hal_ssr_trigger_type type) +{ + struct cvp_hfi_cmd_sys_test_ssr_packet pkt; + int rc = 0; + struct iris_hfi_device *dev; + + if (!device) { + dprintk(CVP_ERR, "invalid device\n"); + return -ENODEV; + } + + dev = device; + if (mutex_trylock(&dev->lock)) { + rc = call_hfi_pkt_op(dev, ssr_cmd, type, &pkt); + if (rc) { + dprintk(CVP_ERR, "%s: failed to create packet\n", + __func__); + goto err_create_pkt; + } + + if (__iface_cmdq_write(dev, &pkt)) + rc = -ENOTEMPTY; + } else { + return -EAGAIN; + } + +err_create_pkt: + mutex_unlock(&dev->lock); + return rc; +} + +static void __set_default_sys_properties(struct iris_hfi_device *device) +{ + if (__sys_set_debug(device, msm_cvp_fw_debug)) + dprintk(CVP_WARN, "Setting fw_debug msg ON failed\n"); + if (__sys_set_power_control(device, msm_cvp_fw_low_power_mode)) + dprintk(CVP_WARN, "Setting h/w power collapse ON failed\n"); +} + +static void __session_clean(struct cvp_hal_session *session) +{ + struct cvp_hal_session *temp, *next; + struct iris_hfi_device *device; + + if (!session || !session->device) { + dprintk(CVP_WARN, "%s: invalid params\n", __func__); + return; + } + device = session->device; + dprintk(CVP_SESS, "deleted the session: %pK\n", session); + /* + * session might have been removed from the device list in + * core_release, so check and remove if it is in the list + */ + list_for_each_entry_safe(temp, next, &device->sess_head, list) { + if (session == temp) { + list_del(&session->list); + break; + } + } + /* Poison the session handle with zeros */ + *session = (struct cvp_hal_session){ {0} }; + kfree(session); +} + +static int iris_hfi_session_clean(void *session) +{ + struct cvp_hal_session *sess_close; + struct iris_hfi_device *device; + + if (!session) { + dprintk(CVP_ERR, "Invalid Params %s\n", __func__); + return -EINVAL; + } + + sess_close = session; + device = sess_close->device; + + if (!device) { + dprintk(CVP_ERR, "Invalid device handle %s\n", __func__); + return -EINVAL; + } + + mutex_lock(&device->lock); + + __session_clean(sess_close); + + mutex_unlock(&device->lock); + return 0; +} + +static int iris_hfi_session_init(void *device, void *session_id, + void **new_session) +{ + struct cvp_hfi_cmd_sys_session_init_packet pkt; + struct iris_hfi_device *dev; + struct cvp_hal_session *s; + + if (!device || !new_session) { + dprintk(CVP_ERR, "%s - invalid input\n", __func__); + return -EINVAL; + } + + dev = device; + mutex_lock(&dev->lock); + + s = kzalloc(sizeof(*s), GFP_KERNEL); + if (!s) { + dprintk(CVP_ERR, "new session fail: Out of memory\n"); + goto err_session_init_fail; + } + + s->session_id = session_id; + s->device = dev; + dprintk(CVP_SESS, + "%s: inst %pK, session %pK\n", __func__, session_id, s); + + list_add_tail(&s->list, &dev->sess_head); + + __set_default_sys_properties(device); + + if (call_hfi_pkt_op(dev, session_init, &pkt, s)) { + dprintk(CVP_ERR, "session_init: failed to create packet\n"); + goto err_session_init_fail; + } + + *new_session = s; + if (__iface_cmdq_write(dev, &pkt)) + goto err_session_init_fail; + + mutex_unlock(&dev->lock); + return 0; + +err_session_init_fail: + if (s) + __session_clean(s); + *new_session = NULL; + mutex_unlock(&dev->lock); + return -EINVAL; +} + +static int __send_session_cmd(struct cvp_hal_session *session, int pkt_type) +{ + struct cvp_hal_session_cmd_pkt pkt; + int rc = 0; + struct iris_hfi_device *device = session->device; + + if (!__is_session_valid(device, session, __func__)) + return -ECONNRESET; + + rc = call_hfi_pkt_op(device, session_cmd, + &pkt, pkt_type, session); + if (rc == -EPERM) + return 0; + + if (rc) { + dprintk(CVP_ERR, "send session cmd: create pkt failed\n"); + goto err_create_pkt; + } + + if (__iface_cmdq_write(session->device, &pkt)) + rc = -ENOTEMPTY; + +err_create_pkt: + return rc; +} + +static int iris_hfi_session_end(void *session) +{ + struct cvp_hal_session *sess; + struct iris_hfi_device *device; + int rc = 0; + + if (!session) { + dprintk(CVP_ERR, "Invalid Params %s\n", __func__); + return -EINVAL; + } + + sess = session; + device = sess->device; + if (!device) { + dprintk(CVP_ERR, "Invalid session %s\n", __func__); + return -EINVAL; + } + + mutex_lock(&device->lock); + + if (msm_cvp_fw_coverage) { + if (__sys_set_coverage(sess->device, msm_cvp_fw_coverage)) + dprintk(CVP_WARN, "Fw_coverage msg ON failed\n"); + } + + rc = __send_session_cmd(session, HFI_CMD_SYS_SESSION_END); + + mutex_unlock(&device->lock); + + return rc; +} + +static int iris_hfi_session_abort(void *sess) +{ + struct cvp_hal_session *session = sess; + struct iris_hfi_device *device; + int rc = 0; + + if (!session || !session->device) { + dprintk(CVP_ERR, "Invalid Params %s\n", __func__); + return -EINVAL; + } + + device = session->device; + + mutex_lock(&device->lock); + + rc = __send_session_cmd(session, HFI_CMD_SYS_SESSION_ABORT); + + mutex_unlock(&device->lock); + + return rc; +} + +static int iris_hfi_session_set_buffers(void *sess, u32 iova, u32 size) +{ + struct cvp_hfi_cmd_session_set_buffers_packet pkt; + int rc = 0; + struct cvp_hal_session *session = sess; + struct iris_hfi_device *device; + + if (!session || !session->device || !iova || !size) { + dprintk(CVP_ERR, "Invalid Params\n"); + return -EINVAL; + } + + device = session->device; + mutex_lock(&device->lock); + + if (!__is_session_valid(device, session, __func__)) { + rc = -ECONNRESET; + goto err_create_pkt; + } + + rc = call_hfi_pkt_op(device, session_set_buffers, + &pkt, session, iova, size); + if (rc) { + dprintk(CVP_ERR, "set buffers: failed to create packet\n"); + goto err_create_pkt; + } + + if (__iface_cmdq_write(session->device, &pkt)) + rc = -ENOTEMPTY; + +err_create_pkt: + mutex_unlock(&device->lock); + return rc; +} + +static int iris_hfi_session_release_buffers(void *sess) +{ + struct cvp_session_release_buffers_packet pkt; + int rc = 0; + struct cvp_hal_session *session = sess; + struct iris_hfi_device *device; + + if (!session || !session->device) { + dprintk(CVP_ERR, "Invalid Params\n"); + return -EINVAL; + } + + device = session->device; + mutex_lock(&device->lock); + + if (!__is_session_valid(device, session, __func__)) { + rc = -ECONNRESET; + goto err_create_pkt; + } + + rc = call_hfi_pkt_op(device, session_release_buffers, &pkt, session); + if (rc) { + dprintk(CVP_ERR, "release buffers: failed to create packet\n"); + goto err_create_pkt; + } + + if (__iface_cmdq_write(session->device, &pkt)) + rc = -ENOTEMPTY; + +err_create_pkt: + mutex_unlock(&device->lock); + return rc; +} + +static int iris_hfi_session_send(void *sess, + struct cvp_kmd_hfi_packet *in_pkt) +{ + int rc = 0; + struct cvp_kmd_hfi_packet pkt; + struct cvp_hal_session *session = sess; + struct iris_hfi_device *device; + + if (!session || !session->device) { + dprintk(CVP_ERR, "invalid session"); + return -ENODEV; + } + + device = session->device; + mutex_lock(&device->lock); + + if (!__is_session_valid(device, session, __func__)) { + rc = -ECONNRESET; + goto err_send_pkt; + } + rc = call_hfi_pkt_op(device, session_send, + &pkt, session, in_pkt); + if (rc) { + dprintk(CVP_ERR, + "failed to create pkt\n"); + goto err_send_pkt; + } + + if (__iface_cmdq_write(session->device, &pkt)) + rc = -ENOTEMPTY; + +err_send_pkt: + mutex_unlock(&device->lock); + return rc; + + return rc; +} + +static int iris_hfi_session_flush(void *sess) +{ + struct cvp_hal_session *session = sess; + struct iris_hfi_device *device; + int rc = 0; + + if (!session || !session->device) { + dprintk(CVP_ERR, "Invalid Params %s\n", __func__); + return -EINVAL; + } + + device = session->device; + + mutex_lock(&device->lock); + + rc = __send_session_cmd(session, HFI_CMD_SESSION_CVP_FLUSH); + + mutex_unlock(&device->lock); + + return rc; +} + +static int __check_core_registered(struct iris_hfi_device *device, + phys_addr_t fw_addr, u8 *reg_addr, u32 reg_size, + phys_addr_t irq) +{ + struct cvp_hal_data *cvp_hal_data; + + if (!device) { + dprintk(CVP_INFO, "no device Registered\n"); + return -EINVAL; + } + + cvp_hal_data = device->cvp_hal_data; + if (!cvp_hal_data) + return -EINVAL; + + if (cvp_hal_data->irq == irq && + (CONTAINS(cvp_hal_data->firmware_base, + FIRMWARE_SIZE, fw_addr) || + CONTAINS(fw_addr, FIRMWARE_SIZE, + cvp_hal_data->firmware_base) || + CONTAINS(cvp_hal_data->register_base, + reg_size, reg_addr) || + CONTAINS(reg_addr, reg_size, + cvp_hal_data->register_base) || + OVERLAPS(cvp_hal_data->register_base, + reg_size, reg_addr, reg_size) || + OVERLAPS(reg_addr, reg_size, + cvp_hal_data->register_base, + reg_size) || + OVERLAPS(cvp_hal_data->firmware_base, + FIRMWARE_SIZE, fw_addr, + FIRMWARE_SIZE) || + OVERLAPS(fw_addr, FIRMWARE_SIZE, + cvp_hal_data->firmware_base, + FIRMWARE_SIZE))) { + return 0; + } + + dprintk(CVP_INFO, "Device not registered\n"); + return -EINVAL; +} + +static void __process_fatal_error( + struct iris_hfi_device *device) +{ + struct msm_cvp_cb_cmd_done cmd_done = {0}; + + cmd_done.device_id = device->device_id; + device->callback(HAL_SYS_ERROR, &cmd_done); +} + +static int __prepare_pc(struct iris_hfi_device *device) +{ + int rc = 0; + struct cvp_hfi_cmd_sys_pc_prep_packet pkt; + + rc = call_hfi_pkt_op(device, sys_pc_prep, &pkt); + if (rc) { + dprintk(CVP_ERR, "Failed to create sys pc prep pkt\n"); + goto err_pc_prep; + } + + if (__iface_cmdq_write(device, &pkt)) + rc = -ENOTEMPTY; + if (rc) + dprintk(CVP_ERR, "Failed to prepare iris for power off"); +err_pc_prep: + return rc; +} + +static void iris_hfi_pm_handler(struct work_struct *work) +{ + int rc = 0; + struct msm_cvp_core *core; + struct iris_hfi_device *device; + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (core) + device = core->device->hfi_device_data; + else + return; + + if (!device) { + dprintk(CVP_ERR, "%s: NULL device\n", __func__); + return; + } + + dprintk(CVP_PWR, + "Entering %s\n", __func__); + /* + * It is ok to check this variable outside the lock since + * it is being updated in this context only + */ + if (device->skip_pc_count >= CVP_MAX_PC_SKIP_COUNT) { + dprintk(CVP_WARN, "Failed to PC for %d times\n", + device->skip_pc_count); + device->skip_pc_count = 0; + __process_fatal_error(device); + return; + } + + mutex_lock(&device->lock); + if (gfa_cv.state == DSP_SUSPEND) + rc = __power_collapse(device, true); + else + rc = __power_collapse(device, false); + mutex_unlock(&device->lock); + switch (rc) { + case 0: + device->skip_pc_count = 0; + /* Cancel pending delayed works if any */ + cancel_delayed_work(&iris_hfi_pm_work); + dprintk(CVP_PWR, "%s: power collapse successful!\n", + __func__); + break; + case -EBUSY: + device->skip_pc_count = 0; + dprintk(CVP_PWR, "%s: retry PC as cvp is busy\n", __func__); + queue_delayed_work(device->iris_pm_workq, + &iris_hfi_pm_work, msecs_to_jiffies( + device->res->msm_cvp_pwr_collapse_delay)); + break; + case -EAGAIN: + device->skip_pc_count++; + dprintk(CVP_WARN, "%s: retry power collapse (count %d)\n", + __func__, device->skip_pc_count); + queue_delayed_work(device->iris_pm_workq, + &iris_hfi_pm_work, msecs_to_jiffies( + device->res->msm_cvp_pwr_collapse_delay)); + break; + default: + dprintk(CVP_ERR, "%s: power collapse failed\n", __func__); + break; + } +} + +static int __power_collapse(struct iris_hfi_device *device, bool force) +{ + int rc = 0; + u32 wfi_status = 0, idle_status = 0, pc_ready = 0; + u32 flags = 0; + int count = 0; + const int max_tries = 150; + + if (!device) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + if (!device->power_enabled) { + dprintk(CVP_PWR, "%s: Power already disabled\n", + __func__); + goto exit; + } + + rc = __core_in_valid_state(device); + if (!rc) { + dprintk(CVP_WARN, + "Core is in bad state, Skipping power collapse\n"); + return -EINVAL; + } + + rc = __dsp_suspend(device, force, flags); + if (rc == -EBUSY) + goto exit; + else if (rc) + goto skip_power_off; + + pc_ready = __read_register(device, CVP_CTRL_STATUS) & + CVP_CTRL_STATUS_PC_READY; + if (!pc_ready) { + wfi_status = __read_register(device, + CVP_WRAPPER_CPU_STATUS); + idle_status = __read_register(device, + CVP_CTRL_STATUS); + if (!(wfi_status & BIT(0))) { + dprintk(CVP_WARN, + "Skipping PC as wfi_status (%#x) bit not set\n", + wfi_status); + goto skip_power_off; + } + if (!(idle_status & BIT(30))) { + dprintk(CVP_WARN, + "Skipping PC as idle_status (%#x) bit not set\n", + idle_status); + goto skip_power_off; + } + + rc = __prepare_pc(device); + if (rc) { + dprintk(CVP_WARN, "Failed PC %d\n", rc); + goto skip_power_off; + } + + while (count < max_tries) { + wfi_status = __read_register(device, + CVP_WRAPPER_CPU_STATUS); + pc_ready = __read_register(device, + CVP_CTRL_STATUS); + if ((wfi_status & BIT(0)) && (pc_ready & + CVP_CTRL_STATUS_PC_READY)) + break; + usleep_range(150, 250); + count++; + } + + if (count == max_tries) { + dprintk(CVP_ERR, + "Skip PC. Core is not in right state (%#x, %#x)\n", + wfi_status, pc_ready); + goto skip_power_off; + } + } + + __flush_debug_queue(device, device->raw_packet); + + rc = __suspend(device); + if (rc) + dprintk(CVP_ERR, "Failed __suspend\n"); + +exit: + return rc; + +skip_power_off: + dprintk(CVP_PWR, "Skip PC(%#x, %#x, %#x)\n", + wfi_status, idle_status, pc_ready); + __flush_debug_queue(device, device->raw_packet); + return -EAGAIN; +} + +static void __process_sys_error(struct iris_hfi_device *device) +{ + struct cvp_hfi_sfr_struct *vsfr = NULL; + + vsfr = (struct cvp_hfi_sfr_struct *)device->sfr.align_virtual_addr; + if (vsfr) { + void *p = memchr(vsfr->rg_data, '\0', vsfr->bufSize); + /* + * SFR isn't guaranteed to be NULL terminated + * since SYS_ERROR indicates that Iris is in the + * process of crashing. + */ + if (p == NULL) + vsfr->rg_data[vsfr->bufSize - 1] = '\0'; + + dprintk(CVP_ERR, "SFR Message from FW: %s\n", + vsfr->rg_data); + } +} + +static void __flush_debug_queue(struct iris_hfi_device *device, u8 *packet) +{ + bool local_packet = false; + enum cvp_msg_prio log_level = CVP_FW; + + if (!device) { + dprintk(CVP_ERR, "%s: Invalid params\n", __func__); + return; + } + + if (!packet) { + packet = kzalloc(CVP_IFACEQ_VAR_HUGE_PKT_SIZE, GFP_KERNEL); + if (!packet) { + dprintk(CVP_ERR, "In %s() Fail to allocate mem\n", + __func__); + return; + } + + local_packet = true; + + /* + * Local packek is used when something FATAL occurred. + * It is good to print these logs by default. + */ + + log_level = CVP_ERR; + } + +#define SKIP_INVALID_PKT(pkt_size, payload_size, pkt_hdr_size) ({ \ + if (pkt_size < pkt_hdr_size || \ + payload_size < MIN_PAYLOAD_SIZE || \ + payload_size > \ + (pkt_size - pkt_hdr_size + sizeof(u8))) { \ + dprintk(CVP_ERR, \ + "%s: invalid msg size - %d\n", \ + __func__, pkt->msg_size); \ + continue; \ + } \ + }) + + while (!__iface_dbgq_read(device, packet)) { + struct cvp_hfi_packet_header *pkt = + (struct cvp_hfi_packet_header *) packet; + + if (pkt->size < sizeof(struct cvp_hfi_packet_header)) { + dprintk(CVP_ERR, "Invalid pkt size - %s\n", + __func__); + continue; + } + + if (pkt->packet_type == HFI_MSG_SYS_DEBUG) { + struct cvp_hfi_msg_sys_debug_packet *pkt = + (struct cvp_hfi_msg_sys_debug_packet *) packet; + + SKIP_INVALID_PKT(pkt->size, + pkt->msg_size, sizeof(*pkt)); + + /* + * All fw messages starts with new line character. This + * causes dprintk to print this message in two lines + * in the kernel log. Ignoring the first character + * from the message fixes this to print it in a single + * line. + */ + pkt->rg_msg_data[pkt->msg_size-1] = '\0'; + dprintk(log_level, "%s", &pkt->rg_msg_data[1]); + } + } +#undef SKIP_INVALID_PKT + + if (local_packet) + kfree(packet); +} + +static bool __is_session_valid(struct iris_hfi_device *device, + struct cvp_hal_session *session, const char *func) +{ + struct cvp_hal_session *temp = NULL; + + if (!device || !session) + goto invalid; + + list_for_each_entry(temp, &device->sess_head, list) + if (session == temp) + return true; + +invalid: + dprintk(CVP_WARN, "%s: device %pK, invalid session %pK\n", + func, device, session); + return false; +} + +static struct cvp_hal_session *__get_session(struct iris_hfi_device *device, + u32 session_id) +{ + struct cvp_hal_session *temp = NULL; + + list_for_each_entry(temp, &device->sess_head, list) { + if (session_id == hash32_ptr(temp)) + return temp; + } + + return NULL; +} + +#define _INVALID_MSG_ "Unrecognized MSG (%#x) session (%pK), discarding\n" +#define _INVALID_STATE_ "Ignore responses from %d to %d invalid state\n" +#define _DEVFREQ_FAIL_ "Failed to add devfreq device bus %s governor %s: %d\n" + +static void process_system_msg(struct msm_cvp_cb_info *info, + struct iris_hfi_device *device, + void *raw_packet) +{ + struct cvp_hal_sys_init_done sys_init_done = {0}; + + switch (info->response_type) { + case HAL_SYS_ERROR: + __process_sys_error(device); + break; + case HAL_SYS_RELEASE_RESOURCE_DONE: + dprintk(CVP_CORE, "Received SYS_RELEASE_RESOURCE\n"); + break; + case HAL_SYS_INIT_DONE: + dprintk(CVP_CORE, "Received SYS_INIT_DONE\n"); + sys_init_done.capabilities = + device->sys_init_capabilities; + cvp_hfi_process_sys_init_done_prop_read( + (struct cvp_hfi_msg_sys_init_done_packet *) + raw_packet, &sys_init_done); + info->response.cmd.data.sys_init_done = sys_init_done; + break; + default: + break; + } +} + + +static void **get_session_id(struct msm_cvp_cb_info *info) +{ + void **session_id = NULL; + + /* For session-related packets, validate session */ + switch (info->response_type) { + case HAL_SESSION_INIT_DONE: + case HAL_SESSION_END_DONE: + case HAL_SESSION_ABORT_DONE: + case HAL_SESSION_STOP_DONE: + case HAL_SESSION_FLUSH_DONE: + case HAL_SESSION_SET_BUFFER_DONE: + case HAL_SESSION_SUSPEND_DONE: + case HAL_SESSION_RESUME_DONE: + case HAL_SESSION_SET_PROP_DONE: + case HAL_SESSION_GET_PROP_DONE: + case HAL_SESSION_RELEASE_BUFFER_DONE: + case HAL_SESSION_REGISTER_BUFFER_DONE: + case HAL_SESSION_UNREGISTER_BUFFER_DONE: + case HAL_SESSION_DFS_CONFIG_CMD_DONE: + case HAL_SESSION_DME_CONFIG_CMD_DONE: + case HAL_SESSION_TME_CONFIG_CMD_DONE: + case HAL_SESSION_ODT_CONFIG_CMD_DONE: + case HAL_SESSION_OD_CONFIG_CMD_DONE: + case HAL_SESSION_NCC_CONFIG_CMD_DONE: + case HAL_SESSION_ICA_CONFIG_CMD_DONE: + case HAL_SESSION_HCD_CONFIG_CMD_DONE: + case HAL_SESSION_DCM_CONFIG_CMD_DONE: + case HAL_SESSION_DC_CONFIG_CMD_DONE: + case HAL_SESSION_PYS_HCD_CONFIG_CMD_DONE: + case HAL_SESSION_DME_BASIC_CONFIG_CMD_DONE: + case HAL_SESSION_DFS_FRAME_CMD_DONE: + case HAL_SESSION_DME_FRAME_CMD_DONE: + case HAL_SESSION_ICA_FRAME_CMD_DONE: + case HAL_SESSION_FD_FRAME_CMD_DONE: + case HAL_SESSION_PERSIST_SET_DONE: + case HAL_SESSION_PERSIST_REL_DONE: + case HAL_SESSION_FD_CONFIG_CMD_DONE: + case HAL_SESSION_MODEL_BUF_CMD_DONE: + case HAL_SESSION_PROPERTY_INFO: + case HAL_SESSION_EVENT_CHANGE: + session_id = &info->response.cmd.session_id; + break; + case HAL_SESSION_ERROR: + session_id = &info->response.data.session_id; + break; + case HAL_RESPONSE_UNUSED: + default: + session_id = NULL; + break; + } + return session_id; +} + +static void print_msg_hdr(void *hdr) +{ + struct cvp_hfi_msg_session_hdr *new_hdr = + (struct cvp_hfi_msg_session_hdr *)hdr; + dprintk(CVP_HFI, "HFI MSG received: %x %x %x %x %x %x %x\n", + new_hdr->size, new_hdr->packet_type, + new_hdr->session_id, + new_hdr->client_data.transaction_id, + new_hdr->client_data.data1, + new_hdr->client_data.data2, + new_hdr->error_type); +} + +static int __response_handler(struct iris_hfi_device *device) +{ + struct msm_cvp_cb_info *packets; + int packet_count = 0; + u8 *raw_packet = NULL; + bool requeue_pm_work = true; + + if (!device || device->state != IRIS_STATE_INIT) + return 0; + + packets = device->response_pkt; + + raw_packet = device->raw_packet; + + if (!raw_packet || !packets) { + dprintk(CVP_ERR, + "%s: Invalid args : Res packet = %p, Raw packet = %p\n", + __func__, packets, raw_packet); + return 0; + } + + if (device->intr_status & CVP_FATAL_INTR_BMSK) { + struct cvp_hfi_sfr_struct *vsfr = (struct cvp_hfi_sfr_struct *) + device->sfr.align_virtual_addr; + struct msm_cvp_cb_info info = { + .response_type = HAL_SYS_WATCHDOG_TIMEOUT, + .response.cmd = { + .device_id = device->device_id, + } + }; + + if (vsfr) + dprintk(CVP_ERR, "SFR Message from FW: %s\n", + vsfr->rg_data); + if (device->intr_status & CVP_WRAPPER_INTR_MASK_CPU_NOC_BMSK) + dprintk(CVP_ERR, "Received Xtensa NOC error\n"); + + if (device->intr_status & CVP_WRAPPER_INTR_MASK_CORE_NOC_BMSK) + dprintk(CVP_ERR, "Received CVP core NOC error\n"); + + if (device->intr_status & CVP_WRAPPER_INTR_MASK_A2HWD_BMSK) + dprintk(CVP_ERR, "Received CVP watchdog timeout\n"); + + packets[packet_count++] = info; + goto exit; + } + + /* Bleed the msg queue dry of packets */ + while (!__iface_msgq_read(device, raw_packet)) { + void **session_id = NULL; + struct msm_cvp_cb_info *info = &packets[packet_count++]; + struct cvp_hfi_msg_session_hdr *hdr = + (struct cvp_hfi_msg_session_hdr *)raw_packet; + int rc = 0; + + print_msg_hdr(hdr); + rc = cvp_hfi_process_msg_packet(device->device_id, + raw_packet, info); + if (rc) { + dprintk(CVP_WARN, + "Corrupt/unknown packet found, discarding\n"); + --packet_count; + continue; + } else if (info->response_type == HAL_NO_RESP) { + --packet_count; + continue; + } + + /* Process the packet types that we're interested in */ + process_system_msg(info, device, raw_packet); + + session_id = get_session_id(info); + /* + * hfi_process_msg_packet provides a session_id that's a hashed + * value of struct cvp_hal_session, we need to coerce the hashed + * value back to pointer that we can use. Ideally, hfi_process\ + * _msg_packet should take care of this, but it doesn't have + * required information for it + */ + if (session_id) { + struct cvp_hal_session *session = NULL; + + if (upper_32_bits((uintptr_t)*session_id) != 0) { + dprintk(CVP_ERR, + "Upper 32-bits != 0 for sess_id=%pK\n", + *session_id); + } + session = __get_session(device, + (u32)(uintptr_t)*session_id); + if (!session) { + dprintk(CVP_ERR, _INVALID_MSG_, + info->response_type, + *session_id); + --packet_count; + continue; + } + + *session_id = session->session_id; + } + + if (packet_count >= cvp_max_packets) { + dprintk(CVP_WARN, + "Too many packets in message queue!\n"); + break; + } + + /* do not read packets after sys error packet */ + if (info->response_type == HAL_SYS_ERROR) + break; + } + + if (requeue_pm_work && device->res->sw_power_collapsible) { + cancel_delayed_work(&iris_hfi_pm_work); + if (!queue_delayed_work(device->iris_pm_workq, + &iris_hfi_pm_work, + msecs_to_jiffies( + device->res->msm_cvp_pwr_collapse_delay))) { + dprintk(CVP_ERR, "PM work already scheduled\n"); + } + } + +exit: + __flush_debug_queue(device, raw_packet); + + return packet_count; +} + +static void iris_hfi_core_work_handler(struct work_struct *work) +{ + struct msm_cvp_core *core; + struct iris_hfi_device *device; + int num_responses = 0, i = 0; + u32 intr_status; + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (core) + device = core->device->hfi_device_data; + else + return; + + mutex_lock(&device->lock); + + + if (!__core_in_valid_state(device)) { + dprintk(CVP_WARN, "%s - Core not in init state\n", __func__); + goto err_no_work; + } + + if (!device->callback) { + dprintk(CVP_ERR, "No interrupt callback function: %pK\n", + device); + goto err_no_work; + } + + if (__resume(device)) { + dprintk(CVP_ERR, "%s: Power enable failed\n", __func__); + goto err_no_work; + } + + __core_clear_interrupt(device); + num_responses = __response_handler(device); + dprintk(CVP_HFI, "%s:: cvp_driver_debug num_responses = %d ", + __func__, num_responses); + +err_no_work: + + /* Keep the interrupt status before releasing device lock */ + intr_status = device->intr_status; + mutex_unlock(&device->lock); + + /* + * Issue the callbacks outside of the locked contex to preserve + * re-entrancy. + */ + + for (i = 0; !IS_ERR_OR_NULL(device->response_pkt) && + i < num_responses; ++i) { + struct msm_cvp_cb_info *r = &device->response_pkt[i]; + void *rsp = (void *)&r->response; + + if (!__core_in_valid_state(device)) { + dprintk(CVP_ERR, + _INVALID_STATE_, (i + 1), num_responses); + break; + } + dprintk(CVP_HFI, "Processing response %d of %d, type %d\n", + (i + 1), num_responses, r->response_type); + device->callback(r->response_type, rsp); + } + + /* We need re-enable the irq which was disabled in ISR handler */ + if (!(intr_status & CVP_WRAPPER_INTR_STATUS_A2HWD_BMSK)) + enable_irq(device->cvp_hal_data->irq); + + /* + * XXX: Don't add any code beyond here. Reacquiring locks after release + * it above doesn't guarantee the atomicity that we're aiming for. + */ +} + +static DECLARE_WORK(iris_hfi_work, iris_hfi_core_work_handler); + +static irqreturn_t iris_hfi_isr(int irq, void *dev) +{ + struct iris_hfi_device *device = dev; + + disable_irq_nosync(irq); + queue_work(device->cvp_workq, &iris_hfi_work); + return IRQ_HANDLED; +} + +static int __init_regs_and_interrupts(struct iris_hfi_device *device, + struct msm_cvp_platform_resources *res) +{ + struct cvp_hal_data *hal = NULL; + int rc = 0; + + rc = __check_core_registered(device, res->firmware_base, + (u8 *)(uintptr_t)res->register_base, + res->register_size, res->irq); + if (!rc) { + dprintk(CVP_ERR, "Core present/Already added\n"); + rc = -EEXIST; + goto err_core_init; + } + + hal = kzalloc(sizeof(*hal), GFP_KERNEL); + if (!hal) { + dprintk(CVP_ERR, "Failed to alloc\n"); + rc = -ENOMEM; + goto err_core_init; + } + + hal->irq = res->irq; + hal->firmware_base = res->firmware_base; + hal->register_base = devm_ioremap_nocache(&res->pdev->dev, + res->register_base, res->register_size); + hal->register_size = res->register_size; + if (!hal->register_base) { + dprintk(CVP_ERR, + "could not map reg addr %pa of size %d\n", + &res->register_base, res->register_size); + goto error_irq_fail; + } + + device->cvp_hal_data = hal; + rc = request_irq(res->irq, iris_hfi_isr, IRQF_TRIGGER_HIGH, + "msm_cvp", device); + if (unlikely(rc)) { + dprintk(CVP_ERR, "() :request_irq failed\n"); + goto error_irq_fail; + } + + disable_irq_nosync(res->irq); + dprintk(CVP_INFO, + "firmware_base = %pa, register_base = %pa, register_size = %d\n", + &res->firmware_base, &res->register_base, + res->register_size); + return rc; + +error_irq_fail: + kfree(hal); +err_core_init: + return rc; + +} + +static inline void __deinit_clocks(struct iris_hfi_device *device) +{ + struct clock_info *cl; + + device->clk_freq = 0; + iris_hfi_for_each_clock_reverse(device, cl) { + if (cl->clk) { + clk_put(cl->clk); + cl->clk = NULL; + } + } +} + +static inline int __init_clocks(struct iris_hfi_device *device) +{ + int rc = 0; + struct clock_info *cl = NULL; + + if (!device) { + dprintk(CVP_ERR, "Invalid params: %pK\n", device); + return -EINVAL; + } + + iris_hfi_for_each_clock(device, cl) { + + dprintk(CVP_PWR, "%s: scalable? %d, count %d\n", + cl->name, cl->has_scaling, cl->count); + } + + iris_hfi_for_each_clock(device, cl) { + if (!cl->clk) { + cl->clk = clk_get(&device->res->pdev->dev, cl->name); + if (IS_ERR_OR_NULL(cl->clk)) { + dprintk(CVP_ERR, + "Failed to get clock: %s\n", cl->name); + rc = PTR_ERR(cl->clk) ?: -EINVAL; + cl->clk = NULL; + goto err_clk_get; + } + } + } + device->clk_freq = 0; + return 0; + +err_clk_get: + __deinit_clocks(device); + return rc; +} + +static int __handle_reset_clk(struct msm_cvp_platform_resources *res, + int reset_index, enum reset_state state, + enum power_state pwr_state) +{ + int rc = 0; + struct reset_control *rst; + struct reset_info rst_info; + struct reset_set *rst_set = &res->reset_set; + + if (!rst_set->reset_tbl) + return 0; + + rst_info = rst_set->reset_tbl[reset_index]; + rst = rst_info.rst; + dprintk(CVP_PWR, "reset_clk: name %s reset_state %d rst %pK ps=%d\n", + rst_set->reset_tbl[reset_index].name, state, rst, pwr_state); + + switch (state) { + case INIT: + if (rst) + goto skip_reset_init; + + rst = devm_reset_control_get(&res->pdev->dev, + rst_set->reset_tbl[reset_index].name); + if (IS_ERR(rst)) + rc = PTR_ERR(rst); + + rst_set->reset_tbl[reset_index].rst = rst; + break; + case ASSERT: + if (!rst) { + rc = PTR_ERR(rst); + goto failed_to_reset; + } + + if (pwr_state != rst_info.required_state) + break; + + rc = reset_control_assert(rst); + break; + case DEASSERT: + if (!rst) { + rc = PTR_ERR(rst); + goto failed_to_reset; + } + + if (pwr_state != rst_info.required_state) + break; + + rc = reset_control_deassert(rst); + break; + default: + dprintk(CVP_ERR, "Invalid reset request\n"); + if (rc) + goto failed_to_reset; + } + + return 0; + +skip_reset_init: +failed_to_reset: + return rc; +} + +static inline void __disable_unprepare_clks(struct iris_hfi_device *device) +{ + struct clock_info *cl; + + if (!device) { + dprintk(CVP_ERR, "Invalid params: %pK\n", device); + return; + } + + iris_hfi_for_each_clock_reverse(device, cl) { + dprintk(CVP_PWR, "Clock: %s disable and unprepare\n", + cl->name); + clk_disable_unprepare(cl->clk); + } +} + +static int reset_ahb2axi_bridge(struct iris_hfi_device *device) +{ + int rc, i; + enum power_state s; + + if (!device) { + dprintk(CVP_ERR, "NULL device\n"); + rc = -EINVAL; + goto failed_to_reset; + } + + if (device->power_enabled) + s = CVP_POWER_ON; + else + s = CVP_POWER_OFF; + + for (i = 0; i < device->res->reset_set.count; i++) { + rc = __handle_reset_clk(device->res, i, ASSERT, s); + if (rc) { + dprintk(CVP_ERR, + "failed to assert reset clocks\n"); + goto failed_to_reset; + } + + /* wait for deassert */ + usleep_range(400, 450); + + rc = __handle_reset_clk(device->res, i, DEASSERT, s); + if (rc) { + dprintk(CVP_ERR, + "failed to deassert reset clocks\n"); + goto failed_to_reset; + } + } + + return 0; + +failed_to_reset: + return rc; +} + +static inline int __prepare_enable_clks(struct iris_hfi_device *device) +{ + struct clock_info *cl = NULL, *cl_fail = NULL; + int rc = 0, c = 0; + + if (!device) { + dprintk(CVP_ERR, "Invalid params: %pK\n", device); + return -EINVAL; + } + + iris_hfi_for_each_clock(device, cl) { + /* + * For the clocks we control, set the rate prior to preparing + * them. Since we don't really have a load at this point, scale + * it to the lowest frequency possible + */ + if (cl->has_scaling) + clk_set_rate(cl->clk, clk_round_rate(cl->clk, 0)); + + rc = clk_prepare_enable(cl->clk); + if (rc) { + dprintk(CVP_ERR, "Failed to enable clocks\n"); + cl_fail = cl; + goto fail_clk_enable; + } + + c++; + dprintk(CVP_PWR, "Clock: %s prepared and enabled\n", cl->name); + } + + return rc; + +fail_clk_enable: + iris_hfi_for_each_clock_reverse_continue(device, cl, c) { + dprintk(CVP_ERR, "Clock: %s disable and unprepare\n", + cl->name); + clk_disable_unprepare(cl->clk); + } + + return rc; +} + +static void __deinit_bus(struct iris_hfi_device *device) +{ + struct bus_info *bus = NULL; + + if (!device) + return; + + kfree(device->bus_vote.data); + device->bus_vote = CVP_DEFAULT_BUS_VOTE; + + iris_hfi_for_each_bus_reverse(device, bus) { + dev_set_drvdata(bus->dev, NULL); + icc_put(bus->client); + bus->client = NULL; + } +} + +static int __init_bus(struct iris_hfi_device *device) +{ + struct bus_info *bus = NULL; + int rc = 0; + + if (!device) + return -EINVAL; + + iris_hfi_for_each_bus(device, bus) { + /* + * This is stupid, but there's no other easy way to ahold + * of struct bus_info in iris_hfi_devfreq_*() + */ + WARN(dev_get_drvdata(bus->dev), "%s's drvdata already set\n", + dev_name(bus->dev)); + dev_set_drvdata(bus->dev, device); + bus->client = icc_get(&device->res->pdev->dev, + bus->master, bus->slave); + if (IS_ERR_OR_NULL(bus->client)) { + rc = PTR_ERR(bus->client) ?: -EBADHANDLE; + dprintk(CVP_ERR, "Failed to register bus %s: %d\n", + bus->name, rc); + bus->client = NULL; + goto err_add_dev; + } + } + + return 0; + +err_add_dev: + __deinit_bus(device); + return rc; +} + +static void __deinit_regulators(struct iris_hfi_device *device) +{ + struct regulator_info *rinfo = NULL; + + iris_hfi_for_each_regulator_reverse(device, rinfo) { + if (rinfo->regulator) { + regulator_put(rinfo->regulator); + rinfo->regulator = NULL; + } + } +} + +static int __init_regulators(struct iris_hfi_device *device) +{ + int rc = 0; + struct regulator_info *rinfo = NULL; + + iris_hfi_for_each_regulator(device, rinfo) { + rinfo->regulator = regulator_get(&device->res->pdev->dev, + rinfo->name); + if (IS_ERR_OR_NULL(rinfo->regulator)) { + rc = PTR_ERR(rinfo->regulator) ?: -EBADHANDLE; + dprintk(CVP_ERR, "Failed to get regulator: %s\n", + rinfo->name); + rinfo->regulator = NULL; + goto err_reg_get; + } + } + + return 0; + +err_reg_get: + __deinit_regulators(device); + return rc; +} + +static void __deinit_subcaches(struct iris_hfi_device *device) +{ + struct subcache_info *sinfo = NULL; + + if (!device) { + dprintk(CVP_ERR, "deinit_subcaches: invalid device %pK\n", + device); + goto exit; + } + + if (!is_sys_cache_present(device)) + goto exit; + + iris_hfi_for_each_subcache_reverse(device, sinfo) { + if (sinfo->subcache) { + dprintk(CVP_CORE, "deinit_subcaches: %s\n", + sinfo->name); + llcc_slice_putd(sinfo->subcache); + sinfo->subcache = NULL; + } + } + +exit: + return; +} + +static int __init_subcaches(struct iris_hfi_device *device) +{ + int rc = 0; + struct subcache_info *sinfo = NULL; + + if (!device) { + dprintk(CVP_ERR, "init_subcaches: invalid device %pK\n", + device); + return -EINVAL; + } + + if (!is_sys_cache_present(device)) + return 0; + + iris_hfi_for_each_subcache(device, sinfo) { + if (!strcmp("cvp", sinfo->name)) { + sinfo->subcache = llcc_slice_getd(LLCC_CVP); + } else if (!strcmp("cvpfw", sinfo->name)) { + sinfo->subcache = llcc_slice_getd(LLCC_CVPFW); + } else { + dprintk(CVP_ERR, "Invalid subcache name %s\n", + sinfo->name); + } + if (IS_ERR_OR_NULL(sinfo->subcache)) { + rc = PTR_ERR(sinfo->subcache) ? + PTR_ERR(sinfo->subcache) : -EBADHANDLE; + dprintk(CVP_ERR, + "init_subcaches: invalid subcache: %s rc %d\n", + sinfo->name, rc); + sinfo->subcache = NULL; + goto err_subcache_get; + } + dprintk(CVP_CORE, "init_subcaches: %s\n", + sinfo->name); + } + + return 0; + +err_subcache_get: + __deinit_subcaches(device); + return rc; +} + +static int __init_resources(struct iris_hfi_device *device, + struct msm_cvp_platform_resources *res) +{ + int i, rc = 0; + + rc = __init_regulators(device); + if (rc) { + dprintk(CVP_ERR, "Failed to get all regulators\n"); + return -ENODEV; + } + + rc = __init_clocks(device); + if (rc) { + dprintk(CVP_ERR, "Failed to init clocks\n"); + rc = -ENODEV; + goto err_init_clocks; + } + + for (i = 0; i < device->res->reset_set.count; i++) { + rc = __handle_reset_clk(res, i, INIT, 0); + if (rc) { + dprintk(CVP_ERR, "Failed to init reset clocks\n"); + rc = -ENODEV; + goto err_init_reset_clk; + } + } + + rc = __init_bus(device); + if (rc) { + dprintk(CVP_ERR, "Failed to init bus: %d\n", rc); + goto err_init_bus; + } + + rc = __init_subcaches(device); + if (rc) + dprintk(CVP_WARN, "Failed to init subcaches: %d\n", rc); + + device->sys_init_capabilities = + kzalloc(sizeof(struct msm_cvp_capability) + * CVP_MAX_SESSIONS, GFP_KERNEL); + + return rc; + +err_init_reset_clk: +err_init_bus: + __deinit_clocks(device); +err_init_clocks: + __deinit_regulators(device); + return rc; +} + +static void __deinit_resources(struct iris_hfi_device *device) +{ + __deinit_subcaches(device); + __deinit_bus(device); + __deinit_clocks(device); + __deinit_regulators(device); + kfree(device->sys_init_capabilities); + device->sys_init_capabilities = NULL; +} + +static int __protect_cp_mem(struct iris_hfi_device *device) +{ + return device ? 0 : -EINVAL; +} + +static int __disable_regulator(struct regulator_info *rinfo, + struct iris_hfi_device *device) +{ + int rc = 0; + + dprintk(CVP_PWR, "Disabling regulator %s\n", rinfo->name); + + /* + * This call is needed. Driver needs to acquire the control back + * from HW in order to disable the regualtor. Else the behavior + * is unknown. + */ + + rc = __acquire_regulator(rinfo, device); + if (rc) { + /* + * This is somewhat fatal, but nothing we can do + * about it. We can't disable the regulator w/o + * getting it back under s/w control + */ + dprintk(CVP_WARN, + "Failed to acquire control on %s\n", + rinfo->name); + + goto disable_regulator_failed; + } + + rc = regulator_disable(rinfo->regulator); + if (rc) { + dprintk(CVP_WARN, + "Failed to disable %s: %d\n", + rinfo->name, rc); + goto disable_regulator_failed; + } + + return 0; +disable_regulator_failed: + + /* Bring attention to this issue */ + msm_cvp_res_handle_fatal_hw_error(device->res, true); + return rc; +} + +static int __enable_hw_power_collapse(struct iris_hfi_device *device) +{ + int rc = 0; + + if (!msm_cvp_fw_low_power_mode) { + dprintk(CVP_PWR, "Not enabling hardware power collapse\n"); + return 0; + } + + rc = __hand_off_regulators(device); + if (rc) + dprintk(CVP_WARN, + "%s : Failed to enable HW power collapse %d\n", + __func__, rc); + return rc; +} + +static int __enable_regulators(struct iris_hfi_device *device) +{ + int rc = 0, c = 0; + struct regulator_info *rinfo; + + dprintk(CVP_PWR, "Enabling regulators\n"); + + iris_hfi_for_each_regulator(device, rinfo) { + rc = regulator_enable(rinfo->regulator); + if (rc) { + dprintk(CVP_ERR, "Failed to enable %s: %d\n", + rinfo->name, rc); + goto err_reg_enable_failed; + } + + dprintk(CVP_PWR, "Enabled regulator %s\n", rinfo->name); + c++; + } + + return 0; + +err_reg_enable_failed: + iris_hfi_for_each_regulator_reverse_continue(device, rinfo, c) + __disable_regulator(rinfo, device); + + return rc; +} + +static int __disable_regulators(struct iris_hfi_device *device) +{ + struct regulator_info *rinfo; + + dprintk(CVP_PWR, "Disabling regulators\n"); + + iris_hfi_for_each_regulator_reverse(device, rinfo) { + __disable_regulator(rinfo, device); + if (rinfo->has_hw_power_collapse) + regulator_set_mode(rinfo->regulator, + REGULATOR_MODE_NORMAL); + } + + return 0; +} + +static int __enable_subcaches(struct iris_hfi_device *device) +{ + int rc = 0; + u32 c = 0; + struct subcache_info *sinfo; + + if (msm_cvp_syscache_disable || !is_sys_cache_present(device)) + return 0; + + /* Activate subcaches */ + iris_hfi_for_each_subcache(device, sinfo) { + rc = llcc_slice_activate(sinfo->subcache); + if (rc) { + dprintk(CVP_WARN, "Failed to activate %s: %d\n", + sinfo->name, rc); + msm_cvp_res_handle_fatal_hw_error(device->res, true); + goto err_activate_fail; + } + sinfo->isactive = true; + dprintk(CVP_CORE, "Activated subcache %s\n", sinfo->name); + c++; + } + + dprintk(CVP_CORE, "Activated %d Subcaches to CVP\n", c); + + return 0; + +err_activate_fail: + __release_subcaches(device); + __disable_subcaches(device); + return 0; +} + +static int __set_subcaches(struct iris_hfi_device *device) +{ + int rc = 0; + u32 c = 0; + struct subcache_info *sinfo; + u32 resource[CVP_MAX_SUBCACHE_SIZE]; + struct cvp_hfi_resource_syscache_info_type *sc_res_info; + struct cvp_hfi_resource_subcache_type *sc_res; + struct cvp_resource_hdr rhdr; + + if (device->res->sys_cache_res_set || msm_cvp_syscache_disable) { + dprintk(CVP_CORE, "Subcaches already set or disabled\n"); + return 0; + } + + memset((void *)resource, 0x0, (sizeof(u32) * CVP_MAX_SUBCACHE_SIZE)); + + sc_res_info = (struct cvp_hfi_resource_syscache_info_type *)resource; + sc_res = &(sc_res_info->rg_subcache_entries[0]); + + iris_hfi_for_each_subcache(device, sinfo) { + if (sinfo->isactive) { + sc_res[c].size = sinfo->subcache->slice_size; + sc_res[c].sc_id = sinfo->subcache->slice_id; + c++; + } + } + + /* Set resource to CVP for activated subcaches */ + if (c) { + dprintk(CVP_CORE, "Setting %d Subcaches\n", c); + + rhdr.resource_handle = sc_res_info; /* cookie */ + rhdr.resource_id = CVP_RESOURCE_SYSCACHE; + + sc_res_info->num_entries = c; + + rc = __core_set_resource(device, &rhdr, (void *)sc_res_info); + if (rc) { + dprintk(CVP_WARN, "Failed to set subcaches %d\n", rc); + goto err_fail_set_subacaches; + } + + iris_hfi_for_each_subcache(device, sinfo) { + if (sinfo->isactive) + sinfo->isset = true; + } + + dprintk(CVP_CORE, "Set Subcaches done to CVP\n"); + device->res->sys_cache_res_set = true; + } + + return 0; + +err_fail_set_subacaches: + __disable_subcaches(device); + + return 0; +} + +static int __release_subcaches(struct iris_hfi_device *device) +{ + struct subcache_info *sinfo; + int rc = 0; + u32 c = 0; + u32 resource[CVP_MAX_SUBCACHE_SIZE]; + struct cvp_hfi_resource_syscache_info_type *sc_res_info; + struct cvp_hfi_resource_subcache_type *sc_res; + struct cvp_resource_hdr rhdr; + + if (msm_cvp_syscache_disable || !is_sys_cache_present(device)) + return 0; + + memset((void *)resource, 0x0, (sizeof(u32) * CVP_MAX_SUBCACHE_SIZE)); + + sc_res_info = (struct cvp_hfi_resource_syscache_info_type *)resource; + sc_res = &(sc_res_info->rg_subcache_entries[0]); + + /* Release resource command to Iris */ + iris_hfi_for_each_subcache_reverse(device, sinfo) { + if (sinfo->isset) { + /* Update the entry */ + sc_res[c].size = sinfo->subcache->slice_size; + sc_res[c].sc_id = sinfo->subcache->slice_id; + c++; + sinfo->isset = false; + } + } + + if (c > 0) { + dprintk(CVP_CORE, "Releasing %d subcaches\n", c); + rhdr.resource_handle = sc_res_info; /* cookie */ + rhdr.resource_id = CVP_RESOURCE_SYSCACHE; + + rc = __core_release_resource(device, &rhdr); + if (rc) + dprintk(CVP_WARN, + "Failed to release %d subcaches\n", c); + } + + device->res->sys_cache_res_set = false; + + return 0; +} + +static int __disable_subcaches(struct iris_hfi_device *device) +{ + struct subcache_info *sinfo; + int rc = 0; + + if (msm_cvp_syscache_disable || !is_sys_cache_present(device)) + return 0; + + /* De-activate subcaches */ + iris_hfi_for_each_subcache_reverse(device, sinfo) { + if (sinfo->isactive) { + dprintk(CVP_CORE, "De-activate subcache %s\n", + sinfo->name); + rc = llcc_slice_deactivate(sinfo->subcache); + if (rc) { + dprintk(CVP_WARN, + "Failed to de-activate %s: %d\n", + sinfo->name, rc); + } + sinfo->isactive = false; + } + } + + return 0; +} + +static void interrupt_init_iris2(struct iris_hfi_device *device) +{ + u32 mask_val = 0; + + /* All interrupts should be disabled initially 0x1F6 : Reset value */ + mask_val = __read_register(device, CVP_WRAPPER_INTR_MASK); + + /* Write 0 to unmask CPU and WD interrupts */ + mask_val &= ~(CVP_FATAL_INTR_BMSK | CVP_WRAPPER_INTR_MASK_A2HCPU_BMSK); + __write_register(device, CVP_WRAPPER_INTR_MASK, mask_val); + dprintk(CVP_REG, "Init irq: reg: %x, mask value %x\n", + CVP_WRAPPER_INTR_MASK, mask_val); +} + +static void setup_dsp_uc_memmap_vpu5(struct iris_hfi_device *device) +{ + /* initialize DSP QTBL & UCREGION with CPU queues */ + __write_register(device, HFI_DSP_QTBL_ADDR, + (u32)device->dsp_iface_q_table.align_device_addr); + __write_register(device, HFI_DSP_UC_REGION_ADDR, + (u32)device->dsp_iface_q_table.align_device_addr); + __write_register(device, HFI_DSP_UC_REGION_SIZE, + device->dsp_iface_q_table.mem_data.size); +} + +static void clock_config_on_enable_vpu5(struct iris_hfi_device *device) +{ + __write_register(device, CVP_WRAPPER_CPU_CLOCK_CONFIG, 0); +} + +static int __set_ubwc_config(struct iris_hfi_device *device) +{ + u8 packet[CVP_IFACEQ_VAR_SMALL_PKT_SIZE]; + int rc = 0; + + struct cvp_hfi_cmd_sys_set_property_packet *pkt = + (struct cvp_hfi_cmd_sys_set_property_packet *) &packet; + + if (!device->res->ubwc_config) + return 0; + + rc = call_hfi_pkt_op(device, sys_ubwc_config, pkt, + device->res->ubwc_config); + if (rc) { + dprintk(CVP_WARN, + "ubwc config setting to FW failed\n"); + rc = -ENOTEMPTY; + goto fail_to_set_ubwc_config; + } + + if (__iface_cmdq_write(device, pkt)) { + rc = -ENOTEMPTY; + goto fail_to_set_ubwc_config; + } + +fail_to_set_ubwc_config: + return rc; +} + +static int __iris_power_on(struct iris_hfi_device *device) +{ + int rc = 0; + + + if (device->power_enabled) + return 0; + + /* Vote for all hardware resources */ + rc = __vote_buses(device, device->bus_vote.data, + device->bus_vote.data_count); + if (rc) { + dprintk(CVP_ERR, "Failed to vote buses, err: %d\n", rc); + goto fail_vote_buses; + } + + rc = __enable_regulators(device); + if (rc) { + dprintk(CVP_ERR, "Failed to enable GDSC, err = %d\n", rc); + goto fail_enable_gdsc; + } + + rc = call_iris_op(device, reset_ahb2axi_bridge, device); + if (rc) { + dprintk(CVP_ERR, "Failed to reset ahb2axi: %d\n", rc); + goto fail_enable_clks; + } + + rc = __prepare_enable_clks(device); + if (rc) { + dprintk(CVP_ERR, "Failed to enable clocks: %d\n", rc); + goto fail_enable_clks; + } + + rc = __scale_clocks(device); + if (rc) { + dprintk(CVP_WARN, + "Failed to scale clocks, perf may regress\n"); + rc = 0; + } + + /*Do not access registers before this point!*/ + device->power_enabled = true; + + dprintk(CVP_PWR, "Done with scaling\n"); + /* + * Re-program all of the registers that get reset as a result of + * regulator_disable() and _enable() + */ + __set_registers(device); + + dprintk(CVP_CORE, "Done with register set\n"); + call_iris_op(device, interrupt_init, device); + dprintk(CVP_CORE, "Done with interrupt enabling\n"); + device->intr_status = 0; + enable_irq(device->cvp_hal_data->irq); + + /* + * Hand off control of regulators to h/w _after_ enabling clocks. + * Note that the GDSC will turn off when switching from normal + * (s/w triggered) to fast (HW triggered) unless the h/w vote is + * present. Since Iris isn't up yet, the GDSC will be off briefly. + */ + if (__enable_hw_power_collapse(device)) + dprintk(CVP_ERR, "Failed to enabled inter-frame PC\n"); + + return rc; + +fail_enable_clks: + __disable_regulators(device); +fail_enable_gdsc: + __unvote_buses(device); +fail_vote_buses: + device->power_enabled = false; + return rc; +} + +void power_off_common(struct iris_hfi_device *device) +{ + if (!device->power_enabled) + return; + + if (!(device->intr_status & CVP_WRAPPER_INTR_STATUS_A2HWD_BMSK)) + disable_irq_nosync(device->cvp_hal_data->irq); + device->intr_status = 0; + + __disable_unprepare_clks(device); + if (__disable_regulators(device)) + dprintk(CVP_WARN, "Failed to disable regulators\n"); + + if (__unvote_buses(device)) + dprintk(CVP_WARN, "Failed to unvote for buses\n"); + device->power_enabled = false; +} + +static inline int __suspend(struct iris_hfi_device *device) +{ + int rc = 0; + + if (!device) { + dprintk(CVP_ERR, "Invalid params: %pK\n", device); + return -EINVAL; + } else if (!device->power_enabled) { + dprintk(CVP_PWR, "Power already disabled\n"); + return 0; + } + + dprintk(CVP_PWR, "Entering suspend\n"); + + if (device->res->pm_qos_latency_us && + pm_qos_request_active(&device->qos)) + pm_qos_remove_request(&device->qos); + + rc = __tzbsp_set_cvp_state(TZ_SUBSYS_STATE_SUSPEND); + if (rc) { + dprintk(CVP_WARN, "Failed to suspend cvp core %d\n", rc); + goto err_tzbsp_suspend; + } + + __disable_subcaches(device); + + call_iris_op(device, power_off, device); + dprintk(CVP_PWR, "Iris power off\n"); + return rc; + +err_tzbsp_suspend: + return rc; +} + +static void power_off_iris2(struct iris_hfi_device *device) +{ + u32 lpi_status, reg_status = 0, count = 0, max_count = 1000; + u32 pc_ready, wfi_status, sbm_ln0_low; + u32 main_sbm_ln0_low, main_sbm_ln1_high; + + if (!device->power_enabled || !device->res->sw_power_collapsible) + return; + + if (!(device->intr_status & CVP_WRAPPER_INTR_STATUS_A2HWD_BMSK)) + disable_irq_nosync(device->cvp_hal_data->irq); + device->intr_status = 0; + + /* HPG 6.1.2 Step 1 */ + __write_register(device, CVP_CPU_CS_X2RPMh, 0x3); + + /* HPG 6.1.2 Step 2, noc to low power */ + __write_register(device, CVP_AON_WRAPPER_MVP_NOC_LPI_CONTROL, 0x1); + while (!reg_status && count < max_count) { + lpi_status = + __read_register(device, + CVP_AON_WRAPPER_MVP_NOC_LPI_STATUS); + reg_status = lpi_status & BIT(0); + /* Wait for noc lpi status to be set */ + usleep_range(50, 100); + count++; + } + dprintk(CVP_PWR, + "Noc: lpi_status %x noc_status %x (count %d)\n", + lpi_status, reg_status, count); + if (count == max_count) { + wfi_status = __read_register(device, CVP_WRAPPER_CPU_STATUS); + pc_ready = __read_register(device, CVP_CTRL_STATUS); + sbm_ln0_low = + __read_register(device, CVP_NOC_SBM_SENSELN0_LOW); + main_sbm_ln0_low = __read_register(device, + CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_LOW); + main_sbm_ln1_high = __read_register(device, + CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN1_HIGH); + dprintk(CVP_WARN, + "NOC not in qaccept status %x %x %x %x %x %x %x\n", + reg_status, lpi_status, wfi_status, pc_ready, + sbm_ln0_low, main_sbm_ln0_low, main_sbm_ln1_high); + } + + /* HPG 6.1.2 Step 3, debug bridge to low power */ + __write_register(device, + CVP_WRAPPER_DEBUG_BRIDGE_LPI_CONTROL, 0x7); + + reg_status = 0; + count = 0; + while ((reg_status != 0x7) && count < max_count) { + lpi_status = __read_register(device, + CVP_WRAPPER_DEBUG_BRIDGE_LPI_STATUS); + reg_status = lpi_status & 0x7; + /* Wait for debug bridge lpi status to be set */ + usleep_range(50, 100); + count++; + } + dprintk(CVP_PWR, + "DBLP Set : lpi_status %d reg_status %d (count %d)\n", + lpi_status, reg_status, count); + if (count == max_count) { + dprintk(CVP_WARN, + "DBLP Set: status %x %x\n", reg_status, lpi_status); + } + + /* HPG 6.1.2 Step 4, debug bridge to lpi release */ + __write_register(device, + CVP_WRAPPER_DEBUG_BRIDGE_LPI_CONTROL, 0x0); + lpi_status = 0x1; + count = 0; + while (lpi_status && count < max_count) { + lpi_status = __read_register(device, + CVP_WRAPPER_DEBUG_BRIDGE_LPI_STATUS); + usleep_range(50, 100); + count++; + } + dprintk(CVP_PWR, + "DBLP Release: lpi_status %d(count %d)\n", + lpi_status, count); + if (count == max_count) { + dprintk(CVP_WARN, + "DBLP Release: lpi_status %x\n", lpi_status); + } + + /* HPG 6.1.2 Step 6 */ + __disable_unprepare_clks(device); + + /* HPG 6.1.2 Step 7 & 8 */ + if (call_iris_op(device, reset_ahb2axi_bridge, device)) + dprintk(CVP_ERR, "Failed to reset ahb2axi\n"); + + if (__unvote_buses(device)) + dprintk(CVP_WARN, "Failed to unvote for buses\n"); + + /* HPG 6.1.2 Step 5 */ + if (__disable_regulators(device)) + dprintk(CVP_WARN, "Failed to disable regulators\n"); + + /*Do not access registers after this point!*/ + device->power_enabled = false; +} + +static inline int __resume(struct iris_hfi_device *device) +{ + int rc = 0; + u32 flags = 0, reg_gdsc, reg_cbcr; + + if (!device) { + dprintk(CVP_ERR, "Invalid params: %pK\n", device); + return -EINVAL; + } else if (device->power_enabled) { + goto exit; + } else if (!__core_in_valid_state(device)) { + dprintk(CVP_PWR, "iris_hfi_device in deinit state."); + return -EINVAL; + } + + dprintk(CVP_PWR, "Resuming from power collapse\n"); + rc = __iris_power_on(device); + if (rc) { + dprintk(CVP_ERR, "Failed to power on cvp\n"); + goto err_iris_power_on; + } + + + + reg_gdsc = __read_register(device, CVP_CC_MVS1C_GDSCR); + reg_cbcr = __read_register(device, CVP_CC_MVS1C_CBCR); + if (!(reg_gdsc & 0x80000000) || (reg_cbcr & 0x80000000)) + dprintk(CVP_ERR, "CVP power on failed gdsc %x cbcr %x\n", + reg_gdsc, reg_cbcr); + + /* Reboot the firmware */ + rc = __tzbsp_set_cvp_state(TZ_SUBSYS_STATE_RESUME); + if (rc) { + dprintk(CVP_ERR, "Failed to resume cvp core %d\n", rc); + goto err_set_cvp_state; + } + + __setup_ucregion_memory_map(device); + /* Wait for boot completion */ + rc = __boot_firmware(device); + if (rc) { + dprintk(CVP_ERR, "Failed to reset cvp core\n"); + goto err_reset_core; + } + + /* + * Work around for H/W bug, need to reprogram these registers once + * firmware is out reset + */ + __set_threshold_registers(device); + + if (device->res->pm_qos_latency_us) + pm_qos_add_request(&device->qos, PM_QOS_CPU_DMA_LATENCY, + device->res->pm_qos_latency_us); + + __sys_set_debug(device, msm_cvp_fw_debug); + + __enable_subcaches(device); + __set_subcaches(device); + + + __dsp_resume(device, flags); + + dprintk(CVP_PWR, "Resumed from power collapse\n"); +exit: + /* Don't reset skip_pc_count for SYS_PC_PREP cmd */ + if (device->last_packet_type != HFI_CMD_SYS_PC_PREP) + device->skip_pc_count = 0; + return rc; +err_reset_core: + __tzbsp_set_cvp_state(TZ_SUBSYS_STATE_SUSPEND); +err_set_cvp_state: + call_iris_op(device, power_off, device); +err_iris_power_on: + dprintk(CVP_ERR, "Failed to resume from power collapse\n"); + return rc; +} + +static int __load_fw(struct iris_hfi_device *device) +{ + int rc = 0; + + /* Initialize resources */ + rc = __init_resources(device, device->res); + if (rc) { + dprintk(CVP_ERR, "Failed to init resources: %d\n", rc); + goto fail_init_res; + } + + rc = __initialize_packetization(device); + if (rc) { + dprintk(CVP_ERR, "Failed to initialize packetization\n"); + goto fail_init_pkt; + } + + rc = __iris_power_on(device); + if (rc) { + dprintk(CVP_ERR, "Failed to power on iris in in load_fw\n"); + goto fail_iris_power_on; + } + + if ((!device->res->use_non_secure_pil && !device->res->firmware_base) + || device->res->use_non_secure_pil) { + if (!device->resources.fw.cookie) + device->resources.fw.cookie = + subsystem_get_with_fwname("evass", + device->res->fw_name); + + if (IS_ERR_OR_NULL(device->resources.fw.cookie)) { + dprintk(CVP_ERR, "Failed to download firmware\n"); + device->resources.fw.cookie = NULL; + rc = -ENOMEM; + goto fail_load_fw; + } + } + + if (!device->res->firmware_base) { + rc = __protect_cp_mem(device); + if (rc) { + dprintk(CVP_ERR, "Failed to protect memory\n"); + goto fail_protect_mem; + } + } + return rc; +fail_protect_mem: + if (device->resources.fw.cookie) + subsystem_put(device->resources.fw.cookie); + device->resources.fw.cookie = NULL; +fail_load_fw: + call_iris_op(device, power_off, device); +fail_iris_power_on: +fail_init_pkt: + __deinit_resources(device); +fail_init_res: + return rc; +} + +static void __unload_fw(struct iris_hfi_device *device) +{ + if (!device->resources.fw.cookie) + return; + + cancel_delayed_work(&iris_hfi_pm_work); + if (device->state != IRIS_STATE_DEINIT) + flush_workqueue(device->iris_pm_workq); + + subsystem_put(device->resources.fw.cookie); + __interface_queues_release(device); + call_iris_op(device, power_off, device); + device->resources.fw.cookie = NULL; + __deinit_resources(device); + + dprintk(CVP_WARN, "Firmware unloaded\n"); +} + +static int iris_hfi_get_fw_info(void *dev, struct cvp_hal_fw_info *fw_info) +{ + int i = 0; + struct iris_hfi_device *device = dev; + + if (!device || !fw_info) { + dprintk(CVP_ERR, + "%s Invalid parameter: device = %pK fw_info = %pK\n", + __func__, device, fw_info); + return -EINVAL; + } + + mutex_lock(&device->lock); + + while (cvp_driver->fw_version[i++] != 'V' && i < CVP_VERSION_LENGTH) + ; + + if (i == CVP_VERSION_LENGTH - 1) { + dprintk(CVP_WARN, "Iris version string is not proper\n"); + fw_info->version[0] = '\0'; + goto fail_version_string; + } + + memcpy(&fw_info->version[0], &cvp_driver->fw_version[0], + CVP_VERSION_LENGTH); + fw_info->version[CVP_VERSION_LENGTH - 1] = '\0'; + +fail_version_string: + dprintk(CVP_CORE, "F/W version retrieved : %s\n", fw_info->version); + fw_info->base_addr = device->cvp_hal_data->firmware_base; + fw_info->register_base = device->res->register_base; + fw_info->register_size = device->cvp_hal_data->register_size; + fw_info->irq = device->cvp_hal_data->irq; + + mutex_unlock(&device->lock); + return 0; +} + +static int iris_hfi_get_core_capabilities(void *dev) +{ + dprintk(CVP_CORE, "%s not supported yet!\n", __func__); + return 0; +} + +static void __noc_error_info_iris2(struct iris_hfi_device *device) +{ + u32 val = 0; + + val = __read_register(device, CVP_NOC_ERR_SWID_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_SWID_LOW: %#x\n", val); + val = __read_register(device, CVP_NOC_ERR_SWID_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_SWID_HIGH: %#x\n", val); + val = __read_register(device, CVP_NOC_ERR_MAINCTL_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_MAINCTL_LOW: %#x\n", val); + val = __read_register(device, CVP_NOC_ERR_ERRVLD_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRVLD_LOW: %#x\n", val); + val = __read_register(device, CVP_NOC_ERR_ERRCLR_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRCLR_LOW: %#x\n", val); + val = __read_register(device, CVP_NOC_ERR_ERRLOG0_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG0_LOW: %#x\n", val); + val = __read_register(device, CVP_NOC_ERR_ERRLOG0_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG0_HIGH: %#x\n", val); + val = __read_register(device, CVP_NOC_ERR_ERRLOG1_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG1_LOW: %#x\n", val); + val = __read_register(device, CVP_NOC_ERR_ERRLOG1_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG1_HIGH: %#x\n", val); + val = __read_register(device, CVP_NOC_ERR_ERRLOG2_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG2_LOW: %#x\n", val); + val = __read_register(device, CVP_NOC_ERR_ERRLOG2_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG2_HIGH: %#x\n", val); + val = __read_register(device, CVP_NOC_ERR_ERRLOG3_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG3_LOW: %#x\n", val); + val = __read_register(device, CVP_NOC_ERR_ERRLOG3_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG3_HIGH: %#x\n", val); + + val = __read_register(device, CVP_NOC_CORE_ERR_SWID_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC__CORE_ERL_MAIN_SWID_LOW: %#x\n", val); + val = __read_register(device, CVP_NOC_CORE_ERR_SWID_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_SWID_HIGH: %#x\n", val); + val = __read_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_MAINCTL_LOW: %#x\n", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRVLD_LOW: %#x\n", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRCLR_LOW: %#x\n", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_LOW: %#x\n", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_HIGH: %#x\n", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_LOW: %#x\n", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_HIGH: %#x\n", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_LOW: %#x\n", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_HIGH: %#x\n", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG3_LOW: %#x\n", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG3_HIGH: %#x\n", val); +} + +static int iris_hfi_noc_error_info(void *dev) +{ + struct iris_hfi_device *device; + + if (!dev) { + dprintk(CVP_ERR, "%s: null device\n", __func__); + return -EINVAL; + } + device = dev; + + mutex_lock(&device->lock); + dprintk(CVP_ERR, "%s: non error information\n", __func__); + + call_iris_op(device, noc_error_info, device); + + mutex_unlock(&device->lock); + + return 0; +} + +static int __initialize_packetization(struct iris_hfi_device *device) +{ + int rc = 0; + + if (!device || !device->res) { + dprintk(CVP_ERR, "%s - invalid param\n", __func__); + return -EINVAL; + } + + device->packetization_type = HFI_PACKETIZATION_4XX; + + device->pkt_ops = cvp_hfi_get_pkt_ops_handle( + device->packetization_type); + if (!device->pkt_ops) { + rc = -EINVAL; + dprintk(CVP_ERR, "Failed to get pkt_ops handle\n"); + } + + return rc; +} + +void __init_cvp_ops(struct iris_hfi_device *device) +{ + device->vpu_ops = &iris2_ops; +} + +static struct iris_hfi_device *__add_device(u32 device_id, + struct msm_cvp_platform_resources *res, + hfi_cmd_response_callback callback) +{ + struct iris_hfi_device *hdevice = NULL; + int rc = 0; + + if (!res || !callback) { + dprintk(CVP_ERR, "Invalid Parameters\n"); + return NULL; + } + + dprintk(CVP_INFO, "%s: device_id: %d\n", __func__, device_id); + + hdevice = kzalloc(sizeof(*hdevice), GFP_KERNEL); + if (!hdevice) { + dprintk(CVP_ERR, "failed to allocate new device\n"); + goto exit; + } + + hdevice->response_pkt = kmalloc_array(cvp_max_packets, + sizeof(*hdevice->response_pkt), GFP_KERNEL); + if (!hdevice->response_pkt) { + dprintk(CVP_ERR, "failed to allocate response_pkt\n"); + goto err_cleanup; + } + + hdevice->raw_packet = + kzalloc(CVP_IFACEQ_VAR_HUGE_PKT_SIZE, GFP_KERNEL); + if (!hdevice->raw_packet) { + dprintk(CVP_ERR, "failed to allocate raw packet\n"); + goto err_cleanup; + } + + rc = __init_regs_and_interrupts(hdevice, res); + if (rc) + goto err_cleanup; + + hdevice->res = res; + hdevice->device_id = device_id; + hdevice->callback = callback; + + __init_cvp_ops(hdevice); + + hdevice->cvp_workq = create_singlethread_workqueue( + "msm_cvp_workerq_iris"); + if (!hdevice->cvp_workq) { + dprintk(CVP_ERR, ": create cvp workq failed\n"); + goto err_cleanup; + } + + hdevice->iris_pm_workq = create_singlethread_workqueue( + "pm_workerq_iris"); + if (!hdevice->iris_pm_workq) { + dprintk(CVP_ERR, ": create pm workq failed\n"); + goto err_cleanup; + } + + mutex_init(&hdevice->lock); + INIT_LIST_HEAD(&hdevice->sess_head); + + return hdevice; + +err_cleanup: + if (hdevice->iris_pm_workq) + destroy_workqueue(hdevice->iris_pm_workq); + if (hdevice->cvp_workq) + destroy_workqueue(hdevice->cvp_workq); + kfree(hdevice->response_pkt); + kfree(hdevice->raw_packet); + kfree(hdevice); +exit: + return NULL; +} + +static struct iris_hfi_device *__get_device(u32 device_id, + struct msm_cvp_platform_resources *res, + hfi_cmd_response_callback callback) +{ + if (!res || !callback) { + dprintk(CVP_ERR, "Invalid params: %pK %pK\n", res, callback); + return NULL; + } + + return __add_device(device_id, res, callback); +} + +void cvp_iris_hfi_delete_device(void *device) +{ + struct msm_cvp_core *core; + struct iris_hfi_device *dev = NULL; + + if (!device) + return; + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (core) + dev = core->device->hfi_device_data; + + if (!dev) + return; + + mutex_destroy(&dev->lock); + destroy_workqueue(dev->cvp_workq); + destroy_workqueue(dev->iris_pm_workq); + free_irq(dev->cvp_hal_data->irq, dev); + iounmap(dev->cvp_hal_data->register_base); + iounmap(dev->cvp_hal_data->gcc_reg_base); + kfree(dev->cvp_hal_data); + kfree(dev->response_pkt); + kfree(dev->raw_packet); + kfree(dev); +} + +static int iris_hfi_validate_session(void *sess, const char *func) +{ + struct cvp_hal_session *session = sess; + int rc = 0; + struct iris_hfi_device *device; + + if (!session || !session->device) { + dprintk(CVP_ERR, " %s Invalid Params %pK\n", __func__, session); + return -EINVAL; + } + + device = session->device; + mutex_lock(&device->lock); + if (!__is_session_valid(device, session, func)) + rc = -ECONNRESET; + + mutex_unlock(&device->lock); + return rc; +} + +static void iris_init_hfi_callbacks(struct cvp_hfi_device *hdev) +{ + hdev->core_init = iris_hfi_core_init; + hdev->core_release = iris_hfi_core_release; + hdev->core_trigger_ssr = iris_hfi_core_trigger_ssr; + hdev->session_init = iris_hfi_session_init; + hdev->session_end = iris_hfi_session_end; + hdev->session_abort = iris_hfi_session_abort; + hdev->session_clean = iris_hfi_session_clean; + hdev->session_set_buffers = iris_hfi_session_set_buffers; + hdev->session_release_buffers = iris_hfi_session_release_buffers; + hdev->session_send = iris_hfi_session_send; + hdev->session_flush = iris_hfi_session_flush; + hdev->scale_clocks = iris_hfi_scale_clocks; + hdev->vote_bus = iris_hfi_vote_buses; + hdev->get_fw_info = iris_hfi_get_fw_info; + hdev->get_core_capabilities = iris_hfi_get_core_capabilities; + hdev->suspend = iris_hfi_suspend; + hdev->resume = iris_hfi_resume; + hdev->flush_debug_queue = iris_hfi_flush_debug_queue; + hdev->noc_error_info = iris_hfi_noc_error_info; + hdev->validate_session = iris_hfi_validate_session; +} + +int cvp_iris_hfi_initialize(struct cvp_hfi_device *hdev, u32 device_id, + struct msm_cvp_platform_resources *res, + hfi_cmd_response_callback callback) +{ + int rc = 0; + + if (!hdev || !res || !callback) { + dprintk(CVP_ERR, "Invalid params: %pK %pK %pK\n", + hdev, res, callback); + rc = -EINVAL; + goto err_iris_hfi_init; + } + + hdev->hfi_device_data = __get_device(device_id, res, callback); + + if (IS_ERR_OR_NULL(hdev->hfi_device_data)) { + rc = PTR_ERR(hdev->hfi_device_data) ?: -EINVAL; + goto err_iris_hfi_init; + } + + iris_init_hfi_callbacks(hdev); + +err_iris_hfi_init: + return rc; +} + diff --git a/msm/eva/cvp_hfi.h b/msm/eva/cvp_hfi.h new file mode 100644 index 0000000000..c7142dcc41 --- /dev/null +++ b/msm/eva/cvp_hfi.h @@ -0,0 +1,216 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#ifndef __H_CVP_HFI_H__ +#define __H_CVP_HFI_H__ + +#include +#include "cvp_hfi_helper.h" +#include "cvp_hfi_api.h" + +#define HFI_CMD_SESSION_CVP_START \ + (HFI_DOMAIN_BASE_CVP + HFI_ARCH_COMMON_OFFSET + \ + HFI_CMD_START_OFFSET + 0x1000) + +#define HFI_CMD_SESSION_CVP_SET_BUFFERS\ + (HFI_CMD_SESSION_CVP_START + 0x001) +#define HFI_CMD_SESSION_CVP_RELEASE_BUFFERS\ + (HFI_CMD_SESSION_CVP_START + 0x002) + +#define HFI_CMD_SESSION_CVP_DS\ + (HFI_CMD_SESSION_CVP_START + 0x003) +#define HFI_CMD_SESSION_CVP_HCD_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x004) +#define HFI_CMD_SESSION_CVP_HCD_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x005) +#define HFI_CMD_SESSION_CVP_CV_HOG_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x006) +#define HFI_CMD_SESSION_CVP_CV_HOG_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x007) +#define HFI_CMD_SESSION_CVP_SVM\ + (HFI_CMD_SESSION_CVP_START + 0x008) +#define HFI_CMD_SESSION_CVP_NCC_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x009) +#define HFI_CMD_SESSION_CVP_NCC_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x00A) +#define HFI_CMD_SESSION_CVP_DFS_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x00B) +#define HFI_CMD_SESSION_CVP_DFS_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x00C) +#define HFI_CMD_SESSION_CVP_FTEXT\ + (HFI_CMD_SESSION_CVP_START + 0x00F) + +/* ==========CHAINED OPERATIONS===================*/ +#define HFI_CMD_SESSION_CVP_CV_HOG_SVM_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x010) +#define HFI_CMD_SESSION_CVP_CV_HOG_SVM_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x011) +#define HFI_CMD_SESSION_CVP_CV_HOG_SVM_HCD_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x012) +#define HFI_CMD_SESSION_CVP_CV_HOG_SVM_HCD_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x013) +#define HFI_CMD_SESSION_CVP_OPTICAL_FLOW\ + (HFI_CMD_SESSION_CVP_START + 0x014) + +/* ===========USECASE OPERATIONS===============*/ +#define HFI_CMD_SESSION_CVP_DC_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x030) +#define HFI_CMD_SESSION_CVP_DC_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x031) +#define HFI_CMD_SESSION_CVP_DCM_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x034) +#define HFI_CMD_SESSION_CVP_DCM_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x035) + +#define HFI_CMD_SESSION_CVP_DME_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x039) +#define HFI_CMD_SESSION_CVP_DME_BASIC_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x03B) +#define HFI_CMD_SESSION_CVP_DME_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x03A) + +#define HFI_CMD_SESSION_CVP_CV_TME_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x047) +#define HFI_CMD_SESSION_CVP_CV_TME_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x048) +#define HFI_CMD_SESSION_CVP_CV_OD_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x049) +#define HFI_CMD_SESSION_CVP_CV_OD_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x04A) +#define HFI_CMD_SESSION_CVP_CV_ODT_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x04B) +#define HFI_CMD_SESSION_CVP_CV_ODT_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x04C) + +#define HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS\ + (HFI_CMD_SESSION_CVP_START + 0x04D) +#define HFI_CMD_SESSION_CVP_PYS_HCD_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x050) +#define HFI_CMD_SESSION_CVP_PYS_HCD_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x051) +#define HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS\ + (HFI_CMD_SESSION_CVP_START + 0x052) +#define HFI_CMD_SESSION_CVP_FD_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x053) +#define HFI_CMD_SESSION_CVP_FD_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x054) +#define HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS\ + (HFI_CMD_SESSION_CVP_START + 0x055) +#define HFI_CMD_SESSION_CVP_FLUSH\ + (HFI_CMD_SESSION_CVP_START + 0x057) +#define HFI_CMD_SESSION_CVP_ICA_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x100) +#define HFI_CMD_SESSION_CVP_ICA_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x101) + + +#define HFI_MSG_SESSION_CVP_START \ + (HFI_DOMAIN_BASE_CVP + HFI_ARCH_COMMON_OFFSET + \ + HFI_MSG_START_OFFSET + 0x1000) + +#define HFI_MSG_SESSION_CVP_SET_BUFFERS\ + (HFI_MSG_SESSION_CVP_START + 0x001) +#define HFI_MSG_SESSION_CVP_RELEASE_BUFFERS \ + (HFI_MSG_SESSION_CVP_START + 0x002) +#define HFI_MSG_SESSION_CVP_DS\ + (HFI_MSG_SESSION_CVP_START + 0x003) +#define HFI_MSG_SESSION_CVP_HCD\ + (HFI_MSG_SESSION_CVP_START + 0x004) +#define HFI_MSG_SESSION_CVP_CV_HOG\ + (HFI_MSG_SESSION_CVP_START + 0x005) +#define HFI_MSG_SESSION_CVP_SVM\ + (HFI_MSG_SESSION_CVP_START + 0x006) +#define HFI_MSG_SESSION_CVP_NCC\ + (HFI_MSG_SESSION_CVP_START + 0x007) +#define HFI_MSG_SESSION_CVP_DFS\ + (HFI_MSG_SESSION_CVP_START + 0x008) +#define HFI_MSG_SESSION_CVP_TME\ + (HFI_MSG_SESSION_CVP_START + 0x009) +#define HFI_MSG_SESSION_CVP_FTEXT\ + (HFI_MSG_SESSION_CVP_START + 0x00A) + +#define HFI_MSG_SESSION_CVP_ICA\ + (HFI_MSG_SESSION_CVP_START + 0x014) + +#define HFI_MSG_SESSION_CVP_DME\ + (HFI_MSG_SESSION_CVP_START + 0x023) +#define HFI_MSG_SESSION_CVP_OPERATION_CONFIG (HFI_MSG_SESSION_CVP_START + 0x030) + +#define HFI_MSG_SESSION_CVP_SET_PERSIST_BUFFERS\ + (HFI_MSG_SESSION_CVP_START + 0x034) +#define HFI_MSG_SESSION_CVP_SET_MODEL_BUFFERS\ + (HFI_MSG_SESSION_CVP_START + 0x036) +#define HFI_MSG_SESSION_CVP_FD\ + (HFI_MSG_SESSION_CVP_START + 0x037) +#define HFI_MSG_SESSION_CVP_RELEASE_PERSIST_BUFFERS\ + (HFI_MSG_SESSION_CVP_START + 0x038) +#define HFI_MSG_SESSION_CVP_FLUSH_DEPRECATE\ + (HFI_CMD_SESSION_CVP_START + 0x03A) +#define HFI_MSG_SESSION_CVP_FLUSH\ + (HFI_MSG_SESSION_CVP_START + 0x03A) + +#define CVP_IFACEQ_MAX_PKT_SIZE 1024 +#define CVP_IFACEQ_MED_PKT_SIZE 768 +#define CVP_IFACEQ_MIN_PKT_SIZE 8 +#define CVP_IFACEQ_VAR_SMALL_PKT_SIZE 100 +#define CVP_IFACEQ_VAR_LARGE_PKT_SIZE 512 +#define CVP_IFACEQ_VAR_HUGE_PKT_SIZE (1024*12) + +struct cvp_hfi_cmd_session_flush_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 flush_type; +}; + +struct cvp_hfi_cmd_session_get_property_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 num_properties; + u32 rg_property_data[1]; +}; + +struct cvp_hfi_msg_sys_session_abort_done_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 error_type; +}; + +struct cvp_hfi_msg_sys_property_info_packet { + u32 size; + u32 packet_type; + u32 num_properties; + u32 rg_property_data[128]; +}; + +enum session_flags { + SESSION_PAUSE = BIT(1), +}; + +struct cvp_hal_session { + struct list_head list; + void *session_id; + u32 flags; + void *device; +}; + +struct msm_cvp_fw { + void *cookie; +}; + +int cvp_hfi_process_msg_packet(u32 device_id, + void *msg_hdr, struct msm_cvp_cb_info *info); + +enum cvp_status cvp_hfi_process_sys_init_done_prop_read( + struct cvp_hfi_msg_sys_init_done_packet *pkt, + struct cvp_hal_sys_init_done *sys_init_done); + +enum cvp_status hfi_process_session_init_done_prop_read( + struct cvp_hfi_msg_sys_session_init_done_packet *pkt, + struct cvp_hal_session_init_done *session_init_done); + +#endif diff --git a/msm/eva/cvp_hfi_api.h b/msm/eva/cvp_hfi_api.h new file mode 100644 index 0000000000..585dad12d3 --- /dev/null +++ b/msm/eva/cvp_hfi_api.h @@ -0,0 +1,379 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#ifndef __CVP_HFI_API_H__ +#define __CVP_HFI_API_H__ + +#include +#include +#include +#include +#include +#include "msm_cvp_core.h" +#include "msm_cvp_resources.h" +#include "cvp_hfi_helper.h" + +#define CONTAINS(__a, __sz, __t) (\ + (__t >= __a) && \ + (__t < __a + __sz) \ +) + +#define OVERLAPS(__t, __tsz, __a, __asz) (\ + (__t <= __a) && \ + (__t + __tsz >= __a + __asz) \ +) + +#define CVP_VERSION_LENGTH 128 + +/* 16 encoder and 16 decoder sessions */ +#define CVP_MAX_SESSIONS 32 + +#define HFI_DFS_CONFIG_CMD_SIZE 38 +#define HFI_DFS_FRAME_CMD_SIZE 16 +#define HFI_DFS_FRAME_BUFFERS_OFFSET 8 +#define HFI_DFS_BUF_NUM 4 + +#define HFI_DME_CONFIG_CMD_SIZE 194 +#define HFI_DME_BASIC_CONFIG_CMD_SIZE 51 +#define HFI_DME_FRAME_CMD_SIZE 28 +#define HFI_DME_FRAME_BUFFERS_OFFSET 12 +#define HFI_DME_BUF_NUM 8 + +#define HFI_PERSIST_CMD_SIZE 11 +#define HFI_PERSIST_BUFFERS_OFFSET 7 +#define HFI_PERSIST_BUF_NUM 2 + +#define HFI_DS_CMD_SIZE 50 +#define HFI_DS_BUFFERS_OFFSET 44 +#define HFI_DS_BUF_NUM 3 + +#define HFI_OF_CONFIG_CMD_SIZE 34 +#define HFI_OF_FRAME_CMD_SIZE 24 +#define HFI_OF_BUFFERS_OFFSET 8 +#define HFI_OF_BUF_NUM 8 + +#define HFI_ODT_CONFIG_CMD_SIZE 23 +#define HFI_ODT_FRAME_CMD_SIZE 33 +#define HFI_ODT_BUFFERS_OFFSET 11 +#define HFI_ODT_BUF_NUM 11 + +#define HFI_OD_CONFIG_CMD_SIZE 24 +#define HFI_OD_FRAME_CMD_SIZE 12 +#define HFI_OD_BUFFERS_OFFSET 6 +#define HFI_OD_BUF_NUM 3 + +#define HFI_NCC_CONFIG_CMD_SIZE 47 +#define HFI_NCC_FRAME_CMD_SIZE 22 +#define HFI_NCC_BUFFERS_OFFSET 8 +#define HFI_NCC_BUF_NUM 7 + +#define HFI_ICA_CONFIG_CMD_SIZE 127 +#define HFI_ICA_FRAME_CMD_SIZE 14 +#define HFI_ICA_BUFFERS_OFFSET 6 +#define HFI_ICA_BUF_NUM 4 + +#define HFI_HCD_CONFIG_CMD_SIZE 46 +#define HFI_HCD_FRAME_CMD_SIZE 18 +#define HFI_HCD_BUFFERS_OFFSET 12 +#define HFI_HCD_BUF_NUM 3 + +#define HFI_DCM_CONFIG_CMD_SIZE 20 +#define HFI_DCM_FRAME_CMD_SIZE 19 +#define HFI_DCM_BUFFERS_OFFSET 9 +#define HFI_DCM_BUF_NUM 5 + +#define HFI_PYS_HCD_CONFIG_CMD_SIZE 461 +#define HFI_PYS_HCD_FRAME_CMD_SIZE 66 +#define HFI_PYS_HCD_BUFFERS_OFFSET 14 +#define HFI_PYS_HCD_BUF_NUM 26 + +#define HFI_FD_CONFIG_CMD_SIZE 28 +#define HFI_FD_FRAME_CMD_SIZE 10 +#define HFI_FD_BUFFERS_OFFSET 6 +#define HFI_FD_BUF_NUM 2 + +#define HFI_MODEL_CMD_SIZE 9 +#define HFI_MODEL_BUFFERS_OFFSET 7 +#define HFI_MODEL_BUF_NUM 1 + +#define HFI_VERSION_MAJOR_MASK 0xFF000000 +#define HFI_VERSION_MAJOR_SHFIT 24 +#define HFI_VERSION_MINOR_MASK 0x00FFFFE0 +#define HFI_VERSION_MINOR_SHIFT 5 +#define HFI_VERSION_BRANCH_MASK 0x0000001F +#define HFI_VERSION_BRANCH_SHIFT 0 + +enum cvp_status { + CVP_ERR_NONE = 0x0, + CVP_ERR_FAIL = 0x80000000, + CVP_ERR_ALLOC_FAIL, + CVP_ERR_ILLEGAL_OP, + CVP_ERR_BAD_PARAM, + CVP_ERR_BAD_HANDLE, + CVP_ERR_NOT_SUPPORTED, + CVP_ERR_BAD_STATE, + CVP_ERR_MAX_CLIENTS, + CVP_ERR_IFRAME_EXPECTED, + CVP_ERR_HW_FATAL, + CVP_ERR_BITSTREAM_ERR, + CVP_ERR_INDEX_NOMORE, + CVP_ERR_SEQHDR_PARSE_FAIL, + CVP_ERR_INSUFFICIENT_BUFFER, + CVP_ERR_BAD_POWER_STATE, + CVP_ERR_NO_VALID_SESSION, + CVP_ERR_TIMEOUT, + CVP_ERR_CMDQFULL, + CVP_ERR_START_CODE_NOT_FOUND, + CVP_ERR_NOC_ERROR, + CVP_ERR_CLIENT_PRESENT = 0x90000001, + CVP_ERR_CLIENT_FATAL, + CVP_ERR_CMD_QUEUE_FULL, + CVP_ERR_UNUSED = 0x10000000 +}; + +enum hal_property { + HAL_UNUSED_PROPERTY = 0xFFFFFFFF, +}; + +enum hal_ssr_trigger_type { + SSR_ERR_FATAL = 1, + SSR_SW_DIV_BY_ZERO, + SSR_HW_WDOG_IRQ, + SSR_SESSION_ABORT, +}; + +enum hal_intra_refresh_mode { + HAL_INTRA_REFRESH_NONE, + HAL_INTRA_REFRESH_CYCLIC, + HAL_INTRA_REFRESH_RANDOM, + HAL_UNUSED_INTRA = 0x10000000, +}; + +enum cvp_resource_id { + CVP_RESOURCE_NONE, + CVP_RESOURCE_SYSCACHE, + CVP_UNUSED_RESOURCE = 0x10000000, +}; + +struct cvp_resource_hdr { + enum cvp_resource_id resource_id; + void *resource_handle; +}; + +struct cvp_hal_fw_info { + char version[CVP_VERSION_LENGTH]; + phys_addr_t base_addr; + int register_base; + int register_size; + int irq; +}; + +enum hal_event_type { + HAL_EVENT_SEQ_CHANGED_SUFFICIENT_RESOURCES, + HAL_EVENT_SEQ_CHANGED_INSUFFICIENT_RESOURCES, + HAL_EVENT_RELEASE_BUFFER_REFERENCE, + HAL_UNUSED_SEQCHG = 0x10000000, +}; + +/* HAL Response */ +#define IS_HAL_SYS_CMD(cmd) ((cmd) >= HAL_SYS_INIT_DONE && \ + (cmd) <= HAL_SYS_ERROR) +#define IS_HAL_SESSION_CMD(cmd) ((cmd) >= HAL_SESSION_EVENT_CHANGE && \ + (cmd) <= HAL_SESSION_ERROR) +enum hal_command_response { + HAL_NO_RESP, + HAL_SYS_INIT_DONE, + HAL_SYS_SET_RESOURCE_DONE, + HAL_SYS_RELEASE_RESOURCE_DONE, + HAL_SYS_PING_ACK_DONE, + HAL_SYS_PC_PREP_DONE, + HAL_SYS_IDLE, + HAL_SYS_DEBUG, + HAL_SYS_WATCHDOG_TIMEOUT, + HAL_SYS_ERROR, + /* SESSION COMMANDS_DONE */ + HAL_SESSION_EVENT_CHANGE, + HAL_SESSION_INIT_DONE, + HAL_SESSION_END_DONE, + HAL_SESSION_SET_BUFFER_DONE, + HAL_SESSION_ABORT_DONE, + HAL_SESSION_STOP_DONE, + HAL_SESSION_CVP_OPERATION_CONFIG, + HAL_SESSION_FLUSH_DONE, + HAL_SESSION_SUSPEND_DONE, + HAL_SESSION_RESUME_DONE, + HAL_SESSION_SET_PROP_DONE, + HAL_SESSION_GET_PROP_DONE, + HAL_SESSION_RELEASE_BUFFER_DONE, + HAL_SESSION_REGISTER_BUFFER_DONE, + HAL_SESSION_UNREGISTER_BUFFER_DONE, + HAL_SESSION_RELEASE_RESOURCE_DONE, + HAL_SESSION_DFS_CONFIG_CMD_DONE, + HAL_SESSION_DFS_FRAME_CMD_DONE, + HAL_SESSION_DME_CONFIG_CMD_DONE, + HAL_SESSION_DME_BASIC_CONFIG_CMD_DONE, + HAL_SESSION_DME_FRAME_CMD_DONE, + HAL_SESSION_TME_CONFIG_CMD_DONE, + HAL_SESSION_ODT_CONFIG_CMD_DONE, + HAL_SESSION_OD_CONFIG_CMD_DONE, + HAL_SESSION_NCC_CONFIG_CMD_DONE, + HAL_SESSION_ICA_CONFIG_CMD_DONE, + HAL_SESSION_HCD_CONFIG_CMD_DONE, + HAL_SESSION_DC_CONFIG_CMD_DONE, + HAL_SESSION_DCM_CONFIG_CMD_DONE, + HAL_SESSION_PYS_HCD_CONFIG_CMD_DONE, + HAL_SESSION_FD_CONFIG_CMD_DONE, + HAL_SESSION_PERSIST_SET_DONE, + HAL_SESSION_PERSIST_REL_DONE, + HAL_SESSION_MODEL_BUF_CMD_DONE, + HAL_SESSION_ICA_FRAME_CMD_DONE, + HAL_SESSION_FD_FRAME_CMD_DONE, + HAL_SESSION_PROPERTY_INFO, + HAL_SESSION_ERROR, + HAL_RESPONSE_UNUSED = 0x10000000, +}; + +struct msm_cvp_capability { + u32 reserved[183]; +}; + +struct cvp_hal_sys_init_done { + u32 dec_codec_supported; + u32 enc_codec_supported; + u32 codec_count; + struct msm_cvp_capability *capabilities; + u32 max_sessions_supported; +}; + +struct cvp_hal_session_init_done { + struct msm_cvp_capability capability; +}; + +struct msm_cvp_cb_cmd_done { + u32 device_id; + void *session_id; + enum cvp_status status; + u32 size; + union { + struct cvp_hfi_msg_session_hdr msg_hdr; + struct cvp_resource_hdr resource_hdr; + struct cvp_hal_sys_init_done sys_init_done; + struct cvp_hal_session_init_done session_init_done; + u32 buffer_addr; + } data; +}; + +struct msm_cvp_cb_data_done { + u32 device_id; + void *session_id; + enum cvp_status status; + u32 size; + u32 client_data; +}; + +struct msm_cvp_cb_info { + enum hal_command_response response_type; + union { + struct msm_cvp_cb_cmd_done cmd; + struct msm_cvp_cb_data_done data; + } response; +}; + +enum msm_cvp_hfi_type { + CVP_HFI_IRIS, +}; + +enum msm_cvp_thermal_level { + CVP_THERMAL_NORMAL = 0, + CVP_THERMAL_LOW, + CVP_THERMAL_HIGH, + CVP_THERMAL_CRITICAL +}; + +struct msm_cvp_gov_data { + struct cvp_bus_vote_data *data; + u32 data_count; +}; + +enum msm_cvp_power_mode { + CVP_POWER_NORMAL = 0, + CVP_POWER_LOW, + CVP_POWER_TURBO +}; + +struct cvp_bus_vote_data { + u32 domain; + u32 ddr_bw; + u32 sys_cache_bw; + enum msm_cvp_power_mode power_mode; + bool use_sys_cache; +}; + +struct cvp_hal_cmd_sys_get_property_packet { + u32 size; + u32 packet_type; + u32 num_properties; + u32 rg_property_data[1]; +}; + +#define call_hfi_op(q, op, args...) \ + (((q) && (q)->op) ? ((q)->op(args)) : 0) + +struct msm_cvp_hfi_defs { + unsigned int size; + unsigned int type; + unsigned int buf_offset; + unsigned int buf_num; + enum hal_command_response resp; +}; + +struct cvp_hfi_device { + void *hfi_device_data; + /*Add function pointers for all the hfi functions below*/ + int (*core_init)(void *device); + int (*core_release)(void *device); + int (*core_trigger_ssr)(void *device, enum hal_ssr_trigger_type); + int (*session_init)(void *device, void *session_id, void **new_session); + int (*session_end)(void *session); + int (*session_abort)(void *session); + int (*session_set_buffers)(void *sess, u32 iova, u32 size); + int (*session_release_buffers)(void *sess); + int (*session_send)(void *sess, struct cvp_kmd_hfi_packet *in_pkt); + int (*session_flush)(void *sess); + int (*scale_clocks)(void *dev, u32 freq); + int (*vote_bus)(void *dev, struct cvp_bus_vote_data *data, + int num_data); + int (*get_fw_info)(void *dev, struct cvp_hal_fw_info *fw_info); + int (*session_clean)(void *sess); + int (*get_core_capabilities)(void *dev); + int (*suspend)(void *dev); + int (*resume)(void *dev); + int (*flush_debug_queue)(void *dev); + int (*noc_error_info)(void *dev); + int (*validate_session)(void *sess, const char *func); +}; + +typedef void (*hfi_cmd_response_callback) (enum hal_command_response cmd, + void *data); +typedef void (*msm_cvp_callback) (enum hal_command_response response, + void *callback); + +struct cvp_hfi_device *cvp_hfi_initialize(enum msm_cvp_hfi_type hfi_type, + u32 device_id, struct msm_cvp_platform_resources *res, + hfi_cmd_response_callback callback); +void cvp_hfi_deinitialize(enum msm_cvp_hfi_type hfi_type, + struct cvp_hfi_device *hdev); + +int get_pkt_index(struct cvp_hal_session_cmd_pkt *hdr); +int get_signal_from_pkt_type(unsigned int type); +int get_hfi_version(void); +unsigned int get_msg_size(void); +unsigned int get_msg_session_id(void *msg); +unsigned int get_msg_errorcode(void *msg); +int get_msg_opconfigs(void *msg, unsigned int *session_id, + unsigned int *error_type, unsigned int *config_id); +extern const struct msm_cvp_hfi_defs cvp_hfi_defs[]; + +#endif /*__CVP_HFI_API_H__ */ diff --git a/msm/eva/cvp_hfi_helper.h b/msm/eva/cvp_hfi_helper.h new file mode 100644 index 0000000000..c9662ef9ab --- /dev/null +++ b/msm/eva/cvp_hfi_helper.h @@ -0,0 +1,453 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#ifndef __H_CVP_HFI_HELPER_H__ +#define __H_CVP_HFI_HELPER_H__ + +#define HFI_COMMON_BASE (0) +#define HFI_DOMAIN_BASE_COMMON (HFI_COMMON_BASE + 0) +#define HFI_DOMAIN_BASE_CVP (HFI_COMMON_BASE + 0x04000000) + +#define HFI_ARCH_COMMON_OFFSET (0) + +#define HFI_CMD_START_OFFSET (0x00010000) +#define HFI_MSG_START_OFFSET (0x00020000) + +#define HFI_ERR_NONE HFI_COMMON_BASE +#define HFI_ERR_SYS_FATAL (HFI_COMMON_BASE + 0x1) +#define HFI_ERR_SYS_INVALID_PARAMETER (HFI_COMMON_BASE + 0x2) +#define HFI_ERR_SYS_VERSION_MISMATCH (HFI_COMMON_BASE + 0x3) +#define HFI_ERR_SYS_INSUFFICIENT_RESOURCES (HFI_COMMON_BASE + 0x4) +#define HFI_ERR_SYS_MAX_SESSIONS_REACHED (HFI_COMMON_BASE + 0x5) +#define HFI_ERR_SYS_UNSUPPORTED_CODEC (HFI_COMMON_BASE + 0x6) +#define HFI_ERR_SYS_SESSION_IN_USE (HFI_COMMON_BASE + 0x7) +#define HFI_ERR_SYS_SESSION_ID_OUT_OF_RANGE (HFI_COMMON_BASE + 0x8) +#define HFI_ERR_SYS_UNSUPPORTED_DOMAIN (HFI_COMMON_BASE + 0x9) +#define HFI_ERR_SYS_NOC_ERROR (HFI_COMMON_BASE + 0x11) +#define HFI_ERR_SESSION_FATAL (HFI_COMMON_BASE + 0x1001) +#define HFI_ERR_SESSION_INVALID_PARAMETER (HFI_COMMON_BASE + 0x1002) +#define HFI_ERR_SESSION_BAD_POINTER (HFI_COMMON_BASE + 0x1003) +#define HFI_ERR_SESSION_INVALID_SESSION_ID (HFI_COMMON_BASE + 0x1004) +#define HFI_ERR_SESSION_INVALID_STREAM_ID (HFI_COMMON_BASE + 0x1005) +#define HFI_ERR_SESSION_INCORRECT_STATE_OPERATION \ + (HFI_COMMON_BASE + 0x1006) +#define HFI_ERR_SESSION_UNSUPPORTED_PROPERTY (HFI_COMMON_BASE + 0x1007) + +#define HFI_ERR_SESSION_UNSUPPORTED_SETTING (HFI_COMMON_BASE + 0x1008) + +#define HFI_ERR_SESSION_INSUFFICIENT_RESOURCES (HFI_COMMON_BASE + 0x1009) + +#define HFI_ERR_SESSION_STREAM_CORRUPT (HFI_COMMON_BASE + 0x100B) +#define HFI_ERR_SESSION_ENC_OVERFLOW (HFI_COMMON_BASE + 0x100C) +#define HFI_ERR_SESSION_UNSUPPORTED_STREAM (HFI_COMMON_BASE + 0x100D) +#define HFI_ERR_SESSION_CMDSIZE (HFI_COMMON_BASE + 0x100E) +#define HFI_ERR_SESSION_UNSUPPORT_CMD (HFI_COMMON_BASE + 0x100F) +#define HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE (HFI_COMMON_BASE + 0x1010) +#define HFI_ERR_SESSION_BUFFERCOUNT_TOOSMALL (HFI_COMMON_BASE + 0x1011) +#define HFI_ERR_SESSION_INVALID_SCALE_FACTOR (HFI_COMMON_BASE + 0x1012) +#define HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED (HFI_COMMON_BASE + 0x1013) +#define HFI_ERR_SESSION_FLUSHED (HFI_COMMON_BASE + 0x101C) + +#define HFI_EVENT_SYS_ERROR (HFI_COMMON_BASE + 0x1) +#define HFI_EVENT_SESSION_ERROR (HFI_COMMON_BASE + 0x2) + +#define HFI_TME_PROFILE_DEFAULT 0x00000001 +#define HFI_TME_PROFILE_FRC 0x00000002 +#define HFI_TME_PROFILE_ASW 0x00000004 +#define HFI_TME_PROFILE_DFS_BOKEH 0x00000008 + +#define HFI_TME_LEVEL_INTEGER 0x00000001 + +#define HFI_BUFFER_INPUT (HFI_COMMON_BASE + 0x1) +#define HFI_BUFFER_OUTPUT (HFI_COMMON_BASE + 0x2) +#define HFI_BUFFER_OUTPUT2 (HFI_COMMON_BASE + 0x3) +#define HFI_BUFFER_INTERNAL_PERSIST (HFI_COMMON_BASE + 0x4) +#define HFI_BUFFER_INTERNAL_PERSIST_1 (HFI_COMMON_BASE + 0x5) +#define HFI_BUFFER_COMMON_INTERNAL_SCRATCH (HFI_COMMON_BASE + 0x6) +#define HFI_BUFFER_COMMON_INTERNAL_SCRATCH_1 (HFI_COMMON_BASE + 0x7) +#define HFI_BUFFER_COMMON_INTERNAL_SCRATCH_2 (HFI_COMMON_BASE + 0x8) +#define HFI_BUFFER_COMMON_INTERNAL_RECON (HFI_COMMON_BASE + 0x9) +#define HFI_BUFFER_EXTRADATA_OUTPUT (HFI_COMMON_BASE + 0xA) +#define HFI_BUFFER_EXTRADATA_OUTPUT2 (HFI_COMMON_BASE + 0xB) +#define HFI_BUFFER_EXTRADATA_INPUT (HFI_COMMON_BASE + 0xC) + + +#define HFI_PROPERTY_SYS_COMMON_START \ + (HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + 0x0000) +#define HFI_PROPERTY_SYS_DEBUG_CONFIG \ + (HFI_PROPERTY_SYS_COMMON_START + 0x001) +#define HFI_PROPERTY_SYS_RESOURCE_OCMEM_REQUIREMENT_INFO \ + (HFI_PROPERTY_SYS_COMMON_START + 0x002) +#define HFI_PROPERTY_SYS_CONFIG_VCODEC_CLKFREQ \ + (HFI_PROPERTY_SYS_COMMON_START + 0x003) +#define HFI_PROPERTY_SYS_IDLE_INDICATOR \ + (HFI_PROPERTY_SYS_COMMON_START + 0x004) +#define HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL \ + (HFI_PROPERTY_SYS_COMMON_START + 0x005) +#define HFI_PROPERTY_SYS_IMAGE_VERSION \ + (HFI_PROPERTY_SYS_COMMON_START + 0x006) +#define HFI_PROPERTY_SYS_CONFIG_COVERAGE \ + (HFI_PROPERTY_SYS_COMMON_START + 0x007) +#define HFI_PROPERTY_SYS_UBWC_CONFIG \ + (HFI_PROPERTY_SYS_COMMON_START + 0x008) + +#define HFI_DEBUG_MSG_LOW 0x00000001 +#define HFI_DEBUG_MSG_MEDIUM 0x00000002 +#define HFI_DEBUG_MSG_HIGH 0x00000004 +#define HFI_DEBUG_MSG_ERROR 0x00000008 +#define HFI_DEBUG_MSG_FATAL 0x00000010 +#define HFI_DEBUG_MSG_PERF 0x00000020 + +#define HFI_DEBUG_MODE_QUEUE 0x00000001 +#define HFI_DEBUG_MODE_QDSS 0x00000002 + +struct cvp_hfi_debug_config { + u32 debug_config; + u32 debug_mode; +}; + +struct cvp_hfi_enable { + u32 enable; +}; + +#define HFI_RESOURCE_SYSCACHE 0x00000002 + +struct cvp_hfi_resource_subcache_type { + u32 size; + u32 sc_id; +}; + +struct cvp_hfi_resource_syscache_info_type { + u32 num_entries; + struct cvp_hfi_resource_subcache_type rg_subcache_entries[1]; +}; + +#define HFI_CMD_SYS_COMMON_START \ +(HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + HFI_CMD_START_OFFSET \ + + 0x0000) +#define HFI_CMD_SYS_INIT (HFI_CMD_SYS_COMMON_START + 0x001) +#define HFI_CMD_SYS_PC_PREP (HFI_CMD_SYS_COMMON_START + 0x002) +#define HFI_CMD_SYS_SET_RESOURCE (HFI_CMD_SYS_COMMON_START + 0x003) +#define HFI_CMD_SYS_RELEASE_RESOURCE (HFI_CMD_SYS_COMMON_START + 0x004) +#define HFI_CMD_SYS_SET_PROPERTY (HFI_CMD_SYS_COMMON_START + 0x005) +#define HFI_CMD_SYS_GET_PROPERTY (HFI_CMD_SYS_COMMON_START + 0x006) +#define HFI_CMD_SYS_SESSION_INIT (HFI_CMD_SYS_COMMON_START + 0x007) +#define HFI_CMD_SYS_SESSION_END (HFI_CMD_SYS_COMMON_START + 0x008) +#define HFI_CMD_SYS_SET_BUFFERS (HFI_CMD_SYS_COMMON_START + 0x009) +#define HFI_CMD_SYS_SESSION_ABORT (HFI_CMD_SYS_COMMON_START + 0x00A) +#define HFI_CMD_SYS_TEST_START (HFI_CMD_SYS_COMMON_START + 0x100) + +#define HFI_MSG_SYS_COMMON_START \ + (HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + \ + HFI_MSG_START_OFFSET + 0x0000) +#define HFI_MSG_SYS_INIT_DONE (HFI_MSG_SYS_COMMON_START + 0x1) +#define HFI_MSG_SYS_PC_PREP_DONE (HFI_MSG_SYS_COMMON_START + 0x2) +#define HFI_MSG_SYS_RELEASE_RESOURCE (HFI_MSG_SYS_COMMON_START + 0x3) +#define HFI_MSG_SYS_DEBUG (HFI_MSG_SYS_COMMON_START + 0x4) +#define HFI_MSG_SYS_SESSION_INIT_DONE (HFI_MSG_SYS_COMMON_START + 0x6) +#define HFI_MSG_SYS_SESSION_END_DONE (HFI_MSG_SYS_COMMON_START + 0x7) +#define HFI_MSG_SYS_IDLE (HFI_MSG_SYS_COMMON_START + 0x8) +#define HFI_MSG_SYS_COV (HFI_MSG_SYS_COMMON_START + 0x9) +#define HFI_MSG_SYS_PROPERTY_INFO (HFI_MSG_SYS_COMMON_START + 0xA) +#define HFI_MSG_SYS_SESSION_ABORT_DONE (HFI_MSG_SYS_COMMON_START + 0xC) +#define HFI_MSG_SESSION_SYNC_DONE (HFI_MSG_SESSION_OX_START + 0xD) + +#define HFI_MSG_SESSION_COMMON_START \ + (HFI_DOMAIN_BASE_COMMON + HFI_ARCH_COMMON_OFFSET + \ + HFI_MSG_START_OFFSET + 0x1000) +#define HFI_MSG_EVENT_NOTIFY (HFI_MSG_SESSION_COMMON_START + 0x1) +#define HFI_MSG_SESSION_GET_SEQUENCE_HEADER_DONE \ + (HFI_MSG_SESSION_COMMON_START + 0x2) + +#define HFI_CMD_SYS_TEST_SSR (HFI_CMD_SYS_TEST_START + 0x1) +#define HFI_TEST_SSR_SW_ERR_FATAL 0x1 +#define HFI_TEST_SSR_SW_DIV_BY_ZERO 0x2 +#define HFI_TEST_SSR_HW_WDOG_IRQ 0x3 + +struct cvp_hal_cmd_pkt_hdr { + u32 size; + u32 packet_type; +}; + +struct cvp_hal_msg_pkt_hdr { + u32 size; + u32 packet; +}; + +struct cvp_hal_session_cmd_pkt { + u32 size; + u32 packet_type; + u32 session_id; +}; + +struct cvp_hfi_cmd_sys_init_packet { + u32 size; + u32 packet_type; + u32 arch_type; +}; + +struct cvp_hfi_cmd_sys_pc_prep_packet { + u32 size; + u32 packet_type; +}; + +struct cvp_hfi_cmd_sys_set_resource_packet { + u32 size; + u32 packet_type; + u32 resource_handle; + u32 resource_type; + u32 rg_resource_data[1]; +}; + +struct cvp_hfi_cmd_sys_release_resource_packet { + u32 size; + u32 packet_type; + u32 resource_type; + u32 resource_handle; +}; + +struct cvp_hfi_cmd_sys_set_property_packet { + u32 size; + u32 packet_type; + u32 num_properties; + u32 rg_property_data[1]; +}; + +struct cvp_hfi_cmd_sys_get_property_packet { + u32 size; + u32 packet_type; + u32 num_properties; + u32 rg_property_data[1]; +}; + +enum HFI_SESSION_TYPE { + HFI_SESSION_CV = 1, + HFI_SESSION_DME, + HFI_SESSION_ODT, + HFI_SESSION_FD +}; + +struct cvp_hfi_cmd_sys_session_init_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 session_type; + u32 session_kmask; + u32 session_prio; + u32 is_secure; + u32 dsp_ac_mask; +}; + +struct cvp_hfi_cmd_sys_session_end_packet { + u32 size; + u32 packet_type; + u32 session_id; +}; + +struct cvp_hfi_cmd_sys_set_buffers_packet { + u32 size; + u32 packet_type; + u32 buffer_type; + u32 buffer_size; + u32 num_buffers; + u32 rg_buffer_addr[1]; +}; + +struct cvp_hfi_cmd_sys_set_ubwc_config_packet_type { + u32 size; + u32 packet_type; + struct { + u32 max_channel_override : 1; + u32 mal_length_override : 1; + u32 hb_override : 1; + u32 bank_swzl_level_override : 1; + u32 bank_spreading_override : 1; + u32 reserved : 27; + } override_bit_info; + u32 max_channels; + u32 mal_length; + u32 highest_bank_bit; + u32 bank_swzl_level; + u32 bank_spreading; + u32 reserved[2]; +}; + +struct cvp_hfi_cmd_session_set_property_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 num_properties; + u32 rg_property_data[1]; +}; + +struct cvp_hfi_client { + u32 transaction_id; + u32 data1; + u32 data2; + u64 kdata; + u32 reserved1; + u32 reserved2; +} __packed; + +struct cvp_hfi_buf_type { + u32 iova; + u32 size; + u32 offset; + u32 flags; + u32 reserved1; + u32 reserved2; +}; + +struct cvp_hfi_cmd_session_set_buffers_packet { + u32 size; + u32 packet_type; + u32 session_id; + struct cvp_hfi_client client_data; + struct cvp_hfi_buf_type buf_type; +} __packed; + +struct cvp_session_release_buffers_packet { + u32 size; + u32 packet_type; + u32 session_id; + struct cvp_hfi_client client_data; + u32 kernel_type; + u32 buffer_type; + u32 num_buffers; + u32 buffer_idx; +} __packed; + +struct cvp_hfi_cmd_session_hdr { + u32 size; + u32 packet_type; + u32 session_id; + struct cvp_hfi_client client_data; + u32 stream_idx; +} __packed; + +struct cvp_hfi_msg_session_hdr { + u32 size; + u32 packet_type; + u32 session_id; + u32 error_type; + struct cvp_hfi_client client_data; + u32 stream_idx; +} __packed; + +struct cvp_hfi_buffer_mapping_type { + u32 index; + u32 device_addr; + u32 size; +}; + +struct cvp_hfi_cmd_session_sync_process_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 sync_id; + u32 rg_data[1]; +}; + +struct cvp_hfi_msg_event_notify_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 event_id; + u32 event_data1; + u32 event_data2; + u32 rg_ext_event_data[1]; +}; + +struct cvp_hfi_msg_session_op_cfg_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 error_type; + struct cvp_hfi_client client_data; + u32 stream_idx; + u32 op_conf_id; +} __packed; + +struct cvp_hfi_msg_sys_init_done_packet { + u32 size; + u32 packet_type; + u32 error_type; + u32 num_properties; + u32 rg_property_data[1]; +}; + +struct cvp_hfi_msg_sys_pc_prep_done_packet { + u32 size; + u32 packet_type; + u32 error_type; +}; + +struct cvp_hfi_msg_sys_release_resource_done_packet { + u32 size; + u32 packet_type; + u32 resource_handle; + u32 error_type; +}; + +struct cvp_hfi_msg_sys_session_init_done_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 error_type; + u32 num_properties; + u32 rg_property_data[1]; +}; + +struct cvp_hfi_msg_sys_session_end_done_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 error_type; +}; + +struct cvp_hfi_msg_session_get_sequence_header_done_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 error_type; + u32 header_len; + u32 sequence_header; +}; + +struct cvp_hfi_msg_sys_debug_packet { + u32 size; + u32 packet_type; + u32 msg_type; + u32 msg_size; + u32 time_stamp_hi; + u32 time_stamp_lo; + u8 rg_msg_data[1]; +}; + +struct cvp_hfi_packet_header { + u32 size; + u32 packet_type; +}; + +struct cvp_hfi_sfr_struct { + u32 bufSize; + u8 rg_data[1]; +}; + +struct cvp_hfi_cmd_sys_test_ssr_packet { + u32 size; + u32 packet_type; + u32 trigger_type; +}; + +struct cvp_hfi_msg_sys_session_flush_done_packet { + u32 size; + u32 packet_type; + u32 session_id; + u32 error_type; + struct cvp_hfi_client client_data; +}; + +#endif diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h new file mode 100644 index 0000000000..fa8933f9cf --- /dev/null +++ b/msm/eva/cvp_hfi_io.h @@ -0,0 +1,223 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#ifndef __CVP_HFI_IO_H__ +#define __CVP_HFI_IO_H__ + +#include + +#define CVP_CPU_BASE_OFFS 0x000A0000 +#define CVP_AON_BASE_OFFS 0x000E0000 + +#define CVP_CPU_CS_A2HSOFTINTEN (CVP_CPU_BASE_OFFS + 0x10) +#define CVP_CPU_CS_A2HSOFTINTENCLR (CVP_CPU_BASE_OFFS + 0x14) +#define CVP_CPU_CS_A2HSOFTINT (CVP_CPU_BASE_OFFS + 0x18) +#define CVP_CPU_CS_A2HSOFTINTCLR (CVP_CPU_BASE_OFFS + 0x1C) +#define CVP_CPU_CS_VMIMSG (CVP_CPU_BASE_OFFS + 0x34) +#define CVP_CPU_CS_VMIMSGAG0 (CVP_CPU_BASE_OFFS + 0x38) +#define CVP_CPU_CS_VMIMSGAG1 (CVP_CPU_BASE_OFFS + 0x3C) +#define CVP_CPU_CS_VMIMSGAG2 (CVP_CPU_BASE_OFFS + 0x40) +#define CVP_CPU_CS_VMIMSGAG3 (CVP_CPU_BASE_OFFS + 0x44) +#define CVP_CPU_CS_SCIACMD (CVP_CPU_BASE_OFFS + 0x48) +#define CVP_CPU_CS_H2XSOFTINTEN (CVP_CPU_BASE_OFFS + 0x148) + +/* CVP_CTRL_STATUS */ +#define CVP_CPU_CS_SCIACMDARG0 (CVP_CPU_BASE_OFFS + 0x4C) +#define CVP_CPU_CS_SCIACMDARG0_BMSK 0xff +#define CVP_CPU_CS_SCIACMDARG0_SHFT 0x0 +#define CVP_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK 0xfe +#define CVP_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_SHFT 0x1 +#define CVP_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_BMSK 0x1 +#define CVP_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_SHFT 0x0 +#define CVP_CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY 0x100 + +/* HFI_QTBL_INFO */ +#define CVP_CPU_CS_SCIACMDARG1 (CVP_CPU_BASE_OFFS + 0x50) + +/* HFI_QTBL_ADDR */ +#define CVP_CPU_CS_SCIACMDARG2 (CVP_CPU_BASE_OFFS + 0x54) + +/* HFI_VERSION_INFO */ +#define CVP_CPU_CS_SCIACMDARG3 (CVP_CPU_BASE_OFFS + 0x58) + +/* CVP_SFR_ADDR */ +#define CVP_CPU_CS_SCIBCMD (CVP_CPU_BASE_OFFS + 0x5C) + +/* CVP_MMAP_ADDR */ +#define CVP_CPU_CS_SCIBCMDARG0 (CVP_CPU_BASE_OFFS + 0x60) + +/* CVP_UC_REGION_ADDR */ +#define CVP_CPU_CS_SCIBARG1 (CVP_CPU_BASE_OFFS + 0x64) + +/* CVP_UC_REGION_ADDR */ +#define CVP_CPU_CS_SCIBARG2 (CVP_CPU_BASE_OFFS + 0x68) + +#define CVP_CPU_CS_SCIBARG3 (CVP_CPU_BASE_OFFS + 0x6C) + +#define CVP_CPU_CS_H2ASOFTINTEN (CVP_CPU_BASE_OFFS + 0x148) +#define CVP_CPU_CS_H2ASOFTINTENCLR (CVP_CPU_BASE_OFFS + 0x14c) +#define CVP_CPU_CS_H2ASOFTINT (CVP_CPU_BASE_OFFS + 0x150) +#define CVP_CPU_CS_H2ASOFTINTCLR (CVP_CPU_BASE_OFFS + 0x154) + +/* FAL10 Feature Control */ +#define CVP_CPU_CS_X2RPMh (CVP_CPU_BASE_OFFS + 0x168) +#define CVP_CPU_CS_X2RPMh_MASK0_BMSK 0x1 +#define CVP_CPU_CS_X2RPMh_MASK0_SHFT 0x0 +#define CVP_CPU_CS_X2RPMh_MASK1_BMSK 0x2 +#define CVP_CPU_CS_X2RPMh_MASK1_SHFT 0x1 +#define CVP_CPU_CS_X2RPMh_SWOVERRIDE_BMSK 0x4 +#define CVP_CPU_CS_X2RPMh_SWOVERRIDE_SHFT 0x3 + +/* + * -------------------------------------------------------------------------- + * MODULE: cvp_wrapper + * -------------------------------------------------------------------------- + */ +#define CVP_WRAPPER_BASE_OFFS 0x000B0000 + +#define CVP_WRAPPER_HW_VERSION (CVP_WRAPPER_BASE_OFFS + 0x00) +#define CVP_WRAPPER_HW_VERSION_MAJOR_VERSION_MASK 0x78000000 +#define CVP_WRAPPER_HW_VERSION_MAJOR_VERSION_SHIFT 28 +#define CVP_WRAPPER_HW_VERSION_MINOR_VERSION_MASK 0xFFF0000 +#define CVP_WRAPPER_HW_VERSION_MINOR_VERSION_SHIFT 16 +#define CVP_WRAPPER_HW_VERSION_STEP_VERSION_MASK 0xFFFF + +#define CVP_WRAPPER_INTR_STATUS (CVP_WRAPPER_BASE_OFFS + 0x0C) +#define CVP_WRAPPER_INTR_STATUS_A2HWD_BMSK 0x8 +#define CVP_WRAPPER_INTR_STATUS_A2H_BMSK 0x4 + +#define CVP_WRAPPER_INTR_MASK (CVP_WRAPPER_BASE_OFFS + 0x10) +#define CVP_FATAL_INTR_BMSK (CVP_WRAPPER_INTR_MASK_CPU_NOC_BMSK | \ + CVP_WRAPPER_INTR_MASK_CORE_NOC_BMSK | \ + CVP_WRAPPER_INTR_MASK_A2HWD_BMSK) +#define CVP_WRAPPER_INTR_MASK_CPU_NOC_BMSK 0x40 +#define CVP_WRAPPER_INTR_MASK_CORE_NOC_BMSK 0x20 +#define CVP_WRAPPER_INTR_MASK_A2HWD_BMSK 0x8 +#define CVP_WRAPPER_INTR_MASK_A2HCPU_BMSK 0x4 +#define CVP_WRAPPER_INTR_MASK_A2HCPU_SHFT 0x2 + +#define CVP_WRAPPER_INTR_CLEAR (CVP_WRAPPER_BASE_OFFS + 0x14) +#define CVP_WRAPPER_TZ_BASE_OFFS 0x000C0000 +#define CVP_WRAPPER_INTR_CLEAR_A2HWD_BMSK 0x10 +#define CVP_WRAPPER_INTR_CLEAR_A2HWD_SHFT 0x4 +#define CVP_WRAPPER_INTR_CLEAR_A2H_BMSK 0x4 +#define CVP_WRAPPER_INTR_CLEAR_A2H_SHFT 0x2 +#define CVP_WRAPPER_CPU_STATUS (CVP_WRAPPER_TZ_BASE_OFFS + 0x10) +#define CVP_WRAPPER_CPU_CGC_DIS (CVP_WRAPPER_BASE_OFFS + 0x2010) + +#define CVP_WRAPPER_CPU_CLOCK_CONFIG (CVP_WRAPPER_BASE_OFFS + 0x50) +#define CVP_WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (CVP_WRAPPER_BASE_OFFS + 0x54) +#define CVP_WRAPPER_DEBUG_BRIDGE_LPI_STATUS (CVP_WRAPPER_BASE_OFFS + 0x58) +#define CVP_WRAPPER_CORE_CLOCK_CONFIG (CVP_WRAPPER_BASE_OFFS + 0x88) + +#define CVP_CTRL_INIT CVP_CPU_CS_SCIACMD + +#define CVP_CTRL_STATUS CVP_CPU_CS_SCIACMDARG0 +#define CVP_CTRL_INIT_STATUS__M \ + CVP_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_STATUS_BMSK +#define CVP_CTRL_ERROR_STATUS__M \ + CVP_CPU_CS_SCIACMDARG0_HFI_CTRL_ERROR_STATUS_BMSK +#define CVP_CTRL_INIT_IDLE_MSG_BMSK \ + CVP_CPU_CS_SCIACMDARG0_HFI_CTRL_INIT_IDLE_MSG_BMSK +#define CVP_CTRL_STATUS_PC_READY \ + CVP_CPU_CS_SCIACMDARG0_HFI_CTRL_PC_READY + + +#define CVP_QTBL_INFO CVP_CPU_CS_SCIACMDARG1 + +#define CVP_QTBL_ADDR CVP_CPU_CS_SCIACMDARG2 + +#define CVP_VERSION_INFO CVP_CPU_CS_SCIACMDARG3 + +#define CVP_SFR_ADDR CVP_CPU_CS_SCIBCMD +#define CVP_MMAP_ADDR CVP_CPU_CS_SCIBCMDARG0 +#define CVP_UC_REGION_ADDR CVP_CPU_CS_SCIBARG1 +#define CVP_UC_REGION_SIZE CVP_CPU_CS_SCIBARG2 + +/* HFI_DSP_QTBL_ADDR + * 31:3 - HFI_DSP_QTBL_ADDR + * 4-byte aligned Address + */ +#define HFI_DSP_QTBL_ADDR CVP_CPU_CS_VMIMSG + +/* HFI_DSP_UC_REGION_ADDR + * 31:20 - HFI_DSP_UC_REGION_ADDR + * 1MB aligned address. + * Uncached Region start Address. This region covers + * HFI DSP QTable, + * HFI DSP Queue Headers, + * HFI DSP Queues, + */ +#define HFI_DSP_UC_REGION_ADDR CVP_CPU_CS_VMIMSGAG0 + +/* HFI_DSP_UC_REGION_SIZE + * 31:20 - HFI_DSP_UC_REGION_SIZE + * Multiples of 1MB. + * Size of the DSP_UC_REGION Uncached Region + */ +#define HFI_DSP_UC_REGION_SIZE CVP_CPU_CS_VMIMSGAG1 + +/* + * -------------------------------------------------------------------------- + * MODULE: vcodec noc error log registers + * -------------------------------------------------------------------------- + */ +#define CVP_NOC_BASE_OFFS 0x000D0000 +#define CVP_NOC_ERR_SWID_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x80) +#define CVP_NOC_ERR_SWID_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0x84) +#define CVP_NOC_ERR_MAINCTL_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x88) +#define CVP_NOC_ERR_ERRVLD_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x90) +#define CVP_NOC_ERR_ERRCLR_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x98) +#define CVP_NOC_ERR_ERRLOG0_LOW_OFFS (CVP_NOC_BASE_OFFS + 0xA0) +#define CVP_NOC_ERR_ERRLOG0_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0xA4) +#define CVP_NOC_ERR_ERRLOG1_LOW_OFFS (CVP_NOC_BASE_OFFS + 0xA8) +#define CVP_NOC_ERR_ERRLOG1_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0xAC) +#define CVP_NOC_ERR_ERRLOG2_LOW_OFFS (CVP_NOC_BASE_OFFS + 0xB0) +#define CVP_NOC_ERR_ERRLOG2_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0xB4) +#define CVP_NOC_ERR_ERRLOG3_LOW_OFFS (CVP_NOC_BASE_OFFS + 0xB8) +#define CVP_NOC_ERR_ERRLOG3_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0xBC) +#define CVP_NOC_SBM_SENSELN0_LOW (CVP_NOC_BASE_OFFS + 0x300) + +#define CVP_NOC_CORE_BASE_OFFS 0x00010000 +#define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_LOW \ + (CVP_NOC_CORE_BASE_OFFS + 0x1100) +#define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN1_HIGH \ + (CVP_NOC_CORE_BASE_OFFS + 0x110C) +#define CVP_NOC_CORE_ERR_SWID_LOW_OFFS \ + (CVP_NOC_CORE_BASE_OFFS + 0x1200) +#define CVP_NOC_CORE_ERR_SWID_HIGH_OFFS \ + (CVP_NOC_CORE_BASE_OFFS + 0x1204) +#define CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS \ + (CVP_NOC_CORE_BASE_OFFS + 0x1208) +#define CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS \ + (CVP_NOC_CORE_BASE_OFFS + 0x1210) +#define CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS \ + (CVP_NOC_CORE_BASE_OFFS + 0x1218) +#define CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS \ + (CVP_NOC_CORE_BASE_OFFS + 0x1220) +#define CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS \ + (CVP_NOC_CORE_BASE_OFFS + 0x1224) +#define CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS \ + (CVP_NOC_CORE_BASE_OFFS + 0x1228) +#define CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS \ + (CVP_NOC_CORE_BASE_OFFS + 0x122C) +#define CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS \ + (CVP_NOC_CORE_BASE_OFFS + 0x1230) +#define CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS \ + (CVP_NOC_CORE_BASE_OFFS + 0x1234) +#define CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS \ + (CVP_NOC_CORE_BASE_OFFS + 0x1238) +#define CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS \ + (CVP_NOC_CORE_BASE_OFFS + 0x123C) + + +#define CVP_AON_WRAPPER_MVP_NOC_LPI_CONTROL (CVP_AON_BASE_OFFS) +#define CVP_AON_WRAPPER_MVP_NOC_LPI_STATUS (CVP_AON_BASE_OFFS + 0x4) + +#define CVP_CC_BASE_OFFS 0x000F0000 +#define CVP_CC_MVS0C_GDSCR (CVP_CC_BASE_OFFS + 0xBF8) +#define CVP_CC_MVS1C_GDSCR (CVP_CC_BASE_OFFS + 0xC98) +#define CVP_CC_MVS1C_CBCR (CVP_CC_BASE_OFFS + 0xCD4) +#endif diff --git a/msm/eva/cvp_private.h b/msm/eva/cvp_private.h new file mode 100644 index 0000000000..e6b84e9d14 --- /dev/null +++ b/msm/eva/cvp_private.h @@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _MSM_V4L2_PRIVATE_H_ +#define _MSM_V4L2_PRIVATE_H_ + +#include +#include "msm_cvp_debug.h" + +long cvp_unblocked_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg); + +long cvp_compat_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg); + +#endif diff --git a/msm/eva/hfi_packetization.c b/msm/eva/hfi_packetization.c new file mode 100644 index 0000000000..107e2d744f --- /dev/null +++ b/msm/eva/hfi_packetization.c @@ -0,0 +1,462 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#include "hfi_packetization.h" +#include "msm_cvp_debug.h" + +/* Set up look-up tables to convert HAL_* to HFI_*. + * + * The tables below mostly take advantage of the fact that most + * HAL_* types are defined bitwise. So if we index them normally + * when declaring the tables, we end up with huge arrays with wasted + * space. So before indexing them, we apply log2 to use a more + * sensible index. + */ + +int cvp_create_pkt_cmd_sys_init(struct cvp_hfi_cmd_sys_init_packet *pkt, + u32 arch_type) +{ + int rc = 0; + + if (!pkt) + return -EINVAL; + + pkt->packet_type = HFI_CMD_SYS_INIT; + pkt->size = sizeof(struct cvp_hfi_cmd_sys_init_packet); + pkt->arch_type = arch_type; + return rc; +} + +int cvp_create_pkt_cmd_sys_pc_prep(struct cvp_hfi_cmd_sys_pc_prep_packet *pkt) +{ + int rc = 0; + + if (!pkt) + return -EINVAL; + + pkt->packet_type = HFI_CMD_SYS_PC_PREP; + pkt->size = sizeof(struct cvp_hfi_cmd_sys_pc_prep_packet); + return rc; +} + +int cvp_create_pkt_cmd_sys_debug_config( + struct cvp_hfi_cmd_sys_set_property_packet *pkt, + u32 mode) +{ + struct cvp_hfi_debug_config *hfi; + + if (!pkt) + return -EINVAL; + + pkt->size = sizeof(struct cvp_hfi_cmd_sys_set_property_packet) + + sizeof(struct cvp_hfi_debug_config) + sizeof(u32); + pkt->packet_type = HFI_CMD_SYS_SET_PROPERTY; + pkt->num_properties = 1; + pkt->rg_property_data[0] = HFI_PROPERTY_SYS_DEBUG_CONFIG; + hfi = (struct cvp_hfi_debug_config *) &pkt->rg_property_data[1]; + hfi->debug_config = mode; + hfi->debug_mode = HFI_DEBUG_MODE_QUEUE; + if (msm_cvp_fw_debug_mode + <= (HFI_DEBUG_MODE_QUEUE | HFI_DEBUG_MODE_QDSS)) + hfi->debug_mode = msm_cvp_fw_debug_mode; + return 0; +} + +int cvp_create_pkt_cmd_sys_coverage_config( + struct cvp_hfi_cmd_sys_set_property_packet *pkt, + u32 mode) +{ + if (!pkt) { + dprintk(CVP_ERR, "In %s(), No input packet\n", __func__); + return -EINVAL; + } + + pkt->size = sizeof(struct cvp_hfi_cmd_sys_set_property_packet) + + sizeof(u32); + pkt->packet_type = HFI_CMD_SYS_SET_PROPERTY; + pkt->num_properties = 1; + pkt->rg_property_data[0] = HFI_PROPERTY_SYS_CONFIG_COVERAGE; + pkt->rg_property_data[1] = mode; + dprintk(CVP_PKT, "Firmware coverage mode %d\n", + pkt->rg_property_data[1]); + return 0; +} + +int cvp_create_pkt_cmd_sys_set_idle_indicator( + struct cvp_hfi_cmd_sys_set_property_packet *pkt, + u32 mode) +{ + if (!pkt) { + dprintk(CVP_ERR, "In %s(), No input packet\n", __func__); + return -EINVAL; + } + + pkt->size = sizeof(struct cvp_hfi_cmd_sys_set_property_packet) + + sizeof(u32); + pkt->packet_type = HFI_CMD_SYS_SET_PROPERTY; + pkt->num_properties = 1; + pkt->rg_property_data[0] = HFI_PROPERTY_SYS_IDLE_INDICATOR; + pkt->rg_property_data[1] = mode; + dprintk(CVP_PKT, "Firmware idle indicator mode %d\n", + pkt->rg_property_data[1]); + return 0; +} + +int cvp_create_pkt_cmd_sys_set_resource( + struct cvp_hfi_cmd_sys_set_resource_packet *pkt, + struct cvp_resource_hdr *res_hdr, + void *res_value) +{ + int rc = 0; + u32 i = 0; + + if (!pkt || !res_hdr || !res_value) { + dprintk(CVP_ERR, + "Invalid paramas pkt %pK res_hdr %pK res_value %pK\n", + pkt, res_hdr, res_value); + return -EINVAL; + } + + pkt->packet_type = HFI_CMD_SYS_SET_RESOURCE; + pkt->size = sizeof(struct cvp_hfi_cmd_sys_set_resource_packet); + pkt->resource_handle = hash32_ptr(res_hdr->resource_handle); + + switch (res_hdr->resource_id) { + case CVP_RESOURCE_SYSCACHE: + { + struct cvp_hfi_resource_syscache_info_type *res_sc_info = + (struct cvp_hfi_resource_syscache_info_type *)res_value; + struct cvp_hfi_resource_subcache_type *res_sc = + (struct cvp_hfi_resource_subcache_type *) + &(res_sc_info->rg_subcache_entries[0]); + + struct cvp_hfi_resource_syscache_info_type *hfi_sc_info = + (struct cvp_hfi_resource_syscache_info_type *) + &pkt->rg_resource_data[0]; + + struct cvp_hfi_resource_subcache_type *hfi_sc = + (struct cvp_hfi_resource_subcache_type *) + &(hfi_sc_info->rg_subcache_entries[0]); + + pkt->resource_type = HFI_RESOURCE_SYSCACHE; + hfi_sc_info->num_entries = res_sc_info->num_entries; + + pkt->size += (sizeof(struct cvp_hfi_resource_subcache_type)) + * hfi_sc_info->num_entries; + + for (i = 0; i < hfi_sc_info->num_entries; i++) { + hfi_sc[i] = res_sc[i]; + dprintk(CVP_PKT, "entry hfi#%d, sc_id %d, size %d\n", + i, hfi_sc[i].sc_id, hfi_sc[i].size); + } + break; + } + default: + dprintk(CVP_ERR, + "Invalid resource_id %d\n", res_hdr->resource_id); + rc = -ENOTSUPP; + } + + return rc; +} + +int cvp_create_pkt_cmd_sys_release_resource( + struct cvp_hfi_cmd_sys_release_resource_packet *pkt, + struct cvp_resource_hdr *res_hdr) +{ + int rc = 0; + + if (!pkt || !res_hdr) { + dprintk(CVP_ERR, + "Invalid paramas pkt %pK res_hdr %pK\n", + pkt, res_hdr); + return -EINVAL; + } + + pkt->size = sizeof(struct cvp_hfi_cmd_sys_release_resource_packet); + pkt->packet_type = HFI_CMD_SYS_RELEASE_RESOURCE; + pkt->resource_handle = hash32_ptr(res_hdr->resource_handle); + + switch (res_hdr->resource_id) { + case CVP_RESOURCE_SYSCACHE: + pkt->resource_type = HFI_RESOURCE_SYSCACHE; + break; + default: + dprintk(CVP_ERR, + "Invalid resource_id %d\n", res_hdr->resource_id); + rc = -ENOTSUPP; + } + + dprintk(CVP_PKT, + "rel_res: pkt_type 0x%x res_type 0x%x prepared\n", + pkt->packet_type, pkt->resource_type); + + return rc; +} + +inline int cvp_create_pkt_cmd_sys_session_init( + struct cvp_hfi_cmd_sys_session_init_packet *pkt, + struct cvp_hal_session *session) +{ + int rc = 0; + struct msm_cvp_inst *inst = session->session_id; + + if (!pkt || !inst) + return -EINVAL; + + pkt->size = sizeof(struct cvp_hfi_cmd_sys_session_init_packet); + pkt->packet_type = HFI_CMD_SYS_SESSION_INIT; + pkt->session_id = hash32_ptr(session); + pkt->session_type = inst->prop.type; + pkt->session_kmask = inst->prop.kernel_mask; + pkt->session_prio = inst->prop.priority; + pkt->is_secure = inst->prop.is_secure; + pkt->dsp_ac_mask = inst->prop.dsp_mask; + + return rc; +} + +static int create_pkt_cmd_sys_ubwc_config( + struct cvp_hfi_cmd_sys_set_property_packet *pkt, + struct msm_cvp_ubwc_config_data *ubwc_config) +{ + int rc = 0; + struct cvp_hfi_cmd_sys_set_ubwc_config_packet_type *hfi; + + if (!pkt) + return -EINVAL; + + pkt->size = sizeof(struct cvp_hfi_cmd_sys_set_property_packet) + + sizeof(struct cvp_hfi_cmd_sys_set_ubwc_config_packet_type) + + sizeof(u32); + + pkt->packet_type = HFI_CMD_SYS_SET_PROPERTY; + pkt->num_properties = 1; + pkt->rg_property_data[0] = HFI_PROPERTY_SYS_UBWC_CONFIG; + hfi = (struct cvp_hfi_cmd_sys_set_ubwc_config_packet_type *) + &pkt->rg_property_data[1]; + + hfi->max_channels = ubwc_config->max_channels; + hfi->override_bit_info.max_channel_override = + ubwc_config->override_bit_info.max_channel_override; + + hfi->mal_length = ubwc_config->mal_length; + hfi->override_bit_info.mal_length_override = + ubwc_config->override_bit_info.mal_length_override; + + hfi->highest_bank_bit = ubwc_config->highest_bank_bit; + hfi->override_bit_info.hb_override = + ubwc_config->override_bit_info.hb_override; + + hfi->bank_swzl_level = ubwc_config->bank_swzl_level; + hfi->override_bit_info.bank_swzl_level_override = + ubwc_config->override_bit_info.bank_swzl_level_override; + + hfi->bank_spreading = ubwc_config->bank_spreading; + hfi->override_bit_info.bank_spreading_override = + ubwc_config->override_bit_info.bank_spreading_override; + hfi->size = sizeof(struct cvp_hfi_cmd_sys_set_ubwc_config_packet_type); + + return rc; +} + +int cvp_create_pkt_cmd_session_cmd(struct cvp_hal_session_cmd_pkt *pkt, + int pkt_type, struct cvp_hal_session *session) +{ + int rc = 0; + + if (!pkt) + return -EINVAL; + + pkt->size = sizeof(struct cvp_hal_session_cmd_pkt); + pkt->packet_type = pkt_type; + pkt->session_id = hash32_ptr(session); + + return rc; +} + +int cvp_create_pkt_cmd_sys_power_control( + struct cvp_hfi_cmd_sys_set_property_packet *pkt, u32 enable) +{ + struct cvp_hfi_enable *hfi; + + if (!pkt) { + dprintk(CVP_ERR, "No input packet\n"); + return -EINVAL; + } + + pkt->size = sizeof(struct cvp_hfi_cmd_sys_set_property_packet) + + sizeof(struct cvp_hfi_enable) + sizeof(u32); + pkt->packet_type = HFI_CMD_SYS_SET_PROPERTY; + pkt->num_properties = 1; + pkt->rg_property_data[0] = HFI_PROPERTY_SYS_CODEC_POWER_PLANE_CTRL; + hfi = (struct cvp_hfi_enable *) &pkt->rg_property_data[1]; + hfi->enable = enable; + return 0; +} + +int cvp_create_pkt_cmd_session_set_buffers( + void *cmd, + struct cvp_hal_session *session, + u32 iova, + u32 size) +{ + int rc = 0; + struct cvp_hfi_cmd_session_set_buffers_packet *pkt; + + if (!cmd || !session) + return -EINVAL; + + pkt = (struct cvp_hfi_cmd_session_set_buffers_packet *)cmd; + pkt->packet_type = HFI_CMD_SESSION_CVP_SET_BUFFERS; + pkt->session_id = hash32_ptr(session); + pkt->buf_type.iova = iova; + pkt->buf_type.size = size; + pkt->size = sizeof(struct cvp_hfi_cmd_session_set_buffers_packet); + + return rc; +} + +int cvp_create_pkt_cmd_session_release_buffers( + void *cmd, + struct cvp_hal_session *session) +{ + struct cvp_session_release_buffers_packet *pkt; + + if (!cmd || !session) + return -EINVAL; + + pkt = (struct cvp_session_release_buffers_packet *)cmd; + pkt->packet_type = HFI_CMD_SESSION_CVP_RELEASE_BUFFERS; + pkt->session_id = hash32_ptr(session); + pkt->num_buffers = 1; + pkt->buffer_type = 0; + pkt->size = sizeof(struct cvp_session_release_buffers_packet) + + ((pkt->num_buffers - 1) * sizeof(u32)); + + return 0; +} + +int cvp_create_pkt_cmd_session_send( + struct cvp_kmd_hfi_packet *out_pkt, + struct cvp_hal_session *session, + struct cvp_kmd_hfi_packet *in_pkt) +{ + int def_idx; + struct cvp_hal_session_cmd_pkt *ptr = + (struct cvp_hal_session_cmd_pkt *)in_pkt; + + if (!out_pkt || !in_pkt || !session) + return -EINVAL; + + if (ptr->size > MAX_HFI_PKT_SIZE * sizeof(unsigned int)) + goto error_hfi_packet; + + if (ptr->session_id != hash32_ptr(session)) + goto error_hfi_packet; + + def_idx = get_pkt_index(ptr); + if (def_idx < 0) { + memcpy(out_pkt, in_pkt, ptr->size); + return 0; + } + + if (cvp_hfi_defs[def_idx].type != ptr->packet_type) + goto error_hfi_packet; + + memcpy(out_pkt, in_pkt, ptr->size); + + return 0; + +error_hfi_packet: + dprintk(CVP_ERR, "%s incorrect packet: size=%d type=%d sessionid=%d\n", + __func__, ptr->size, ptr->packet_type, ptr->session_id); + + return -EINVAL; +} + +static int get_hfi_ssr_type(enum hal_ssr_trigger_type type) +{ + int rc = HFI_TEST_SSR_HW_WDOG_IRQ; + + switch (type) { + case SSR_ERR_FATAL: + rc = HFI_TEST_SSR_SW_ERR_FATAL; + break; + case SSR_SW_DIV_BY_ZERO: + rc = HFI_TEST_SSR_SW_DIV_BY_ZERO; + break; + case SSR_HW_WDOG_IRQ: + rc = HFI_TEST_SSR_HW_WDOG_IRQ; + break; + default: + dprintk(CVP_WARN, + "SSR trigger type not recognized, using WDOG.\n"); + } + return rc; +} + +int cvp_create_pkt_ssr_cmd(enum hal_ssr_trigger_type type, + struct cvp_hfi_cmd_sys_test_ssr_packet *pkt) +{ + if (!pkt) { + dprintk(CVP_ERR, "Invalid params, device: %pK\n", pkt); + return -EINVAL; + } + pkt->size = sizeof(struct cvp_hfi_cmd_sys_test_ssr_packet); + pkt->packet_type = HFI_CMD_SYS_TEST_SSR; + pkt->trigger_type = get_hfi_ssr_type(type); + return 0; +} + +int cvp_create_pkt_cmd_sys_image_version( + struct cvp_hfi_cmd_sys_get_property_packet *pkt) +{ + if (!pkt) { + dprintk(CVP_ERR, "%s invalid param :%pK\n", __func__, pkt); + return -EINVAL; + } + pkt->size = sizeof(struct cvp_hfi_cmd_sys_get_property_packet); + pkt->packet_type = HFI_CMD_SYS_GET_PROPERTY; + pkt->num_properties = 1; + pkt->rg_property_data[0] = HFI_PROPERTY_SYS_IMAGE_VERSION; + return 0; +} + +static struct cvp_hfi_packetization_ops hfi_default = { + .sys_init = cvp_create_pkt_cmd_sys_init, + .sys_pc_prep = cvp_create_pkt_cmd_sys_pc_prep, + .sys_power_control = cvp_create_pkt_cmd_sys_power_control, + .sys_set_resource = cvp_create_pkt_cmd_sys_set_resource, + .sys_debug_config = cvp_create_pkt_cmd_sys_debug_config, + .sys_coverage_config = cvp_create_pkt_cmd_sys_coverage_config, + .sys_set_idle_indicator = cvp_create_pkt_cmd_sys_set_idle_indicator, + .sys_release_resource = cvp_create_pkt_cmd_sys_release_resource, + .sys_image_version = cvp_create_pkt_cmd_sys_image_version, + .sys_ubwc_config = create_pkt_cmd_sys_ubwc_config, + .ssr_cmd = cvp_create_pkt_ssr_cmd, + .session_init = cvp_create_pkt_cmd_sys_session_init, + .session_cmd = cvp_create_pkt_cmd_session_cmd, + .session_set_buffers = + cvp_create_pkt_cmd_session_set_buffers, + .session_release_buffers = + cvp_create_pkt_cmd_session_release_buffers, + .session_send = cvp_create_pkt_cmd_session_send, +}; + +struct cvp_hfi_packetization_ops *cvp_hfi_get_pkt_ops_handle( + enum hfi_packetization_type type) +{ + dprintk(CVP_HFI, "%s selected\n", + type == HFI_PACKETIZATION_4XX ? + "4xx packetization" : "Unknown hfi"); + + switch (type) { + case HFI_PACKETIZATION_4XX: + return &hfi_default; + } + + return NULL; +} diff --git a/msm/eva/hfi_packetization.h b/msm/eva/hfi_packetization.h new file mode 100644 index 0000000000..757fe7b96a --- /dev/null +++ b/msm/eva/hfi_packetization.h @@ -0,0 +1,75 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ +#ifndef __HFI_PACKETIZATION__ +#define __HFI_PACKETIZATION__ + +#include +#include "cvp_hfi_helper.h" +#include "cvp_hfi.h" +#include "cvp_hfi_api.h" + +#define call_hfi_pkt_op(q, op, ...) \ + (((q) && (q)->pkt_ops && (q)->pkt_ops->op) ? \ + ((q)->pkt_ops->op(__VA_ARGS__)) : 0) + +enum hfi_packetization_type { + HFI_PACKETIZATION_4XX, +}; + +struct cvp_hfi_packetization_ops { + int (*sys_init)(struct cvp_hfi_cmd_sys_init_packet *pkt, u32 arch_type); + int (*sys_pc_prep)(struct cvp_hfi_cmd_sys_pc_prep_packet *pkt); + int (*sys_power_control)( + struct cvp_hfi_cmd_sys_set_property_packet *pkt, + u32 enable); + int (*sys_set_resource)( + struct cvp_hfi_cmd_sys_set_resource_packet *pkt, + struct cvp_resource_hdr *resource_hdr, + void *resource_value); + int (*sys_debug_config)(struct cvp_hfi_cmd_sys_set_property_packet *pkt, + u32 mode); + int (*sys_coverage_config)( + struct cvp_hfi_cmd_sys_set_property_packet *pkt, + u32 mode); + int (*sys_set_idle_indicator)( + struct cvp_hfi_cmd_sys_set_property_packet *pkt, + u32 mode); + int (*sys_release_resource)( + struct cvp_hfi_cmd_sys_release_resource_packet *pkt, + struct cvp_resource_hdr *resource_hdr); + int (*sys_image_version)( + struct cvp_hfi_cmd_sys_get_property_packet *pkt); + int (*sys_ubwc_config)(struct cvp_hfi_cmd_sys_set_property_packet *pkt, + struct msm_cvp_ubwc_config_data *ubwc_config); + int (*ssr_cmd)(enum hal_ssr_trigger_type type, + struct cvp_hfi_cmd_sys_test_ssr_packet *pkt); + int (*session_init)( + struct cvp_hfi_cmd_sys_session_init_packet *pkt, + struct cvp_hal_session *session); + int (*session_cmd)(struct cvp_hal_session_cmd_pkt *pkt, + int pkt_type, struct cvp_hal_session *session); + int (*session_set_buffers)( + void *pkt, + struct cvp_hal_session *session, + u32 iova, + u32 size); + int (*session_release_buffers)( + void *pkt, + struct cvp_hal_session *session); + int (*session_get_buf_req)( + struct cvp_hfi_cmd_session_get_property_packet *pkt, + struct cvp_hal_session *session); + int (*session_sync_process)( + struct cvp_hfi_cmd_session_sync_process_packet *pkt, + struct cvp_hal_session *session); + int (*session_send)( + struct cvp_kmd_hfi_packet *out_pkt, + struct cvp_hal_session *session, + struct cvp_kmd_hfi_packet *in_pkt); +}; + +struct cvp_hfi_packetization_ops *cvp_hfi_get_pkt_ops_handle( + enum hfi_packetization_type); +#endif diff --git a/msm/eva/hfi_response_handler.c b/msm/eva/hfi_response_handler.c new file mode 100644 index 0000000000..e9cadb0d42 --- /dev/null +++ b/msm/eva/hfi_response_handler.c @@ -0,0 +1,676 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include "cvp_hfi_helper.h" +#include "cvp_hfi_io.h" +#include "msm_cvp_debug.h" +#include "cvp_hfi.h" +#include "msm_cvp_common.h" + +extern struct msm_cvp_drv *cvp_driver; + +static enum cvp_status hfi_map_err_status(u32 hfi_err) +{ + enum cvp_status cvp_err; + + switch (hfi_err) { + case HFI_ERR_NONE: + cvp_err = CVP_ERR_NONE; + break; + case HFI_ERR_SYS_FATAL: + cvp_err = CVP_ERR_HW_FATAL; + break; + case HFI_ERR_SYS_NOC_ERROR: + cvp_err = CVP_ERR_NOC_ERROR; + break; + case HFI_ERR_SYS_VERSION_MISMATCH: + case HFI_ERR_SYS_INVALID_PARAMETER: + case HFI_ERR_SYS_SESSION_ID_OUT_OF_RANGE: + case HFI_ERR_SESSION_INVALID_PARAMETER: + case HFI_ERR_SESSION_INVALID_SESSION_ID: + case HFI_ERR_SESSION_INVALID_STREAM_ID: + cvp_err = CVP_ERR_BAD_PARAM; + break; + case HFI_ERR_SYS_INSUFFICIENT_RESOURCES: + case HFI_ERR_SYS_UNSUPPORTED_DOMAIN: + case HFI_ERR_SYS_UNSUPPORTED_CODEC: + case HFI_ERR_SESSION_UNSUPPORTED_PROPERTY: + case HFI_ERR_SESSION_UNSUPPORTED_SETTING: + case HFI_ERR_SESSION_INSUFFICIENT_RESOURCES: + case HFI_ERR_SESSION_UNSUPPORTED_STREAM: + cvp_err = CVP_ERR_NOT_SUPPORTED; + break; + case HFI_ERR_SYS_MAX_SESSIONS_REACHED: + cvp_err = CVP_ERR_MAX_CLIENTS; + break; + case HFI_ERR_SYS_SESSION_IN_USE: + cvp_err = CVP_ERR_CLIENT_PRESENT; + break; + case HFI_ERR_SESSION_FATAL: + cvp_err = CVP_ERR_CLIENT_FATAL; + break; + case HFI_ERR_SESSION_BAD_POINTER: + cvp_err = CVP_ERR_BAD_PARAM; + break; + case HFI_ERR_SESSION_INCORRECT_STATE_OPERATION: + cvp_err = CVP_ERR_BAD_STATE; + break; + default: + cvp_err = CVP_ERR_FAIL; + break; + } + return cvp_err; +} + +static int hfi_process_sys_error(u32 device_id, + struct cvp_hfi_msg_event_notify_packet *pkt, + struct msm_cvp_cb_info *info) +{ + struct msm_cvp_cb_cmd_done cmd_done = {0}; + + cmd_done.device_id = device_id; + cmd_done.status = hfi_map_err_status(pkt->event_data1); + + info->response_type = HAL_SYS_ERROR; + info->response.cmd = cmd_done; + + return 0; +} + +static int hfi_process_session_error(u32 device_id, + struct cvp_hfi_msg_event_notify_packet *pkt, + struct msm_cvp_cb_info *info) +{ + struct msm_cvp_cb_cmd_done cmd_done = {0}; + + cmd_done.device_id = device_id; + cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.status = hfi_map_err_status(pkt->event_data1); + info->response.cmd = cmd_done; + dprintk(CVP_INFO, "Received: SESSION_ERROR with event id : %#x %#x\n", + pkt->event_data1, pkt->event_data2); + switch (pkt->event_data1) { + /* Ignore below errors */ + case HFI_ERR_SESSION_INVALID_SCALE_FACTOR: + case HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED: + dprintk(CVP_INFO, "Non Fatal: HFI_EVENT_SESSION_ERROR\n"); + info->response_type = HAL_RESPONSE_UNUSED; + break; + default: + dprintk(CVP_ERR, + "%s: session %x data1 %#x, data2 %#x\n", __func__, + pkt->session_id, pkt->event_data1, pkt->event_data2); + info->response_type = HAL_RESPONSE_UNUSED; + break; + } + + return 0; +} + +static int hfi_process_event_notify(u32 device_id, + void *hdr, struct msm_cvp_cb_info *info) +{ + struct cvp_hfi_msg_event_notify_packet *pkt = + (struct cvp_hfi_msg_event_notify_packet *)hdr; + + dprintk(CVP_HFI, "Received: EVENT_NOTIFY\n"); + + if (pkt->size < sizeof(struct cvp_hfi_msg_event_notify_packet)) { + dprintk(CVP_ERR, "Invalid Params\n"); + return -E2BIG; + } + + switch (pkt->event_id) { + case HFI_EVENT_SYS_ERROR: + dprintk(CVP_ERR, "HFI_EVENT_SYS_ERROR: %d, %#x\n", + pkt->event_data1, pkt->event_data2); + return hfi_process_sys_error(device_id, pkt, info); + + case HFI_EVENT_SESSION_ERROR: + dprintk(CVP_INFO, "HFI_EVENT_SESSION_ERROR[%#x]\n", + pkt->session_id); + return hfi_process_session_error(device_id, pkt, info); + + default: + *info = (struct msm_cvp_cb_info) { + .response_type = HAL_RESPONSE_UNUSED, + }; + + return 0; + } +} + +static int hfi_process_sys_init_done(u32 device_id, + void *hdr, struct msm_cvp_cb_info *info) +{ + struct cvp_hfi_msg_sys_init_done_packet *pkt = + (struct cvp_hfi_msg_sys_init_done_packet *)hdr; + struct msm_cvp_cb_cmd_done cmd_done = {0}; + enum cvp_status status = CVP_ERR_NONE; + + dprintk(CVP_CORE, "RECEIVED: SYS_INIT_DONE\n"); + if (sizeof(struct cvp_hfi_msg_sys_init_done_packet) > pkt->size) { + dprintk(CVP_ERR, "%s: bad_pkt_size: %d\n", __func__, + pkt->size); + return -E2BIG; + } + if (!pkt->num_properties) { + dprintk(CVP_CORE, + "hal_process_sys_init_done: no_properties\n"); + goto err_no_prop; + } + + status = hfi_map_err_status(pkt->error_type); + if (status) { + dprintk(CVP_ERR, "%s: status %#x\n", + __func__, status); + goto err_no_prop; + } + +err_no_prop: + cmd_done.device_id = device_id; + cmd_done.session_id = NULL; + cmd_done.status = (u32)status; + cmd_done.size = sizeof(struct cvp_hal_sys_init_done); + + info->response_type = HAL_SYS_INIT_DONE; + info->response.cmd = cmd_done; + + return 0; +} + +enum cvp_status cvp_hfi_process_sys_init_done_prop_read( + struct cvp_hfi_msg_sys_init_done_packet *pkt, + struct cvp_hal_sys_init_done *sys_init_done) +{ + enum cvp_status status = CVP_ERR_NONE; + u32 rem_bytes, num_properties; + u8 *data_ptr; + + if (!pkt || !sys_init_done) { + dprintk(CVP_ERR, + "hfi_msg_sys_init_done: Invalid input\n"); + return CVP_ERR_FAIL; + } + + rem_bytes = pkt->size - sizeof(struct + cvp_hfi_msg_sys_init_done_packet) + sizeof(u32); + + if (!rem_bytes) { + dprintk(CVP_ERR, + "hfi_msg_sys_init_done: missing_prop_info\n"); + return CVP_ERR_FAIL; + } + + status = hfi_map_err_status(pkt->error_type); + if (status) { + dprintk(CVP_ERR, "%s: status %#x\n", __func__, status); + return status; + } + + data_ptr = (u8 *) &pkt->rg_property_data[0]; + num_properties = pkt->num_properties; + dprintk(CVP_HFI, + "%s: data_start %pK, num_properties %#x\n", + __func__, data_ptr, num_properties); + + sys_init_done->capabilities = NULL; + return status; +} + +static int hfi_process_session_init_done(u32 device_id, + void *hdr, struct msm_cvp_cb_info *info) +{ + struct cvp_hfi_msg_sys_session_init_done_packet *pkt = + (struct cvp_hfi_msg_sys_session_init_done_packet *)hdr; + struct msm_cvp_cb_cmd_done cmd_done = {0}; + struct cvp_hal_session_init_done session_init_done = { {0} }; + + dprintk(CVP_SESS, "RECEIVED: SESSION_INIT_DONE[%x]\n", pkt->session_id); + + if (sizeof(struct cvp_hfi_msg_sys_session_init_done_packet) + > pkt->size) { + dprintk(CVP_ERR, + "hal_process_session_init_done: bad_pkt_size\n"); + return -E2BIG; + } + + cmd_done.device_id = device_id; + cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.status = hfi_map_err_status(pkt->error_type); + cmd_done.data.session_init_done = session_init_done; + cmd_done.size = sizeof(struct cvp_hal_session_init_done); + + info->response_type = HAL_SESSION_INIT_DONE; + info->response.cmd = cmd_done; + + return 0; +} +static int hfi_process_session_end_done(u32 device_id, + void *hdr, struct msm_cvp_cb_info *info) +{ + struct cvp_hfi_msg_sys_session_end_done_packet *pkt = + (struct cvp_hfi_msg_sys_session_end_done_packet *)hdr; + struct msm_cvp_cb_cmd_done cmd_done = {0}; + + dprintk(CVP_SESS, "RECEIVED: SESSION_END_DONE[%#x]\n", pkt->session_id); + + if (!pkt || pkt->size != + sizeof(struct cvp_hfi_msg_sys_session_end_done_packet)) { + dprintk(CVP_ERR, "%s: bad packet/packet size\n", __func__); + return -E2BIG; + } + + cmd_done.device_id = device_id; + cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.status = hfi_map_err_status(pkt->error_type); + cmd_done.size = 0; + + info->response_type = HAL_SESSION_END_DONE; + info->response.cmd = cmd_done; + + return 0; +} + +static int hfi_process_session_abort_done(u32 device_id, + void *hdr, struct msm_cvp_cb_info *info) +{ + struct cvp_hfi_msg_sys_session_abort_done_packet *pkt = + (struct cvp_hfi_msg_sys_session_abort_done_packet *)hdr; + struct msm_cvp_cb_cmd_done cmd_done = {0}; + + dprintk(CVP_SESS, "RECEIVED: SESSION_ABORT_DONE[%#x]\n", + pkt->session_id); + + if (!pkt || pkt->size != + sizeof(struct cvp_hfi_msg_sys_session_abort_done_packet)) { + dprintk(CVP_ERR, "%s: bad packet/packet size: %d\n", + __func__, pkt ? pkt->size : 0); + return -E2BIG; + } + cmd_done.device_id = device_id; + cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.status = hfi_map_err_status(pkt->error_type); + cmd_done.size = 0; + + info->response_type = HAL_SESSION_ABORT_DONE; + info->response.cmd = cmd_done; + + return 0; +} + +static int hfi_process_session_set_buf_done(u32 device_id, + void *hdr, struct msm_cvp_cb_info *info) +{ + struct cvp_hfi_msg_session_hdr *pkt = + (struct cvp_hfi_msg_session_hdr *)hdr; + struct msm_cvp_cb_cmd_done cmd_done = {0}; + unsigned int pkt_size = get_msg_size(); + + if (!pkt || pkt->size < pkt_size) { + dprintk(CVP_ERR, "bad packet/packet size %d\n", + pkt ? pkt->size : 0); + return -E2BIG; + } + dprintk(CVP_SESS, "RECEIVED:CVP_SET_BUFFER_DONE[%#x]\n", + pkt->session_id); + + cmd_done.device_id = device_id; + cmd_done.session_id = (void *)(uintptr_t)get_msg_session_id(pkt); + cmd_done.status = hfi_map_err_status(get_msg_errorcode(pkt)); + cmd_done.size = 0; + + info->response_type = HAL_SESSION_SET_BUFFER_DONE; + info->response.cmd = cmd_done; + + return 0; +} + +static int hfi_process_session_flush_done(u32 device_id, + void *hdr, struct msm_cvp_cb_info *info) +{ + struct cvp_hfi_msg_sys_session_flush_done_packet *pkt = + (struct cvp_hfi_msg_sys_session_flush_done_packet *)hdr; + struct msm_cvp_cb_cmd_done cmd_done = {0}; + + dprintk(CVP_SESS, "RECEIVED: SESSION_FLUSH_DONE[%#x]\n", + pkt->session_id); + + if (!pkt || pkt->size < + sizeof(struct cvp_hfi_msg_sys_session_flush_done_packet)) { + dprintk(CVP_ERR, "%s: bad packet/packet size: %d\n", + __func__, pkt ? pkt->size : 0); + return -E2BIG; + } + cmd_done.device_id = device_id; + cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.status = hfi_map_err_status(pkt->error_type); + cmd_done.size = 0; + + info->response_type = HAL_SESSION_FLUSH_DONE; + info->response.cmd = cmd_done; + + return 0; +} + +static int hfi_process_session_rel_buf_done(u32 device_id, + void *hdr, struct msm_cvp_cb_info *info) +{ + struct cvp_hfi_msg_session_hdr *pkt = + (struct cvp_hfi_msg_session_hdr *)hdr; + struct msm_cvp_cb_cmd_done cmd_done = {0}; + unsigned int pkt_size = get_msg_size(); + + if (!pkt || pkt->size < pkt_size) { + dprintk(CVP_ERR, "bad packet/packet size %d\n", + pkt ? pkt->size : 0); + return -E2BIG; + } + dprintk(CVP_SESS, "RECEIVED:CVP_RELEASE_BUFFER_DONE[%#x]\n", + pkt->session_id); + + cmd_done.device_id = device_id; + cmd_done.session_id = (void *)(uintptr_t)get_msg_session_id(pkt); + cmd_done.status = hfi_map_err_status(get_msg_errorcode(pkt)); + cmd_done.size = 0; + + info->response_type = HAL_SESSION_RELEASE_BUFFER_DONE; + info->response.cmd = cmd_done; + + return 0; +} + +static int hfi_process_session_cvp_operation_config(u32 device_id, + void *hdr, struct msm_cvp_cb_info *info) +{ + struct cvp_hfi_msg_session_op_cfg_packet *pkt = + (struct cvp_hfi_msg_session_op_cfg_packet *)hdr; + struct msm_cvp_cb_cmd_done cmd_done = {0}; + int signal; + unsigned int conf_id, session_id, error_type; + + if (!pkt) { + dprintk(CVP_ERR, "%s: invalid param\n", __func__); + return -EINVAL; + } else if (pkt->size < get_msg_size()) { + dprintk(CVP_ERR, + "%s: bad_pkt_size\n", __func__); + return -E2BIG; + } + + get_msg_opconfigs(pkt, &session_id, &error_type, &conf_id); + cmd_done.device_id = device_id; + cmd_done.session_id = (void *)(uintptr_t)session_id; + cmd_done.status = hfi_map_err_status(error_type); + cmd_done.size = 0; + + dprintk(CVP_HFI, + "%s: device_id=%d status=%d, sessionid=%pK config=%x\n", + __func__, device_id, cmd_done.status, + cmd_done.session_id, pkt->op_conf_id); + + if (pkt->packet_type == HFI_MSG_SESSION_CVP_SET_PERSIST_BUFFERS) + signal = get_signal_from_pkt_type( + HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS); + else if (pkt->packet_type == + HFI_MSG_SESSION_CVP_RELEASE_PERSIST_BUFFERS) + signal = get_signal_from_pkt_type( + HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS); + else if (pkt->packet_type == HFI_MSG_SESSION_CVP_SET_MODEL_BUFFERS) + signal = get_signal_from_pkt_type( + HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS); + else + signal = get_signal_from_pkt_type(conf_id); + + if (signal < 0) { + dprintk(CVP_ERR, "%s Invalid op config id\n", __func__); + return -EINVAL; + } + + info->response_type = signal; + info->response.cmd = cmd_done; + return 0; +} + +static struct msm_cvp_inst *cvp_get_inst_from_id(struct msm_cvp_core *core, + unsigned int session_id) +{ + struct msm_cvp_inst *inst = NULL; + bool match = false; + int count = 0; + + if (!core || !session_id) + return NULL; + +retry: + if (mutex_trylock(&core->lock)) { + list_for_each_entry(inst, &core->instances, list) { + if (hash32_ptr(inst->session) == session_id) { + match = true; + break; + } + } + + inst = match ? inst : NULL; + mutex_unlock(&core->lock); + } else { + if (core->state == CVP_CORE_UNINIT) + return NULL; + usleep_range(100, 200); + count++; + if (count < 1000) + goto retry; + else + dprintk(CVP_ERR, "timeout locking core mutex\n"); + } + + return inst; + +} + +static int hfi_process_session_cvp_msg(u32 device_id, + void *hdr, struct msm_cvp_cb_info *info) +{ + struct cvp_hfi_msg_session_hdr *pkt = + (struct cvp_hfi_msg_session_hdr *)hdr; + struct cvp_session_msg *sess_msg; + struct msm_cvp_inst *inst = NULL; + struct msm_cvp_core *core; + void *session_id; + struct cvp_session_queue *sq; + + if (!pkt) { + dprintk(CVP_ERR, "%s: invalid param\n", __func__); + return -EINVAL; + } else if (pkt->size > MAX_HFI_PKT_SIZE * sizeof(unsigned int)) { + dprintk(CVP_ERR, "%s: bad_pkt_size %d\n", __func__, pkt->size); + return -E2BIG; + } + session_id = (void *)(uintptr_t)get_msg_session_id(pkt); + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + inst = cvp_get_inst_from_id(core, (unsigned int)session_id); + + if (!inst) { + dprintk(CVP_ERR, "%s: invalid session\n", __func__); + return -EINVAL; + } + + if (pkt->client_data.kdata & FENCE_BIT) + sq = &inst->session_queue_fence; + else + sq = &inst->session_queue; + + sess_msg = kmem_cache_alloc(cvp_driver->msg_cache, GFP_KERNEL); + if (sess_msg == NULL) { + dprintk(CVP_ERR, "%s runs out msg cache memory\n", __func__); + return -ENOMEM; + } + + memcpy(&sess_msg->pkt, pkt, get_msg_size()); + + dprintk(CVP_HFI, + "%s: Received msg %x cmd_done.status=%d sessionid=%x\n", + __func__, pkt->packet_type, + hfi_map_err_status(get_msg_errorcode(pkt)), session_id); + + spin_lock(&sq->lock); + if (sq->msg_count >= MAX_NUM_MSGS_PER_SESSION) { + dprintk(CVP_ERR, "Reached session queue size limit\n"); + goto error_handle_msg; + } + list_add_tail(&sess_msg->node, &sq->msgs); + sq->msg_count++; + spin_unlock(&sq->lock); + + wake_up_all(&sq->wq); + + info->response_type = HAL_NO_RESP; + + return 0; + +error_handle_msg: + spin_unlock(&sq->lock); + kmem_cache_free(cvp_driver->msg_cache, sess_msg); + return -ENOMEM; +} + +static void hfi_process_sys_get_prop_image_version( + struct cvp_hfi_msg_sys_property_info_packet *pkt) +{ + int i = 0; + const u32 version_string_size = 128; + u8 *str_image_version; + int req_bytes; + + req_bytes = pkt->size - sizeof(*pkt); + if (req_bytes < version_string_size || + !pkt->rg_property_data[1] || + pkt->num_properties > 1) { + dprintk(CVP_ERR, "%s: bad_pkt: %d\n", __func__, req_bytes); + return; + } + str_image_version = (u8 *)&pkt->rg_property_data[1]; + /* + * The version string returned by firmware includes null + * characters at the start and in between. Replace the null + * characters with space, to print the version info. + */ + for (i = 0; i < version_string_size; i++) { + if (str_image_version[i] != '\0') + cvp_driver->fw_version[i] = str_image_version[i]; + else + cvp_driver->fw_version[i] = ' '; + } + cvp_driver->fw_version[i - 1] = '\0'; + dprintk(CVP_HFI, "F/W version: %s\n", cvp_driver->fw_version); +} + +static int hfi_process_sys_property_info(u32 device_id, + void *hdr, struct msm_cvp_cb_info *info) +{ + struct cvp_hfi_msg_sys_property_info_packet *pkt = + (struct cvp_hfi_msg_sys_property_info_packet *)hdr; + if (!pkt) { + dprintk(CVP_ERR, "%s: invalid param\n", __func__); + return -EINVAL; + } else if (pkt->size > sizeof(*pkt)) { + dprintk(CVP_ERR, + "%s: bad_pkt_size %d\n", __func__, pkt->size); + return -E2BIG; + } else if (!pkt->num_properties) { + dprintk(CVP_WARN, + "%s: no_properties\n", __func__); + return -EINVAL; + } + + switch (pkt->rg_property_data[0]) { + case HFI_PROPERTY_SYS_IMAGE_VERSION: + hfi_process_sys_get_prop_image_version(pkt); + + *info = (struct msm_cvp_cb_info) { + .response_type = HAL_RESPONSE_UNUSED, + }; + return 0; + default: + dprintk(CVP_WARN, + "%s: unknown_prop_id: %x\n", + __func__, pkt->rg_property_data[0]); + return -ENOTSUPP; + } + +} + +int cvp_hfi_process_msg_packet(u32 device_id, void *hdr, + struct msm_cvp_cb_info *info) +{ + typedef int (*pkt_func_def)(u32, void *, struct msm_cvp_cb_info *info); + pkt_func_def pkt_func = NULL; + struct cvp_hal_msg_pkt_hdr *msg_hdr = (struct cvp_hal_msg_pkt_hdr *)hdr; + + if (!info || !msg_hdr || msg_hdr->size < CVP_IFACEQ_MIN_PKT_SIZE) { + dprintk(CVP_ERR, "%s: bad packet/packet size\n", + __func__); + return -EINVAL; + } + + dprintk(CVP_HFI, "Received HFI MSG with type %#x\n", msg_hdr->packet); + switch (msg_hdr->packet) { + case HFI_MSG_EVENT_NOTIFY: + pkt_func = (pkt_func_def)hfi_process_event_notify; + break; + case HFI_MSG_SYS_INIT_DONE: + pkt_func = (pkt_func_def)hfi_process_sys_init_done; + break; + case HFI_MSG_SYS_SESSION_INIT_DONE: + pkt_func = (pkt_func_def)hfi_process_session_init_done; + break; + case HFI_MSG_SYS_PROPERTY_INFO: + pkt_func = (pkt_func_def)hfi_process_sys_property_info; + break; + case HFI_MSG_SYS_SESSION_END_DONE: + pkt_func = (pkt_func_def)hfi_process_session_end_done; + break; + case HFI_MSG_SESSION_CVP_SET_BUFFERS: + pkt_func = (pkt_func_def) hfi_process_session_set_buf_done; + break; + case HFI_MSG_SESSION_CVP_RELEASE_BUFFERS: + pkt_func = (pkt_func_def)hfi_process_session_rel_buf_done; + break; + case HFI_MSG_SYS_SESSION_ABORT_DONE: + pkt_func = (pkt_func_def)hfi_process_session_abort_done; + break; + case HFI_MSG_SESSION_CVP_FLUSH: + case HFI_MSG_SESSION_CVP_FLUSH_DEPRECATE: + pkt_func = (pkt_func_def)hfi_process_session_flush_done; + break; + case HFI_MSG_SESSION_CVP_OPERATION_CONFIG: + case HFI_MSG_SESSION_CVP_SET_PERSIST_BUFFERS: + case HFI_MSG_SESSION_CVP_RELEASE_PERSIST_BUFFERS: + case HFI_MSG_SESSION_CVP_SET_MODEL_BUFFERS: + pkt_func = + (pkt_func_def)hfi_process_session_cvp_operation_config; + break; + case HFI_MSG_SESSION_CVP_DS: + case HFI_MSG_SESSION_CVP_DFS: + case HFI_MSG_SESSION_CVP_DME: + case HFI_MSG_SESSION_CVP_FD: + pkt_func = (pkt_func_def)hfi_process_session_cvp_msg; + break; + default: + dprintk(CVP_HFI, "Use default msg handler: %#x\n", + msg_hdr->packet); + pkt_func = (pkt_func_def)hfi_process_session_cvp_msg; + break; + } + + return pkt_func ? + pkt_func(device_id, hdr, info) : -ENOTSUPP; +} diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c new file mode 100644 index 0000000000..9e8f9a4a41 --- /dev/null +++ b/msm/eva/msm_cvp.c @@ -0,0 +1,1646 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#include "msm_cvp.h" +#include "cvp_hfi.h" +#include "cvp_core_hfi.h" +#include "msm_cvp_buf.h" + +struct cvp_power_level { + unsigned long core_sum; + unsigned long op_core_sum; + unsigned long bw_sum; +}; + +static int msm_cvp_get_session_info(struct msm_cvp_inst *inst, + struct cvp_kmd_session_info *session) +{ + int rc = 0; + struct msm_cvp_inst *s; + + if (!inst || !inst->core || !session) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + s = cvp_get_inst_validate(inst->core, inst); + if (!s) + return -ECONNRESET; + + s->cur_cmd_type = CVP_KMD_GET_SESSION_INFO; + session->session_id = hash32_ptr(inst->session); + dprintk(CVP_SESS, "%s: id 0x%x\n", __func__, session->session_id); + + s->cur_cmd_type = 0; + cvp_put_inst(s); + return rc; +} + + + +static bool cvp_msg_pending(struct cvp_session_queue *sq, + struct cvp_session_msg **msg, u64 *ktid) +{ + struct cvp_session_msg *mptr, *dummy; + bool result = false; + + mptr = NULL; + spin_lock(&sq->lock); + if (sq->state != QUEUE_ACTIVE) { + /* The session is being deleted */ + spin_unlock(&sq->lock); + *msg = NULL; + return true; + } + result = list_empty(&sq->msgs); + if (!result) { + if (!ktid) { + mptr = + list_first_entry(&sq->msgs, struct cvp_session_msg, + node); + list_del_init(&mptr->node); + sq->msg_count--; + } else { + result = true; + list_for_each_entry_safe(mptr, dummy, &sq->msgs, node) { + if (*ktid == mptr->pkt.client_data.kdata) { + list_del_init(&mptr->node); + sq->msg_count--; + result = false; + break; + } + } + if (result) + mptr = NULL; + } + } + spin_unlock(&sq->lock); + *msg = mptr; + return !result; +} + +static int cvp_wait_process_message(struct msm_cvp_inst *inst, + struct cvp_session_queue *sq, u64 *ktid, + unsigned long timeout, + struct cvp_kmd_hfi_packet *out) +{ + struct cvp_session_msg *msg = NULL; + struct cvp_hfi_msg_session_hdr *hdr; + int rc = 0; + + if (wait_event_timeout(sq->wq, + cvp_msg_pending(sq, &msg, ktid), timeout) == 0) { + dprintk(CVP_WARN, "session queue wait timeout\n"); + rc = -ETIMEDOUT; + goto exit; + } + + if (msg == NULL) { + dprintk(CVP_WARN, "%s: queue state %d, msg cnt %d\n", __func__, + sq->state, sq->msg_count); + + if (inst->state >= MSM_CVP_CLOSE_DONE || + sq->state != QUEUE_ACTIVE) { + rc = -ECONNRESET; + goto exit; + } + + msm_cvp_comm_kill_session(inst); + goto exit; + } + + if (out) + memcpy(out, &msg->pkt, sizeof(struct cvp_hfi_msg_session_hdr)); + + kmem_cache_free(cvp_driver->msg_cache, msg); + hdr = (struct cvp_hfi_msg_session_hdr *)out; + msm_cvp_unmap_frame(inst, hdr->client_data.kdata); + +exit: + return rc; +} + +static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst, + struct cvp_kmd_hfi_packet *out_pkt) +{ + unsigned long wait_time; + struct cvp_session_queue *sq; + struct msm_cvp_inst *s; + int rc = 0; + + if (!inst) { + dprintk(CVP_ERR, "%s invalid session\n", __func__); + return -EINVAL; + } + + s = cvp_get_inst_validate(inst->core, inst); + if (!s) + return -ECONNRESET; + + s->cur_cmd_type = CVP_KMD_RECEIVE_MSG_PKT; + wait_time = msecs_to_jiffies(CVP_MAX_WAIT_TIME); + sq = &inst->session_queue; + + rc = cvp_wait_process_message(inst, sq, NULL, wait_time, out_pkt); + + s->cur_cmd_type = 0; + cvp_put_inst(inst); + return rc; +} + +static int msm_cvp_session_process_hfi( + struct msm_cvp_inst *inst, + struct cvp_kmd_hfi_packet *in_pkt, + unsigned int in_offset, + unsigned int in_buf_num) +{ + int pkt_idx, pkt_type, rc = 0; + struct cvp_hfi_device *hdev; + unsigned int offset, buf_num, signal; + struct cvp_session_queue *sq; + struct msm_cvp_inst *s; + + if (!inst || !inst->core || !in_pkt) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + s = cvp_get_inst_validate(inst->core, inst); + if (!s) + return -ECONNRESET; + + inst->cur_cmd_type = CVP_KMD_SEND_CMD_PKT; + hdev = inst->core->device; + + pkt_idx = get_pkt_index((struct cvp_hal_session_cmd_pkt *)in_pkt); + if (pkt_idx < 0) { + dprintk(CVP_ERR, "%s incorrect packet %d, %x\n", __func__, + in_pkt->pkt_data[0], + in_pkt->pkt_data[1]); + offset = in_offset; + buf_num = in_buf_num; + signal = HAL_NO_RESP; + } else { + offset = cvp_hfi_defs[pkt_idx].buf_offset; + buf_num = cvp_hfi_defs[pkt_idx].buf_num; + signal = cvp_hfi_defs[pkt_idx].resp; + } + if (signal == HAL_NO_RESP) { + /* Frame packets are not allowed before session starts*/ + sq = &inst->session_queue; + spin_lock(&sq->lock); + if (sq->state != QUEUE_ACTIVE) { + spin_unlock(&sq->lock); + dprintk(CVP_ERR, "%s: invalid queue state\n", __func__); + rc = -EINVAL; + goto exit; + } + spin_unlock(&sq->lock); + } + + if (in_offset && in_buf_num) { + offset = in_offset; + buf_num = in_buf_num; + } + if (!is_buf_param_valid(buf_num, offset)) { + dprintk(CVP_ERR, "Incorrect buffer num and offset in cmd\n"); + return -EINVAL; + } + pkt_type = in_pkt->pkt_data[1]; + if (pkt_type == HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS || + pkt_type == HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS) + rc = msm_cvp_map_user_persist(inst, in_pkt, offset, buf_num); + else if (pkt_type == HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS) + rc = msm_cvp_mark_user_persist(inst, in_pkt, offset, buf_num); + else + rc = msm_cvp_map_frame(inst, in_pkt, offset, buf_num); + + if (rc) + goto exit; + + rc = call_hfi_op(hdev, session_send, (void *)inst->session, in_pkt); + if (rc) { + dprintk(CVP_ERR, + "%s: Failed in call_hfi_op %d, %x\n", + __func__, in_pkt->pkt_data[0], in_pkt->pkt_data[1]); + goto exit; + } + + if (signal != HAL_NO_RESP) { + rc = wait_for_sess_signal_receipt(inst, signal); + if (rc) { + dprintk(CVP_ERR, + "%s: wait for signal failed, rc %d %d, %x %d\n", + __func__, rc, + in_pkt->pkt_data[0], + in_pkt->pkt_data[1], + signal); + goto exit; + } + if (pkt_type == HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS) + rc = msm_cvp_unmap_user_persist(inst, in_pkt, + offset, buf_num); + + } +exit: + inst->cur_cmd_type = 0; + cvp_put_inst(inst); + return rc; +} + +static bool cvp_fence_wait(struct cvp_fence_queue *q, + struct cvp_fence_command **fence, + enum queue_state *state) +{ + struct cvp_fence_command *f; + + *fence = NULL; + mutex_lock(&q->lock); + *state = q->state; + if (*state != QUEUE_ACTIVE) { + mutex_unlock(&q->lock); + return true; + } + + if (list_empty(&q->wait_list)) { + mutex_unlock(&q->lock); + return false; + } + + f = list_first_entry(&q->wait_list, struct cvp_fence_command, list); + list_del_init(&f->list); + list_add_tail(&q->sched_list, &f->list); + + mutex_unlock(&q->lock); + *fence = f; + + return true; +} + +static int cvp_fence_proc(struct msm_cvp_inst *inst, + struct cvp_fence_command *fc, + struct cvp_hfi_cmd_session_hdr *pkt) +{ + int rc = 0; + unsigned long timeout; + u64 ktid; + int synx_state = SYNX_STATE_SIGNALED_SUCCESS; + struct cvp_hfi_device *hdev; + struct cvp_session_queue *sq; + u32 hfi_err = HFI_ERR_NONE; + struct cvp_hfi_msg_session_hdr *hdr; + + dprintk(CVP_SYNX, "%s %s\n", current->comm, __func__); + + hdev = inst->core->device; + sq = &inst->session_queue_fence; + ktid = pkt->client_data.kdata; + + if (cvp_synx_ops(inst, CVP_INPUT_SYNX, fc, &synx_state)) { + msm_cvp_unmap_frame(inst, pkt->client_data.kdata); + goto exit; + } + + rc = call_hfi_op(hdev, session_send, (void *)inst->session, + (struct cvp_kmd_hfi_packet *)pkt); + if (rc) { + dprintk(CVP_ERR, "%s %s: Failed in call_hfi_op %d, %x\n", + current->comm, __func__, pkt->size, pkt->packet_type); + synx_state = SYNX_STATE_SIGNALED_ERROR; + goto exit; + } + + timeout = msecs_to_jiffies(CVP_MAX_WAIT_TIME); + rc = cvp_wait_process_message(inst, sq, &ktid, timeout, + (struct cvp_kmd_hfi_packet *)pkt); + hdr = (struct cvp_hfi_msg_session_hdr *)pkt; + hfi_err = hdr->error_type; + if (rc) { + dprintk(CVP_ERR, "%s %s: cvp_wait_process_message rc %d\n", + current->comm, __func__, rc); + synx_state = SYNX_STATE_SIGNALED_ERROR; + goto exit; + } + if (hfi_err == HFI_ERR_SESSION_FLUSHED) { + dprintk(CVP_SYNX, "%s %s: cvp_wait_process_message flushed\n", + current->comm, __func__); + synx_state = SYNX_STATE_SIGNALED_CANCEL; + } else if (hfi_err == HFI_ERR_SESSION_STREAM_CORRUPT) { + dprintk(CVP_WARN, "%s %s: cvp_wait_process_msg non-fatal %d\n", + current->comm, __func__, hfi_err); + synx_state = SYNX_STATE_SIGNALED_SUCCESS; + } else if (hfi_err != HFI_ERR_NONE) { + dprintk(CVP_ERR, "%s %s: cvp_wait_process_message hfi err %d\n", + current->comm, __func__, hfi_err); + synx_state = SYNX_STATE_SIGNALED_CANCEL; + } + +exit: + rc = cvp_synx_ops(inst, CVP_OUTPUT_SYNX, fc, &synx_state); + + return rc; +} + +static int cvp_alloc_fence_data(struct cvp_fence_command **f, u32 size) +{ + struct cvp_fence_command *fcmd; + + fcmd = kzalloc(sizeof(struct cvp_fence_command), GFP_KERNEL); + if (!fcmd) + return -ENOMEM; + + fcmd->pkt = kzalloc(size, GFP_KERNEL); + if (!fcmd->pkt) { + kfree(fcmd); + return -ENOMEM; + } + + *f = fcmd; + return 0; +} + +static void cvp_free_fence_data(struct cvp_fence_command *f) +{ + kfree(f->pkt); + f->pkt = NULL; + kfree(f); + f = NULL; +} + +static int cvp_fence_thread(void *data) +{ + int rc = 0; + struct msm_cvp_inst *inst; + struct cvp_fence_queue *q; + enum queue_state state; + struct cvp_fence_command *f; + struct cvp_hfi_cmd_session_hdr *pkt; + u32 *synx; + u64 ktid; + + dprintk(CVP_SYNX, "Enter %s\n", current->comm); + + inst = (struct msm_cvp_inst *)data; + if (!inst || !inst->core || !inst->core->device) { + dprintk(CVP_ERR, "%s invalid inst %pK\n", current->comm, inst); + rc = -EINVAL; + goto exit; + } + + q = &inst->fence_cmd_queue; + +wait: + dprintk(CVP_SYNX, "%s starts wait\n", current->comm); + + f = NULL; + wait_event_interruptible(q->wq, cvp_fence_wait(q, &f, &state)); + if (state != QUEUE_ACTIVE) + goto exit; + + if (!f) + goto wait; + + pkt = f->pkt; + synx = (u32 *)f->synx; + + ktid = pkt->client_data.kdata & (FENCE_BIT - 1); + dprintk(CVP_SYNX, "%s pkt type %d on ktid %llu frameID %llu\n", + current->comm, pkt->packet_type, ktid, f->frame_id); + + rc = cvp_fence_proc(inst, f, pkt); + + mutex_lock(&q->lock); + cvp_release_synx(inst, f); + list_del_init(&f->list); + mutex_unlock(&q->lock); + + dprintk(CVP_SYNX, "%s done with %d ktid %llu frameID %llu rc %d\n", + current->comm, pkt->packet_type, ktid, f->frame_id, rc); + + cvp_free_fence_data(f); + + goto wait; + +exit: + dprintk(CVP_SYNX, "%s exit\n", current->comm); + cvp_put_inst(inst); + do_exit(rc); +} + +static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst, + struct cvp_kmd_arg *arg) +{ + int rc = 0; + int idx; + struct cvp_kmd_hfi_fence_packet *fence_pkt; + struct cvp_kmd_hfi_synx_packet *synx_pkt; + struct cvp_kmd_fence_ctrl *kfc; + struct cvp_hfi_cmd_session_hdr *pkt; + unsigned int offset, buf_num, in_offset, in_buf_num; + struct msm_cvp_inst *s; + struct cvp_fence_command *f; + struct cvp_fence_queue *q; + u32 *fence; + enum op_mode mode; + + if (!inst || !inst->core || !arg || !inst->core->device) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + s = cvp_get_inst_validate(inst->core, inst); + if (!s) + return -ECONNRESET; + + q = &inst->fence_cmd_queue; + + mutex_lock(&q->lock); + mode = q->mode; + mutex_unlock(&q->lock); + + if (mode == OP_DRAINING) { + dprintk(CVP_SYNX, "%s: flush in progress\n", __func__); + rc = -EBUSY; + goto exit; + } + + in_offset = arg->buf_offset; + in_buf_num = arg->buf_num; + + fence_pkt = &arg->data.hfi_fence_pkt; + pkt = (struct cvp_hfi_cmd_session_hdr *)&fence_pkt->pkt_data; + idx = get_pkt_index((struct cvp_hal_session_cmd_pkt *)pkt); + + if (idx < 0 || pkt->size > MAX_HFI_FENCE_OFFSET) { + dprintk(CVP_ERR, "%s incorrect packet %d %#x\n", __func__, + pkt->size, pkt->packet_type); + goto exit; + } + + if (in_offset && in_buf_num) { + offset = in_offset; + buf_num = in_buf_num; + } else { + offset = cvp_hfi_defs[idx].buf_offset; + buf_num = cvp_hfi_defs[idx].buf_num; + } + + if (!is_buf_param_valid(buf_num, offset)) { + dprintk(CVP_ERR, "Incorrect buf num and offset in cmd\n"); + goto exit; + } + rc = msm_cvp_map_frame(inst, (struct cvp_kmd_hfi_packet *)pkt, offset, + buf_num); + if (rc) + goto exit; + + rc = cvp_alloc_fence_data(&f, pkt->size); + if (rc) + goto exit; + + f->type = cvp_hfi_defs[idx].type; + f->mode = OP_NORMAL; + + synx_pkt = &arg->data.hfi_synx_pkt; + if (synx_pkt->fence_data[0] != 0xFEEDFACE) { + dprintk(CVP_ERR, "%s deprecated synx path\n", __func__); + cvp_free_fence_data(f); + msm_cvp_unmap_frame(inst, pkt->client_data.kdata); + goto exit; + } else { + kfc = &synx_pkt->fc; + fence = (u32 *)&kfc->fences; + f->frame_id = kfc->frame_id; + f->signature = 0xFEEDFACE; + f->num_fences = kfc->num_fences; + f->output_index = kfc->output_index; + } + + + dprintk(CVP_SYNX, "%s: frameID %llu ktid %llu\n", + __func__, f->frame_id, pkt->client_data.kdata); + + memcpy(f->pkt, pkt, pkt->size); + + f->pkt->client_data.kdata |= FENCE_BIT; + + rc = cvp_import_synx(inst, f, fence); + if (rc) { + kfree(f); + goto exit; + } + + mutex_lock(&q->lock); + list_add_tail(&f->list, &inst->fence_cmd_queue.wait_list); + mutex_unlock(&q->lock); + + wake_up(&inst->fence_cmd_queue.wq); + +exit: + cvp_put_inst(s); + return rc; +} + +static inline int div_by_1dot5(unsigned int a) +{ + unsigned long i = a << 1; + + return (unsigned int) i/3; +} + +static inline int max_3(unsigned int a, unsigned int b, unsigned int c) +{ + return (a >= b) ? ((a >= c) ? a : c) : ((b >= c) ? b : c); +} + +static bool is_subblock_profile_existed(struct msm_cvp_inst *inst) +{ + return (inst->prop.od_cycles || + inst->prop.mpu_cycles || + inst->prop.fdu_cycles || + inst->prop.ica_cycles); +} + +static void aggregate_power_update(struct msm_cvp_core *core, + struct cvp_power_level *nrt_pwr, + struct cvp_power_level *rt_pwr, + unsigned int max_clk_rate) +{ + struct msm_cvp_inst *inst; + int i; + unsigned long fdu_sum[2] = {0}, od_sum[2] = {0}, mpu_sum[2] = {0}; + unsigned long ica_sum[2] = {0}, fw_sum[2] = {0}; + unsigned long op_fdu_max[2] = {0}, op_od_max[2] = {0}; + unsigned long op_mpu_max[2] = {0}, op_ica_max[2] = {0}; + unsigned long op_fw_max[2] = {0}, bw_sum[2] = {0}, op_bw_max[2] = {0}; + + list_for_each_entry(inst, &core->instances, list) { + if (inst->state == MSM_CVP_CORE_INVALID || + inst->state == MSM_CVP_CORE_UNINIT || + !is_subblock_profile_existed(inst)) + continue; + if (inst->prop.priority <= CVP_RT_PRIO_THRESHOLD) { + /* Non-realtime session use index 0 */ + i = 0; + } else { + i = 1; + } + dprintk(CVP_PROF, "pwrUpdate %pK fdu %u od %u mpu %u ica %u\n", + inst->prop.fdu_cycles, + inst->prop.od_cycles, + inst->prop.mpu_cycles, + inst->prop.ica_cycles); + + dprintk(CVP_PROF, "pwrUpdate fw %u fdu_o %u od_o %u mpu_o %u\n", + inst->prop.fw_cycles, + inst->prop.fdu_op_cycles, + inst->prop.od_op_cycles, + inst->prop.mpu_op_cycles); + + dprintk(CVP_PROF, "pwrUpdate ica_o %u fw_o %u bw %u bw_o %u\n", + inst->prop.ica_op_cycles, + inst->prop.fw_op_cycles, + inst->prop.ddr_bw, + inst->prop.ddr_op_bw); + + fdu_sum[i] += inst->prop.fdu_cycles; + od_sum[i] += inst->prop.od_cycles; + mpu_sum[i] += inst->prop.mpu_cycles; + ica_sum[i] += inst->prop.ica_cycles; + fw_sum[i] += inst->prop.fw_cycles; + op_fdu_max[i] = + (op_fdu_max[i] >= inst->prop.fdu_op_cycles) ? + op_fdu_max[i] : inst->prop.fdu_op_cycles; + op_od_max[i] = + (op_od_max[i] >= inst->prop.od_op_cycles) ? + op_od_max[i] : inst->prop.od_op_cycles; + op_mpu_max[i] = + (op_mpu_max[i] >= inst->prop.mpu_op_cycles) ? + op_mpu_max[i] : inst->prop.mpu_op_cycles; + op_ica_max[i] = + (op_ica_max[i] >= inst->prop.ica_op_cycles) ? + op_ica_max[i] : inst->prop.ica_op_cycles; + op_fw_max[i] = + (op_fw_max[i] >= inst->prop.fw_op_cycles) ? + op_fw_max[i] : inst->prop.fw_op_cycles; + bw_sum[i] += inst->prop.ddr_bw; + op_bw_max[i] = + (op_bw_max[i] >= inst->prop.ddr_op_bw) ? + op_bw_max[i] : inst->prop.ddr_op_bw; + } + + for (i = 0; i < 2; i++) { + fdu_sum[i] = max_3(fdu_sum[i], od_sum[i], mpu_sum[i]); + fdu_sum[i] = max_3(fdu_sum[i], ica_sum[i], fw_sum[i]); + + op_fdu_max[i] = max_3(op_fdu_max[i], op_od_max[i], + op_mpu_max[i]); + op_fdu_max[i] = max_3(op_fdu_max[i], + op_ica_max[i], op_fw_max[i]); + op_fdu_max[i] = + (op_fdu_max[i] > max_clk_rate) ? + max_clk_rate : op_fdu_max[i]; + bw_sum[i] = (bw_sum[i] >= op_bw_max[i]) ? + bw_sum[i] : op_bw_max[i]; + } + + nrt_pwr->core_sum += fdu_sum[0]; + nrt_pwr->op_core_sum = (nrt_pwr->op_core_sum >= op_fdu_max[0]) ? + nrt_pwr->op_core_sum : op_fdu_max[0]; + nrt_pwr->bw_sum += bw_sum[0]; + rt_pwr->core_sum += fdu_sum[1]; + rt_pwr->op_core_sum = (rt_pwr->op_core_sum >= op_fdu_max[1]) ? + rt_pwr->op_core_sum : op_fdu_max[1]; + rt_pwr->bw_sum += bw_sum[1]; +} + +/** + * adjust_bw_freqs(): calculate CVP clock freq and bw required to sustain + * required use case. + * Bandwidth vote will be best-effort, not returning error if the request + * b/w exceeds max limit. + * Clock vote from non-realtime sessions will be best effort, not returning + * error if the aggreated session clock request exceeds max limit. + * Clock vote from realtime session will be hard request. If aggregated + * session clock request exceeds max limit, the function will return + * error. + */ +static int adjust_bw_freqs(void) +{ + struct msm_cvp_core *core; + struct iris_hfi_device *hdev; + struct bus_info *bus; + struct clock_set *clocks; + struct clock_info *cl; + struct allowed_clock_rates_table *tbl = NULL; + unsigned int tbl_size; + unsigned int cvp_min_rate, cvp_max_rate, max_bw, min_bw; + struct cvp_power_level rt_pwr = {0}, nrt_pwr = {0}; + unsigned long tmp, core_sum, op_core_sum, bw_sum; + int i, rc = 0; + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + + hdev = core->device->hfi_device_data; + clocks = &core->resources.clock_set; + cl = &clocks->clock_tbl[clocks->count - 1]; + tbl = core->resources.allowed_clks_tbl; + tbl_size = core->resources.allowed_clks_tbl_size; + cvp_min_rate = tbl[0].clock_rate; + cvp_max_rate = tbl[tbl_size - 1].clock_rate; + bus = &core->resources.bus_set.bus_tbl[1]; + max_bw = bus->range[1]; + min_bw = max_bw/10; + + aggregate_power_update(core, &nrt_pwr, &rt_pwr, cvp_max_rate); + dprintk(CVP_PROF, "PwrUpdate nrt %u %u rt %u %u\n", + nrt_pwr.core_sum, nrt_pwr.op_core_sum, + rt_pwr.core_sum, rt_pwr.op_core_sum); + + if (rt_pwr.core_sum > cvp_max_rate) { + dprintk(CVP_WARN, "%s clk vote out of range %lld\n", + __func__, rt_pwr.core_sum); + return -ENOTSUPP; + } + + core_sum = rt_pwr.core_sum + nrt_pwr.core_sum; + op_core_sum = (rt_pwr.op_core_sum >= nrt_pwr.op_core_sum) ? + rt_pwr.op_core_sum : nrt_pwr.op_core_sum; + + core_sum = (core_sum >= op_core_sum) ? + core_sum : op_core_sum; + + if (core_sum > cvp_max_rate) { + core_sum = cvp_max_rate; + } else if (core_sum < cvp_min_rate) { + core_sum = cvp_min_rate; + } else { + for (i = 1; i < tbl_size; i++) + if (core_sum <= tbl[i].clock_rate) + break; + core_sum = tbl[i].clock_rate; + } + + bw_sum = rt_pwr.bw_sum + nrt_pwr.bw_sum; + bw_sum = bw_sum >> 10; + bw_sum = (bw_sum > max_bw) ? max_bw : bw_sum; + bw_sum = (bw_sum < min_bw) ? min_bw : bw_sum; + + dprintk(CVP_PROF, "%s %lld %lld\n", __func__, + core_sum, bw_sum); + if (!cl->has_scaling) { + dprintk(CVP_ERR, "Cannot scale CVP clock\n"); + return -EINVAL; + } + + tmp = core->curr_freq; + core->curr_freq = core_sum; + rc = msm_cvp_set_clocks(core); + if (rc) { + dprintk(CVP_ERR, + "Failed to set clock rate %u %s: %d %s\n", + core_sum, cl->name, rc, __func__); + core->curr_freq = tmp; + return rc; + } + hdev->clk_freq = core->curr_freq; + rc = icc_set_bw(bus->client, bw_sum, 0); + if (rc) + dprintk(CVP_ERR, "Failed voting bus %s to ab %u\n", + bus->name, bw_sum); + + return rc; +} + +static int msm_cvp_update_power(struct msm_cvp_inst *inst) +{ + int rc = 0; + struct msm_cvp_core *core; + struct msm_cvp_inst *s; + + if (!inst) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + s = cvp_get_inst_validate(inst->core, inst); + if (!s) + return -ECONNRESET; + + inst->cur_cmd_type = CVP_KMD_UPDATE_POWER; + core = inst->core; + + mutex_lock(&core->lock); + rc = adjust_bw_freqs(); + mutex_unlock(&core->lock); + inst->cur_cmd_type = 0; + cvp_put_inst(s); + + return rc; +} + +static int msm_cvp_register_buffer(struct msm_cvp_inst *inst, + struct cvp_kmd_buffer *buf) +{ + struct cvp_hfi_device *hdev; + struct cvp_hal_session *session; + struct msm_cvp_inst *s; + int rc = 0; + + if (!inst || !inst->core || !buf) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + if (!buf->index) + return 0; + + s = cvp_get_inst_validate(inst->core, inst); + if (!s) + return -ECONNRESET; + + inst->cur_cmd_type = CVP_KMD_REGISTER_BUFFER; + session = (struct cvp_hal_session *)inst->session; + if (!session) { + dprintk(CVP_ERR, "%s: invalid session\n", __func__); + rc = -EINVAL; + goto exit; + } + hdev = inst->core->device; + print_client_buffer(CVP_HFI, "register", inst, buf); + + rc = msm_cvp_map_buf_dsp(inst, buf); +exit: + inst->cur_cmd_type = 0; + cvp_put_inst(s); + return rc; +} + +static int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst, + struct cvp_kmd_buffer *buf) +{ + struct msm_cvp_inst *s; + int rc = 0; + + if (!inst || !inst->core || !buf) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + if (!buf->index) + return 0; + + s = cvp_get_inst_validate(inst->core, inst); + if (!s) + return -ECONNRESET; + + inst->cur_cmd_type = CVP_KMD_UNREGISTER_BUFFER; + print_client_buffer(CVP_HFI, "unregister", inst, buf); + + rc = msm_cvp_unmap_buf_dsp(inst, buf); + inst->cur_cmd_type = 0; + cvp_put_inst(s); + return rc; +} + +static int msm_cvp_session_create(struct msm_cvp_inst *inst) +{ + int rc = 0; + struct synx_initialization_params params; + + if (!inst || !inst->core) + return -EINVAL; + + if (inst->state >= MSM_CVP_CLOSE_DONE) + return -ECONNRESET; + + if (inst->state != MSM_CVP_CORE_INIT_DONE || + inst->state > MSM_CVP_OPEN_DONE) { + dprintk(CVP_ERR, + "%s Incorrect CVP state %d to create session\n", + __func__, inst->state); + return -EINVAL; + } + + rc = msm_cvp_comm_try_state(inst, MSM_CVP_OPEN_DONE); + if (rc) { + dprintk(CVP_ERR, + "Failed to move instance to open done state\n"); + goto fail_init; + } + + rc = cvp_comm_set_arp_buffers(inst); + if (rc) { + dprintk(CVP_ERR, + "Failed to set ARP buffers\n"); + goto fail_init; + } + + params.name = "cvp-kernel-client"; + if (synx_initialize(&inst->synx_session_id, ¶ms)) { + dprintk(CVP_ERR, "%s synx_initialize failed\n", __func__); + rc = -EFAULT; + } + +fail_init: + return rc; +} + +static int session_state_check_init(struct msm_cvp_inst *inst) +{ + mutex_lock(&inst->lock); + if (inst->state == MSM_CVP_OPEN || inst->state == MSM_CVP_OPEN_DONE) { + mutex_unlock(&inst->lock); + return 0; + } + mutex_unlock(&inst->lock); + + return msm_cvp_session_create(inst); +} + +static int cvp_fence_thread_start(struct msm_cvp_inst *inst) +{ + u32 tnum = 0; + u32 i = 0; + int rc = 0; + char tname[16]; + struct task_struct *thread; + struct cvp_fence_queue *q; + struct cvp_session_queue *sq; + + if (!inst->prop.fthread_nr) + return 0; + + q = &inst->fence_cmd_queue; + mutex_lock(&q->lock); + q->state = QUEUE_ACTIVE; + mutex_unlock(&q->lock); + + for (i = 0; i < inst->prop.fthread_nr; ++i) { + if (!cvp_get_inst_validate(inst->core, inst)) { + rc = -ECONNRESET; + goto exit; + } + + snprintf(tname, sizeof(tname), "fthread_%d", tnum++); + thread = kthread_run(cvp_fence_thread, inst, tname); + if (!thread) { + dprintk(CVP_ERR, "%s create %s fail", __func__, tname); + rc = -ECHILD; + goto exit; + } + } + + sq = &inst->session_queue_fence; + spin_lock(&sq->lock); + sq->state = QUEUE_ACTIVE; + spin_unlock(&sq->lock); + +exit: + if (rc) { + mutex_lock(&q->lock); + q->state = QUEUE_STOP; + mutex_unlock(&q->lock); + wake_up_all(&q->wq); + } + return rc; +} + +static int cvp_fence_thread_stop(struct msm_cvp_inst *inst) +{ + struct cvp_fence_queue *q; + struct cvp_session_queue *sq; + + if (!inst->prop.fthread_nr) + return 0; + + q = &inst->fence_cmd_queue; + + mutex_lock(&q->lock); + q->state = QUEUE_STOP; + mutex_unlock(&q->lock); + + sq = &inst->session_queue_fence; + spin_lock(&sq->lock); + sq->state = QUEUE_STOP; + spin_unlock(&sq->lock); + + wake_up_all(&q->wq); + wake_up_all(&sq->wq); + + return 0; +} + +static int msm_cvp_session_start(struct msm_cvp_inst *inst, + struct cvp_kmd_arg *arg) +{ + struct cvp_session_queue *sq; + + sq = &inst->session_queue; + spin_lock(&sq->lock); + if (sq->msg_count) { + dprintk(CVP_ERR, "session start failed queue not empty%d\n", + sq->msg_count); + spin_unlock(&sq->lock); + return -EINVAL; + } + sq->state = QUEUE_ACTIVE; + spin_unlock(&sq->lock); + + return cvp_fence_thread_start(inst); +} + +static int msm_cvp_session_stop(struct msm_cvp_inst *inst, + struct cvp_kmd_arg *arg) +{ + struct cvp_session_queue *sq; + struct cvp_kmd_session_control *sc = &arg->data.session_ctrl; + + sq = &inst->session_queue; + + spin_lock(&sq->lock); + if (sq->msg_count) { + dprintk(CVP_ERR, "session stop incorrect: queue not empty%d\n", + sq->msg_count); + sc->ctrl_data[0] = sq->msg_count; + spin_unlock(&sq->lock); + return -EUCLEAN; + } + sq->state = QUEUE_STOP; + + pr_info(CVP_DBG_TAG "Stop session: %pK session_id = %d\n", + "sess", inst, hash32_ptr(inst->session)); + spin_unlock(&sq->lock); + + wake_up_all(&inst->session_queue.wq); + + return cvp_fence_thread_stop(inst); +} + +int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst) +{ + struct cvp_session_queue *sq; + + sq = &inst->session_queue; + + spin_lock(&sq->lock); + + if (sq->state == QUEUE_STOP) { + spin_unlock(&sq->lock); + return 0; + } + + sq->state = QUEUE_STOP; + + dprintk(CVP_SESS, "Stop session queue: %pK session_id = %d\n", + inst, hash32_ptr(inst->session)); + spin_unlock(&sq->lock); + + wake_up_all(&inst->session_queue.wq); + + return cvp_fence_thread_stop(inst); +} + +static int msm_cvp_session_ctrl(struct msm_cvp_inst *inst, + struct cvp_kmd_arg *arg) +{ + struct cvp_kmd_session_control *ctrl = &arg->data.session_ctrl; + int rc = 0; + unsigned int ctrl_type; + + ctrl_type = ctrl->ctrl_type; + + if (!inst && ctrl_type != SESSION_CREATE) { + dprintk(CVP_ERR, "%s invalid session\n", __func__); + return -EINVAL; + } + + switch (ctrl_type) { + case SESSION_STOP: + rc = msm_cvp_session_stop(inst, arg); + break; + case SESSION_START: + rc = msm_cvp_session_start(inst, arg); + break; + case SESSION_CREATE: + rc = msm_cvp_session_create(inst); + case SESSION_DELETE: + break; + case SESSION_INFO: + default: + dprintk(CVP_ERR, "%s Unsupported session ctrl%d\n", + __func__, ctrl->ctrl_type); + rc = -EINVAL; + } + return rc; +} + +static int msm_cvp_get_sysprop(struct msm_cvp_inst *inst, + struct cvp_kmd_arg *arg) +{ + struct cvp_kmd_sys_properties *props = &arg->data.sys_properties; + struct cvp_hfi_device *hdev; + struct iris_hfi_device *hfi; + int i, rc = 0; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + hdev = inst->core->device; + hfi = hdev->hfi_device_data; + + for (i = 0; i < props->prop_num; i++) { + switch (props->prop_data[i].prop_type) { + case CVP_KMD_PROP_HFI_VERSION: + { + props->prop_data[i].data = hfi->version; + break; + } + default: + dprintk(CVP_ERR, "unrecognized sys property %d\n", + props->prop_data[i].prop_type); + rc = -EFAULT; + } + } + return rc; +} + +static int msm_cvp_set_sysprop(struct msm_cvp_inst *inst, + struct cvp_kmd_arg *arg) +{ + struct cvp_kmd_sys_properties *props = &arg->data.sys_properties; + struct cvp_kmd_sys_property *prop_array; + struct cvp_session_prop *session_prop; + int i, rc = 0; + + if (!inst) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + if (props->prop_num >= MAX_KMD_PROP_NUM) { + dprintk(CVP_ERR, "Too many properties %d to set\n", + props->prop_num); + return -E2BIG; + } + + prop_array = &arg->data.sys_properties.prop_data[0]; + session_prop = &inst->prop; + + for (i = 0; i < props->prop_num; i++) { + switch (prop_array[i].prop_type) { + case CVP_KMD_PROP_SESSION_TYPE: + session_prop->type = prop_array[i].data; + break; + case CVP_KMD_PROP_SESSION_KERNELMASK: + session_prop->kernel_mask = prop_array[i].data; + break; + case CVP_KMD_PROP_SESSION_PRIORITY: + session_prop->priority = prop_array[i].data; + break; + case CVP_KMD_PROP_SESSION_SECURITY: + session_prop->is_secure = prop_array[i].data; + break; + case CVP_KMD_PROP_SESSION_DSPMASK: + session_prop->dsp_mask = prop_array[i].data; + break; + case CVP_KMD_PROP_PWR_FDU: + session_prop->fdu_cycles = prop_array[i].data; + break; + case CVP_KMD_PROP_PWR_ICA: + session_prop->ica_cycles = + div_by_1dot5(prop_array[i].data); + break; + case CVP_KMD_PROP_PWR_OD: + session_prop->od_cycles = prop_array[i].data; + break; + case CVP_KMD_PROP_PWR_MPU: + session_prop->mpu_cycles = prop_array[i].data; + break; + case CVP_KMD_PROP_PWR_FW: + session_prop->fw_cycles = + div_by_1dot5(prop_array[i].data); + break; + case CVP_KMD_PROP_PWR_DDR: + session_prop->ddr_bw = prop_array[i].data; + break; + case CVP_KMD_PROP_PWR_SYSCACHE: + session_prop->ddr_cache = prop_array[i].data; + break; + case CVP_KMD_PROP_PWR_FDU_OP: + session_prop->fdu_op_cycles = prop_array[i].data; + break; + case CVP_KMD_PROP_PWR_ICA_OP: + session_prop->ica_op_cycles = + div_by_1dot5(prop_array[i].data); + break; + case CVP_KMD_PROP_PWR_OD_OP: + session_prop->od_op_cycles = prop_array[i].data; + break; + case CVP_KMD_PROP_PWR_MPU_OP: + session_prop->mpu_op_cycles = prop_array[i].data; + break; + case CVP_KMD_PROP_PWR_FW_OP: + session_prop->fw_op_cycles = + div_by_1dot5(prop_array[i].data); + break; + case CVP_KMD_PROP_PWR_DDR_OP: + session_prop->ddr_op_bw = prop_array[i].data; + break; + case CVP_KMD_PROP_PWR_SYSCACHE_OP: + session_prop->ddr_op_cache = prop_array[i].data; + break; + default: + dprintk(CVP_ERR, + "unrecognized sys property to set %d\n", + prop_array[i].prop_type); + rc = -EFAULT; + } + } + return rc; +} + +static int cvp_drain_fence_cmd_queue_partial(struct msm_cvp_inst *inst) +{ + unsigned long wait_time; + struct cvp_fence_queue *q; + struct cvp_fence_command *f; + int rc = 0; + int count = 0, max_count = 0; + + q = &inst->fence_cmd_queue; + + mutex_lock(&q->lock); + + list_for_each_entry(f, &q->sched_list, list) { + if (f->mode == OP_FLUSH) + continue; + ++count; + } + + list_for_each_entry(f, &q->wait_list, list) { + if (f->mode == OP_FLUSH) + continue; + ++count; + } + + mutex_unlock(&q->lock); + wait_time = count * CVP_MAX_WAIT_TIME * 1000; + + dprintk(CVP_SYNX, "%s: wait %d us for %d fence command\n", + __func__, wait_time, count); + + count = 0; + max_count = wait_time / 100; + +retry: + mutex_lock(&q->lock); + f = list_first_entry(&q->sched_list, struct cvp_fence_command, list); + + /* Wait for all normal frames to finish before return */ + if ((f && f->mode == OP_FLUSH) || + (list_empty(&q->sched_list) && list_empty(&q->wait_list))) { + mutex_unlock(&q->lock); + return rc; + } + + mutex_unlock(&q->lock); + usleep_range(100, 200); + ++count; + if (count < max_count) { + goto retry; + } else { + rc = -ETIMEDOUT; + dprintk(CVP_ERR, "%s: timed out!\n", __func__); + } + + return rc; +} + +static int cvp_drain_fence_sched_list(struct msm_cvp_inst *inst) +{ + unsigned long wait_time; + struct cvp_fence_queue *q; + struct cvp_fence_command *f; + int rc = 0; + int count = 0, max_count = 0; + u64 ktid; + + q = &inst->fence_cmd_queue; + + mutex_lock(&q->lock); + list_for_each_entry(f, &q->sched_list, list) { + ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1); + dprintk(CVP_SYNX, "%s: frame %llu is in sched_list\n", + __func__, ktid); + dprintk(CVP_SYNX, "%s: frameID %llu is in sched_list\n", + __func__, f->frame_id); + ++count; + } + mutex_unlock(&q->lock); + wait_time = count * CVP_MAX_WAIT_TIME * 1000; + + dprintk(CVP_SYNX, "%s: wait %d us for %d fence command\n", + __func__, wait_time, count); + + count = 0; + max_count = wait_time / 100; + +retry: + mutex_lock(&q->lock); + if (list_empty(&q->sched_list)) { + mutex_unlock(&q->lock); + return rc; + } + + mutex_unlock(&q->lock); + usleep_range(100, 200); + ++count; + if (count < max_count) { + goto retry; + } else { + rc = -ETIMEDOUT; + dprintk(CVP_ERR, "%s: timed out!\n", __func__); + } + + return rc; +} + +static int cvp_flush_all(struct msm_cvp_inst *inst) +{ + int rc = 0; + struct msm_cvp_inst *s; + struct cvp_fence_queue *q; + struct cvp_fence_command *f, *d; + struct cvp_hfi_device *hdev; + u64 ktid; + + if (!inst || !inst->core) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + s = cvp_get_inst_validate(inst->core, inst); + if (!s) + return -ECONNRESET; + + q = &inst->fence_cmd_queue; + hdev = inst->core->device; + + mutex_lock(&q->lock); + q->mode = OP_DRAINING; + + list_for_each_entry_safe(f, d, &q->wait_list, list) { + ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1); + + dprintk(CVP_SESS, "%s: flush frame %llu from wait_list\n", + __func__, ktid); + dprintk(CVP_SESS, "%s: flush frameID %llu from wait_list\n", + __func__, f->frame_id); + + list_del_init(&f->list); + msm_cvp_unmap_frame(inst, f->pkt->client_data.kdata); + cvp_cancel_synx(inst, CVP_OUTPUT_SYNX, f); + cvp_release_synx(inst, f); + cvp_free_fence_data(f); + } + + list_for_each_entry(f, &q->sched_list, list) { + ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1); + + dprintk(CVP_SESS, "%s: flush frame %llu from sched_list\n", + __func__, ktid); + dprintk(CVP_SESS, "%s: flush frameID %llu from sched_list\n", + __func__, f->frame_id); + cvp_cancel_synx(inst, CVP_INPUT_SYNX, f); + } + + mutex_unlock(&q->lock); + + dprintk(CVP_SESS, "%s: send flush to fw\n", __func__); + + /* Send flush to FW */ + rc = call_hfi_op(hdev, session_flush, (void *)inst->session); + if (rc) { + dprintk(CVP_WARN, "%s: continue flush without fw. rc %d\n", + __func__, rc); + goto exit; + } + + /* Wait for FW response */ + rc = wait_for_sess_signal_receipt(inst, HAL_SESSION_FLUSH_DONE); + if (rc) + dprintk(CVP_WARN, "%s: wait for signal failed, rc %d\n", + __func__, rc); + + dprintk(CVP_SESS, "%s: received flush from fw\n", __func__); + +exit: + rc = cvp_drain_fence_sched_list(inst); + + mutex_lock(&q->lock); + q->mode = OP_NORMAL; + mutex_unlock(&q->lock); + + cvp_put_inst(s); + return rc; +} + +static void cvp_mark_fence_command(struct msm_cvp_inst *inst, u64 frame_id) +{ + int found = false; + struct cvp_fence_queue *q; + struct cvp_fence_command *f; + + q = &inst->fence_cmd_queue; + + list_for_each_entry(f, &q->sched_list, list) { + if (found) { + f->mode = OP_FLUSH; + continue; + } + + if (f->frame_id >= frame_id) { + found = true; + f->mode = OP_FLUSH; + } + } + + list_for_each_entry(f, &q->wait_list, list) { + if (found) { + f->mode = OP_FLUSH; + continue; + } + + if (f->frame_id >= frame_id) { + found = true; + f->mode = OP_FLUSH; + } + } +} + +static int cvp_flush_frame(struct msm_cvp_inst *inst, u64 frame_id) +{ + int rc = 0; + struct msm_cvp_inst *s; + struct cvp_fence_queue *q; + struct cvp_fence_command *f, *d; + u64 ktid; + + if (!inst || !inst->core) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + s = cvp_get_inst_validate(inst->core, inst); + if (!s) + return -ECONNRESET; + + q = &inst->fence_cmd_queue; + + mutex_lock(&q->lock); + q->mode = OP_DRAINING; + + cvp_mark_fence_command(inst, frame_id); + + list_for_each_entry_safe(f, d, &q->wait_list, list) { + if (f->mode != OP_FLUSH) + continue; + + ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1); + + dprintk(CVP_SESS, "%s: flush frame %llu from wait_list\n", + __func__, ktid); + dprintk(CVP_SESS, "%s: flush frameID %llu from wait_list\n", + __func__, f->frame_id); + + list_del_init(&f->list); + msm_cvp_unmap_frame(inst, f->pkt->client_data.kdata); + cvp_cancel_synx(inst, CVP_OUTPUT_SYNX, f); + cvp_release_synx(inst, f); + cvp_free_fence_data(f); + } + + list_for_each_entry(f, &q->sched_list, list) { + if (f->mode != OP_FLUSH) + continue; + + ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1); + + dprintk(CVP_SESS, "%s: flush frame %llu from sched_list\n", + __func__, ktid); + dprintk(CVP_SESS, "%s: flush frameID %llu from sched_list\n", + __func__, f->frame_id); + cvp_cancel_synx(inst, CVP_INPUT_SYNX, f); + } + + mutex_unlock(&q->lock); + + rc = cvp_drain_fence_cmd_queue_partial(inst); + if (rc) + dprintk(CVP_WARN, "%s: continue flush. rc %d\n", + __func__, rc); + + rc = cvp_flush_all(inst); + + cvp_put_inst(s); + return rc; +} + +int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct cvp_kmd_arg *arg) +{ + int rc = 0; + + if (!inst || !arg) { + dprintk(CVP_ERR, "%s: invalid args\n", __func__); + return -EINVAL; + } + dprintk(CVP_HFI, "%s: arg->type = %x", __func__, arg->type); + + if (arg->type != CVP_KMD_SESSION_CONTROL && + arg->type != CVP_KMD_SET_SYS_PROPERTY && + arg->type != CVP_KMD_GET_SYS_PROPERTY) { + + rc = session_state_check_init(inst); + if (rc) { + dprintk(CVP_ERR, + "Incorrect session state %d for command %#x", + inst->state, arg->type); + return rc; + } + } + + switch (arg->type) { + case CVP_KMD_GET_SESSION_INFO: + { + struct cvp_kmd_session_info *session = + (struct cvp_kmd_session_info *)&arg->data.session; + + rc = msm_cvp_get_session_info(inst, session); + break; + } + case CVP_KMD_UPDATE_POWER: + { + rc = msm_cvp_update_power(inst); + break; + } + case CVP_KMD_REGISTER_BUFFER: + { + struct cvp_kmd_buffer *buf = + (struct cvp_kmd_buffer *)&arg->data.regbuf; + + rc = msm_cvp_register_buffer(inst, buf); + break; + } + case CVP_KMD_UNREGISTER_BUFFER: + { + struct cvp_kmd_buffer *buf = + (struct cvp_kmd_buffer *)&arg->data.unregbuf; + + rc = msm_cvp_unregister_buffer(inst, buf); + break; + } + case CVP_KMD_RECEIVE_MSG_PKT: + { + struct cvp_kmd_hfi_packet *out_pkt = + (struct cvp_kmd_hfi_packet *)&arg->data.hfi_pkt; + rc = msm_cvp_session_receive_hfi(inst, out_pkt); + break; + } + case CVP_KMD_SEND_CMD_PKT: + { + struct cvp_kmd_hfi_packet *in_pkt = + (struct cvp_kmd_hfi_packet *)&arg->data.hfi_pkt; + + rc = msm_cvp_session_process_hfi(inst, in_pkt, + arg->buf_offset, arg->buf_num); + break; + } + case CVP_KMD_SEND_FENCE_CMD_PKT: + { + rc = msm_cvp_session_process_hfi_fence(inst, arg); + break; + } + case CVP_KMD_SESSION_CONTROL: + rc = msm_cvp_session_ctrl(inst, arg); + break; + case CVP_KMD_GET_SYS_PROPERTY: + rc = msm_cvp_get_sysprop(inst, arg); + break; + case CVP_KMD_SET_SYS_PROPERTY: + rc = msm_cvp_set_sysprop(inst, arg); + break; + case CVP_KMD_FLUSH_ALL: + rc = cvp_flush_all(inst); + break; + case CVP_KMD_FLUSH_FRAME: + rc = cvp_flush_frame(inst, arg->data.frame_id); + break; + default: + dprintk(CVP_HFI, "%s: unknown arg type %#x\n", + __func__, arg->type); + rc = -ENOTSUPP; + break; + } + + return rc; +} + +int msm_cvp_session_deinit(struct msm_cvp_inst *inst) +{ + int rc = 0; + struct cvp_hal_session *session; + + if (!inst || !inst->core) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + dprintk(CVP_SESS, "%s: inst %pK (%#x)\n", __func__, + inst, hash32_ptr(inst->session)); + + session = (struct cvp_hal_session *)inst->session; + if (!session) + return rc; + + rc = msm_cvp_comm_try_state(inst, MSM_CVP_CLOSE_DONE); + if (rc) + dprintk(CVP_ERR, "%s: close failed\n", __func__); + + rc = msm_cvp_session_deinit_buffers(inst); + return rc; +} + +int msm_cvp_session_init(struct msm_cvp_inst *inst) +{ + int rc = 0; + + if (!inst) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + dprintk(CVP_SESS, "%s: inst %pK (%#x)\n", __func__, + inst, hash32_ptr(inst->session)); + + /* set default frequency */ + inst->clk_data.core_id = 0; + inst->clk_data.min_freq = 1000; + inst->clk_data.ddr_bw = 1000; + inst->clk_data.sys_cache_bw = 1000; + + inst->prop.type = HFI_SESSION_CV; + if (inst->session_type == MSM_CVP_KERNEL) + inst->prop.type = HFI_SESSION_DME; + + inst->prop.kernel_mask = 0xFFFFFFFF; + inst->prop.priority = 0; + inst->prop.is_secure = 0; + inst->prop.dsp_mask = 0; + inst->prop.fthread_nr = 2; + + return rc; +} diff --git a/msm/eva/msm_cvp.h b/msm/eva/msm_cvp.h new file mode 100644 index 0000000000..5875b631c1 --- /dev/null +++ b/msm/eva/msm_cvp.h @@ -0,0 +1,36 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _MSM_CVP_H_ +#define _MSM_CVP_H_ + +#include "msm_cvp_internal.h" +#include "msm_cvp_common.h" +#include "msm_cvp_clocks.h" +#include "msm_cvp_debug.h" +#include "msm_cvp_dsp.h" + +static inline bool is_buf_param_valid(u32 buf_num, u32 offset) +{ + int max_buf_num; + + max_buf_num = sizeof(struct cvp_kmd_hfi_packet) / + sizeof(struct cvp_buf_type); + + if (buf_num > max_buf_num) + return false; + + if ((offset + buf_num * sizeof(struct cvp_buf_type)) > + sizeof(struct cvp_kmd_hfi_packet)) + return false; + + return true; +} + +int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct cvp_kmd_arg *arg); +int msm_cvp_session_init(struct msm_cvp_inst *inst); +int msm_cvp_session_deinit(struct msm_cvp_inst *inst); +int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst); +#endif diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c new file mode 100644 index 0000000000..f67c2a25f7 --- /dev/null +++ b/msm/eva/msm_cvp_buf.c @@ -0,0 +1,936 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include "msm_cvp_common.h" +#include "cvp_hfi_api.h" +#include "msm_cvp_debug.h" +#include "msm_cvp_core.h" +#include "msm_cvp_dsp.h" + +void print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, + struct msm_cvp_smem *smem) +{ + if (!(tag & msm_cvp_debug) || !inst || !smem) + return; + + if (smem->dma_buf) { + dprintk(tag, "%s: %x : %s size %d flags %#x iova %#x", str, + hash32_ptr(inst->session), smem->dma_buf->name, + smem->size, smem->flags, smem->device_addr); + } +} + +static void print_internal_buffer(u32 tag, const char *str, + struct msm_cvp_inst *inst, struct cvp_internal_buf *cbuf) +{ + if (!(tag & msm_cvp_debug) || !inst || !cbuf) + return; + + if (cbuf->smem->dma_buf) { + dprintk(tag, + "%s: %x : fd %d off %d %s size %d iova %#x", + str, hash32_ptr(inst->session), cbuf->fd, + cbuf->offset, cbuf->smem->dma_buf->name, cbuf->size, + cbuf->smem->device_addr); + } else { + dprintk(tag, + "%s: %x : idx %2d fd %d off %d size %d iova %#x", + str, hash32_ptr(inst->session), cbuf->fd, + cbuf->offset, cbuf->size, cbuf->smem->device_addr); + } +} + +void print_cvp_buffer(u32 tag, const char *str, struct msm_cvp_inst *inst, + struct cvp_internal_buf *cbuf) +{ + dprintk(tag, "%s addr: %x size %u\n", str, + cbuf->smem->device_addr, cbuf->size); +} + +void print_client_buffer(u32 tag, const char *str, + struct msm_cvp_inst *inst, struct cvp_kmd_buffer *cbuf) +{ + if (!(tag & msm_cvp_debug) || !inst || !cbuf) + return; + + dprintk(tag, + "%s: %x : idx %2d fd %d off %d size %d type %d flags 0x%x\n", + str, hash32_ptr(inst->session), cbuf->index, cbuf->fd, + cbuf->offset, cbuf->size, cbuf->type, cbuf->flags); +} + +int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct cvp_kmd_buffer *buf) +{ + int rc = 0; + bool found = false; + struct cvp_internal_buf *cbuf; + struct msm_cvp_smem *smem = NULL; + struct cvp_hal_session *session; + struct dma_buf *dma_buf = NULL; + + if (!inst || !inst->core || !buf) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + if (buf->fd < 0) { + dprintk(CVP_ERR, "%s: Invalid fd = %d", __func__, buf->fd); + return 0; + } + + if (buf->offset) { + dprintk(CVP_ERR, + "%s: offset is deprecated, set to 0.\n", + __func__); + return -EINVAL; + } + + session = (struct cvp_hal_session *)inst->session; + + mutex_lock(&inst->cvpdspbufs.lock); + list_for_each_entry(cbuf, &inst->cvpdspbufs.list, list) { + if (cbuf->fd == buf->fd) { + if (cbuf->size != buf->size) { + dprintk(CVP_ERR, "%s: buf size mismatch\n", + __func__); + mutex_unlock(&inst->cvpdspbufs.lock); + return -EINVAL; + } + found = true; + break; + } + } + mutex_unlock(&inst->cvpdspbufs.lock); + if (found) { + print_internal_buffer(CVP_ERR, "duplicate", inst, cbuf); + return -EINVAL; + } + + dma_buf = msm_cvp_smem_get_dma_buf(buf->fd); + if (!dma_buf) { + dprintk(CVP_ERR, "%s: Invalid fd = %d", __func__, buf->fd); + return 0; + } + + cbuf = kmem_cache_zalloc(cvp_driver->buf_cache, GFP_KERNEL); + if (!cbuf) + return -ENOMEM; + + smem = kmem_cache_zalloc(cvp_driver->smem_cache, GFP_KERNEL); + if (!smem) { + kmem_cache_free(cvp_driver->buf_cache, cbuf); + return -ENOMEM; + } + + smem->dma_buf = dma_buf; + smem->bitmap_index = MAX_DMABUF_NUMS; + dprintk(CVP_DSP, "%s: dma_buf = %llx\n", __func__, dma_buf); + rc = msm_cvp_map_smem(inst, smem, "map dsp"); + if (rc) { + print_client_buffer(CVP_ERR, "map failed", inst, buf); + goto exit; + } + + if (buf->index) { + rc = cvp_dsp_register_buffer(hash32_ptr(session), buf->fd, + smem->dma_buf->size, buf->size, buf->offset, + buf->index, (uint32_t)smem->device_addr); + if (rc) { + dprintk(CVP_ERR, + "%s: failed dsp registration for fd=%d rc=%d", + __func__, buf->fd, rc); + goto exit; + } + } else { + dprintk(CVP_ERR, "%s: buf index is 0 fd=%d", __func__, buf->fd); + rc = -EINVAL; + goto exit; + } + + cbuf->smem = smem; + cbuf->fd = buf->fd; + cbuf->size = buf->size; + cbuf->offset = buf->offset; + cbuf->ownership = CLIENT; + cbuf->index = buf->index; + + mutex_lock(&inst->cvpdspbufs.lock); + list_add_tail(&cbuf->list, &inst->cvpdspbufs.list); + mutex_unlock(&inst->cvpdspbufs.lock); + + return rc; + +exit: + if (smem->device_addr) { + msm_cvp_unmap_smem(inst, smem, "unmap dsp"); + msm_cvp_smem_put_dma_buf(smem->dma_buf); + } + kmem_cache_free(cvp_driver->buf_cache, cbuf); + cbuf = NULL; + kmem_cache_free(cvp_driver->smem_cache, smem); + smem = NULL; + return rc; +} + +int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, struct cvp_kmd_buffer *buf) +{ + int rc = 0; + bool found; + struct cvp_internal_buf *cbuf; + struct cvp_hal_session *session; + + if (!inst || !inst->core || !buf) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + session = (struct cvp_hal_session *)inst->session; + if (!session) { + dprintk(CVP_ERR, "%s: invalid session\n", __func__); + return -EINVAL; + } + + mutex_lock(&inst->cvpdspbufs.lock); + found = false; + list_for_each_entry(cbuf, &inst->cvpdspbufs.list, list) { + if (cbuf->fd == buf->fd) { + found = true; + break; + } + } + mutex_unlock(&inst->cvpdspbufs.lock); + if (!found) { + print_client_buffer(CVP_ERR, "invalid", inst, buf); + return -EINVAL; + } + + if (buf->index) { + rc = cvp_dsp_deregister_buffer(hash32_ptr(session), buf->fd, + cbuf->smem->dma_buf->size, buf->size, buf->offset, + buf->index, (uint32_t)cbuf->smem->device_addr); + if (rc) { + dprintk(CVP_ERR, + "%s: failed dsp deregistration fd=%d rc=%d", + __func__, buf->fd, rc); + return rc; + } + } + + if (cbuf->smem->device_addr) { + msm_cvp_unmap_smem(inst, cbuf->smem, "unmap dsp"); + msm_cvp_smem_put_dma_buf(cbuf->smem->dma_buf); + } + + mutex_lock(&inst->cvpdspbufs.lock); + list_del(&cbuf->list); + mutex_unlock(&inst->cvpdspbufs.lock); + + kmem_cache_free(cvp_driver->smem_cache, cbuf->smem); + kmem_cache_free(cvp_driver->buf_cache, cbuf); + return rc; +} + +void msm_cvp_cache_operations(struct msm_cvp_smem *smem, u32 type, + u32 offset, u32 size) +{ + enum smem_cache_ops cache_op; + + if (msm_cvp_cacheop_disabled) + return; + + if (!smem) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return; + } + + switch (type) { + case CVP_KMD_BUFTYPE_INPUT: + cache_op = SMEM_CACHE_CLEAN; + break; + case CVP_KMD_BUFTYPE_OUTPUT: + cache_op = SMEM_CACHE_INVALIDATE; + break; + default: + cache_op = SMEM_CACHE_CLEAN_INVALIDATE; + } + + dprintk(CVP_MEM, + "%s: cache operation enabled for dma_buf: %llx, cache_op: %d, offset: %d, size: %d\n", + __func__, smem->dma_buf, cache_op, offset, size); + msm_cvp_smem_cache_operations(smem->dma_buf, cache_op, offset, size); +} + +static struct msm_cvp_smem *msm_cvp_session_find_smem(struct msm_cvp_inst *inst, + struct dma_buf *dma_buf) +{ + struct msm_cvp_smem *smem; + int i; + + if (inst->dma_cache.nr > MAX_DMABUF_NUMS) + return NULL; + + mutex_lock(&inst->dma_cache.lock); + for (i = 0; i < inst->dma_cache.nr; i++) + if (inst->dma_cache.entries[i]->dma_buf == dma_buf) { + set_bit(i, &inst->dma_cache.usage_bitmap); + smem = inst->dma_cache.entries[i]; + smem->bitmap_index = i; + atomic_inc(&smem->refcount); + /* + * If we find it, it means we already increased + * refcount before, so we put it to avoid double + * incremental. + */ + msm_cvp_smem_put_dma_buf(smem->dma_buf); + mutex_unlock(&inst->dma_cache.lock); + print_smem(CVP_MEM, "found", inst, smem); + return smem; + } + + mutex_unlock(&inst->dma_cache.lock); + + return NULL; +} + +static int msm_cvp_session_add_smem(struct msm_cvp_inst *inst, + struct msm_cvp_smem *smem) +{ + unsigned int i; + struct msm_cvp_smem *smem2; + + mutex_lock(&inst->dma_cache.lock); + if (inst->dma_cache.nr < MAX_DMABUF_NUMS) { + inst->dma_cache.entries[inst->dma_cache.nr] = smem; + set_bit(inst->dma_cache.nr, &inst->dma_cache.usage_bitmap); + smem->bitmap_index = inst->dma_cache.nr; + inst->dma_cache.nr++; + i = smem->bitmap_index; + } else { + i = find_first_zero_bit(&inst->dma_cache.usage_bitmap, + MAX_DMABUF_NUMS); + if (i < MAX_DMABUF_NUMS) { + smem2 = inst->dma_cache.entries[i]; + msm_cvp_unmap_smem(inst, smem2, "unmap cpu"); + msm_cvp_smem_put_dma_buf(smem2->dma_buf); + kmem_cache_free(cvp_driver->smem_cache, smem2); + + inst->dma_cache.entries[i] = smem; + smem->bitmap_index = i; + set_bit(i, &inst->dma_cache.usage_bitmap); + } else { + dprintk(CVP_WARN, "%s: not enough memory\n", __func__); + mutex_unlock(&inst->dma_cache.lock); + return -ENOMEM; + } + } + + atomic_inc(&smem->refcount); + mutex_unlock(&inst->dma_cache.lock); + dprintk(CVP_MEM, "Add entry %d into cache\n", i); + + return 0; +} + +static struct msm_cvp_smem *msm_cvp_session_get_smem(struct msm_cvp_inst *inst, + struct cvp_buf_type *buf) +{ + int rc = 0, found = 1; + struct msm_cvp_smem *smem = NULL; + struct dma_buf *dma_buf = NULL; + + if (buf->fd < 0) { + dprintk(CVP_ERR, "%s: Invalid fd = %d", __func__, buf->fd); + return NULL; + } + + dma_buf = msm_cvp_smem_get_dma_buf(buf->fd); + if (!dma_buf) { + dprintk(CVP_ERR, "%s: Invalid fd = %d", __func__, buf->fd); + return NULL; + } + + smem = msm_cvp_session_find_smem(inst, dma_buf); + if (!smem) { + found = 0; + smem = kmem_cache_zalloc(cvp_driver->smem_cache, GFP_KERNEL); + if (!smem) + return NULL; + + smem->dma_buf = dma_buf; + smem->bitmap_index = MAX_DMABUF_NUMS; + rc = msm_cvp_map_smem(inst, smem, "map cpu"); + if (rc) + goto exit; + + rc = msm_cvp_session_add_smem(inst, smem); + if (rc && rc != -ENOMEM) + goto exit2; + } + + if (buf->size > smem->size || buf->size > smem->size - buf->offset) { + dprintk(CVP_ERR, "%s: invalid offset %d or size %d\n", + __func__, buf->offset, buf->size); + if (found) { + mutex_lock(&inst->dma_cache.lock); + atomic_dec(&smem->refcount); + mutex_unlock(&inst->dma_cache.lock); + return NULL; + } + goto exit2; + } + + return smem; + +exit2: + msm_cvp_unmap_smem(inst, smem, "unmap cpu"); +exit: + msm_cvp_smem_put_dma_buf(dma_buf); + kmem_cache_free(cvp_driver->smem_cache, smem); + smem = NULL; + return smem; +} + +static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, + struct cvp_buf_type *buf) +{ + u32 iova = 0; + struct msm_cvp_smem *smem = NULL; + struct cvp_internal_buf *pbuf; + + if (!inst) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + pbuf = kmem_cache_zalloc(cvp_driver->buf_cache, GFP_KERNEL); + if (!pbuf) + return 0; + + smem = msm_cvp_session_get_smem(inst, buf); + if (!smem) + goto exit; + + pbuf->smem = smem; + pbuf->fd = buf->fd; + pbuf->size = buf->size; + pbuf->offset = buf->offset; + pbuf->ownership = CLIENT; + + mutex_lock(&inst->persistbufs.lock); + list_add_tail(&pbuf->list, &inst->persistbufs.list); + mutex_unlock(&inst->persistbufs.lock); + + print_internal_buffer(CVP_MEM, "map persist", inst, pbuf); + + iova = smem->device_addr + buf->offset; + + return iova; + +exit: + kmem_cache_free(cvp_driver->buf_cache, pbuf); + return 0; +} + +u32 msm_cvp_map_frame_buf(struct msm_cvp_inst *inst, + struct cvp_buf_type *buf, + struct msm_cvp_frame *frame) +{ + u32 iova = 0; + struct msm_cvp_smem *smem = NULL; + u32 nr; + u32 type; + + if (!inst || !frame) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return 0; + } + + nr = frame->nr; + if (nr == MAX_FRAME_BUFFER_NUMS) { + dprintk(CVP_ERR, "%s: max frame buffer reached\n", __func__); + return 0; + } + + smem = msm_cvp_session_get_smem(inst, buf); + if (!smem) + return 0; + + frame->bufs[nr].fd = buf->fd; + frame->bufs[nr].smem = smem; + frame->bufs[nr].size = buf->size; + frame->bufs[nr].offset = buf->offset; + + print_internal_buffer(CVP_MEM, "map cpu", inst, &frame->bufs[nr]); + + frame->nr++; + + type = CVP_KMD_BUFTYPE_INPUT | CVP_KMD_BUFTYPE_OUTPUT; + msm_cvp_cache_operations(smem, type, buf->offset, buf->size); + + iova = smem->device_addr + buf->offset; + + return iova; +} + +static void msm_cvp_unmap_frame_buf(struct msm_cvp_inst *inst, + struct msm_cvp_frame *frame) +{ + u32 i; + u32 type; + struct msm_cvp_smem *smem = NULL; + struct cvp_internal_buf *buf; + + type = CVP_KMD_BUFTYPE_OUTPUT; + + for (i = 0; i < frame->nr; ++i) { + buf = &frame->bufs[i]; + smem = buf->smem; + msm_cvp_cache_operations(smem, type, buf->offset, buf->size); + + if (smem->bitmap_index >= MAX_DMABUF_NUMS) { + /* smem not in dmamap cache */ + msm_cvp_unmap_smem(inst, smem, "unmap cpu"); + dma_buf_put(smem->dma_buf); + kmem_cache_free(cvp_driver->smem_cache, smem); + buf->smem = NULL; + } else if (atomic_dec_and_test(&smem->refcount)) { + clear_bit(smem->bitmap_index, + &inst->dma_cache.usage_bitmap); + } + } + + kmem_cache_free(cvp_driver->frame_cache, frame); +} + +void msm_cvp_unmap_frame(struct msm_cvp_inst *inst, u64 ktid) +{ + struct msm_cvp_frame *frame, *dummy1; + bool found; + + if (!inst) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return; + } + + ktid &= (FENCE_BIT - 1); + dprintk(CVP_MEM, "%s: unmap frame %llu\n", __func__, ktid); + + found = false; + mutex_lock(&inst->frames.lock); + list_for_each_entry_safe(frame, dummy1, &inst->frames.list, list) { + if (frame->ktid == ktid) { + found = true; + list_del(&frame->list); + break; + } + } + mutex_unlock(&inst->frames.lock); + + if (found) + msm_cvp_unmap_frame_buf(inst, frame); + else + dprintk(CVP_WARN, "%s frame %llu not found!\n", __func__, ktid); +} + +int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, + struct cvp_kmd_hfi_packet *in_pkt, + unsigned int offset, unsigned int buf_num) +{ + struct cvp_hfi_cmd_session_hdr *cmd_hdr; + struct cvp_internal_buf *pbuf, *dummy; + u64 ktid; + int rc = 0; + struct msm_cvp_smem *smem = NULL; + + if (!offset || !buf_num) + return 0; + + cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; + ktid = cmd_hdr->client_data.kdata & (FENCE_BIT - 1); + + mutex_lock(&inst->persistbufs.lock); + list_for_each_entry_safe(pbuf, dummy, &inst->persistbufs.list, list) { + if (pbuf->ktid == ktid && pbuf->ownership == CLIENT) { + list_del(&pbuf->list); + smem = pbuf->smem; + + dprintk(CVP_MEM, "unmap persist: %x %d %d %#x", + hash32_ptr(inst->session), pbuf->fd, + pbuf->size, smem->device_addr); + + if (smem->bitmap_index >= MAX_DMABUF_NUMS) { + /* smem not in dmamap cache */ + msm_cvp_unmap_smem(inst, smem, + "unmap cpu"); + dma_buf_put(smem->dma_buf); + kmem_cache_free( + cvp_driver->smem_cache, + smem); + pbuf->smem = NULL; + } else if (atomic_dec_and_test( + &smem->refcount)) { + clear_bit(smem->bitmap_index, + &inst->dma_cache.usage_bitmap); + } + + kmem_cache_free(cvp_driver->buf_cache, pbuf); + } + } + mutex_unlock(&inst->persistbufs.lock); + return rc; +} + +int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst, + struct cvp_kmd_hfi_packet *in_pkt, + unsigned int offset, unsigned int buf_num) +{ + struct cvp_hfi_cmd_session_hdr *cmd_hdr; + struct cvp_internal_buf *pbuf, *dummy; + u64 ktid; + struct cvp_buf_type *buf; + int i, rc = 0; + + if (!offset || !buf_num) + return 0; + + cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; + ktid = atomic64_inc_return(&inst->core->kernel_trans_id); + ktid &= (FENCE_BIT - 1); + cmd_hdr->client_data.kdata = ktid; + + for (i = 0; i < buf_num; i++) { + buf = (struct cvp_buf_type *)&in_pkt->pkt_data[offset]; + offset += sizeof(*buf) >> 2; + + if (buf->fd < 0 || !buf->size) + continue; + + mutex_lock(&inst->persistbufs.lock); + list_for_each_entry_safe(pbuf, dummy, &inst->persistbufs.list, + list) { + if (pbuf->ownership == CLIENT) { + if (pbuf->fd == buf->fd && + pbuf->size == buf->size) + buf->fd = pbuf->smem->device_addr; + rc = 1; + break; + } + } + mutex_unlock(&inst->persistbufs.lock); + if (!rc) { + dprintk(CVP_ERR, "%s No persist buf %d found\n", + __func__, buf->fd); + rc = -EFAULT; + break; + } + pbuf->ktid = ktid; + rc = 0; + } + return rc; +} + +int msm_cvp_map_user_persist(struct msm_cvp_inst *inst, + struct cvp_kmd_hfi_packet *in_pkt, + unsigned int offset, unsigned int buf_num) +{ + struct cvp_buf_type *buf; + int i; + u32 iova; + + if (!offset || !buf_num) + return 0; + + for (i = 0; i < buf_num; i++) { + buf = (struct cvp_buf_type *)&in_pkt->pkt_data[offset]; + offset += sizeof(*buf) >> 2; + + if (buf->fd < 0 || !buf->size) + continue; + + iova = msm_cvp_map_user_persist_buf(inst, buf); + if (!iova) { + dprintk(CVP_ERR, + "%s: buf %d register failed.\n", + __func__, i); + + return -EINVAL; + } + buf->fd = iova; + } + return 0; +} + +int msm_cvp_map_frame(struct msm_cvp_inst *inst, + struct cvp_kmd_hfi_packet *in_pkt, + unsigned int offset, unsigned int buf_num) +{ + struct cvp_buf_type *buf; + int i; + u32 iova; + u64 ktid; + struct msm_cvp_frame *frame; + struct cvp_hfi_cmd_session_hdr *cmd_hdr; + + if (!offset || !buf_num) + return 0; + + cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; + ktid = atomic64_inc_return(&inst->core->kernel_trans_id); + ktid &= (FENCE_BIT - 1); + cmd_hdr->client_data.kdata = ktid; + + frame = kmem_cache_zalloc(cvp_driver->frame_cache, GFP_KERNEL); + if (!frame) + return -ENOMEM; + + frame->ktid = ktid; + frame->nr = 0; + frame->pkt_type = cmd_hdr->packet_type; + + for (i = 0; i < buf_num; i++) { + buf = (struct cvp_buf_type *)&in_pkt->pkt_data[offset]; + offset += sizeof(*buf) >> 2; + + if (buf->fd < 0 || !buf->size) + continue; + + iova = msm_cvp_map_frame_buf(inst, buf, frame); + if (!iova) { + dprintk(CVP_ERR, + "%s: buf %d register failed.\n", + __func__, i); + + msm_cvp_unmap_frame_buf(inst, frame); + return -EINVAL; + } + buf->fd = iova; + } + + mutex_lock(&inst->frames.lock); + list_add_tail(&frame->list, &inst->frames.list); + mutex_unlock(&inst->frames.lock); + dprintk(CVP_MEM, "%s: map frame %llu\n", __func__, ktid); + + return 0; +} + +int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) +{ + int rc = 0, i; + struct cvp_internal_buf *cbuf, *dummy; + struct msm_cvp_frame *frame, *dummy1; + struct msm_cvp_smem *smem; + struct cvp_hal_session *session; + + session = (struct cvp_hal_session *)inst->session; + + mutex_lock(&inst->frames.lock); + list_for_each_entry_safe(frame, dummy1, &inst->frames.list, list) { + list_del(&frame->list); + msm_cvp_unmap_frame_buf(inst, frame); + } + mutex_unlock(&inst->frames.lock); + + mutex_lock(&inst->dma_cache.lock); + for (i = 0; i < inst->dma_cache.nr; i++) { + smem = inst->dma_cache.entries[i]; + if (atomic_read(&smem->refcount) == 0) { + print_smem(CVP_MEM, "free", inst, smem); + } else { + print_smem(CVP_WARN, "in use", inst, smem); + } + msm_cvp_unmap_smem(inst, smem, "unmap cpu"); + msm_cvp_smem_put_dma_buf(smem->dma_buf); + kmem_cache_free(cvp_driver->smem_cache, smem); + inst->dma_cache.entries[i] = NULL; + } + mutex_unlock(&inst->dma_cache.lock); + + mutex_lock(&inst->cvpdspbufs.lock); + list_for_each_entry_safe(cbuf, dummy, &inst->cvpdspbufs.list, + list) { + print_internal_buffer(CVP_MEM, "remove dspbufs", inst, cbuf); + rc = cvp_dsp_deregister_buffer(hash32_ptr(session), + cbuf->fd, cbuf->smem->dma_buf->size, cbuf->size, + cbuf->offset, cbuf->index, + (uint32_t)cbuf->smem->device_addr); + if (rc) + dprintk(CVP_ERR, + "%s: failed dsp deregistration fd=%d rc=%d", + __func__, cbuf->fd, rc); + + msm_cvp_unmap_smem(inst, cbuf->smem, "unmap dsp"); + msm_cvp_smem_put_dma_buf(cbuf->smem->dma_buf); + list_del(&cbuf->list); + kmem_cache_free(cvp_driver->buf_cache, cbuf); + } + mutex_unlock(&inst->cvpdspbufs.lock); + + return rc; +} + +void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst) +{ + struct cvp_internal_buf *buf; + int i; + + if (!inst) { + dprintk(CVP_ERR, "%s - invalid param %pK\n", + __func__, inst); + return; + } + + dprintk(CVP_ERR, "active session cmd %d\n", inst->cur_cmd_type); + dprintk(CVP_ERR, + "---Buffer details for inst: %pK of type: %d---\n", + inst, inst->session_type); + mutex_lock(&inst->dma_cache.lock); + dprintk(CVP_ERR, "dma cache:\n"); + if (inst->dma_cache.nr <= MAX_DMABUF_NUMS) + for (i = 0; i < inst->dma_cache.nr; i++) + print_smem(CVP_ERR, "bufdump", inst, + inst->dma_cache.entries[i]); + mutex_unlock(&inst->dma_cache.lock); + + mutex_lock(&inst->cvpdspbufs.lock); + dprintk(CVP_ERR, "dsp buffer list:\n"); + list_for_each_entry(buf, &inst->cvpdspbufs.list, list) + print_cvp_buffer(CVP_ERR, "bufdump", inst, buf); + mutex_unlock(&inst->cvpdspbufs.lock); + + mutex_lock(&inst->persistbufs.lock); + dprintk(CVP_ERR, "persist buffer list:\n"); + list_for_each_entry(buf, &inst->persistbufs.list, list) + print_cvp_buffer(CVP_ERR, "bufdump", inst, buf); + mutex_unlock(&inst->persistbufs.lock); +} + +struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, + u32 buffer_size) +{ + struct cvp_internal_buf *buf; + struct msm_cvp_list *buf_list; + u32 smem_flags = SMEM_UNCACHED; + int rc = 0; + + if (!inst) { + dprintk(CVP_ERR, "%s Invalid input\n", __func__); + return NULL; + } + + buf_list = &inst->persistbufs; + + if (!buffer_size) + return NULL; + + /* PERSIST buffer requires secure mapping */ + smem_flags |= SMEM_SECURE | SMEM_NON_PIXEL; + + buf = kmem_cache_zalloc(cvp_driver->buf_cache, GFP_KERNEL); + if (!buf) { + dprintk(CVP_ERR, "%s Out of memory\n", __func__); + goto fail_kzalloc; + } + + buf->smem = kmem_cache_zalloc(cvp_driver->smem_cache, GFP_KERNEL); + if (!buf->smem) { + dprintk(CVP_ERR, "%s Out of memory\n", __func__); + goto fail_kzalloc; + } + + rc = msm_cvp_smem_alloc(buffer_size, 1, smem_flags, 0, + &(inst->core->resources), buf->smem); + if (rc) { + dprintk(CVP_ERR, "Failed to allocate ARP memory\n"); + goto err_no_mem; + } + + buf->size = buf->smem->size; + buf->type = HFI_BUFFER_INTERNAL_PERSIST_1; + buf->ownership = DRIVER; + + mutex_lock(&buf_list->lock); + list_add_tail(&buf->list, &buf_list->list); + mutex_unlock(&buf_list->lock); + return buf; + +err_no_mem: + kmem_cache_free(cvp_driver->buf_cache, buf); +fail_kzalloc: + return NULL; +} + +int cvp_release_arp_buffers(struct msm_cvp_inst *inst) +{ + struct msm_cvp_smem *smem; + struct list_head *ptr, *next; + struct cvp_internal_buf *buf; + int rc = 0; + struct msm_cvp_core *core; + struct cvp_hfi_device *hdev; + + if (!inst) { + dprintk(CVP_ERR, "Invalid instance pointer = %pK\n", inst); + return -EINVAL; + } + + core = inst->core; + if (!core) { + dprintk(CVP_ERR, "Invalid core pointer = %pK\n", core); + return -EINVAL; + } + hdev = core->device; + if (!hdev) { + dprintk(CVP_ERR, "Invalid device pointer = %pK\n", hdev); + return -EINVAL; + } + + dprintk(CVP_MEM, "release persist buffer!\n"); + + mutex_lock(&inst->persistbufs.lock); + /* Workaround for FW: release buffer means release all */ + if (inst->state <= MSM_CVP_CLOSE_DONE) { + rc = call_hfi_op(hdev, session_release_buffers, + (void *)inst->session); + if (!rc) { + mutex_unlock(&inst->persistbufs.lock); + rc = wait_for_sess_signal_receipt(inst, + HAL_SESSION_RELEASE_BUFFER_DONE); + if (rc) + dprintk(CVP_WARN, + "%s: wait for signal failed, rc %d\n", + __func__, rc); + mutex_lock(&inst->persistbufs.lock); + } else { + dprintk(CVP_WARN, "Fail to send Rel prst buf\n"); + } + } + + list_for_each_safe(ptr, next, &inst->persistbufs.list) { + buf = list_entry(ptr, struct cvp_internal_buf, list); + smem = buf->smem; + if (!smem) { + dprintk(CVP_ERR, "%s invalid smem\n", __func__); + mutex_unlock(&inst->persistbufs.lock); + return -EINVAL; + } + + list_del(&buf->list); + + if (buf->ownership == DRIVER) { + dprintk(CVP_MEM, + "%s: %x : fd %d %s size %d", + "free arp", hash32_ptr(inst->session), buf->fd, + smem->dma_buf->name, buf->size); + msm_cvp_smem_free(smem); + kmem_cache_free(cvp_driver->smem_cache, smem); + } + buf->smem = NULL; + kmem_cache_free(cvp_driver->buf_cache, buf); + } + mutex_unlock(&inst->persistbufs.lock); + return rc; +} + diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h new file mode 100644 index 0000000000..a911745979 --- /dev/null +++ b/msm/eva/msm_cvp_buf.h @@ -0,0 +1,198 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _MSM_CVP_BUF_H_ +#define _MSM_CVP_BUF_H_ + +#include +#include +#include +#include +#include +#include +#include + +#define MAX_FRAME_BUFFER_NUMS 30 +#define MAX_DMABUF_NUMS 64 + +struct msm_cvp_inst; +struct msm_cvp_platform_resources; +struct msm_cvp_list; + +enum smem_cache_ops { + SMEM_CACHE_CLEAN, + SMEM_CACHE_INVALIDATE, + SMEM_CACHE_CLEAN_INVALIDATE, +}; + +enum smem_prop { + SMEM_UNCACHED = 0x1, + SMEM_CACHED = 0x2, + SMEM_SECURE = 0x4, + SMEM_ADSP = 0x8, + SMEM_NON_PIXEL = 0x10 +}; + +struct msm_cvp_list { + struct list_head list; + struct mutex lock; +}; + +static inline void INIT_MSM_CVP_LIST(struct msm_cvp_list *mlist) +{ + mutex_init(&mlist->lock); + INIT_LIST_HEAD(&mlist->list); +} + +static inline void DEINIT_MSM_CVP_LIST(struct msm_cvp_list *mlist) +{ + mutex_destroy(&mlist->lock); +} + +struct cvp_dma_mapping_info { + struct device *dev; + struct iommu_domain *domain; + struct sg_table *table; + struct dma_buf_attachment *attach; + struct dma_buf *buf; + void *cb_info; +}; + +struct msm_cvp_smem { + struct list_head list; + atomic_t refcount; + struct dma_buf *dma_buf; + void *kvaddr; + u32 device_addr; + dma_addr_t dma_handle; + u32 size; + u32 bitmap_index; + u32 flags; + u32 ion_flags; + struct cvp_dma_mapping_info mapping_info; +}; + +struct cvp_dmamap_cache { + unsigned long usage_bitmap; + struct mutex lock; + struct msm_cvp_smem *entries[MAX_DMABUF_NUMS]; + unsigned int nr; +}; + +static inline void INIT_DMAMAP_CACHE(struct cvp_dmamap_cache *cache) +{ + mutex_init(&cache->lock); + cache->usage_bitmap = 0; + cache->nr = 0; +} + +static inline void DEINIT_DMAMAP_CACHE(struct cvp_dmamap_cache *cache) +{ + mutex_destroy(&cache->lock); +} + +struct cvp_buf_type { + s32 fd; + u32 size; + u32 offset; + u32 flags; + union { + struct dma_buf *dbuf; + struct { + u32 reserved1; + u32 reserved2; + }; + }; +}; + +enum buffer_owner { + DRIVER, + FIRMWARE, + CLIENT, + MAX_OWNER +}; + +struct cvp_internal_buf { + struct list_head list; + s32 fd; + u32 size; + u32 offset; + u32 type; + u32 index; + u64 ktid; + enum buffer_owner ownership; + struct msm_cvp_smem *smem; +}; + +struct msm_cvp_frame { + struct list_head list; + struct cvp_internal_buf bufs[MAX_FRAME_BUFFER_NUMS]; + u32 nr; + u64 ktid; + u32 pkt_type; +}; + +void print_cvp_buffer(u32 tag, const char *str, + struct msm_cvp_inst *inst, + struct cvp_internal_buf *cbuf); +void print_cvp_buffer(u32 tag, const char *str, + struct msm_cvp_inst *inst, + struct cvp_internal_buf *cbuf); +void print_client_buffer(u32 tag, const char *str, + struct msm_cvp_inst *inst, + struct cvp_kmd_buffer *cbuf); +void print_smem(u32 tag, const char *str, + struct msm_cvp_inst *inst, + struct msm_cvp_smem *smem); + +/*Kernel DMA buffer and IOMMU mapping functions*/ +int msm_cvp_smem_alloc(size_t size, u32 align, u32 flags, int map_kernel, + void *res, struct msm_cvp_smem *smem); +int msm_cvp_smem_free(struct msm_cvp_smem *smem); +struct context_bank_info *msm_cvp_smem_get_context_bank(bool is_secure, + struct msm_cvp_platform_resources *res, + unsigned long ion_flags); +int msm_cvp_map_smem(struct msm_cvp_inst *inst, + struct msm_cvp_smem *smem, + const char *str); +int msm_cvp_unmap_smem(struct msm_cvp_inst *inst, + struct msm_cvp_smem *smem, + const char *str); +struct dma_buf *msm_cvp_smem_get_dma_buf(int fd); +void msm_cvp_smem_put_dma_buf(void *dma_buf); +int msm_cvp_smem_cache_operations(struct dma_buf *dbuf, + enum smem_cache_ops cache_op, + unsigned long offset, + unsigned long size); + +/* CVP driver internal buffer management functions*/ +struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, + u32 buffer_size); +int cvp_release_arp_buffers(struct msm_cvp_inst *inst); +int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, + struct cvp_kmd_buffer *buf); +int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, + struct cvp_kmd_buffer *buf); +void msm_cvp_cache_operations(struct msm_cvp_smem *smem, + u32 type, u32 offset, u32 size); +u32 msm_cvp_map_frame_buf(struct msm_cvp_inst *inst, + struct cvp_buf_type *buf, + struct msm_cvp_frame *frame); +int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst, + struct cvp_kmd_hfi_packet *in_pkt, + unsigned int offset, unsigned int buf_num); +int msm_cvp_map_user_persist(struct msm_cvp_inst *inst, + struct cvp_kmd_hfi_packet *in_pkt, + unsigned int offset, unsigned int buf_num); +int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, + struct cvp_kmd_hfi_packet *in_pkt, + unsigned int offset, unsigned int buf_num); +int msm_cvp_map_frame(struct msm_cvp_inst *inst, + struct cvp_kmd_hfi_packet *in_pkt, + unsigned int offset, unsigned int buf_num); +void msm_cvp_unmap_frame(struct msm_cvp_inst *inst, u64 ktid); +int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst); +void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst); +#endif diff --git a/msm/eva/msm_cvp_clocks.c b/msm/eva/msm_cvp_clocks.c new file mode 100644 index 0000000000..43300c82df --- /dev/null +++ b/msm/eva/msm_cvp_clocks.c @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#include "msm_cvp_common.h" +#include "cvp_hfi_api.h" +#include "msm_cvp_debug.h" +#include "msm_cvp_clocks.h" + +int msm_cvp_set_clocks(struct msm_cvp_core *core) +{ + struct cvp_hfi_device *hdev; + int rc; + + if (!core || !core->device) { + dprintk(CVP_ERR, "%s Invalid args: %pK\n", __func__, core); + return -EINVAL; + } + + hdev = core->device; + rc = call_hfi_op(hdev, scale_clocks, + hdev->hfi_device_data, core->curr_freq); + return rc; +} diff --git a/msm/eva/msm_cvp_clocks.h b/msm/eva/msm_cvp_clocks.h new file mode 100644 index 0000000000..401f89d472 --- /dev/null +++ b/msm/eva/msm_cvp_clocks.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + + +#ifndef _MSM_CVP_CLOCKS_H_ +#define _MSM_CVP_CLOCKS_H_ +#include "msm_cvp_internal.h" + +int msm_cvp_set_clocks(struct msm_cvp_core *core); +#endif diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c new file mode 100644 index 0000000000..446a90d06f --- /dev/null +++ b/msm/eva/msm_cvp_common.c @@ -0,0 +1,1610 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "msm_cvp_common.h" +#include "cvp_hfi_api.h" +#include "msm_cvp_debug.h" +#include "msm_cvp_clocks.h" +#include "msm_cvp.h" +#include "cvp_core_hfi.h" + +#define IS_ALREADY_IN_STATE(__p, __d) (\ + (__p >= __d)\ +) + +static void handle_session_error(enum hal_command_response cmd, void *data); + +static void dump_hfi_queue(struct iris_hfi_device *device) +{ + struct cvp_hfi_queue_header *queue; + struct cvp_iface_q_info *qinfo; + int i; + u32 *read_ptr, read_idx; + + dprintk(CVP_ERR, "HFI queues in order of cmd(rd, wr), msg and dbg:\n"); + + /* + * mb() to ensure driver reads the updated header values from + * main memory. + */ + mb(); + for (i = 0; i <= CVP_IFACEQ_DBGQ_IDX; i++) { + qinfo = &device->iface_queues[i]; + queue = (struct cvp_hfi_queue_header *)qinfo->q_hdr; + if (!queue) { + dprintk(CVP_ERR, "HFI queue not init, fail to dump\n"); + return; + } + dprintk(CVP_ERR, "queue details: %d %d\n", + queue->qhdr_read_idx, queue->qhdr_write_idx); + if (queue->qhdr_read_idx != queue->qhdr_write_idx) { + read_idx = queue->qhdr_read_idx; + read_ptr = (u32 *)((qinfo->q_array.align_virtual_addr) + + (read_idx << 2)); + dprintk(CVP_ERR, "queue payload: %x %x %x %x\n", + read_ptr[0], read_ptr[1], + read_ptr[2], read_ptr[3]); + } + + } +} + +struct msm_cvp_core *get_cvp_core(int core_id) +{ + struct msm_cvp_core *core; + int found = 0; + + if (core_id > MSM_CVP_CORES_MAX) { + dprintk(CVP_ERR, "Core id = %d is greater than max = %d\n", + core_id, MSM_CVP_CORES_MAX); + return NULL; + } + mutex_lock(&cvp_driver->lock); + list_for_each_entry(core, &cvp_driver->cores, list) { + if (core->id == core_id) { + found = 1; + break; + } + } + mutex_unlock(&cvp_driver->lock); + if (found) + return core; + return NULL; +} + +static void handle_sys_init_done(enum hal_command_response cmd, void *data) +{ + struct msm_cvp_cb_cmd_done *response = data; + struct msm_cvp_core *core; + struct cvp_hal_sys_init_done *sys_init_msg; + u32 index; + + if (!IS_HAL_SYS_CMD(cmd)) { + dprintk(CVP_ERR, "%s - invalid cmd\n", __func__); + return; + } + + index = SYS_MSG_INDEX(cmd); + + if (!response) { + dprintk(CVP_ERR, + "Failed to get valid response for sys init\n"); + return; + } + core = get_cvp_core(response->device_id); + if (!core) { + dprintk(CVP_ERR, "Wrong device_id received\n"); + return; + } + sys_init_msg = &response->data.sys_init_done; + if (!sys_init_msg) { + dprintk(CVP_ERR, "sys_init_done message not proper\n"); + return; + } + + /* This should come from sys_init_done */ + core->resources.max_inst_count = + sys_init_msg->max_sessions_supported ? + min_t(u32, sys_init_msg->max_sessions_supported, + MAX_SUPPORTED_INSTANCES) : MAX_SUPPORTED_INSTANCES; + + core->resources.max_secure_inst_count = + core->resources.max_secure_inst_count ? + core->resources.max_secure_inst_count : + core->resources.max_inst_count; + + memcpy(core->capabilities, sys_init_msg->capabilities, + sys_init_msg->codec_count * sizeof(struct msm_cvp_capability)); + + dprintk(CVP_CORE, + "%s: max_inst_count %d, max_secure_inst_count %d\n", + __func__, core->resources.max_inst_count, + core->resources.max_secure_inst_count); + + complete(&(core->completions[index])); +} + +static void put_inst_helper(struct kref *kref) +{ + struct msm_cvp_inst *inst = container_of(kref, + struct msm_cvp_inst, kref); + + msm_cvp_destroy(inst); +} + +void cvp_put_inst(struct msm_cvp_inst *inst) +{ + if (!inst) + return; + + kref_put(&inst->kref, put_inst_helper); +} + +struct msm_cvp_inst *cvp_get_inst(struct msm_cvp_core *core, + void *session_id) +{ + struct msm_cvp_inst *inst = NULL; + bool matches = false; + + if (!core || !session_id) + return NULL; + + mutex_lock(&core->lock); + /* + * This is as good as !list_empty(!inst->list), but at this point + * we don't really know if inst was kfree'd via close syscall before + * hardware could respond. So manually walk thru the list of active + * sessions + */ + list_for_each_entry(inst, &core->instances, list) { + if (inst == session_id) { + /* + * Even if the instance is valid, we really shouldn't + * be receiving or handling callbacks when we've deleted + * our session with HFI + */ + matches = !!inst->session; + break; + } + } + + /* + * kref_* is atomic_int backed, so no need for inst->lock. But we can + * always acquire inst->lock and release it in cvp_put_inst + * for a stronger locking system. + */ + inst = (matches && kref_get_unless_zero(&inst->kref)) ? inst : NULL; + mutex_unlock(&core->lock); + + return inst; +} + +struct msm_cvp_inst *cvp_get_inst_validate(struct msm_cvp_core *core, + void *session_id) +{ + int rc = 0; + struct cvp_hfi_device *hdev; + struct msm_cvp_inst *s; + + s = cvp_get_inst(core, session_id); + if (!s) { + dprintk(CVP_ERR, "%s session doesn't exit\n", + __builtin_return_address(0)); + return NULL; + } + + hdev = s->core->device; + rc = call_hfi_op(hdev, validate_session, s->session, __func__); + if (rc) { + cvp_put_inst(s); + s = NULL; + } + + return s; +} + +static void cvp_handle_session_cmd_done(enum hal_command_response cmd, + void *data) +{ + struct msm_cvp_cb_cmd_done *response = data; + struct msm_cvp_inst *inst; + + if (!response) { + dprintk(CVP_ERR, "%s: Invalid release_buf_done response\n", + __func__); + return; + } + + inst = cvp_get_inst(get_cvp_core(response->device_id), + response->session_id); + if (!inst) { + dprintk(CVP_ERR, "%s: Got response for an inactive session\n", + __func__); + return; + } + + if (response->status) + dprintk(CVP_ERR, "HFI MSG error %d cmd response %d\n", + response->status, cmd); + + dprintk(CVP_SESS, "%s: inst=%pK\n", __func__, inst); + + if (IS_HAL_SESSION_CMD(cmd)) { + dprintk(CVP_INFO, "%s: calling completion for index = %d", + __func__, SESSION_MSG_INDEX(cmd)); + complete(&inst->completions[SESSION_MSG_INDEX(cmd)]); + } else + dprintk(CVP_ERR, + "%s: Invalid inst cmd response: %d\n", __func__, cmd); + cvp_put_inst(inst); +} + +static void handle_session_set_buf_done(enum hal_command_response cmd, + void *data) +{ + struct msm_cvp_cb_cmd_done *response = data; + struct msm_cvp_inst *inst; + + if (!response) { + dprintk(CVP_ERR, "Invalid set_buf_done response\n"); + return; + } + + inst = cvp_get_inst(get_cvp_core(response->device_id), + response->session_id); + if (!inst) { + dprintk(CVP_WARN, "set_buf_done has an inactive session\n"); + return; + } + + if (response->status) { + dprintk(CVP_ERR, + "set ARP buffer error from FW : %#x\n", + response->status); + } + + if (IS_HAL_SESSION_CMD(cmd)) + complete(&inst->completions[SESSION_MSG_INDEX(cmd)]); + else + dprintk(CVP_ERR, "set_buf_done: invalid cmd: %d\n", cmd); + cvp_put_inst(inst); + +} + +static void handle_session_release_buf_done(enum hal_command_response cmd, + void *data) +{ + struct msm_cvp_cb_cmd_done *response = data; + struct msm_cvp_inst *inst; + struct cvp_internal_buf *buf; + struct list_head *ptr, *next; + u32 buf_found = false; + u32 address; + + if (!response) { + dprintk(CVP_ERR, "Invalid release_buf_done response\n"); + return; + } + + inst = cvp_get_inst(get_cvp_core(response->device_id), + response->session_id); + if (!inst) { + dprintk(CVP_WARN, + "%s: Got a response for an inactive session\n", + __func__); + return; + } + + address = response->data.buffer_addr; + + mutex_lock(&inst->persistbufs.lock); + list_for_each_safe(ptr, next, &inst->persistbufs.list) { + buf = list_entry(ptr, struct cvp_internal_buf, list); + if (address == buf->smem->device_addr + buf->offset) { + dprintk(CVP_SESS, "releasing persist: %#x\n", + buf->smem->device_addr); + buf_found = true; + } + } + mutex_unlock(&inst->persistbufs.lock); + + if (IS_HAL_SESSION_CMD(cmd)) + complete(&inst->completions[SESSION_MSG_INDEX(cmd)]); + else + dprintk(CVP_ERR, "Invalid inst cmd response: %d\n", cmd); + + cvp_put_inst(inst); +} + +static void handle_sys_release_res_done( + enum hal_command_response cmd, void *data) +{ + struct msm_cvp_cb_cmd_done *response = data; + struct msm_cvp_core *core; + + if (!response) { + dprintk(CVP_ERR, + "Failed to get valid response for sys init\n"); + return; + } + core = get_cvp_core(response->device_id); + if (!core) { + dprintk(CVP_ERR, "Wrong device_id received\n"); + return; + } + complete(&core->completions[ + SYS_MSG_INDEX(HAL_SYS_RELEASE_RESOURCE_DONE)]); +} + +void change_cvp_inst_state(struct msm_cvp_inst *inst, enum instance_state state) +{ + if (!inst) { + dprintk(CVP_ERR, "Invalid parameter %s\n", __func__); + return; + } + mutex_lock(&inst->lock); + if (inst->state == MSM_CVP_CORE_INVALID) { + dprintk(CVP_SESS, + "Inst: %pK is in bad state can't change state to %d\n", + inst, state); + goto exit; + } + dprintk(CVP_SESS, "Moved inst: %pK from state: %d to state: %d\n", + inst, inst->state, state); + inst->state = state; +exit: + mutex_unlock(&inst->lock); +} + +static int signal_session_msg_receipt(enum hal_command_response cmd, + struct msm_cvp_inst *inst) +{ + if (!inst) { + dprintk(CVP_ERR, "Invalid(%pK) instance id\n", inst); + return -EINVAL; + } + if (IS_HAL_SESSION_CMD(cmd)) { + complete(&inst->completions[SESSION_MSG_INDEX(cmd)]); + } else { + dprintk(CVP_ERR, "Invalid inst cmd response: %d\n", cmd); + return -EINVAL; + } + return 0; +} + +int wait_for_sess_signal_receipt(struct msm_cvp_inst *inst, + enum hal_command_response cmd) +{ + int rc = 0; + struct cvp_hfi_device *hdev; + + if (!IS_HAL_SESSION_CMD(cmd)) { + dprintk(CVP_ERR, "Invalid inst cmd response: %d\n", cmd); + return -EINVAL; + } + hdev = (struct cvp_hfi_device *)(inst->core->device); + rc = wait_for_completion_timeout( + &inst->completions[SESSION_MSG_INDEX(cmd)], + msecs_to_jiffies( + inst->core->resources.msm_cvp_hw_rsp_timeout)); + if (!rc) { + dprintk(CVP_WARN, "Wait interrupted or timed out: %d\n", + SESSION_MSG_INDEX(cmd)); + call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data); + dump_hfi_queue(hdev->hfi_device_data); + rc = -EIO; + } else { + rc = 0; + } + return rc; +} + +static int wait_for_state(struct msm_cvp_inst *inst, + enum instance_state flipped_state, + enum instance_state desired_state, + enum hal_command_response hal_cmd) +{ + int rc = 0; + + if (IS_ALREADY_IN_STATE(flipped_state, desired_state)) { + dprintk(CVP_INFO, "inst: %pK is already in state: %d\n", + inst, inst->state); + goto err_same_state; + } + dprintk(CVP_SESS, "Waiting for hal_cmd: %d\n", hal_cmd); + rc = wait_for_sess_signal_receipt(inst, hal_cmd); + if (!rc) + change_cvp_inst_state(inst, desired_state); +err_same_state: + return rc; +} + +void msm_cvp_notify_event(struct msm_cvp_inst *inst, int event_type) +{ +} + +static void msm_cvp_comm_generate_max_clients_error(struct msm_cvp_inst *inst) +{ + enum hal_command_response cmd = HAL_SESSION_ERROR; + struct msm_cvp_cb_cmd_done response = {0}; + + if (!inst) { + dprintk(CVP_ERR, "%s: invalid input parameters\n", __func__); + return; + } + dprintk(CVP_ERR, "%s: Too many clients\n", __func__); + response.session_id = inst; + response.status = CVP_ERR_MAX_CLIENTS; + handle_session_error(cmd, (void *)&response); +} + +static void handle_session_init_done(enum hal_command_response cmd, void *data) +{ + struct msm_cvp_cb_cmd_done *response = data; + struct msm_cvp_inst *inst = NULL; + + if (!response) { + dprintk(CVP_ERR, + "Failed to get valid response for session init\n"); + return; + } + + inst = cvp_get_inst(get_cvp_core(response->device_id), + response->session_id); + + if (!inst) { + dprintk(CVP_WARN, "%s:Got a response for an inactive session\n", + __func__); + return; + } + + if (response->status) { + dprintk(CVP_ERR, + "Session init response from FW : %#x\n", + response->status); + if (response->status == CVP_ERR_MAX_CLIENTS) + msm_cvp_comm_generate_max_clients_error(inst); + else + msm_cvp_comm_generate_session_error(inst); + + signal_session_msg_receipt(cmd, inst); + cvp_put_inst(inst); + return; + } + + dprintk(CVP_SESS, "%s: cvp session %#x\n", __func__, + hash32_ptr(inst->session)); + + signal_session_msg_receipt(cmd, inst); + cvp_put_inst(inst); + return; + +} + +static void handle_event_change(enum hal_command_response cmd, void *data) +{ + dprintk(CVP_WARN, "%s is not supported on CVP!\n", __func__); +} + +static void handle_release_res_done(enum hal_command_response cmd, void *data) +{ + struct msm_cvp_cb_cmd_done *response = data; + struct msm_cvp_inst *inst; + + if (!response) { + dprintk(CVP_ERR, + "Failed to get valid response for release resource\n"); + return; + } + + inst = cvp_get_inst(get_cvp_core(response->device_id), + response->session_id); + if (!inst) { + dprintk(CVP_WARN, "%s:Got a response for an inactive session\n", + __func__); + return; + } + + signal_session_msg_receipt(cmd, inst); + cvp_put_inst(inst); +} + +static void handle_session_flush(enum hal_command_response cmd, void *data) +{ + struct msm_cvp_cb_cmd_done *response = data; + struct msm_cvp_inst *inst; + + if (!response) { + dprintk(CVP_ERR, + "Failed to get valid response for release resource\n"); + return; + } + + inst = cvp_get_inst(get_cvp_core(response->device_id), + response->session_id); + if (!inst) { + dprintk(CVP_WARN, "%s:Got a response for an inactive session\n", + __func__); + return; + } + + signal_session_msg_receipt(cmd, inst); + cvp_put_inst(inst); +} + +static void handle_session_error(enum hal_command_response cmd, void *data) +{ + struct msm_cvp_cb_cmd_done *response = data; + struct cvp_hfi_device *hdev = NULL; + struct msm_cvp_inst *inst = NULL; + int event = CVP_SYS_ERROR_EVENT; + + if (!response) { + dprintk(CVP_ERR, + "Failed to get valid response for session error\n"); + return; + } + + inst = cvp_get_inst(get_cvp_core(response->device_id), + response->session_id); + if (!inst) { + dprintk(CVP_WARN, "%s: response for an inactive session\n", + __func__); + return; + } + + hdev = inst->core->device; + dprintk(CVP_ERR, "Session error received for inst %pK session %x\n", + inst, hash32_ptr(inst->session)); + + if (response->status == CVP_ERR_MAX_CLIENTS) { + dprintk(CVP_WARN, "Too many clients, rejecting %pK", inst); + event = CVP_MAX_CLIENTS_EVENT; + + /* + * Clean the HFI session now. Since inst->state is moved to + * INVALID, forward thread doesn't know FW has valid session + * or not. This is the last place driver knows that there is + * no session in FW. Hence clean HFI session now. + */ + + msm_cvp_comm_session_clean(inst); + } else if (response->status == CVP_ERR_NOT_SUPPORTED) { + dprintk(CVP_WARN, "Unsupported bitstream in %pK", inst); + event = CVP_HW_UNSUPPORTED_EVENT; + } else { + dprintk(CVP_WARN, "Unknown session error (%d) for %pK\n", + response->status, inst); + event = CVP_SYS_ERROR_EVENT; + } + + /* change state before sending error to client */ + change_cvp_inst_state(inst, MSM_CVP_CORE_INVALID); + msm_cvp_notify_event(inst, event); + cvp_put_inst(inst); +} + +static void msm_comm_clean_notify_client(struct msm_cvp_core *core) +{ + struct msm_cvp_inst *inst = NULL; + + if (!core) { + dprintk(CVP_ERR, "%s: Invalid params\n", __func__); + return; + } + + dprintk(CVP_WARN, "%s: Core %pK\n", __func__, core); + mutex_lock(&core->lock); + + list_for_each_entry(inst, &core->instances, list) { + mutex_lock(&inst->lock); + inst->state = MSM_CVP_CORE_INVALID; + mutex_unlock(&inst->lock); + dprintk(CVP_WARN, + "%s Send sys error for inst %pK\n", __func__, inst); + msm_cvp_notify_event(inst, + CVP_SYS_ERROR_EVENT); + } + mutex_unlock(&core->lock); +} + +static void handle_sys_error(enum hal_command_response cmd, void *data) +{ + struct msm_cvp_cb_cmd_done *response = data; + struct msm_cvp_core *core = NULL; + struct cvp_hfi_device *hdev = NULL; + struct msm_cvp_inst *inst = NULL; + int rc = 0; + unsigned long flags = 0; + enum cvp_core_state cur_state; + + subsystem_crashed("evass"); + if (!response) { + dprintk(CVP_ERR, + "Failed to get valid response for sys error\n"); + return; + } + + core = get_cvp_core(response->device_id); + if (!core) { + dprintk(CVP_ERR, + "Got SYS_ERR but unable to identify core\n"); + return; + } + hdev = core->device; + + mutex_lock(&core->lock); + if (core->state == CVP_CORE_UNINIT) { + dprintk(CVP_ERR, + "%s: Core %pK already moved to state %d\n", + __func__, core, core->state); + mutex_unlock(&core->lock); + return; + } + + cur_state = core->state; + core->state = CVP_CORE_UNINIT; + dprintk(CVP_WARN, "SYS_ERROR received for core %pK\n", core); + msm_cvp_noc_error_info(core); + call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data); + list_for_each_entry(inst, &core->instances, list) { + dprintk(CVP_WARN, + "%s: sys error inst %#x kref %x, cmd %x state %x\n", + __func__, inst, kref_read(&inst->kref), + inst->cur_cmd_type, inst->state); + if (inst->state != MSM_CVP_CORE_INVALID) { + change_cvp_inst_state(inst, MSM_CVP_CORE_INVALID); + spin_lock_irqsave(&inst->event_handler.lock, flags); + inst->event_handler.event = CVP_SSR_EVENT; + spin_unlock_irqrestore( + &inst->event_handler.lock, flags); + wake_up_all(&inst->event_handler.wq); + } + + if (!core->trigger_ssr) + msm_cvp_print_inst_bufs(inst); + } + + /* handle the hw error before core released to get full debug info */ + msm_cvp_handle_hw_error(core); + if (response->status == CVP_ERR_NOC_ERROR) { + dprintk(CVP_WARN, "Got NOC error"); + MSM_CVP_ERROR(true); + } + + dprintk(CVP_CORE, "Calling core_release\n"); + rc = call_hfi_op(hdev, core_release, hdev->hfi_device_data); + if (rc) { + dprintk(CVP_ERR, "core_release failed\n"); + core->state = cur_state; + mutex_unlock(&core->lock); + return; + } + mutex_unlock(&core->lock); + + dprintk(CVP_WARN, "SYS_ERROR handled.\n"); +} + +void msm_cvp_comm_session_clean(struct msm_cvp_inst *inst) +{ + int rc = 0; + struct cvp_hfi_device *hdev = NULL; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(CVP_ERR, "%s invalid params\n", __func__); + return; + } + if (!inst->session) { + dprintk(CVP_SESS, "%s: inst %pK session already cleaned\n", + __func__, inst); + return; + } + + hdev = inst->core->device; + mutex_lock(&inst->lock); + dprintk(CVP_SESS, "%s: inst %pK\n", __func__, inst); + rc = call_hfi_op(hdev, session_clean, + (void *)inst->session); + if (rc) { + dprintk(CVP_ERR, + "Session clean failed :%pK\n", inst); + } + inst->session = NULL; + mutex_unlock(&inst->lock); +} + +static void handle_session_close(enum hal_command_response cmd, void *data) +{ + struct msm_cvp_cb_cmd_done *response = data; + struct msm_cvp_inst *inst; + + if (!response) { + dprintk(CVP_ERR, + "Failed to get valid response for session close\n"); + return; + } + + inst = cvp_get_inst(get_cvp_core(response->device_id), + response->session_id); + if (!inst) { + dprintk(CVP_WARN, "%s: response for an inactive session\n", + __func__); + return; + } + + signal_session_msg_receipt(cmd, inst); + show_stats(inst); + cvp_put_inst(inst); +} + +void cvp_handle_cmd_response(enum hal_command_response cmd, void *data) +{ + dprintk(CVP_HFI, "Command response = %d\n", cmd); + switch (cmd) { + case HAL_SYS_INIT_DONE: + handle_sys_init_done(cmd, data); + break; + case HAL_SYS_RELEASE_RESOURCE_DONE: + handle_sys_release_res_done(cmd, data); + break; + case HAL_SESSION_INIT_DONE: + handle_session_init_done(cmd, data); + break; + case HAL_SESSION_RELEASE_RESOURCE_DONE: + handle_release_res_done(cmd, data); + break; + case HAL_SESSION_END_DONE: + case HAL_SESSION_ABORT_DONE: + handle_session_close(cmd, data); + break; + case HAL_SESSION_EVENT_CHANGE: + handle_event_change(cmd, data); + break; + case HAL_SESSION_FLUSH_DONE: + handle_session_flush(cmd, data); + break; + case HAL_SYS_WATCHDOG_TIMEOUT: + case HAL_SYS_ERROR: + handle_sys_error(cmd, data); + break; + case HAL_SESSION_ERROR: + handle_session_error(cmd, data); + break; + case HAL_SESSION_SET_BUFFER_DONE: + handle_session_set_buf_done(cmd, data); + break; + case HAL_SESSION_RELEASE_BUFFER_DONE: + handle_session_release_buf_done(cmd, data); + break; + case HAL_SESSION_DFS_CONFIG_CMD_DONE: + case HAL_SESSION_DFS_FRAME_CMD_DONE: + case HAL_SESSION_DME_CONFIG_CMD_DONE: + case HAL_SESSION_DME_BASIC_CONFIG_CMD_DONE: + case HAL_SESSION_DME_FRAME_CMD_DONE: + case HAL_SESSION_PERSIST_SET_DONE: + case HAL_SESSION_PERSIST_REL_DONE: + case HAL_SESSION_TME_CONFIG_CMD_DONE: + case HAL_SESSION_ODT_CONFIG_CMD_DONE: + case HAL_SESSION_OD_CONFIG_CMD_DONE: + case HAL_SESSION_NCC_CONFIG_CMD_DONE: + case HAL_SESSION_ICA_CONFIG_CMD_DONE: + case HAL_SESSION_HCD_CONFIG_CMD_DONE: + case HAL_SESSION_DCM_CONFIG_CMD_DONE: + case HAL_SESSION_DC_CONFIG_CMD_DONE: + case HAL_SESSION_PYS_HCD_CONFIG_CMD_DONE: + case HAL_SESSION_FD_CONFIG_CMD_DONE: + case HAL_SESSION_MODEL_BUF_CMD_DONE: + case HAL_SESSION_ICA_FRAME_CMD_DONE: + case HAL_SESSION_FD_FRAME_CMD_DONE: + cvp_handle_session_cmd_done(cmd, data); + break; + default: + dprintk(CVP_HFI, "response unhandled: %d\n", cmd); + break; + } +} + +static inline enum msm_cvp_thermal_level msm_comm_cvp_thermal_level(int level) +{ + switch (level) { + case 0: + return CVP_THERMAL_NORMAL; + case 1: + return CVP_THERMAL_LOW; + case 2: + return CVP_THERMAL_HIGH; + default: + return CVP_THERMAL_CRITICAL; + } +} + +static bool is_core_turbo(struct msm_cvp_core *core, unsigned long freq) +{ + int i = 0; + struct allowed_clock_rates_table *allowed_clks_tbl = NULL; + u32 max_freq = 0; + + allowed_clks_tbl = core->resources.allowed_clks_tbl; + for (i = 0; i < core->resources.allowed_clks_tbl_size; i++) { + if (max_freq < allowed_clks_tbl[i].clock_rate) + max_freq = allowed_clks_tbl[i].clock_rate; + } + return freq >= max_freq; +} + +static bool is_thermal_permissible(struct msm_cvp_core *core) +{ + enum msm_cvp_thermal_level tl; + unsigned long freq = 0; + bool is_turbo = false; + + if (!core->resources.thermal_mitigable) + return true; + + if (msm_cvp_thermal_mitigation_disabled) { + dprintk(CVP_CORE, + "Thermal mitigation not enabled. debugfs %d\n", + msm_cvp_thermal_mitigation_disabled); + return true; + } + + tl = msm_comm_cvp_thermal_level(cvp_driver->thermal_level); + freq = core->curr_freq; + + is_turbo = is_core_turbo(core, freq); + dprintk(CVP_CORE, + "Core freq %ld Thermal level %d Turbo mode %d\n", + freq, tl, is_turbo); + + if (is_turbo && tl >= CVP_THERMAL_LOW) { + dprintk(CVP_ERR, + "CVP session not allowed. Turbo mode %d Thermal level %d\n", + is_turbo, tl); + return false; + } + return true; +} + +static int msm_comm_session_abort(struct msm_cvp_inst *inst) +{ + int rc = 0, abort_completion = 0; + struct cvp_hfi_device *hdev; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(CVP_ERR, "%s invalid params\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + abort_completion = SESSION_MSG_INDEX(HAL_SESSION_ABORT_DONE); + + dprintk(CVP_WARN, "%s: inst %pK session %x\n", __func__, + inst, hash32_ptr(inst->session)); + rc = call_hfi_op(hdev, session_abort, (void *)inst->session); + if (rc) { + dprintk(CVP_ERR, + "%s session_abort failed rc: %d\n", __func__, rc); + goto exit; + } + rc = wait_for_completion_timeout( + &inst->completions[abort_completion], + msecs_to_jiffies( + inst->core->resources.msm_cvp_hw_rsp_timeout)); + if (!rc) { + dprintk(CVP_ERR, "%s: inst %pK session %x abort timed out\n", + __func__, inst, hash32_ptr(inst->session)); + call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data); + dump_hfi_queue(hdev->hfi_device_data); + msm_cvp_comm_generate_sys_error(inst); + rc = -EBUSY; + } else { + rc = 0; + } +exit: + return rc; +} + +static void handle_thermal_event(struct msm_cvp_core *core) +{ + int rc = 0; + struct msm_cvp_inst *inst; + + if (!core || !core->device) { + dprintk(CVP_ERR, "%s Invalid params\n", __func__); + return; + } + mutex_lock(&core->lock); + list_for_each_entry(inst, &core->instances, list) { + if (!inst->session) + continue; + + mutex_unlock(&core->lock); + if (inst->state >= MSM_CVP_OPEN_DONE && + inst->state < MSM_CVP_CLOSE_DONE) { + dprintk(CVP_WARN, "%s: abort inst %pK\n", + __func__, inst); + rc = msm_comm_session_abort(inst); + if (rc) { + dprintk(CVP_ERR, + "%s session_abort failed rc: %d\n", + __func__, rc); + goto err_sess_abort; + } + change_cvp_inst_state(inst, MSM_CVP_CORE_INVALID); + dprintk(CVP_WARN, + "%s Send sys error for inst %pK\n", + __func__, inst); + msm_cvp_notify_event(inst, + CVP_SYS_ERROR_EVENT); + } else { + msm_cvp_comm_generate_session_error(inst); + } + mutex_lock(&core->lock); + } + mutex_unlock(&core->lock); + return; + +err_sess_abort: + msm_comm_clean_notify_client(core); +} + +void msm_cvp_comm_handle_thermal_event(void) +{ + struct msm_cvp_core *core; + + list_for_each_entry(core, &cvp_driver->cores, list) { + if (!is_thermal_permissible(core)) { + dprintk(CVP_WARN, + "Thermal level critical, stop all active sessions!\n"); + handle_thermal_event(core); + } + } +} + +int msm_cvp_comm_check_core_init(struct msm_cvp_core *core) +{ + int rc = 0; + struct cvp_hfi_device *hdev; + + mutex_lock(&core->lock); + if (core->state >= CVP_CORE_INIT_DONE) { + dprintk(CVP_INFO, "CVP core: %d is already in state: %d\n", + core->id, core->state); + goto exit; + } + dprintk(CVP_CORE, "Waiting for SYS_INIT_DONE\n"); + rc = wait_for_completion_timeout( + &core->completions[SYS_MSG_INDEX(HAL_SYS_INIT_DONE)], + msecs_to_jiffies(core->resources.msm_cvp_hw_rsp_timeout)); + if (!rc) { + dprintk(CVP_ERR, "%s: Wait interrupted or timed out: %d\n", + __func__, SYS_MSG_INDEX(HAL_SYS_INIT_DONE)); + hdev = core->device; + call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data); + dump_hfi_queue(hdev->hfi_device_data); + rc = -EIO; + goto exit; + } else { + core->state = CVP_CORE_INIT_DONE; + rc = 0; + } + dprintk(CVP_CORE, "SYS_INIT_DONE!!!\n"); +exit: + mutex_unlock(&core->lock); + return rc; +} + +static int msm_comm_init_core_done(struct msm_cvp_inst *inst) +{ + int rc = 0; + + rc = msm_cvp_comm_check_core_init(inst->core); + if (rc) { + dprintk(CVP_ERR, "%s - failed to initialize core\n", __func__); + msm_cvp_comm_generate_sys_error(inst); + return rc; + } + change_cvp_inst_state(inst, MSM_CVP_CORE_INIT_DONE); + return rc; +} + +static int msm_comm_init_core(struct msm_cvp_inst *inst) +{ + int rc = 0; + struct cvp_hfi_device *hdev; + struct msm_cvp_core *core; + + if (!inst || !inst->core || !inst->core->device) + return -EINVAL; + + core = inst->core; + hdev = core->device; + mutex_lock(&core->lock); + if (core->state >= CVP_CORE_INIT) { + dprintk(CVP_CORE, "CVP core: %d is already in state: %d\n", + core->id, core->state); + goto core_already_inited; + } + if (!core->capabilities) { + core->capabilities = kcalloc(CVP_MAX_SESSIONS, + sizeof(struct msm_cvp_capability), GFP_KERNEL); + if (!core->capabilities) { + dprintk(CVP_ERR, + "%s: failed to allocate capabilities\n", + __func__); + rc = -ENOMEM; + goto fail_cap_alloc; + } + } else { + dprintk(CVP_WARN, + "%s: capabilities memory is expected to be freed\n", + __func__); + } + dprintk(CVP_CORE, "%s: core %pK\n", __func__, core); + rc = call_hfi_op(hdev, core_init, hdev->hfi_device_data); + if (rc) { + dprintk(CVP_ERR, "Failed to init core, id = %d\n", + core->id); + goto fail_core_init; + } + core->state = CVP_CORE_INIT; + core->smmu_fault_handled = false; + core->trigger_ssr = false; + +core_already_inited: + change_cvp_inst_state(inst, MSM_CVP_CORE_INIT); + mutex_unlock(&core->lock); + + return rc; + +fail_core_init: + kfree(core->capabilities); +fail_cap_alloc: + core->capabilities = NULL; + core->state = CVP_CORE_UNINIT; + mutex_unlock(&core->lock); + return rc; +} + +int msm_cvp_deinit_core(struct msm_cvp_inst *inst) +{ + struct msm_cvp_core *core; + struct cvp_hfi_device *hdev; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(CVP_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + + core = inst->core; + hdev = core->device; + + mutex_lock(&core->lock); + if (core->state == CVP_CORE_UNINIT) { + dprintk(CVP_INFO, "CVP core: %d is already in state: %d\n", + core->id, core->state); + goto core_already_uninited; + } + + if (!core->resources.never_unload_fw) { + cancel_delayed_work(&core->fw_unload_work); + + /* + * Delay unloading of firmware. This is useful + * in avoiding firmware download delays in cases where we + * will have a burst of back to back cvp sessions + */ + schedule_delayed_work(&core->fw_unload_work, + msecs_to_jiffies(core->state == CVP_CORE_INIT_DONE ? + core->resources.msm_cvp_firmware_unload_delay : 0)); + + dprintk(CVP_CORE, "firmware unload delayed by %u ms\n", + core->state == CVP_CORE_INIT_DONE ? + core->resources.msm_cvp_firmware_unload_delay : 0); + } + +core_already_uninited: + change_cvp_inst_state(inst, MSM_CVP_CORE_UNINIT); + mutex_unlock(&core->lock); + return 0; +} + +static int msm_comm_session_init_done(int flipped_state, + struct msm_cvp_inst *inst) +{ + int rc; + + dprintk(CVP_SESS, "inst %pK: waiting for session init done\n", inst); + rc = wait_for_state(inst, flipped_state, MSM_CVP_OPEN_DONE, + HAL_SESSION_INIT_DONE); + if (rc) { + dprintk(CVP_ERR, "Session init failed for inst %pK\n", inst); + msm_cvp_comm_generate_sys_error(inst); + return rc; + } + + return rc; +} + +static int msm_comm_session_init(int flipped_state, + struct msm_cvp_inst *inst) +{ + int rc = 0; + struct cvp_hfi_device *hdev; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(CVP_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + hdev = inst->core->device; + + if (IS_ALREADY_IN_STATE(flipped_state, MSM_CVP_OPEN)) { + dprintk(CVP_INFO, "inst: %pK is already in state: %d\n", + inst, inst->state); + goto exit; + } + + dprintk(CVP_SESS, "%s: inst %pK\n", __func__, inst); + rc = call_hfi_op(hdev, session_init, hdev->hfi_device_data, + inst, &inst->session); + + if (rc || !inst->session) { + dprintk(CVP_ERR, + "Failed to call session init for: %pK, %pK, %d\n", + inst->core->device, inst, inst->session_type); + rc = -EINVAL; + goto exit; + } + change_cvp_inst_state(inst, MSM_CVP_OPEN); + +exit: + return rc; +} + +static int msm_comm_session_close(int flipped_state, + struct msm_cvp_inst *inst) +{ + int rc = 0; + struct cvp_hfi_device *hdev; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(CVP_ERR, "%s invalid params\n", __func__); + return -EINVAL; + } + if (IS_ALREADY_IN_STATE(flipped_state, MSM_CVP_CLOSE)) { + dprintk(CVP_INFO, + "inst: %pK is already in state: %d\n", + inst, inst->state); + goto exit; + } + hdev = inst->core->device; + dprintk(CVP_SESS, "%s: inst %pK\n", __func__, inst); + rc = call_hfi_op(hdev, session_end, (void *) inst->session); + if (rc) { + dprintk(CVP_ERR, + "Failed to send close\n"); + goto exit; + } + change_cvp_inst_state(inst, MSM_CVP_CLOSE); +exit: + return rc; +} + +int msm_cvp_comm_suspend(int core_id) +{ + struct cvp_hfi_device *hdev; + struct msm_cvp_core *core; + int rc = 0; + + core = get_cvp_core(core_id); + if (!core) { + dprintk(CVP_ERR, + "%s: Failed to find core for core_id = %d\n", + __func__, core_id); + return -EINVAL; + } + + hdev = (struct cvp_hfi_device *)core->device; + if (!hdev) { + dprintk(CVP_ERR, "%s Invalid device handle\n", __func__); + return -EINVAL; + } + + rc = call_hfi_op(hdev, suspend, hdev->hfi_device_data); + if (rc) + dprintk(CVP_WARN, "Failed to suspend\n"); + + return rc; +} + +static int get_flipped_state(int present_state, int desired_state) +{ + int flipped_state = present_state; + + if (flipped_state < MSM_CVP_CLOSE && desired_state > MSM_CVP_CLOSE) { + flipped_state = MSM_CVP_CLOSE + (MSM_CVP_CLOSE - flipped_state); + flipped_state &= 0xFFFE; + flipped_state = flipped_state - 1; + } else if (flipped_state > MSM_CVP_CLOSE + && desired_state < MSM_CVP_CLOSE) { + flipped_state = MSM_CVP_CLOSE - + (flipped_state - MSM_CVP_CLOSE + 1); + flipped_state &= 0xFFFE; + flipped_state = flipped_state - 1; + } + return flipped_state; +} + +int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state) +{ + int rc = 0; + int flipped_state; + + if (!inst) { + dprintk(CVP_ERR, "%s: invalid params %pK", __func__, inst); + return -EINVAL; + } + dprintk(CVP_SESS, + "Trying to move inst: %pK (%#x) from: %#x to %#x\n", + inst, hash32_ptr(inst->session), inst->state, state); + + mutex_lock(&inst->sync_lock); + if (inst->state == MSM_CVP_CORE_INVALID) { + dprintk(CVP_ERR, "%s: inst %pK is in invalid\n", + __func__, inst); + mutex_unlock(&inst->sync_lock); + return -EINVAL; + } + + flipped_state = get_flipped_state(inst->state, state); + dprintk(CVP_SESS, + "inst: %pK (%#x) flipped_state = %#x %x\n", + inst, hash32_ptr(inst->session), flipped_state, state); + switch (flipped_state) { + case MSM_CVP_CORE_UNINIT_DONE: + case MSM_CVP_CORE_INIT: + rc = msm_comm_init_core(inst); + if (rc || state <= get_flipped_state(inst->state, state)) + break; + case MSM_CVP_CORE_INIT_DONE: + rc = msm_comm_init_core_done(inst); + if (rc || state <= get_flipped_state(inst->state, state)) + break; + case MSM_CVP_OPEN: + rc = msm_comm_session_init(flipped_state, inst); + if (rc || state <= get_flipped_state(inst->state, state)) + break; + case MSM_CVP_OPEN_DONE: + rc = msm_comm_session_init_done(flipped_state, inst); + if (rc || state <= get_flipped_state(inst->state, state)) + break; + case MSM_CVP_CLOSE: + dprintk(CVP_INFO, "to CVP_CLOSE state\n"); + rc = msm_comm_session_close(flipped_state, inst); + if (rc || state <= get_flipped_state(inst->state, state)) + break; + case MSM_CVP_CLOSE_DONE: + dprintk(CVP_INFO, "to CVP_CLOSE_DONE state\n"); + rc = wait_for_state(inst, flipped_state, MSM_CVP_CLOSE_DONE, + HAL_SESSION_END_DONE); + if (rc || state <= get_flipped_state(inst->state, state)) + break; + msm_cvp_comm_session_clean(inst); + case MSM_CVP_CORE_UNINIT: + case MSM_CVP_CORE_INVALID: + dprintk(CVP_INFO, "Sending core uninit\n"); + rc = msm_cvp_deinit_core(inst); + if (rc || state <= get_flipped_state(inst->state, state)) + break; + default: + dprintk(CVP_ERR, "State not recognized\n"); + rc = -EINVAL; + break; + } + + mutex_unlock(&inst->sync_lock); + + if (rc) { + dprintk(CVP_ERR, + "Failed to move from state: %d to %d\n", + inst->state, state); + msm_cvp_comm_kill_session(inst); + } + return rc; +} + +int msm_cvp_noc_error_info(struct msm_cvp_core *core) +{ + struct cvp_hfi_device *hdev; + + if (!core || !core->device) { + dprintk(CVP_WARN, "%s: Invalid parameters: %pK\n", + __func__, core); + return -EINVAL; + } + + if (!core->resources.non_fatal_pagefaults) + return 0; + + if (!core->smmu_fault_handled) + return 0; + + hdev = core->device; + call_hfi_op(hdev, noc_error_info, hdev->hfi_device_data); + + return 0; +} + +int msm_cvp_trigger_ssr(struct msm_cvp_core *core, + enum hal_ssr_trigger_type type) +{ + if (!core) { + dprintk(CVP_WARN, "%s: Invalid parameters\n", __func__); + return -EINVAL; + } + core->ssr_type = type; + schedule_work(&core->ssr_work); + return 0; +} + +void msm_cvp_ssr_handler(struct work_struct *work) +{ + int rc; + struct msm_cvp_core *core; + struct cvp_hfi_device *hdev; + + core = container_of(work, struct msm_cvp_core, ssr_work); + if (!core || !core->device) { + dprintk(CVP_ERR, "%s: Invalid params\n", __func__); + return; + } + hdev = core->device; + + if (core->ssr_type == SSR_SESSION_ABORT) { + struct msm_cvp_inst *inst = NULL, *s; + + dprintk(CVP_ERR, "Session abort triggered\n"); + list_for_each_entry(inst, &core->instances, list) { + dprintk(CVP_WARN, + "Session to abort: inst %#x cmd %x ref %x\n", + inst, inst->cur_cmd_type, + kref_read(&inst->kref)); + break; + } + + if (inst != NULL) { + s = cvp_get_inst_validate(inst->core, inst); + if (!s) + return; + + call_hfi_op(hdev, flush_debug_queue, + hdev->hfi_device_data); + dump_hfi_queue(hdev->hfi_device_data); + msm_cvp_comm_kill_session(inst); + cvp_put_inst(s); + } else { + dprintk(CVP_WARN, "No active CVP session to abort\n"); + } + + return; + } + +send_again: + mutex_lock(&core->lock); + if (core->state == CVP_CORE_INIT_DONE) { + dprintk(CVP_WARN, "%s: ssr type %d\n", __func__, + core->ssr_type); + /* + * In current implementation user-initiated SSR triggers + * a fatal error from hardware. However, there is no way + * to know if fatal error is due to SSR or not. Handle + * user SSR as non-fatal. + */ + core->trigger_ssr = true; + rc = call_hfi_op(hdev, core_trigger_ssr, + hdev->hfi_device_data, core->ssr_type); + if (rc) { + if (rc == -EAGAIN) { + core->trigger_ssr = false; + mutex_unlock(&core->lock); + usleep_range(500, 1000); + dprintk(CVP_WARN, "Retry ssr\n"); + goto send_again; + } + dprintk(CVP_ERR, "%s: trigger_ssr failed\n", + __func__); + core->trigger_ssr = false; + } + } else { + dprintk(CVP_WARN, "%s: cvp core %pK not initialized\n", + __func__, core); + } + mutex_unlock(&core->lock); +} + +void msm_cvp_comm_generate_session_error(struct msm_cvp_inst *inst) +{ + enum hal_command_response cmd = HAL_SESSION_ERROR; + struct msm_cvp_cb_cmd_done response = {0}; + + if (!inst || !inst->core) { + dprintk(CVP_ERR, "%s: invalid input parameters\n", __func__); + return; + } + dprintk(CVP_WARN, "%s: inst %pK\n", __func__, inst); + response.session_id = inst; + response.status = CVP_ERR_FAIL; + handle_session_error(cmd, (void *)&response); +} + +void msm_cvp_comm_generate_sys_error(struct msm_cvp_inst *inst) +{ + struct msm_cvp_core *core; + enum hal_command_response cmd = HAL_SYS_ERROR; + struct msm_cvp_cb_cmd_done response = {0}; + + if (!inst || !inst->core) { + dprintk(CVP_ERR, "%s: invalid input parameters\n", __func__); + return; + } + dprintk(CVP_WARN, "%s: inst %pK\n", __func__, inst); + core = inst->core; + response.device_id = (u32) core->id; + handle_sys_error(cmd, (void *) &response); + +} + +int msm_cvp_comm_kill_session(struct msm_cvp_inst *inst) +{ + int rc = 0; + unsigned long flags = 0; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(CVP_ERR, "%s: invalid input parameters\n", __func__); + return -EINVAL; + } else if (!inst->session) { + dprintk(CVP_ERR, "%s: no session to kill for inst %pK\n", + __func__, inst); + return 0; + } + dprintk(CVP_WARN, "%s: inst %pK, session %x state %d\n", __func__, + inst, hash32_ptr(inst->session), inst->state); + /* + * We're internally forcibly killing the session, if fw is aware of + * the session send session_abort to firmware to clean up and release + * the session, else just kill the session inside the driver. + */ + if (inst->state >= MSM_CVP_OPEN_DONE && + inst->state < MSM_CVP_CLOSE_DONE) { + rc = msm_comm_session_abort(inst); + if (rc) { + dprintk(CVP_ERR, + "%s: inst %pK session %x abort failed\n", + __func__, inst, hash32_ptr(inst->session)); + change_cvp_inst_state(inst, MSM_CVP_CORE_INVALID); + } else { + change_cvp_inst_state(inst, MSM_CVP_CORE_UNINIT); + } + } + + if (inst->state >= MSM_CVP_CORE_UNINIT) { + spin_lock_irqsave(&inst->event_handler.lock, flags); + inst->event_handler.event = CVP_SSR_EVENT; + spin_unlock_irqrestore(&inst->event_handler.lock, flags); + wake_up_all(&inst->event_handler.wq); + } + + return rc; +} + +void msm_cvp_fw_unload_handler(struct work_struct *work) +{ + struct msm_cvp_core *core = NULL; + struct cvp_hfi_device *hdev = NULL; + int rc = 0; + + core = container_of(work, struct msm_cvp_core, fw_unload_work.work); + if (!core || !core->device) { + dprintk(CVP_ERR, "%s - invalid work or core handle\n", + __func__); + return; + } + + hdev = core->device; + + mutex_lock(&core->lock); + if (list_empty(&core->instances) && + core->state != CVP_CORE_UNINIT) { + if (core->state > CVP_CORE_INIT) { + dprintk(CVP_CORE, "Calling cvp_hal_core_release\n"); + rc = call_hfi_op(hdev, core_release, + hdev->hfi_device_data); + if (rc) { + dprintk(CVP_ERR, + "Failed to release core, id = %d\n", + core->id); + mutex_unlock(&core->lock); + return; + } + } + core->state = CVP_CORE_UNINIT; + kfree(core->capabilities); + core->capabilities = NULL; + } + mutex_unlock(&core->lock); +} + +static int set_internal_buf_on_fw(struct msm_cvp_inst *inst, + struct msm_cvp_smem *handle) +{ + struct cvp_hfi_device *hdev; + int rc = 0; + u32 iova; + u32 size; + + if (!inst || !inst->core || !inst->core->device || !handle) { + dprintk(CVP_ERR, "%s - invalid params\n", __func__); + return -EINVAL; + } + + hdev = inst->core->device; + + iova = handle->device_addr; + size = handle->size; + + dprintk(CVP_SESS, "%s: allocated ARP buffer : %x\n", __func__, iova); + + rc = call_hfi_op(hdev, session_set_buffers, + (void *) inst->session, iova, size); + if (rc) { + dprintk(CVP_ERR, "cvp_session_set_buffers failed\n"); + return rc; + } + return 0; +} + +/* Set ARP buffer for CVP firmware to handle concurrency */ +int cvp_comm_set_arp_buffers(struct msm_cvp_inst *inst) +{ + int rc = 0; + struct cvp_internal_buf *buf; + + if (!inst || !inst->core || !inst->core->device) { + dprintk(CVP_ERR, "%s invalid parameters\n", __func__); + return -EINVAL; + } + + buf = cvp_allocate_arp_bufs(inst, ARP_BUF_SIZE); + if (!buf) { + rc = -ENOMEM; + goto error; + } + + rc = set_internal_buf_on_fw(inst, buf->smem); + if (rc) + goto error; + + rc = wait_for_sess_signal_receipt(inst, HAL_SESSION_SET_BUFFER_DONE); + if (rc) { + dprintk(CVP_WARN, "wait for set_buffer_done timeout %d\n", rc); + goto error; + } + + return rc; + +error: + cvp_release_arp_buffers(inst); + return rc; +} + + + + diff --git a/msm/eva/msm_cvp_common.h b/msm/eva/msm_cvp_common.h new file mode 100644 index 0000000000..bfef327fc9 --- /dev/null +++ b/msm/eva/msm_cvp_common.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + + +#ifndef _MSM_CVP_COMMON_H_ +#define _MSM_CVP_COMMON_H_ +#include "msm_cvp_internal.h" + +void cvp_put_inst(struct msm_cvp_inst *inst); +struct msm_cvp_inst *cvp_get_inst(struct msm_cvp_core *core, + void *session_id); +struct msm_cvp_inst *cvp_get_inst_validate(struct msm_cvp_core *core, + void *session_id); +void cvp_change_inst_state(struct msm_cvp_inst *inst, + enum instance_state state); +struct msm_cvp_core *get_cvp_core(int core_id); +int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state); +int msm_cvp_deinit_core(struct msm_cvp_inst *inst); +int msm_cvp_comm_suspend(int core_id); +void msm_cvp_comm_session_clean(struct msm_cvp_inst *inst); +int msm_cvp_comm_kill_session(struct msm_cvp_inst *inst); +void msm_cvp_comm_generate_session_error(struct msm_cvp_inst *inst); +void msm_cvp_comm_generate_sys_error(struct msm_cvp_inst *inst); +int msm_cvp_comm_smem_cache_operations(struct msm_cvp_inst *inst, + struct msm_cvp_smem *mem, enum smem_cache_ops cache_ops); +int msm_cvp_comm_check_core_init(struct msm_cvp_core *core); +int wait_for_sess_signal_receipt(struct msm_cvp_inst *inst, + enum hal_command_response cmd); +int cvp_comm_set_arp_buffers(struct msm_cvp_inst *inst); +int cvp_comm_release_persist_buffers(struct msm_cvp_inst *inst); +int msm_cvp_noc_error_info(struct msm_cvp_core *core); +#endif diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c new file mode 100644 index 0000000000..72315f6e9a --- /dev/null +++ b/msm/eva/msm_cvp_core.c @@ -0,0 +1,394 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include "msm_cvp_core.h" +#include "msm_cvp_internal.h" +#include "msm_cvp_debug.h" +#include "msm_cvp.h" +#include "msm_cvp_common.h" +#include +#include "cvp_hfi_api.h" +#include "msm_cvp_clocks.h" +#include +#include + +#define MAX_EVENTS 30 +#define NUM_CYCLES16X16_HCD_FRAME 95 +#define NUM_CYCLES16X16_DME_FRAME 600 +#define NUM_CYCLES16X16_NCC_FRAME 400 +#define NUM_CYCLES16X16_DS_FRAME 80 +#define NUM_CYCLESFW_FRAME 1680000 +#define NUM_DME_MAX_FEATURE_POINTS 500 +#define CYCLES_MARGIN_IN_POWEROF2 3 + +int msm_cvp_poll(void *instance, struct file *filp, + struct poll_table_struct *wait) +{ + return 0; +} +EXPORT_SYMBOL(msm_cvp_poll); + +int msm_cvp_private(void *cvp_inst, unsigned int cmd, + struct cvp_kmd_arg *arg) +{ + int rc = 0; + struct msm_cvp_inst *inst = (struct msm_cvp_inst *)cvp_inst; + + if (!inst || !arg) { + dprintk(CVP_ERR, "%s: invalid args\n", __func__); + return -EINVAL; + } + + rc = msm_cvp_handle_syscall(inst, arg); + + return rc; +} +EXPORT_SYMBOL(msm_cvp_private); + +static bool msm_cvp_check_for_inst_overload(struct msm_cvp_core *core) +{ + u32 instance_count = 0; + u32 secure_instance_count = 0; + struct msm_cvp_inst *inst = NULL; + bool overload = false; + + mutex_lock(&core->lock); + list_for_each_entry(inst, &core->instances, list) { + instance_count++; + /* This flag is not updated yet for the current instance */ + if (inst->flags & CVP_SECURE) + secure_instance_count++; + } + mutex_unlock(&core->lock); + + /* Instance count includes current instance as well. */ + + if ((instance_count >= core->resources.max_inst_count) || + (secure_instance_count >= + core->resources.max_secure_inst_count)) + overload = true; + return overload; +} + +static int __init_session_queue(struct msm_cvp_inst *inst) +{ + spin_lock_init(&inst->session_queue.lock); + INIT_LIST_HEAD(&inst->session_queue.msgs); + inst->session_queue.msg_count = 0; + init_waitqueue_head(&inst->session_queue.wq); + inst->session_queue.state = QUEUE_ACTIVE; + return 0; +} + +static void __init_fence_queue(struct msm_cvp_inst *inst) +{ + mutex_init(&inst->fence_cmd_queue.lock); + INIT_LIST_HEAD(&inst->fence_cmd_queue.wait_list); + INIT_LIST_HEAD(&inst->fence_cmd_queue.sched_list); + init_waitqueue_head(&inst->fence_cmd_queue.wq); + inst->fence_cmd_queue.state = QUEUE_ACTIVE; + inst->fence_cmd_queue.mode = OP_NORMAL; + + spin_lock_init(&inst->session_queue_fence.lock); + INIT_LIST_HEAD(&inst->session_queue_fence.msgs); + inst->session_queue_fence.msg_count = 0; + init_waitqueue_head(&inst->session_queue_fence.wq); + inst->session_queue_fence.state = QUEUE_ACTIVE; +} + +static void __deinit_fence_queue(struct msm_cvp_inst *inst) +{ + mutex_destroy(&inst->fence_cmd_queue.lock); + inst->fence_cmd_queue.state = QUEUE_INVALID; + inst->fence_cmd_queue.mode = OP_INVALID; +} + +static void __deinit_session_queue(struct msm_cvp_inst *inst) +{ + struct cvp_session_msg *msg, *tmpmsg; + + /* free all messages */ + spin_lock(&inst->session_queue.lock); + list_for_each_entry_safe(msg, tmpmsg, &inst->session_queue.msgs, node) { + list_del_init(&msg->node); + kmem_cache_free(cvp_driver->msg_cache, msg); + } + inst->session_queue.msg_count = 0; + inst->session_queue.state = QUEUE_STOP; + spin_unlock(&inst->session_queue.lock); + + wake_up_all(&inst->session_queue.wq); +} + +void *msm_cvp_open(int core_id, int session_type) +{ + struct msm_cvp_inst *inst = NULL; + struct msm_cvp_core *core = NULL; + int rc = 0; + int i = 0; + + if (core_id >= MSM_CVP_CORES_MAX || + session_type >= MSM_CVP_MAX_DEVICES) { + dprintk(CVP_ERR, "Invalid input, core_id = %d, session = %d\n", + core_id, session_type); + goto err_invalid_core; + } + core = get_cvp_core(core_id); + if (!core) { + dprintk(CVP_ERR, + "Failed to find core for core_id = %d\n", core_id); + goto err_invalid_core; + } + + if (!core->resources.auto_pil && session_type == MSM_CVP_BOOT) { + dprintk(CVP_SESS, "Auto PIL disabled, bypass CVP init at boot"); + goto err_invalid_core; + } + + core->resources.max_inst_count = MAX_SUPPORTED_INSTANCES; + if (msm_cvp_check_for_inst_overload(core)) { + dprintk(CVP_ERR, "Instance num reached Max, rejecting session"); + mutex_lock(&core->lock); + list_for_each_entry(inst, &core->instances, list) + dprintk(CVP_ERR, "inst %pK, cmd %d id %d\n", + inst, inst->cur_cmd_type, + hash32_ptr(inst->session)); + mutex_unlock(&core->lock); + + return NULL; + } + + inst = kzalloc(sizeof(*inst), GFP_KERNEL); + if (!inst) { + dprintk(CVP_ERR, "Failed to allocate memory\n"); + rc = -ENOMEM; + goto err_invalid_core; + } + + pr_info(CVP_DBG_TAG "Opening cvp instance: %pK\n", "sess", inst); + mutex_init(&inst->sync_lock); + mutex_init(&inst->lock); + spin_lock_init(&inst->event_handler.lock); + + INIT_MSM_CVP_LIST(&inst->persistbufs); + INIT_DMAMAP_CACHE(&inst->dma_cache); + INIT_MSM_CVP_LIST(&inst->cvpdspbufs); + INIT_MSM_CVP_LIST(&inst->frames); + + init_waitqueue_head(&inst->event_handler.wq); + + kref_init(&inst->kref); + + inst->session_type = session_type; + inst->state = MSM_CVP_CORE_UNINIT_DONE; + inst->core = core; + inst->clk_data.min_freq = 0; + inst->clk_data.curr_freq = 0; + inst->clk_data.ddr_bw = 0; + inst->clk_data.sys_cache_bw = 0; + inst->clk_data.bitrate = 0; + inst->clk_data.core_id = 0; + + for (i = SESSION_MSG_INDEX(SESSION_MSG_START); + i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) { + init_completion(&inst->completions[i]); + } + + msm_cvp_session_init(inst); + + mutex_lock(&core->lock); + list_add_tail(&inst->list, &core->instances); + mutex_unlock(&core->lock); + + __init_fence_queue(inst); + + rc = __init_session_queue(inst); + if (rc) + goto fail_init; + + rc = msm_cvp_comm_try_state(inst, MSM_CVP_CORE_INIT_DONE); + if (rc) { + dprintk(CVP_ERR, + "Failed to move cvp instance to init state\n"); + goto fail_init; + } + + inst->debugfs_root = + msm_cvp_debugfs_init_inst(inst, core->debugfs_root); + + return inst; +fail_init: + __deinit_session_queue(inst); + mutex_lock(&core->lock); + list_del(&inst->list); + mutex_unlock(&core->lock); + mutex_destroy(&inst->sync_lock); + mutex_destroy(&inst->lock); + + DEINIT_MSM_CVP_LIST(&inst->persistbufs); + DEINIT_DMAMAP_CACHE(&inst->dma_cache); + DEINIT_MSM_CVP_LIST(&inst->cvpdspbufs); + DEINIT_MSM_CVP_LIST(&inst->frames); + + kfree(inst); + inst = NULL; +err_invalid_core: + return inst; +} +EXPORT_SYMBOL(msm_cvp_open); + +static void msm_cvp_clean_sess_queue(struct msm_cvp_inst *inst, + struct cvp_session_queue *sq) +{ + struct cvp_session_msg *mptr, *dummy; + u64 ktid; + + spin_lock(&sq->lock); + if (sq->msg_count && sq->state != QUEUE_ACTIVE) { + list_for_each_entry_safe(mptr, dummy, &sq->msgs, node) { + ktid = mptr->pkt.client_data.kdata; + if (ktid) { + list_del_init(&mptr->node); + sq->msg_count--; + msm_cvp_unmap_frame(inst, ktid); + kmem_cache_free(cvp_driver->msg_cache, mptr); + } + } + } + spin_unlock(&sq->lock); +} + +static void msm_cvp_cleanup_instance(struct msm_cvp_inst *inst) +{ + bool empty; + int max_retries; + struct msm_cvp_frame *frame; + struct cvp_session_queue *sq, *sqf; + + if (!inst) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return; + } + + sqf = &inst->session_queue_fence; + sq = &inst->session_queue; + + max_retries = inst->core->resources.msm_cvp_hw_rsp_timeout >> 1; + msm_cvp_session_queue_stop(inst); + +wait: + mutex_lock(&inst->frames.lock); + empty = list_empty(&inst->frames.list); + if (!empty && max_retries > 0) { + mutex_unlock(&inst->frames.lock); + usleep_range(1000, 2000); + msm_cvp_clean_sess_queue(inst, sqf); + msm_cvp_clean_sess_queue(inst, sq); + max_retries--; + goto wait; + } + mutex_unlock(&inst->frames.lock); + + if (!empty) { + dprintk(CVP_WARN, + "Failed to process frames before session close\n"); + mutex_lock(&inst->frames.lock); + list_for_each_entry(frame, &inst->frames.list, list) + dprintk(CVP_WARN, "Unprocessed frame %d\n", + frame->pkt_type); + mutex_unlock(&inst->frames.lock); + cvp_dump_fence_queue(inst); + } + + if (cvp_release_arp_buffers(inst)) + dprintk(CVP_ERR, + "Failed to release persist buffers\n"); +} + +int msm_cvp_destroy(struct msm_cvp_inst *inst) +{ + struct msm_cvp_core *core; + + if (!inst || !inst->core) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + core = inst->core; + + mutex_lock(&core->lock); + /* inst->list lives in core->instances */ + list_del(&inst->list); + mutex_unlock(&core->lock); + + DEINIT_MSM_CVP_LIST(&inst->persistbufs); + DEINIT_DMAMAP_CACHE(&inst->dma_cache); + DEINIT_MSM_CVP_LIST(&inst->cvpdspbufs); + DEINIT_MSM_CVP_LIST(&inst->frames); + + mutex_destroy(&inst->sync_lock); + mutex_destroy(&inst->lock); + + msm_cvp_debugfs_deinit_inst(inst); + + __deinit_session_queue(inst); + __deinit_fence_queue(inst); + synx_uninitialize(inst->synx_session_id); + + pr_info(CVP_DBG_TAG "Closed cvp instance: %pK session_id = %d\n", + "sess", inst, hash32_ptr(inst->session)); + if (inst->cur_cmd_type) + dprintk(CVP_ERR, "deleted instance has pending cmd %d\n", + inst->cur_cmd_type); + inst->session = (void *)0xdeadbeef; + kfree(inst); + return 0; +} + +static void close_helper(struct kref *kref) +{ + struct msm_cvp_inst *inst = container_of(kref, + struct msm_cvp_inst, kref); + + msm_cvp_destroy(inst); +} + +int msm_cvp_close(void *instance) +{ + struct msm_cvp_inst *inst = instance; + int rc = 0; + + if (!inst || !inst->core) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + if (inst->session_type != MSM_CVP_BOOT) { + msm_cvp_cleanup_instance(inst); + msm_cvp_session_deinit(inst); + } + + rc = msm_cvp_comm_try_state(inst, MSM_CVP_CORE_UNINIT); + if (rc) { + dprintk(CVP_ERR, + "Failed to move inst %pK to uninit state\n", inst); + rc = msm_cvp_deinit_core(inst); + } + + msm_cvp_comm_session_clean(inst); + + kref_put(&inst->kref, close_helper); + return 0; +} +EXPORT_SYMBOL(msm_cvp_close); + +int msm_cvp_suspend(int core_id) +{ + return msm_cvp_comm_suspend(core_id); +} +EXPORT_SYMBOL(msm_cvp_suspend); diff --git a/msm/eva/msm_cvp_core.h b/msm/eva/msm_cvp_core.h new file mode 100644 index 0000000000..215b16df49 --- /dev/null +++ b/msm/eva/msm_cvp_core.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _MSM_CVP_CORE_H_ +#define _MSM_CVP_CORE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include "msm_cvp_buf.h" +#include "msm_cvp_synx.h" + +enum core_id { + MSM_CORE_CVP = 0, + MSM_CVP_CORES_MAX, +}; + +enum session_type { + MSM_CVP_USER = 1, + MSM_CVP_KERNEL, + MSM_CVP_BOOT, + MSM_CVP_UNKNOWN, + MSM_CVP_MAX_DEVICES = MSM_CVP_UNKNOWN, +}; + +void *msm_cvp_open(int core_id, int session_type); +int msm_cvp_close(void *instance); +int msm_cvp_suspend(int core_id); +int msm_cvp_poll(void *instance, struct file *filp, + struct poll_table_struct *pt); +int msm_cvp_private(void *cvp_inst, unsigned int cmd, + struct cvp_kmd_arg *arg); + +#endif diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c new file mode 100644 index 0000000000..64f882a5d1 --- /dev/null +++ b/msm/eva/msm_cvp_debug.c @@ -0,0 +1,540 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#include +#include "msm_cvp_debug.h" +#include "msm_cvp_common.h" +#include "cvp_core_hfi.h" +#include "cvp_hfi_api.h" + +#define CREATE_TRACE_POINTS +#define MAX_SSR_STRING_LEN 10 +int msm_cvp_debug = CVP_ERR | CVP_WARN | CVP_FW; +EXPORT_SYMBOL(msm_cvp_debug); + +int msm_cvp_debug_out = CVP_OUT_PRINTK; +EXPORT_SYMBOL(msm_cvp_debug_out); + +int msm_cvp_fw_debug = 0x18; +int msm_cvp_fw_debug_mode = 1; +int msm_cvp_fw_low_power_mode = 1; +bool msm_cvp_fw_coverage = !true; +bool msm_cvp_thermal_mitigation_disabled = !true; +bool msm_cvp_cacheop_disabled = true; +int msm_cvp_clock_voting = !1; +bool msm_cvp_syscache_disable = !true; +bool msm_cvp_dsp_disable = !true; + +#define MAX_DBG_BUF_SIZE 4096 + +struct cvp_core_inst_pair { + struct msm_cvp_core *core; + struct msm_cvp_inst *inst; +}; + +static int core_info_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + dprintk(CVP_INFO, "%s: Enter\n", __func__); + return 0; +} + +static u32 write_str(char *buffer, + size_t size, const char *fmt, ...) +{ + va_list args; + u32 len; + + va_start(args, fmt); + len = vscnprintf(buffer, size, fmt, args); + va_end(args); + return len; +} + +static ssize_t core_info_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + struct msm_cvp_core *core = file->private_data; + struct cvp_hfi_device *hdev; + struct cvp_hal_fw_info fw_info = { {0} }; + char *dbuf, *cur, *end; + int i = 0, rc = 0; + ssize_t len = 0; + + if (!core || !core->device) { + dprintk(CVP_ERR, "Invalid params, core: %pK\n", core); + return 0; + } + + dbuf = kzalloc(MAX_DBG_BUF_SIZE, GFP_KERNEL); + if (!dbuf) { + dprintk(CVP_ERR, "%s: Allocation failed!\n", __func__); + return -ENOMEM; + } + cur = dbuf; + end = cur + MAX_DBG_BUF_SIZE; + hdev = core->device; + + cur += write_str(cur, end - cur, "===============================\n"); + cur += write_str(cur, end - cur, "CORE %d: %pK\n", core->id, core); + cur += write_str(cur, end - cur, "===============================\n"); + cur += write_str(cur, end - cur, "Core state: %d\n", core->state); + rc = call_hfi_op(hdev, get_fw_info, hdev->hfi_device_data, &fw_info); + if (rc) { + dprintk(CVP_WARN, "Failed to read FW info\n"); + goto err_fw_info; + } + + cur += write_str(cur, end - cur, + "FW version : %s\n", &fw_info.version); + cur += write_str(cur, end - cur, + "base addr: 0x%x\n", fw_info.base_addr); + cur += write_str(cur, end - cur, + "register_base: 0x%x\n", fw_info.register_base); + cur += write_str(cur, end - cur, + "register_size: %u\n", fw_info.register_size); + cur += write_str(cur, end - cur, "irq: %u\n", fw_info.irq); + +err_fw_info: + for (i = SYS_MSG_START; i < SYS_MSG_END; i++) { + cur += write_str(cur, end - cur, "completions[%d]: %s\n", i, + completion_done(&core->completions[SYS_MSG_INDEX(i)]) ? + "pending" : "done"); + } + len = simple_read_from_buffer(buf, count, ppos, + dbuf, cur - dbuf); + + kfree(dbuf); + return len; +} + +static const struct file_operations core_info_fops = { + .open = core_info_open, + .read = core_info_read, +}; + +static int trigger_ssr_open(struct inode *inode, struct file *file) +{ + file->private_data = inode->i_private; + dprintk(CVP_INFO, "%s: Enter\n", __func__); + return 0; +} + +static ssize_t trigger_ssr_write(struct file *filp, const char __user *buf, + size_t count, loff_t *ppos) +{ + unsigned long ssr_trigger_val = 0; + int rc = 0; + struct msm_cvp_core *core = filp->private_data; + size_t size = MAX_SSR_STRING_LEN; + char kbuf[MAX_SSR_STRING_LEN + 1] = {0}; + + if (!buf) + return -EINVAL; + + if (!count) + goto exit; + + if (count < size) + size = count; + + if (copy_from_user(kbuf, buf, size)) { + dprintk(CVP_WARN, "%s User memory fault\n", __func__); + rc = -EFAULT; + goto exit; + } + + rc = kstrtoul(kbuf, 0, &ssr_trigger_val); + if (rc) { + dprintk(CVP_WARN, "returning error err %d\n", rc); + rc = -EINVAL; + } else { + msm_cvp_trigger_ssr(core, ssr_trigger_val); + rc = count; + } +exit: + return rc; +} + +static const struct file_operations ssr_fops = { + .open = trigger_ssr_open, + .write = trigger_ssr_write, +}; + +static int cvp_power_get(void *data, u64 *val) +{ + struct cvp_hfi_device *hfi_ops; + struct msm_cvp_core *core; + struct iris_hfi_device *hfi_device; + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (!core) + return 0; + hfi_ops = core->device; + if (!hfi_ops) + return 0; + + hfi_device = hfi_ops->hfi_device_data; + if (!hfi_device) + return 0; + + *val = hfi_device->power_enabled; + return 0; +} + +#define MIN_PC_INTERVAL 1000 +#define MAX_PC_INTERVAL 1000000 + +static int cvp_power_set(void *data, u64 val) +{ + struct cvp_hfi_device *hfi_ops; + struct msm_cvp_core *core; + struct iris_hfi_device *hfi_device; + int rc = 0; + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (!core) + return -EINVAL; + + hfi_ops = core->device; + if (!hfi_ops) + return -EINVAL; + + hfi_device = hfi_ops->hfi_device_data; + if (!hfi_device) + return -EINVAL; + + if (val >= MAX_PC_INTERVAL) { + hfi_device->res->sw_power_collapsible = 0; + } else if (val > MIN_PC_INTERVAL) { + hfi_device->res->sw_power_collapsible = 1; + hfi_device->res->msm_cvp_pwr_collapse_delay = + (unsigned int)val; + } + + if (core->state == CVP_CORE_UNINIT) + return -EINVAL; + + if (val > 0) { + rc = call_hfi_op(hfi_ops, resume, hfi_ops->hfi_device_data); + if (rc) + dprintk(CVP_ERR, "debugfs fail to power on cvp\n"); + } + return rc; +} + +DEFINE_DEBUGFS_ATTRIBUTE(cvp_pwr_fops, cvp_power_get, cvp_power_set, "%llu\n"); + +struct dentry *msm_cvp_debugfs_init_drv(void) +{ + bool ok = false; + struct dentry *dir = NULL; + + dir = debugfs_create_dir("msm_cvp", NULL); + if (IS_ERR_OR_NULL(dir)) { + dir = NULL; + goto failed_create_dir; + } + +#define __debugfs_create(__type, __name, __value) ({ \ + struct dentry *f = debugfs_create_##__type(__name, 0644, \ + dir, __value); \ + if (IS_ERR_OR_NULL(f)) { \ + dprintk(CVP_ERR, "Failed creating debugfs file '%pd/%s'\n", \ + dir, __name); \ + f = NULL; \ + } \ + f; \ +}) + + ok = + __debugfs_create(x32, "debug_level", &msm_cvp_debug) && + __debugfs_create(x32, "fw_level", &msm_cvp_fw_debug) && + __debugfs_create(u32, "fw_debug_mode", &msm_cvp_fw_debug_mode) && + __debugfs_create(bool, "fw_coverage", &msm_cvp_fw_coverage) && + __debugfs_create(u32, "fw_low_power_mode", + &msm_cvp_fw_low_power_mode) && + __debugfs_create(u32, "debug_output", &msm_cvp_debug_out) && + __debugfs_create(bool, "disable_thermal_mitigation", + &msm_cvp_thermal_mitigation_disabled) && + __debugfs_create(bool, "disable_cacheop", + &msm_cvp_cacheop_disabled) && + __debugfs_create(bool, "disable_cvp_syscache", + &msm_cvp_syscache_disable); + +#undef __debugfs_create + + if (!ok) + goto failed_create_dir; + + debugfs_create_file("cvp_power", 0644, dir, NULL, &cvp_pwr_fops); + + return dir; + +failed_create_dir: + if (dir) + debugfs_remove_recursive(cvp_driver->debugfs_root); + + return NULL; +} + +static int _clk_rate_set(void *data, u64 val) +{ + struct msm_cvp_core *core; + struct cvp_hfi_device *dev; + struct allowed_clock_rates_table *tbl = NULL; + unsigned int tbl_size, i; + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + dev = core->device; + tbl = core->resources.allowed_clks_tbl; + tbl_size = core->resources.allowed_clks_tbl_size; + + if (val == 0) { + struct iris_hfi_device *hdev = dev->hfi_device_data; + + msm_cvp_clock_voting = 0; + call_hfi_op(dev, scale_clocks, hdev, hdev->clk_freq); + return 0; + } + + for (i = 0; i < tbl_size; i++) + if (val <= tbl[i].clock_rate) + break; + + if (i == tbl_size) + msm_cvp_clock_voting = tbl[tbl_size-1].clock_rate; + else + msm_cvp_clock_voting = tbl[i].clock_rate; + + dprintk(CVP_WARN, "Override cvp_clk_rate with %d\n", + msm_cvp_clock_voting); + + call_hfi_op(dev, scale_clocks, dev->hfi_device_data, + msm_cvp_clock_voting); + + return 0; +} + +static int _clk_rate_get(void *data, u64 *val) +{ + struct msm_cvp_core *core; + struct iris_hfi_device *hdev; + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + hdev = core->device->hfi_device_data; + if (msm_cvp_clock_voting) + *val = msm_cvp_clock_voting; + else + *val = hdev->clk_freq; + + return 0; +} + +DEFINE_DEBUGFS_ATTRIBUTE(clk_rate_fops, _clk_rate_get, _clk_rate_set, "%llu\n"); + + +struct dentry *msm_cvp_debugfs_init_core(struct msm_cvp_core *core, + struct dentry *parent) +{ + struct dentry *dir = NULL; + char debugfs_name[MAX_DEBUGFS_NAME]; + + if (!core) { + dprintk(CVP_ERR, "Invalid params, core: %pK\n", core); + goto failed_create_dir; + } + + snprintf(debugfs_name, MAX_DEBUGFS_NAME, "core%d", core->id); + dir = debugfs_create_dir(debugfs_name, parent); + if (IS_ERR_OR_NULL(dir)) { + dir = NULL; + dprintk(CVP_ERR, "Failed to create debugfs for msm_cvp\n"); + goto failed_create_dir; + } + if (!debugfs_create_file("info", 0444, dir, core, &core_info_fops)) { + dprintk(CVP_ERR, "debugfs_create_file: fail\n"); + goto failed_create_dir; + } + if (!debugfs_create_file("trigger_ssr", 0200, + dir, core, &ssr_fops)) { + dprintk(CVP_ERR, "debugfs_create_file: fail\n"); + goto failed_create_dir; + } + if (!debugfs_create_file("clock_rate", 0644, dir, + NULL, &clk_rate_fops)) { + dprintk(CVP_ERR, "debugfs_create_file: clock_rate fail\n"); + goto failed_create_dir; + } + +failed_create_dir: + return dir; +} + +static int inst_info_open(struct inode *inode, struct file *file) +{ + dprintk(CVP_INFO, "Open inode ptr: %pK\n", inode->i_private); + file->private_data = inode->i_private; + return 0; +} + +static int publish_unreleased_reference(struct msm_cvp_inst *inst, + char **dbuf, char *end) +{ + dprintk(CVP_SESS, "%s deprecated function\n", __func__); + return 0; +} + +static void put_inst_helper(struct kref *kref) +{ + struct msm_cvp_inst *inst = container_of(kref, + struct msm_cvp_inst, kref); + + msm_cvp_destroy(inst); +} + +static ssize_t inst_info_read(struct file *file, char __user *buf, + size_t count, loff_t *ppos) +{ + struct cvp_core_inst_pair *idata = file->private_data; + struct msm_cvp_core *core; + struct msm_cvp_inst *inst, *temp = NULL; + char *dbuf, *cur, *end; + int i; + ssize_t len = 0; + + if (!idata || !idata->core || !idata->inst) { + dprintk(CVP_ERR, "%s: Invalid params\n", __func__); + return 0; + } + + core = idata->core; + inst = idata->inst; + + mutex_lock(&core->lock); + list_for_each_entry(temp, &core->instances, list) { + if (temp == inst) + break; + } + inst = ((temp == inst) && kref_get_unless_zero(&inst->kref)) ? + inst : NULL; + mutex_unlock(&core->lock); + + if (!inst) { + dprintk(CVP_ERR, "%s: Instance has become obsolete", __func__); + return 0; + } + + dbuf = kzalloc(MAX_DBG_BUF_SIZE, GFP_KERNEL); + if (!dbuf) { + dprintk(CVP_ERR, "%s: Allocation failed!\n", __func__); + len = -ENOMEM; + goto failed_alloc; + } + cur = dbuf; + end = cur + MAX_DBG_BUF_SIZE; + + cur += write_str(cur, end - cur, "==============================\n"); + cur += write_str(cur, end - cur, "INSTANCE: %pK (%s)\n", inst, + inst->session_type == MSM_CVP_USER ? "User" : "Kernel"); + cur += write_str(cur, end - cur, "==============================\n"); + cur += write_str(cur, end - cur, "core: %pK\n", inst->core); + cur += write_str(cur, end - cur, "state: %d\n", inst->state); + cur += write_str(cur, end - cur, "secure: %d\n", + !!(inst->flags & CVP_SECURE)); + for (i = SESSION_MSG_START; i < SESSION_MSG_END; i++) { + cur += write_str(cur, end - cur, "completions[%d]: %s\n", i, + completion_done(&inst->completions[SESSION_MSG_INDEX(i)]) ? + "pending" : "done"); + } + + publish_unreleased_reference(inst, &cur, end); + len = simple_read_from_buffer(buf, count, ppos, + dbuf, cur - dbuf); + + kfree(dbuf); +failed_alloc: + kref_put(&inst->kref, put_inst_helper); + return len; +} + +static int inst_info_release(struct inode *inode, struct file *file) +{ + dprintk(CVP_INFO, "Release inode ptr: %pK\n", inode->i_private); + file->private_data = NULL; + return 0; +} + +static const struct file_operations inst_info_fops = { + .open = inst_info_open, + .read = inst_info_read, + .release = inst_info_release, +}; + +struct dentry *msm_cvp_debugfs_init_inst(struct msm_cvp_inst *inst, + struct dentry *parent) +{ + struct dentry *dir = NULL, *info = NULL; + char debugfs_name[MAX_DEBUGFS_NAME]; + struct cvp_core_inst_pair *idata = NULL; + + if (!inst) { + dprintk(CVP_ERR, "Invalid params, inst: %pK\n", inst); + goto exit; + } + snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%p", inst); + + idata = kzalloc(sizeof(*idata), GFP_KERNEL); + if (!idata) { + dprintk(CVP_ERR, "%s: Allocation failed!\n", __func__); + goto exit; + } + + idata->core = inst->core; + idata->inst = inst; + + dir = debugfs_create_dir(debugfs_name, parent); + if (IS_ERR_OR_NULL(dir)) { + dir = NULL; + dprintk(CVP_ERR, "Failed to create debugfs for msm_cvp\n"); + goto failed_create_dir; + } + + info = debugfs_create_file("info", 0444, dir, + idata, &inst_info_fops); + if (!info) { + dprintk(CVP_ERR, "debugfs_create_file: info fail\n"); + goto failed_create_file; + } + + dir->d_inode->i_private = info->d_inode->i_private; + inst->debug.pdata[FRAME_PROCESSING].sampling = true; + return dir; + +failed_create_file: + debugfs_remove_recursive(dir); + dir = NULL; +failed_create_dir: + kfree(idata); +exit: + return dir; +} + +void msm_cvp_debugfs_deinit_inst(struct msm_cvp_inst *inst) +{ + struct dentry *dentry = NULL; + + if (!inst || !inst->debugfs_root) + return; + + dentry = inst->debugfs_root; + if (dentry->d_inode) { + dprintk(CVP_INFO, "Destroy %pK\n", dentry->d_inode->i_private); + kfree(dentry->d_inode->i_private); + dentry->d_inode->i_private = NULL; + } + debugfs_remove_recursive(dentry); + inst->debugfs_root = NULL; +} diff --git a/msm/eva/msm_cvp_debug.h b/msm/eva/msm_cvp_debug.h new file mode 100644 index 0000000000..05f60007d1 --- /dev/null +++ b/msm/eva/msm_cvp_debug.h @@ -0,0 +1,181 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#ifndef __MSM_CVP_DEBUG__ +#define __MSM_CVP_DEBUG__ +#include +#include +#include "msm_cvp_internal.h" +#include "trace/events/msm_cvp_events.h" + +#ifndef CVP_DBG_LABEL +#define CVP_DBG_LABEL "msm_cvp" +#endif + +#define CVP_DBG_TAG CVP_DBG_LABEL ": %4s: " + +/* To enable messages OR these values and + * echo the result to debugfs file. + * + * To enable all messages set debug_level = 0x101F + */ + +enum cvp_msg_prio { + CVP_ERR = 0x000001, + CVP_WARN = 0x000002, + CVP_INFO = 0x000004, + CVP_PROF = 0x000010, + CVP_PKT = 0x000020, + CVP_MEM = 0x000040, + CVP_SYNX = 0x000080, + CVP_CORE = 0x000100, + CVP_REG = 0x000200, + CVP_PWR = 0x000400, + CVP_DSP = 0x000800, + CVP_FW = 0x001000, + CVP_SESS = 0x002000, + CVP_HFI = 0x004000, + CVP_DBG = CVP_MEM | CVP_SYNX | CVP_CORE | CVP_REG | + CVP_PWR | CVP_DSP | CVP_SESS | CVP_HFI, +}; + +enum cvp_msg_out { + CVP_OUT_PRINTK = 0, +}; + +enum msm_cvp_debugfs_event { + MSM_CVP_DEBUGFS_EVENT_ETB, + MSM_CVP_DEBUGFS_EVENT_EBD, + MSM_CVP_DEBUGFS_EVENT_FTB, + MSM_CVP_DEBUGFS_EVENT_FBD, +}; + +extern int msm_cvp_debug; +extern int msm_cvp_debug_out; +extern int msm_cvp_fw_debug; +extern int msm_cvp_fw_debug_mode; +extern int msm_cvp_fw_low_power_mode; +extern bool msm_cvp_fw_coverage; +extern bool msm_cvp_thermal_mitigation_disabled; +extern bool msm_cvp_cacheop_disabled; +extern int msm_cvp_clock_voting; +extern bool msm_cvp_syscache_disable; +extern bool msm_cvp_dsp_disable; + +#define dprintk(__level, __fmt, arg...) \ + do { \ + if (msm_cvp_debug & __level) { \ + if (msm_cvp_debug_out == CVP_OUT_PRINTK) { \ + pr_info(CVP_DBG_TAG __fmt, \ + get_debug_level_str(__level), \ + ## arg); \ + } \ + } \ + } while (0) + +#define MSM_CVP_ERROR(value) \ + do { if (value) \ + dprintk(CVP_ERR, "BugOn"); \ + WARN_ON(value); \ + } while (0) + + +struct dentry *msm_cvp_debugfs_init_drv(void); +struct dentry *msm_cvp_debugfs_init_core(struct msm_cvp_core *core, + struct dentry *parent); +struct dentry *msm_cvp_debugfs_init_inst(struct msm_cvp_inst *inst, + struct dentry *parent); +void msm_cvp_debugfs_deinit_inst(struct msm_cvp_inst *inst); + +static inline char *get_debug_level_str(int level) +{ + switch (level) { + case CVP_ERR: + return "err"; + case CVP_WARN: + return "warn"; + case CVP_INFO: + return "info"; + case CVP_DBG: + return "dbg"; + case CVP_PROF: + return "prof"; + case CVP_PKT: + return "pkt"; + case CVP_MEM: + return "mem"; + case CVP_SYNX: + return "synx"; + case CVP_CORE: + return "core"; + case CVP_REG: + return "reg"; + case CVP_PWR: + return "pwr"; + case CVP_DSP: + return "dsp"; + case CVP_FW: + return "fw"; + case CVP_SESS: + return "sess"; + case CVP_HFI: + return "hfi"; + default: + return "???"; + } +} + +static inline void show_stats(struct msm_cvp_inst *i) +{ + int x; + + for (x = 0; x < MAX_PROFILING_POINTS; x++) { + if (i->debug.pdata[x].name[0] && + (msm_cvp_debug & CVP_PROF)) { + if (i->debug.samples) { + dprintk(CVP_PROF, "%s averaged %d ms/sample\n", + i->debug.pdata[x].name, + i->debug.pdata[x].cumulative / + i->debug.samples); + } + + dprintk(CVP_PROF, "%s Samples: %d\n", + i->debug.pdata[x].name, + i->debug.samples); + } + } +} + +static inline void msm_cvp_res_handle_fatal_hw_error( + struct msm_cvp_platform_resources *resources, + bool enable_fatal) +{ + enable_fatal &= resources->debug_timeout; + MSM_CVP_ERROR(enable_fatal); +} + +static inline void msm_cvp_handle_hw_error(struct msm_cvp_core *core) +{ + bool enable_fatal = true; + + /* + * In current implementation user-initiated SSR triggers + * a fatal error from hardware. However, there is no way + * to know if fatal error is due to SSR or not. Handle + * user SSR as non-fatal. + */ + if (core->trigger_ssr) { + core->trigger_ssr = false; + enable_fatal = false; + } + + /* CVP driver can decide FATAL handling of HW errors + * based on multiple factors. This condition check will + * be enhanced later. + */ + msm_cvp_res_handle_fatal_hw_error(&core->resources, enable_fatal); +} + +#endif diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c new file mode 100644 index 0000000000..ae39770344 --- /dev/null +++ b/msm/eva/msm_cvp_dsp.c @@ -0,0 +1,599 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ +#include +#include +#include +#include +#include +#include "msm_cvp_dsp.h" +#include "msm_cvp_internal.h" + +struct cvp_dsp_apps gfa_cv; +static int hlosVM[HLOS_VM_NUM] = {VMID_HLOS}; +static int dspVM[DSP_VM_NUM] = {VMID_HLOS, VMID_CDSP_Q6}; +static int dspVMperm[DSP_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC, + PERM_READ | PERM_WRITE | PERM_EXEC }; +static int hlosVMperm[HLOS_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC }; + +static int cvp_dsp_send_cmd(struct cvp_dsp_cmd_msg *cmd, uint32_t len) +{ + int rc = 0; + struct cvp_dsp_apps *me = &gfa_cv; + + dprintk(CVP_DSP, "%s: cmd = %d\n", __func__, cmd->type); + + if (IS_ERR_OR_NULL(me->chan)) { + dprintk(CVP_ERR, "%s: DSP GLink is not ready\n", __func__); + rc = -EINVAL; + goto exit; + } + rc = rpmsg_send(me->chan->ept, cmd, len); + if (rc) { + dprintk(CVP_ERR, "%s: DSP rpmsg_send failed rc=%d\n", + __func__, rc); + goto exit; + } + +exit: + return rc; +} + +static int cvp_dsp_send_cmd_sync(struct cvp_dsp_cmd_msg *cmd, uint32_t len) +{ + int rc = 0; + struct cvp_dsp_apps *me = &gfa_cv; + + dprintk(CVP_DSP, "%s: cmd = %d\n", __func__, cmd->type); + + me->pending_dsp2cpu_rsp.type = cmd->type; + rc = cvp_dsp_send_cmd(cmd, len); + if (rc) { + dprintk(CVP_ERR, "%s: cvp_dsp_send_cmd failed rc=%d\n", + __func__, rc); + goto exit; + } + + if (!wait_for_completion_timeout(&me->completions[cmd->type], + msecs_to_jiffies(CVP_DSP_RESPONSE_TIMEOUT))) { + dprintk(CVP_ERR, "%s cmd %d timeout\n", __func__, cmd->type); + rc = -ETIMEDOUT; + goto exit; + } + +exit: + me->pending_dsp2cpu_rsp.type = CVP_INVALID_RPMSG_TYPE; + return rc; +} + +static int cvp_dsp_send_cmd_hfi_queue(phys_addr_t *phys_addr, + uint32_t size_in_bytes) +{ + int rc = 0; + struct cvp_dsp_cmd_msg cmd; + + cmd.type = CPU2DSP_SEND_HFI_QUEUE; + cmd.msg_ptr = (uint64_t)phys_addr; + cmd.msg_ptr_len = size_in_bytes; + cmd.ddr_type = of_fdt_get_ddrtype(); + if (cmd.ddr_type < 0) { + dprintk(CVP_ERR, + "%s: Incorrect DDR type value %d\n", + __func__, cmd.ddr_type); + return -EINVAL; + } + + dprintk(CVP_DSP, + "%s: address of buffer, PA=0x%pK size_buff=%d ddr_type=%d\n", + __func__, phys_addr, size_in_bytes, cmd.ddr_type); + + rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg)); + if (rc) { + dprintk(CVP_ERR, + "%s: cvp_dsp_send_cmd failed rc = %d\n", + __func__, rc); + goto exit; + } +exit: + return rc; +} + +static int cvp_hyp_assign_to_dsp(uint64_t addr, uint32_t size) +{ + int rc = 0; + struct cvp_dsp_apps *me = &gfa_cv; + + if (!me->hyp_assigned) { + rc = hyp_assign_phys(addr, size, hlosVM, HLOS_VM_NUM, dspVM, + dspVMperm, DSP_VM_NUM); + if (rc) { + dprintk(CVP_ERR, "%s failed. rc=%d\n", __func__, rc); + return rc; + } + me->addr = addr; + me->size = size; + me->hyp_assigned = true; + } + + return rc; +} + +static int cvp_hyp_assign_from_dsp(void) +{ + int rc = 0; + struct cvp_dsp_apps *me = &gfa_cv; + + if (me->hyp_assigned) { + rc = hyp_assign_phys(me->addr, me->size, dspVM, DSP_VM_NUM, + hlosVM, hlosVMperm, HLOS_VM_NUM); + if (rc) { + dprintk(CVP_ERR, "%s failed. rc=%d\n", __func__, rc); + return rc; + } + me->addr = 0; + me->size = 0; + me->hyp_assigned = false; + } + + return rc; +} + +static int cvp_dsp_rpmsg_probe(struct rpmsg_device *rpdev) +{ + struct cvp_dsp_apps *me = &gfa_cv; + + if (strcmp(rpdev->dev.parent->of_node->name, "cdsp")) { + dprintk(CVP_ERR, + "%s: Failed to probe rpmsg device.Node name:%s\n", + __func__, rpdev->dev.parent->of_node->name); + return -EINVAL; + } + + mutex_lock(&me->lock); + me->chan = rpdev; + me->state = DSP_PROBED; + complete(&me->completions[CPU2DSP_MAX_CMD]); + mutex_unlock(&me->lock); + + return 0; +} + +static void cvp_dsp_rpmsg_remove(struct rpmsg_device *rpdev) +{ + struct cvp_dsp_apps *me = &gfa_cv; + + dprintk(CVP_WARN, "%s: CDSP SSR triggered\n", __func__); + + mutex_lock(&me->lock); + cvp_hyp_assign_from_dsp(); + + me->chan = NULL; + me->state = DSP_UNINIT; + mutex_unlock(&me->lock); + /* kernel driver needs clean all dsp sessions */ + +} + +static int cvp_dsp_rpmsg_callback(struct rpmsg_device *rpdev, + void *data, int len, void *priv, u32 addr) +{ + struct cvp_dsp_rsp_msg *rsp = (struct cvp_dsp_rsp_msg *)data; + struct cvp_dsp_apps *me = &gfa_cv; + + dprintk(CVP_DSP, "%s: type = 0x%x ret = 0x%x len = 0x%x\n", + __func__, rsp->type, rsp->ret, len); + + if (rsp->type < CPU2DSP_MAX_CMD && len == sizeof(*rsp)) { + if (me->pending_dsp2cpu_rsp.type == rsp->type) { + memcpy(&me->pending_dsp2cpu_rsp, rsp, + sizeof(struct cvp_dsp_rsp_msg)); + complete(&me->completions[rsp->type]); + } else { + dprintk(CVP_ERR, "%s: CPU2DSP resp %d, pending %d\n", + __func__, rsp->type, + me->pending_dsp2cpu_rsp.type); + goto exit; + } + } else if (rsp->type < CVP_DSP_MAX_CMD && + len == sizeof(struct cvp_dsp2cpu_cmd_msg)) { + if (me->pending_dsp2cpu_cmd.type != CVP_INVALID_RPMSG_TYPE) { + dprintk(CVP_ERR, "%s: DSP2CPU cmd:%d pending %d\n", + __func__, rsp->type, + me->pending_dsp2cpu_cmd.type); + goto exit; + } + memcpy(&me->pending_dsp2cpu_cmd, rsp, + sizeof(struct cvp_dsp2cpu_cmd_msg)); + complete(&me->completions[CPU2DSP_MAX_CMD]); + } else { + dprintk(CVP_ERR, "%s: Invalid type: %d\n", __func__, rsp->type); + return 0; + } + + return 0; +exit: + dprintk(CVP_ERR, "concurrent dsp cmd type = %d, rsp type = %d\n", + me->pending_dsp2cpu_cmd.type, + me->pending_dsp2cpu_rsp.type); + return 0; +} + +int cvp_dsp_suspend(uint32_t session_flag) +{ + int rc = 0; + struct cvp_dsp_cmd_msg cmd; + struct cvp_dsp_apps *me = &gfa_cv; + + cmd.type = CPU2DSP_SUSPEND; + + mutex_lock(&me->lock); + if (me->state != DSP_READY) + goto exit; + + /* Use cvp_dsp_send_cmd_sync after dsp driver is ready */ + rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg)); + if (rc) { + dprintk(CVP_ERR, + "%s: cvp_dsp_send_cmd failed rc = %d\n", + __func__, rc); + goto exit; + } + + me->state = DSP_SUSPEND; + +exit: + mutex_unlock(&me->lock); + return rc; +} + +int cvp_dsp_resume(uint32_t session_flag) +{ + int rc = 0; + struct cvp_dsp_cmd_msg cmd; + struct cvp_dsp_apps *me = &gfa_cv; + + cmd.type = CPU2DSP_RESUME; + + mutex_lock(&me->lock); + if (me->state != DSP_SUSPEND) + goto exit; + + /* Use cvp_dsp_send_cmd_sync after dsp driver is ready */ + rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg)); + if (rc) { + dprintk(CVP_ERR, + "%s: cvp_dsp_send_cmd failed rc = %d\n", + __func__, rc); + goto exit; + } + + me->state = DSP_READY; + +exit: + mutex_unlock(&me->lock); + return rc; +} + +int cvp_dsp_shutdown(uint32_t session_flag) +{ + struct cvp_dsp_apps *me = &gfa_cv; + int rc = 0; + struct cvp_dsp_cmd_msg cmd; + + cmd.type = CPU2DSP_SHUTDOWN; + + mutex_lock(&me->lock); + if (me->state == DSP_INVALID) + goto exit; + + me->state = DSP_INACTIVE; + rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg)); + if (rc) { + dprintk(CVP_ERR, + "%s: cvp_dsp_send_cmd failed with rc = %d\n", + __func__, rc); + cvp_hyp_assign_from_dsp(); + goto exit; + } + + rc = cvp_hyp_assign_from_dsp(); + +exit: + mutex_unlock(&me->lock); + return rc; +} + +int cvp_dsp_register_buffer(uint32_t session_id, uint32_t buff_fd, + uint32_t buff_fd_size, uint32_t buff_size, + uint32_t buff_offset, uint32_t buff_index, + uint32_t buff_fd_iova) +{ + struct cvp_dsp_cmd_msg cmd; + int rc; + struct cvp_dsp_apps *me = &gfa_cv; + + cmd.type = CPU2DSP_REGISTER_BUFFER; + cmd.session_id = session_id; + cmd.buff_fd = buff_fd; + cmd.buff_fd_size = buff_fd_size; + cmd.buff_size = buff_size; + cmd.buff_offset = buff_offset; + cmd.buff_index = buff_index; + cmd.buff_fd_iova = buff_fd_iova; + + dprintk(CVP_DSP, + "%s: type=0x%x, buff_fd_iova=0x%x buff_index=0x%x\n", + __func__, cmd.type, buff_fd_iova, + cmd.buff_index); + dprintk(CVP_DSP, "%s: buff_size=0x%x session_id=0x%x\n", + __func__, cmd.buff_size, cmd.session_id); + + mutex_lock(&me->lock); + rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg)); + if (rc) { + dprintk(CVP_ERR, "%s send failed rc = %d\n", __func__, rc); + goto exit; + } + +exit: + mutex_unlock(&me->lock); + return rc; +} + +int cvp_dsp_deregister_buffer(uint32_t session_id, uint32_t buff_fd, + uint32_t buff_fd_size, uint32_t buff_size, + uint32_t buff_offset, uint32_t buff_index, + uint32_t buff_fd_iova) +{ + struct cvp_dsp_cmd_msg cmd; + int rc; + struct cvp_dsp_apps *me = &gfa_cv; + + cmd.type = CPU2DSP_DEREGISTER_BUFFER; + cmd.session_id = session_id; + cmd.buff_fd = buff_fd; + cmd.buff_fd_size = buff_fd_size; + cmd.buff_size = buff_size; + cmd.buff_offset = buff_offset; + cmd.buff_index = buff_index; + cmd.buff_fd_iova = buff_fd_iova; + + dprintk(CVP_DSP, + "%s: type=0x%x, buff_fd_iova=0x%x buff_index=0x%x\n", + __func__, cmd.type, buff_fd_iova, + cmd.buff_index); + dprintk(CVP_DSP, "%s: buff_size=0x%x session_id=0x%x\n", + __func__, cmd.buff_size, cmd.session_id); + + mutex_lock(&me->lock); + rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg)); + if (rc) { + dprintk(CVP_ERR, "%s send failed rc = %d\n", __func__, rc); + goto exit; + } + +exit: + mutex_unlock(&me->lock); + return rc; +} + +static const struct rpmsg_device_id cvp_dsp_rpmsg_match[] = { + { CVP_APPS_DSP_GLINK_GUID }, + { }, +}; + +static struct rpmsg_driver cvp_dsp_rpmsg_client = { + .id_table = cvp_dsp_rpmsg_match, + .probe = cvp_dsp_rpmsg_probe, + .remove = cvp_dsp_rpmsg_remove, + .callback = cvp_dsp_rpmsg_callback, + .drv = { + .name = "qcom,msm_cvp_dsp_rpmsg", + }, +}; + +void cvp_dsp_send_hfi_queue(void) +{ + struct msm_cvp_core *core; + struct iris_hfi_device *device; + struct cvp_dsp_apps *me = &gfa_cv; + uint64_t addr; + uint32_t size; + int rc; + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (core && core->device) + device = core->device->hfi_device_data; + else + return; + + if (!device) { + dprintk(CVP_ERR, "%s: NULL device\n", __func__); + return; + } + + dprintk(CVP_DSP, "Entering %s\n", __func__); + + mutex_lock(&device->lock); + mutex_lock(&me->lock); + + addr = (uint64_t)device->dsp_iface_q_table.mem_data.dma_handle; + size = device->dsp_iface_q_table.mem_data.size; + + if (!addr || !size) { + dprintk(CVP_DSP, "%s: HFI queue is not ready\n", __func__); + goto exit; + } + + if (me->state != DSP_PROBED && me->state != DSP_INACTIVE) + goto exit; + + rc = cvp_hyp_assign_to_dsp(addr, size); + if (rc) { + dprintk(CVP_ERR, "%s: cvp_hyp_assign_to_dsp. rc=%d\n", + __func__, rc); + goto exit; + } + + rc = cvp_dsp_send_cmd_hfi_queue((phys_addr_t *)addr, size); + if (rc) { + dprintk(CVP_WARN, "%s: Send HFI Queue failed rc = %d\n", + __func__, rc); + + goto exit; + } + + dprintk(CVP_DSP, "%s: dsp initialized\n", __func__); + me->state = DSP_READY; + +exit: + mutex_unlock(&me->lock); + mutex_unlock(&device->lock); +} + +static int cvp_dsp_thread(void *data) +{ + int rc = 0, old_state; + struct cvp_dsp_apps *me = &gfa_cv; + struct cvp_dsp_cmd_msg cmd; + struct cvp_hfi_device *hdev; + struct msm_cvp_core *core; + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (!core) { + dprintk(CVP_ERR, "%s: Failed to find core\n", __func__); + rc = -EINVAL; + goto exit; + } + + hdev = (struct cvp_hfi_device *)core->device; + if (!hdev) { + dprintk(CVP_ERR, "%s Invalid device handle\n", __func__); + rc = -EINVAL; + goto exit; + } + +wait_dsp: + rc = wait_for_completion_interruptible( + &me->completions[CPU2DSP_MAX_CMD]); + + if (me->state == DSP_INVALID) + goto exit; + + if (me->state == DSP_UNINIT) + goto wait_dsp; + + if (me->state == DSP_PROBED) { + cvp_dsp_send_hfi_queue(); + goto wait_dsp; + } + + cmd.type = me->pending_dsp2cpu_cmd.type; + + if (rc == -ERESTARTSYS) { + dprintk(CVP_WARN, "%s received interrupt signal\n", __func__); + } else { + mutex_lock(&me->lock); + switch (me->pending_dsp2cpu_cmd.type) { + case DSP2CPU_POWERON: + { + if (me->state == DSP_READY) + break; + + mutex_unlock(&me->lock); + old_state = me->state; + me->state = DSP_READY; + rc = call_hfi_op(hdev, resume, hdev->hfi_device_data); + if (rc) { + dprintk(CVP_WARN, "%s Failed to resume cvp\n", + __func__); + mutex_lock(&me->lock); + me->state = old_state; + cmd.ret = 1; + break; + } + mutex_lock(&me->lock); + cmd.ret = 0; + break; + } + case DSP2CPU_POWEROFF: + { + me->state = DSP_SUSPEND; + cmd.ret = 0; + break; + } + default: + dprintk(CVP_ERR, "unrecognaized dsp cmds: %d\n", + me->pending_dsp2cpu_cmd.type); + break; + } + me->pending_dsp2cpu_cmd.type = CVP_INVALID_RPMSG_TYPE; + mutex_unlock(&me->lock); + } + /* Responds to DSP */ + rc = cvp_dsp_send_cmd(&cmd, sizeof(struct cvp_dsp_cmd_msg)); + if (rc) + dprintk(CVP_ERR, + "%s: cvp_dsp_send_cmd failed rc = %d cmd type=%d\n", + __func__, rc, cmd.type); + goto wait_dsp; +exit: + dprintk(CVP_DBG, "dsp thread exit\n"); + do_exit(rc); +} + +int cvp_dsp_device_init(void) +{ + struct cvp_dsp_apps *me = &gfa_cv; + char tname[16]; + int rc; + int i; + + mutex_init(&me->lock); + me->state = DSP_INVALID; + me->hyp_assigned = false; + + for (i = 0; i <= CPU2DSP_MAX_CMD; i++) + init_completion(&me->completions[i]); + + me->pending_dsp2cpu_cmd.type = CVP_INVALID_RPMSG_TYPE; + me->pending_dsp2cpu_rsp.type = CVP_INVALID_RPMSG_TYPE; + + rc = register_rpmsg_driver(&cvp_dsp_rpmsg_client); + if (rc) { + dprintk(CVP_ERR, + "%s : register_rpmsg_driver failed rc = %d\n", + __func__, rc); + goto register_bail; + } + snprintf(tname, sizeof(tname), "cvp-dsp-thread"); + me->state = DSP_UNINIT; + me->dsp_thread = kthread_run(cvp_dsp_thread, me, tname); + if (!me->dsp_thread) { + dprintk(CVP_ERR, "%s create %s fail", __func__, tname); + rc = -ECHILD; + me->state = DSP_INVALID; + goto register_bail; + } + return 0; + +register_bail: + return rc; +} + +void cvp_dsp_device_exit(void) +{ + struct cvp_dsp_apps *me = &gfa_cv; + int i; + + mutex_lock(&me->lock); + me->state = DSP_INVALID; + mutex_unlock(&me->lock); + + for (i = 0; i <= CPU2DSP_MAX_CMD; i++) + complete_all(&me->completions[i]); + + mutex_destroy(&me->lock); + unregister_rpmsg_driver(&cvp_dsp_rpmsg_client); +} diff --git a/msm/eva/msm_cvp_dsp.h b/msm/eva/msm_cvp_dsp.h new file mode 100644 index 0000000000..0ea8b690f5 --- /dev/null +++ b/msm/eva/msm_cvp_dsp.h @@ -0,0 +1,145 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#ifndef MSM_CVP_DSP_H +#define MSM_CVP_DSP_H + +#include +#include "msm_cvp_debug.h" +#include "cvp_core_hfi.h" + +#define CVP_APPS_DSP_GLINK_GUID "cvp-glink-apps-dsp" +#define CVP_APPS_DSP_SMD_GUID "cvp-smd-apps-dsp" + +#define VMID_CDSP_Q6 (30) +#define HLOS_VM_NUM 1 +#define DSP_VM_NUM 2 +#define CVP_DSP_MAX_RESERVED 5 +#define CVP_DSP2CPU_RESERVED 8 +#define CVP_DSP_RESPONSE_TIMEOUT 300 +#define CVP_INVALID_RPMSG_TYPE 0xBADDFACE + +int cvp_dsp_device_init(void); +void cvp_dsp_device_exit(void); +void cvp_dsp_send_hfi_queue(void); + +enum CVP_DSP_COMMAND { + CPU2DSP_SEND_HFI_QUEUE = 0, + CPU2DSP_SUSPEND = 1, + CPU2DSP_RESUME = 2, + CPU2DSP_SHUTDOWN = 3, + CPU2DSP_REGISTER_BUFFER = 4, + CPU2DSP_DEREGISTER_BUFFER = 5, + CPU2DSP_MAX_CMD = 6, + DSP2CPU_POWERON = 6, + DSP2CPU_POWEROFF = 7, + CVP_DSP_MAX_CMD = 8, +}; + +struct cvp_dsp_cmd_msg { + uint32_t type; + int32_t ret; + uint64_t msg_ptr; + uint32_t msg_ptr_len; + uint32_t buff_fd_iova; + uint32_t buff_index; + uint32_t buff_size; + uint32_t session_id; + int32_t ddr_type; + uint32_t buff_fd; + uint32_t buff_offset; + uint32_t buff_fd_size; + uint32_t reserved1; + uint32_t reserved2; +}; + +struct cvp_dsp_rsp_msg { + uint32_t type; + int32_t ret; + uint32_t reserved[CVP_DSP_MAX_RESERVED]; +}; + +struct cvp_dsp2cpu_cmd_msg { + uint32_t type; + uint32_t ver; + uint32_t len; + uint32_t data[CVP_DSP2CPU_RESERVED]; +}; + +struct cvp_dsp_apps { + struct mutex lock; + struct rpmsg_device *chan; + uint32_t state; + bool hyp_assigned; + uint64_t addr; + uint32_t size; + struct completion completions[CPU2DSP_MAX_CMD + 1]; + struct cvp_dsp2cpu_cmd_msg pending_dsp2cpu_cmd; + struct cvp_dsp_rsp_msg pending_dsp2cpu_rsp; + struct task_struct *dsp_thread; +}; + +extern struct cvp_dsp_apps gfa_cv; +/* + * API for CVP driver to suspend CVP session during + * power collapse + * + * @param session_flag + * Flag to share details of session. + */ +int cvp_dsp_suspend(uint32_t session_flag); + +/* + * API for CVP driver to resume CVP session during + * power collapse + * + * @param session_flag + * Flag to share details of session. + */ +int cvp_dsp_resume(uint32_t session_flag); + +/* + * API for CVP driver to shutdown CVP session during + * cvp subsystem error. + * + * @param session_flag + * Flag to share details of session. + */ +int cvp_dsp_shutdown(uint32_t session_flag); + +/* + * API to register iova buffer address with CDSP + * + * @session_id: cvp session id + * @buff_fd: buffer fd + * @buff_fd_size: total size of fd in bytes + * @buff_size: size in bytes of cvp buffer + * @buff_offset: buffer offset + * @buff_index: buffer index + * @iova_buff_addr: IOVA buffer address + */ +int cvp_dsp_register_buffer(uint32_t session_id, uint32_t buff_fd, + uint32_t buff_fd_size, uint32_t buff_size, + uint32_t buff_offset, uint32_t buff_index, + uint32_t buff_fd_iova); + +/* + * API to de-register iova buffer address from CDSP + * + * @session_id: cvp session id + * @buff_fd: buffer fd + * @buff_fd_size: total size of fd in bytes + * @buff_size: size in bytes of cvp buffer + * @buff_offset: buffer offset + * @buff_index: buffer index + * @iova_buff_addr: IOVA buffer address + */ +int cvp_dsp_deregister_buffer(uint32_t session_id, uint32_t buff_fd, + uint32_t buff_fd_size, uint32_t buff_size, + uint32_t buff_offset, uint32_t buff_index, + uint32_t buff_fd_iova); + +#endif // MSM_CVP_DSP_H + diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h new file mode 100644 index 0000000000..86442666d3 --- /dev/null +++ b/msm/eva/msm_cvp_internal.h @@ -0,0 +1,315 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _MSM_CVP_INTERNAL_H_ +#define _MSM_CVP_INTERNAL_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm_cvp_core.h" +#include +#include +#include "cvp_hfi_api.h" +#include + +#define MAX_SUPPORTED_INSTANCES 16 +#define MAX_NAME_LENGTH 64 +#define MAX_DEBUGFS_NAME 50 +#define MAX_DSP_INIT_ATTEMPTS 16 +#define FENCE_WAIT_SIGNAL_TIMEOUT 100 +#define FENCE_WAIT_SIGNAL_RETRY_TIMES 20 +#define FENCE_BIT (1ULL << 63) + +#define FENCE_DME_ICA_ENABLED_IDX 0 +#define FENCE_DME_DS_IDX 1 +#define FENCE_DME_OUTPUT_IDX 7 + +#define SYS_MSG_START HAL_SYS_INIT_DONE +#define SYS_MSG_END HAL_SYS_ERROR +#define SESSION_MSG_START HAL_SESSION_EVENT_CHANGE +#define SESSION_MSG_END HAL_SESSION_ERROR +#define SYS_MSG_INDEX(__msg) (__msg - SYS_MSG_START) +#define SESSION_MSG_INDEX(__msg) (__msg - SESSION_MSG_START) + +#define ARP_BUF_SIZE 0x100000 + +#define CVP_RT_PRIO_THRESHOLD 1 + +struct msm_cvp_inst; + +enum cvp_core_state { + CVP_CORE_UNINIT = 0, + CVP_CORE_INIT, + CVP_CORE_INIT_DONE, +}; + +/* + * Do not change the enum values unless + * you know what you are doing + */ +enum instance_state { + MSM_CVP_CORE_UNINIT_DONE = 0x0001, + MSM_CVP_CORE_INIT, + MSM_CVP_CORE_INIT_DONE, + MSM_CVP_OPEN, + MSM_CVP_OPEN_DONE, + MSM_CVP_CLOSE, + MSM_CVP_CLOSE_DONE, + MSM_CVP_CORE_UNINIT, + MSM_CVP_CORE_INVALID +}; + +enum dsp_state { + DSP_INVALID, + DSP_UNINIT, + DSP_PROBED, + DSP_READY, + DSP_SUSPEND, + DSP_INACTIVE, +}; + +struct msm_cvp_common_data { + char key[128]; + int value; +}; + +enum sku_version { + SKU_VERSION_0 = 0, + SKU_VERSION_1, + SKU_VERSION_2, +}; + +enum vpu_version { + VPU_VERSION_4 = 1, + VPU_VERSION_5, +}; + +struct msm_cvp_ubwc_config_data { + struct { + u32 max_channel_override : 1; + u32 mal_length_override : 1; + u32 hb_override : 1; + u32 bank_swzl_level_override : 1; + u32 bank_spreading_override : 1; + u32 reserved : 27; + } override_bit_info; + + u32 max_channels; + u32 mal_length; + u32 highest_bank_bit; + u32 bank_swzl_level; + u32 bank_spreading; +}; + +struct msm_cvp_platform_data { + struct msm_cvp_common_data *common_data; + unsigned int common_data_length; + unsigned int sku_version; + uint32_t vpu_ver; + struct msm_cvp_ubwc_config_data *ubwc_config; +}; + +struct msm_cvp_drv { + struct mutex lock; + struct list_head cores; + int num_cores; + struct dentry *debugfs_root; + int thermal_level; + u32 sku_version; + struct kmem_cache *msg_cache; + struct kmem_cache *frame_cache; + struct kmem_cache *buf_cache; + struct kmem_cache *smem_cache; + char fw_version[CVP_VERSION_LENGTH]; +}; + +enum profiling_points { + SYS_INIT = 0, + SESSION_INIT, + LOAD_RESOURCES, + FRAME_PROCESSING, + FW_IDLE, + MAX_PROFILING_POINTS, +}; + +struct cvp_clock_data { + int buffer_counter; + int load; + int load_low; + int load_norm; + int load_high; + int min_threshold; + int max_threshold; + unsigned long bitrate; + unsigned long min_freq; + unsigned long curr_freq; + u32 ddr_bw; + u32 sys_cache_bw; + u32 operating_rate; + u32 core_id; + bool low_latency_mode; + bool turbo_mode; +}; + +struct cvp_profile_data { + int start; + int stop; + int cumulative; + char name[64]; + int sampling; + int average; +}; + +struct msm_cvp_debug { + struct cvp_profile_data pdata[MAX_PROFILING_POINTS]; + int profile; + int samples; +}; + +enum msm_cvp_modes { + CVP_SECURE = BIT(0), + CVP_TURBO = BIT(1), + CVP_THUMBNAIL = BIT(2), + CVP_LOW_POWER = BIT(3), + CVP_REALTIME = BIT(4), +}; + +#define MAX_NUM_MSGS_PER_SESSION 128 +#define CVP_MAX_WAIT_TIME 2000 + +struct cvp_session_msg { + struct list_head node; + struct cvp_hfi_msg_session_hdr pkt; +}; + +struct cvp_session_queue { + spinlock_t lock; + enum queue_state state; + unsigned int msg_count; + struct list_head msgs; + wait_queue_head_t wq; +}; + +struct cvp_session_prop { + u32 type; + u32 kernel_mask; + u32 priority; + u32 is_secure; + u32 dsp_mask; + u32 fthread_nr; + u32 fdu_cycles; + u32 od_cycles; + u32 mpu_cycles; + u32 ica_cycles; + u32 fw_cycles; + u32 fdu_op_cycles; + u32 od_op_cycles; + u32 mpu_op_cycles; + u32 ica_op_cycles; + u32 fw_op_cycles; + u32 ddr_bw; + u32 ddr_op_bw; + u32 ddr_cache; + u32 ddr_op_cache; +}; + +enum cvp_event_t { + CVP_NO_EVENT, + CVP_SSR_EVENT = 1, + CVP_SYS_ERROR_EVENT, + CVP_MAX_CLIENTS_EVENT, + CVP_HW_UNSUPPORTED_EVENT, + CVP_INVALID_EVENT, +}; + +struct cvp_session_event { + spinlock_t lock; + enum cvp_event_t event; + wait_queue_head_t wq; +}; + +struct msm_cvp_core { + struct list_head list; + struct mutex lock; + int id; + dev_t dev_num; + struct cdev cdev; + struct class *class; + struct device *dev; + struct cvp_hfi_device *device; + struct msm_cvp_platform_data *platform_data; + struct list_head instances; + struct dentry *debugfs_root; + enum cvp_core_state state; + struct completion completions[SYS_MSG_END - SYS_MSG_START + 1]; + enum msm_cvp_hfi_type hfi_type; + struct msm_cvp_platform_resources resources; + struct msm_cvp_capability *capabilities; + struct delayed_work fw_unload_work; + struct work_struct ssr_work; + enum hal_ssr_trigger_type ssr_type; + bool smmu_fault_handled; + u32 last_fault_addr; + bool trigger_ssr; + unsigned long curr_freq; + atomic64_t kernel_trans_id; +}; + +struct msm_cvp_inst { + struct list_head list; + struct mutex sync_lock, lock; + struct msm_cvp_core *core; + enum session_type session_type; + struct cvp_session_queue session_queue; + struct cvp_session_queue session_queue_fence; + struct cvp_session_event event_handler; + void *session; + enum instance_state state; + struct msm_cvp_list freqs; + struct msm_cvp_list persistbufs; + struct cvp_dmamap_cache dma_cache; + struct msm_cvp_list cvpdspbufs; + struct msm_cvp_list frames; + struct completion completions[SESSION_MSG_END - SESSION_MSG_START + 1]; + struct dentry *debugfs_root; + struct msm_cvp_debug debug; + struct cvp_clock_data clk_data; + enum msm_cvp_modes flags; + struct msm_cvp_capability capability; + struct kref kref; + struct cvp_session_prop prop; + u32 cur_cmd_type; + struct synx_session synx_session_id; + struct cvp_fence_queue fence_cmd_queue; +}; + +extern struct msm_cvp_drv *cvp_driver; + +void cvp_handle_cmd_response(enum hal_command_response cmd, void *data); +int msm_cvp_trigger_ssr(struct msm_cvp_core *core, + enum hal_ssr_trigger_type type); +int msm_cvp_noc_error_info(struct msm_cvp_core *core); +void msm_cvp_comm_handle_thermal_event(void); + +void msm_cvp_fw_unload_handler(struct work_struct *work); +void msm_cvp_ssr_handler(struct work_struct *work); +/* + * XXX: normally should be in msm_cvp_core.h, but that's meant for public APIs, + * whereas this is private + */ +int msm_cvp_destroy(struct msm_cvp_inst *inst); +void *cvp_get_drv_data(struct device *dev); +#endif diff --git a/msm/eva/msm_cvp_ioctl.c b/msm/eva/msm_cvp_ioctl.c new file mode 100644 index 0000000000..47a3f6e834 --- /dev/null +++ b/msm/eva/msm_cvp_ioctl.c @@ -0,0 +1,650 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#include "cvp_private.h" +#include "cvp_hfi_api.h" + +static int _get_pkt_hdr_from_user(struct cvp_kmd_arg __user *up, + struct cvp_hal_session_cmd_pkt *pkt_hdr) +{ + struct cvp_kmd_hfi_packet *u; + + u = &up->data.hfi_pkt; + + if (get_user(pkt_hdr->size, &u->pkt_data[0])) + return -EFAULT; + + if (get_user(pkt_hdr->packet_type, &u->pkt_data[1])) + return -EFAULT; + + if (get_pkt_index(pkt_hdr) < 0) { + dprintk(CVP_ERR, "user mode provides incorrect hfi\n"); + goto set_default_pkt_hdr; + } + + if (pkt_hdr->size > MAX_HFI_PKT_SIZE*sizeof(unsigned int)) { + dprintk(CVP_ERR, "user HFI packet too large %x\n", + pkt_hdr->size); + return -EINVAL; + } + + return 0; + +set_default_pkt_hdr: + pkt_hdr->size = get_msg_size(); + return 0; +} + +static int _get_fence_pkt_hdr_from_user(struct cvp_kmd_arg __user *up, + struct cvp_hal_session_cmd_pkt *pkt_hdr) +{ + struct cvp_kmd_hfi_synx_packet __user *u; + + u = &up->data.hfi_synx_pkt; + + if (get_user(pkt_hdr->size, &u->pkt_data[0])) + return -EFAULT; + + if (get_user(pkt_hdr->packet_type, &u->pkt_data[1])) + return -EFAULT; + + if (pkt_hdr->size > (MAX_HFI_PKT_SIZE*sizeof(unsigned int))) + return -EINVAL; + + return 0; +} + +/* Size is in unit of u32 */ +static int _copy_pkt_from_user(struct cvp_kmd_arg *kp, + struct cvp_kmd_arg __user *up, + unsigned int size) +{ + struct cvp_kmd_hfi_packet *k, *u; + int i; + + k = &kp->data.hfi_pkt; + u = &up->data.hfi_pkt; + for (i = 0; i < size; i++) + if (get_user(k->pkt_data[i], &u->pkt_data[i])) + return -EFAULT; + + return 0; +} + +static int _copy_synx_data_from_user( + struct cvp_kmd_hfi_synx_packet *k, + struct cvp_kmd_hfi_synx_packet __user *u) +{ + int i; + + for (i = 0; i < MAX_FENCE_DATA_SIZE; i++) { + if (get_user(k->fence_data[i], &u->fence_data[i])) + return -EFAULT; + } + + return 0; +} + +/* Size is in unit of u32 */ +static int _copy_fence_data_from_user_deprecate( + struct cvp_kmd_hfi_fence_packet *k, + struct cvp_kmd_hfi_fence_packet __user *u) +{ + int i; + + for (i = 0; i < MAX_HFI_FENCE_SIZE; i++) { + if (get_user(k->fence_data[i], &u->fence_data[i])) + return -EFAULT; + } + + if (get_user(k->frame_id, &u->frame_id)) { + dprintk(CVP_ERR, "Failed to get frame id from fence pkt\n"); + return -EFAULT; + } + + return 0; +} + +static int _copy_fence_pkt_from_user(struct cvp_kmd_arg *kp, + struct cvp_kmd_arg __user *up) +{ struct cvp_kmd_hfi_synx_packet *k; + struct cvp_kmd_hfi_synx_packet __user *u; + struct cvp_kmd_hfi_fence_packet __user *u1; + int i; + + k = &kp->data.hfi_synx_pkt; + u = &up->data.hfi_synx_pkt; + u1 = &up->data.hfi_fence_pkt; + + for (i = 0; i < MAX_HFI_PKT_SIZE; i++) + if (get_user(k->pkt_data[i], &u->pkt_data[i])) + return -EFAULT; + + if (get_user(k->fence_data[0], &u->fence_data[0])) + return -EFAULT; + + if (k->fence_data[0] == 0xFEEDFACE) + return _copy_synx_data_from_user(k, u); + else + return _copy_fence_data_from_user_deprecate( + (struct cvp_kmd_hfi_fence_packet *)k, u1); +} + +static int _copy_frameid_from_user(struct cvp_kmd_arg *kp, + struct cvp_kmd_arg __user *up) +{ + if (get_user(kp->data.frame_id, &up->data.frame_id)) { + dprintk(CVP_ERR, "Failed to get frame id from user\n"); + return -EFAULT; + } + + return 0; +} + +static int _copy_sysprop_from_user(struct cvp_kmd_arg *kp, + struct cvp_kmd_arg __user *up) +{ + struct cvp_kmd_sys_properties *k, *u; + + k = &kp->data.sys_properties; + u = &up->data.sys_properties; + + if (get_user(k->prop_num, &u->prop_num)) + return -EFAULT; + + if (k->prop_num < 1 || k->prop_num > 32) { + dprintk(CVP_ERR, "Num of prop out of range %d\n", k->prop_num); + return -EFAULT; + } + + return _copy_pkt_from_user(kp, up, + (k->prop_num*((sizeof(struct cvp_kmd_sys_property)>>2)+1))); +} + +static int _copy_pkt_to_user(struct cvp_kmd_arg *kp, + struct cvp_kmd_arg __user *up, + unsigned int size) +{ + struct cvp_kmd_hfi_packet *k, *u; + int i; + + k = &kp->data.hfi_pkt; + u = &up->data.hfi_pkt; + for (i = 0; i < size; i++) + if (put_user(k->pkt_data[i], &u->pkt_data[i])) + return -EFAULT; + + return 0; +} + +static int _copy_fence_pkt_to_user(struct cvp_kmd_arg *kp, + struct cvp_kmd_arg __user *up) +{ + struct cvp_kmd_hfi_synx_packet *k; + struct cvp_kmd_hfi_synx_packet __user *u; + int i; + + k = &kp->data.hfi_synx_pkt; + u = &up->data.hfi_synx_pkt; + for (i = 0; i < MAX_HFI_PKT_SIZE; i++) { + if (put_user(k->pkt_data[i], &u->pkt_data[i])) + return -EFAULT; + } + + return 0; +} + +static int _copy_sysprop_to_user(struct cvp_kmd_arg *kp, + struct cvp_kmd_arg __user *up) +{ + struct cvp_kmd_sys_properties *k; + struct cvp_kmd_sys_properties __user *u; + int i; + + k = &kp->data.sys_properties; + u = &up->data.sys_properties; + + for (i = 0; i < 8; i++) + if (put_user(k->prop_data[i].data, &u->prop_data[i].data)) + return -EFAULT; + + return 0; + +} + +static void print_hfi_short(struct cvp_kmd_arg __user *up) +{ + struct cvp_kmd_hfi_packet *pkt; + unsigned int words[5]; + + pkt = &up->data.hfi_pkt; + if (get_user(words[0], &up->type) || + get_user(words[1], &up->buf_offset) || + get_user(words[2], &up->buf_num) || + get_user(words[3], &pkt->pkt_data[0]) || + get_user(words[4], &pkt->pkt_data[1])) + dprintk(CVP_ERR, "Failed to print ioctl cmd\n"); + + dprintk(CVP_HFI, "IOCTL cmd type %#x, offset %d, num %d, pkt %d %#x\n", + words[0], words[1], words[2], words[3], words[4]); +} + +static int _copy_session_ctrl_to_user( + struct cvp_kmd_session_control *k, + struct cvp_kmd_session_control *u) +{ + int i; + + if (put_user(k->ctrl_type, &u->ctrl_type)) + return -EFAULT; + for (i = 0; i < 8; i++) + if (put_user(k->ctrl_data[i], &u->ctrl_data[i])) + return -EFAULT; + return 0; +} + +static int _get_session_ctrl_from_user( + struct cvp_kmd_session_control *k, + struct cvp_kmd_session_control *u) +{ + int i; + + if (get_user(k->ctrl_type, &u->ctrl_type)) + return -EFAULT; + + for (i = 0; i < 8; i++) + if (get_user(k->ctrl_data[i], &u->ctrl_data[i])) + return -EFAULT; + return 0; +} + +static int _get_session_info_from_user( + struct cvp_kmd_session_info *k, + struct cvp_kmd_session_info __user *u) +{ + int i; + + if (get_user(k->session_id, &u->session_id)) + return -EFAULT; + + for (i = 0; i < 10; i++) + if (get_user(k->reserved[i], &u->reserved[i])) + return -EFAULT; + return 0; +} + +static int convert_from_user(struct cvp_kmd_arg *kp, + unsigned long arg, + struct msm_cvp_inst *inst) +{ + int rc = 0; + int i; + struct cvp_kmd_arg __user *up = (struct cvp_kmd_arg *)arg; + struct cvp_hal_session_cmd_pkt pkt_hdr; + int pkt_idx; + + if (!kp || !up) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + print_hfi_short(up); + + if (get_user(kp->type, &up->type)) + return -EFAULT; + + if (get_user(kp->buf_offset, &up->buf_offset) || + get_user(kp->buf_num, &up->buf_num)) + return -EFAULT; + + switch (kp->type) { + case CVP_KMD_GET_SESSION_INFO: + { + struct cvp_kmd_session_info *k; + struct cvp_kmd_session_info __user *u; + + k = &kp->data.session; + u = &up->data.session; + if (_get_session_info_from_user(k, u)) { + dprintk(CVP_ERR, "fail to get sess info\n"); + return -EFAULT; + } + + break; + } + case CVP_KMD_REGISTER_BUFFER: + { + struct cvp_kmd_buffer *k, *u; + + k = &kp->data.regbuf; + u = &up->data.regbuf; + if (get_user(k->type, &u->type) || + get_user(k->index, &u->index) || + get_user(k->fd, &u->fd) || + get_user(k->size, &u->size) || + get_user(k->offset, &u->offset) || + get_user(k->pixelformat, &u->pixelformat) || + get_user(k->flags, &u->flags)) + return -EFAULT; + for (i = 0; i < 5; i++) + if (get_user(k->reserved[i], &u->reserved[i])) + return -EFAULT; + break; + } + case CVP_KMD_UNREGISTER_BUFFER: + { + struct cvp_kmd_buffer *k, *u; + + k = &kp->data.unregbuf; + u = &up->data.unregbuf; + if (get_user(k->type, &u->type) || + get_user(k->index, &u->index) || + get_user(k->fd, &u->fd) || + get_user(k->size, &u->size) || + get_user(k->offset, &u->offset) || + get_user(k->pixelformat, &u->pixelformat) || + get_user(k->flags, &u->flags)) + return -EFAULT; + for (i = 0; i < 5; i++) + if (get_user(k->reserved[i], &u->reserved[i])) + return -EFAULT; + break; + } + case CVP_KMD_SEND_CMD_PKT: + { + if (_get_pkt_hdr_from_user(up, &pkt_hdr)) { + dprintk(CVP_ERR, "Invalid syscall: %x, %x, %x\n", + kp->type, pkt_hdr.size, pkt_hdr.packet_type); + return -EFAULT; + } + + rc = _copy_pkt_from_user(kp, up, (pkt_hdr.size >> 2)); + break; + } + case CVP_KMD_SEND_FENCE_CMD_PKT: + { + if (_get_fence_pkt_hdr_from_user(up, &pkt_hdr)) { + dprintk(CVP_ERR, "Invalid syscall: %x, %x, %x\n", + kp->type, pkt_hdr.size, pkt_hdr.packet_type); + return -EFAULT; + } + dprintk(CVP_HFI, "system call cmd pkt: %d 0x%x\n", + pkt_hdr.size, pkt_hdr.packet_type); + + pkt_idx = get_pkt_index(&pkt_hdr); + if (pkt_idx < 0) { + dprintk(CVP_ERR, "%s incorrect packet %d, %x\n", + __func__, + pkt_hdr.size, + pkt_hdr.packet_type); + return -EFAULT; + } + + rc = _copy_fence_pkt_from_user(kp, up); + break; + } + case CVP_KMD_RECEIVE_MSG_PKT: + break; + case CVP_KMD_SESSION_CONTROL: + { + struct cvp_kmd_session_control *k, *u; + + k = &kp->data.session_ctrl; + u = &up->data.session_ctrl; + + rc = _get_session_ctrl_from_user(k, u); + break; + } + case CVP_KMD_GET_SYS_PROPERTY: + { + if (_copy_sysprop_from_user(kp, up)) { + dprintk(CVP_ERR, "Failed to get sysprop from user\n"); + return -EFAULT; + } + break; + } + case CVP_KMD_SET_SYS_PROPERTY: + { + if (_copy_sysprop_from_user(kp, up)) { + dprintk(CVP_ERR, "Failed to set sysprop from user\n"); + return -EFAULT; + } + break; + } + case CVP_KMD_FLUSH_ALL: + case CVP_KMD_UPDATE_POWER: + break; + case CVP_KMD_FLUSH_FRAME: + { + if (_copy_frameid_from_user(kp, up)) + return -EFAULT; + break; + } + default: + dprintk(CVP_ERR, "%s: unknown cmd type 0x%x\n", + __func__, kp->type); + rc = -EINVAL; + break; + } + + return rc; +} + +static int _put_user_session_info( + struct cvp_kmd_session_info *k, + struct cvp_kmd_session_info __user *u) +{ + int i; + + if (put_user(k->session_id, &u->session_id)) + return -EFAULT; + + for (i = 0; i < 10; i++) + if (put_user(k->reserved[i], &u->reserved[i])) + return -EFAULT; + + return 0; +} + +static int convert_to_user(struct cvp_kmd_arg *kp, unsigned long arg) +{ + int rc = 0; + int i, size = get_msg_size() >> 2; + struct cvp_kmd_arg __user *up = (struct cvp_kmd_arg *)arg; + struct cvp_hal_session_cmd_pkt pkt_hdr; + + if (!kp || !up) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + if (put_user(kp->type, &up->type)) + return -EFAULT; + + switch (kp->type) { + case CVP_KMD_RECEIVE_MSG_PKT: + { + struct cvp_kmd_hfi_packet *k, *u; + + k = &kp->data.hfi_pkt; + u = &up->data.hfi_pkt; + for (i = 0; i < size; i++) + if (put_user(k->pkt_data[i], &u->pkt_data[i])) + return -EFAULT; + break; + } + case CVP_KMD_GET_SESSION_INFO: + { + struct cvp_kmd_session_info *k; + struct cvp_kmd_session_info __user *u; + + k = &kp->data.session; + u = &up->data.session; + if (_put_user_session_info(k, u)) { + dprintk(CVP_ERR, "fail to copy sess info to user\n"); + return -EFAULT; + } + + break; + } + case CVP_KMD_REGISTER_BUFFER: + { + struct cvp_kmd_buffer *k, *u; + + k = &kp->data.regbuf; + u = &up->data.regbuf; + if (put_user(k->type, &u->type) || + put_user(k->index, &u->index) || + put_user(k->fd, &u->fd) || + put_user(k->size, &u->size) || + put_user(k->offset, &u->offset) || + put_user(k->pixelformat, &u->pixelformat) || + put_user(k->flags, &u->flags)) + return -EFAULT; + for (i = 0; i < 5; i++) + if (put_user(k->reserved[i], &u->reserved[i])) + return -EFAULT; + break; + } + case CVP_KMD_UNREGISTER_BUFFER: + { + struct cvp_kmd_buffer *k, *u; + + k = &kp->data.unregbuf; + u = &up->data.unregbuf; + if (put_user(k->type, &u->type) || + put_user(k->index, &u->index) || + put_user(k->fd, &u->fd) || + put_user(k->size, &u->size) || + put_user(k->offset, &u->offset) || + put_user(k->pixelformat, &u->pixelformat) || + put_user(k->flags, &u->flags)) + return -EFAULT; + for (i = 0; i < 5; i++) + if (put_user(k->reserved[i], &u->reserved[i])) + return -EFAULT; + break; + } + case CVP_KMD_SEND_CMD_PKT: + { + if (_get_pkt_hdr_from_user(up, &pkt_hdr)) + return -EFAULT; + + dprintk(CVP_HFI, "Send user cmd pkt: %d %d\n", + pkt_hdr.size, pkt_hdr.packet_type); + rc = _copy_pkt_to_user(kp, up, (pkt_hdr.size >> 2)); + break; + } + case CVP_KMD_SEND_FENCE_CMD_PKT: + { + if (_get_fence_pkt_hdr_from_user(up, &pkt_hdr)) + return -EFAULT; + + dprintk(CVP_HFI, "Send user cmd pkt: %d %d\n", + pkt_hdr.size, pkt_hdr.packet_type); + + rc = _copy_fence_pkt_to_user(kp, up); + break; + } + case CVP_KMD_SESSION_CONTROL: + { + struct cvp_kmd_session_control *k, *u; + + k = &kp->data.session_ctrl; + u = &up->data.session_ctrl; + rc = _copy_session_ctrl_to_user(k, u); + break; + } + case CVP_KMD_GET_SYS_PROPERTY: + { + if (_copy_sysprop_to_user(kp, up)) { + dprintk(CVP_ERR, "Fail to copy sysprop to user\n"); + return -EFAULT; + } + break; + } + case CVP_KMD_FLUSH_ALL: + case CVP_KMD_FLUSH_FRAME: + case CVP_KMD_SET_SYS_PROPERTY: + case CVP_KMD_UPDATE_POWER: + break; + default: + dprintk(CVP_ERR, "%s: unknown cmd type 0x%x\n", + __func__, kp->type); + rc = -EINVAL; + break; + } + + return rc; +} + +static long cvp_ioctl(struct msm_cvp_inst *inst, + unsigned int cmd, unsigned long arg) +{ + int rc; + struct cvp_kmd_arg *karg; + + if (!inst) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + karg = kzalloc(sizeof(*karg), GFP_KERNEL); + if (!karg) + return -ENOMEM; + + if (convert_from_user(karg, arg, inst)) { + dprintk(CVP_ERR, "%s: failed to get from user cmd %x\n", + __func__, karg->type); + kfree(karg); + return -EFAULT; + } + + rc = msm_cvp_private((void *)inst, cmd, karg); + if (rc) { + dprintk(CVP_ERR, "%s: failed cmd type %x %d\n", + __func__, karg->type, rc); + kfree(karg); + return rc; + } + + if (convert_to_user(karg, arg)) { + dprintk(CVP_ERR, "%s: failed to copy to user cmd %x\n", + __func__, karg->type); + kfree(karg); + return -EFAULT; + } + + kfree(karg); + return rc; +} + +long cvp_unblocked_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg) +{ + struct msm_cvp_inst *inst; + + if (!filp || !filp->private_data) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + inst = filp->private_data; + return cvp_ioctl(inst, cmd, arg); +} + +long cvp_compat_ioctl(struct file *filp, + unsigned int cmd, unsigned long arg) +{ + struct msm_cvp_inst *inst; + + if (!filp || !filp->private_data) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + inst = filp->private_data; + return cvp_ioctl(inst, cmd, (unsigned long)compat_ptr(arg)); +} diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c new file mode 100644 index 0000000000..bc9d55fe93 --- /dev/null +++ b/msm/eva/msm_cvp_platform.c @@ -0,0 +1,233 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm_cvp_internal.h" +#include "msm_cvp_debug.h" + +#define DDR_TYPE_LPDDR4 0x6 +#define DDR_TYPE_LPDDR4X 0x7 +#define DDR_TYPE_LPDDR4Y 0x8 +#define DDR_TYPE_LPDDR5 0x9 + +#define UBWC_CONFIG(mco, mlo, hbo, bslo, bso, rs, mc, ml, hbb, bsl, bsp) \ +{ \ + .override_bit_info.max_channel_override = mco, \ + .override_bit_info.mal_length_override = mlo, \ + .override_bit_info.hb_override = hbo, \ + .override_bit_info.bank_swzl_level_override = bslo, \ + .override_bit_info.bank_spreading_override = bso, \ + .override_bit_info.reserved = rs, \ + .max_channels = mc, \ + .mal_length = ml, \ + .highest_bank_bit = hbb, \ + .bank_swzl_level = bsl, \ + .bank_spreading = bsp, \ +} + +static struct msm_cvp_common_data default_common_data[] = { + { + .key = "qcom,never-unload-fw", + .value = 1, + }, +}; + +static struct msm_cvp_common_data sm8250_common_data[] = { + { + .key = "qcom,never-unload-fw", + .value = 1, + }, + { + .key = "qcom,sw-power-collapse", + .value = 1, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 1, + }, + { + .key = "qcom,max-secure-instances", + .value = 2, /* + * As per design driver allows 3rd + * instance as well since the secure + * flags were updated later for the + * current instance. Hence total + * secure sessions would be + * max-secure-instances + 1. + */ + }, + { + .key = "qcom,max-hw-load", + .value = 3916800, /* + * 1920x1088/256 MBs@480fps. It is less + * any other usecases (ex: + * 3840x2160@120fps, 4096x2160@96ps, + * 7680x4320@30fps) + */ + }, + { + .key = "qcom,power-collapse-delay", + .value = 3000, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 2000, + }, + { + .key = "qcom,dsp-resp-timeout", + .value = 1000 + }, + { + .key = "qcom,debug-timeout", + .value = 0, + } +}; + +static struct msm_cvp_common_data sm8350_common_data[] = { + { + .key = "qcom,auto-pil", + .value = 1, + }, + { + .key = "qcom,never-unload-fw", + .value = 1, + }, + { + .key = "qcom,sw-power-collapse", + .value = 1, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 1, + }, + { + .key = "qcom,max-secure-instances", + .value = 2, /* + * As per design driver allows 3rd + * instance as well since the secure + * flags were updated later for the + * current instance. Hence total + * secure sessions would be + * max-secure-instances + 1. + */ + }, + { + .key = "qcom,max-hw-load", + .value = 3916800, /* + * 1920x1088/256 MBs@480fps. It is less + * any other usecases (ex: + * 3840x2160@120fps, 4096x2160@96ps, + * 7680x4320@30fps) + */ + }, + { + .key = "qcom,power-collapse-delay", + .value = 3000, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 2000, + }, + { + .key = "qcom,dsp-resp-timeout", + .value = 1000 + }, + { + .key = "qcom,debug-timeout", + .value = 0, + } +}; + + +/* Default UBWC config for LPDDR5 */ +static struct msm_cvp_ubwc_config_data kona_ubwc_data[] = { + UBWC_CONFIG(1, 1, 1, 0, 0, 0, 8, 32, 16, 0, 0), +}; + + +static struct msm_cvp_platform_data default_data = { + .common_data = default_common_data, + .common_data_length = ARRAY_SIZE(default_common_data), + .sku_version = 0, + .vpu_ver = VPU_VERSION_5, + .ubwc_config = 0x0, +}; + +static struct msm_cvp_platform_data sm8250_data = { + .common_data = sm8250_common_data, + .common_data_length = ARRAY_SIZE(sm8250_common_data), + .sku_version = 0, + .vpu_ver = VPU_VERSION_5, + .ubwc_config = kona_ubwc_data, +}; + +static struct msm_cvp_platform_data sm8350_data = { + .common_data = sm8350_common_data, + .common_data_length = ARRAY_SIZE(sm8350_common_data), + .sku_version = 0, + .vpu_ver = VPU_VERSION_5, + .ubwc_config = kona_ubwc_data, +}; + +static const struct of_device_id msm_cvp_dt_match[] = { + { + .compatible = "qcom,lahaina-cvp", + .data = &sm8350_data, + }, + { + .compatible = "qcom,kona-cvp", + .data = &sm8250_data, + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, msm_cvp_dt_match); + +void *cvp_get_drv_data(struct device *dev) +{ + struct msm_cvp_platform_data *driver_data; + const struct of_device_id *match; + uint32_t ddr_type = DDR_TYPE_LPDDR5; + + driver_data = &default_data; + + if (!IS_ENABLED(CONFIG_OF) || !dev->of_node) + goto exit; + + match = of_match_node(msm_cvp_dt_match, dev->of_node); + + if (!match) + return NULL; + + driver_data = (struct msm_cvp_platform_data *)match->data; + + if (!strcmp(match->compatible, "qcom,kona-cvp")) { + ddr_type = of_fdt_get_ddrtype(); + if (ddr_type == -ENOENT) { + dprintk(CVP_ERR, + "Failed to get ddr type, use LPDDR5\n"); + } + + if (driver_data->ubwc_config && + (ddr_type == DDR_TYPE_LPDDR4 || + ddr_type == DDR_TYPE_LPDDR4X || + ddr_type == DDR_TYPE_LPDDR4Y)) + driver_data->ubwc_config->highest_bank_bit = 15; + } +exit: + return driver_data; +} diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c new file mode 100644 index 0000000000..59fc1d3bfa --- /dev/null +++ b/msm/eva/msm_cvp_res_parse.c @@ -0,0 +1,1073 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include "msm_cvp_debug.h" +#include "msm_cvp_resources.h" +#include "msm_cvp_res_parse.h" +#include "soc/qcom/secure_buffer.h" + +enum clock_properties { + CLOCK_PROP_HAS_SCALING = 1 << 0, + CLOCK_PROP_HAS_MEM_RETENTION = 1 << 1, +}; + +#define PERF_GOV "performance" + +static inline struct device *msm_iommu_get_ctx(const char *ctx_name) +{ + return NULL; +} + +static size_t get_u32_array_num_elements(struct device_node *np, + char *name) +{ + int len; + size_t num_elements = 0; + + if (!of_get_property(np, name, &len)) { + dprintk(CVP_ERR, "Failed to read %s from device tree\n", + name); + goto fail_read; + } + + num_elements = len / sizeof(u32); + if (num_elements <= 0) { + dprintk(CVP_ERR, "%s not specified in device tree\n", + name); + goto fail_read; + } + return num_elements; + +fail_read: + return 0; +} + +static inline void msm_cvp_free_allowed_clocks_table( + struct msm_cvp_platform_resources *res) +{ + res->allowed_clks_tbl = NULL; +} + +static inline void msm_cvp_free_cycles_per_mb_table( + struct msm_cvp_platform_resources *res) +{ + res->clock_freq_tbl.clk_prof_entries = NULL; +} + +static inline void msm_cvp_free_reg_table( + struct msm_cvp_platform_resources *res) +{ + res->reg_set.reg_tbl = NULL; +} + +static inline void msm_cvp_free_qdss_addr_table( + struct msm_cvp_platform_resources *res) +{ + res->qdss_addr_set.addr_tbl = NULL; +} + +static inline void msm_cvp_free_bus_vectors( + struct msm_cvp_platform_resources *res) +{ + kfree(res->bus_set.bus_tbl); + res->bus_set.bus_tbl = NULL; + res->bus_set.count = 0; +} + +static inline void msm_cvp_free_regulator_table( + struct msm_cvp_platform_resources *res) +{ + int c = 0; + + for (c = 0; c < res->regulator_set.count; ++c) { + struct regulator_info *rinfo = + &res->regulator_set.regulator_tbl[c]; + + rinfo->name = NULL; + } + + res->regulator_set.regulator_tbl = NULL; + res->regulator_set.count = 0; +} + +static inline void msm_cvp_free_clock_table( + struct msm_cvp_platform_resources *res) +{ + res->clock_set.clock_tbl = NULL; + res->clock_set.count = 0; +} + +void msm_cvp_free_platform_resources( + struct msm_cvp_platform_resources *res) +{ + msm_cvp_free_clock_table(res); + msm_cvp_free_regulator_table(res); + msm_cvp_free_allowed_clocks_table(res); + msm_cvp_free_reg_table(res); + msm_cvp_free_qdss_addr_table(res); + msm_cvp_free_bus_vectors(res); +} + +static int msm_cvp_load_reg_table(struct msm_cvp_platform_resources *res) +{ + struct reg_set *reg_set; + struct platform_device *pdev = res->pdev; + int i; + int rc = 0; + + if (!of_find_property(pdev->dev.of_node, "qcom,reg-presets", NULL)) { + /* + * qcom,reg-presets is an optional property. It likely won't be + * present if we don't have any register settings to program + */ + dprintk(CVP_CORE, "qcom,reg-presets not found\n"); + return 0; + } + + reg_set = &res->reg_set; + reg_set->count = get_u32_array_num_elements(pdev->dev.of_node, + "qcom,reg-presets"); + reg_set->count /= sizeof(*reg_set->reg_tbl) / sizeof(u32); + + if (!reg_set->count) { + dprintk(CVP_CORE, "no elements in reg set\n"); + return rc; + } + + reg_set->reg_tbl = devm_kzalloc(&pdev->dev, reg_set->count * + sizeof(*(reg_set->reg_tbl)), GFP_KERNEL); + if (!reg_set->reg_tbl) { + dprintk(CVP_ERR, "%s Failed to alloc register table\n", + __func__); + return -ENOMEM; + } + + if (of_property_read_u32_array(pdev->dev.of_node, "qcom,reg-presets", + (u32 *)reg_set->reg_tbl, reg_set->count * 2)) { + dprintk(CVP_ERR, "Failed to read register table\n"); + msm_cvp_free_reg_table(res); + return -EINVAL; + } + for (i = 0; i < reg_set->count; i++) { + dprintk(CVP_CORE, + "reg = %x, value = %x\n", + reg_set->reg_tbl[i].reg, + reg_set->reg_tbl[i].value + ); + } + return rc; +} +static int msm_cvp_load_qdss_table(struct msm_cvp_platform_resources *res) +{ + struct addr_set *qdss_addr_set; + struct platform_device *pdev = res->pdev; + int i; + int rc = 0; + + if (!of_find_property(pdev->dev.of_node, "qcom,qdss-presets", NULL)) { + /* + * qcom,qdss-presets is an optional property. It likely won't be + * present if we don't have any register settings to program + */ + dprintk(CVP_CORE, "qcom,qdss-presets not found\n"); + return rc; + } + + qdss_addr_set = &res->qdss_addr_set; + qdss_addr_set->count = get_u32_array_num_elements(pdev->dev.of_node, + "qcom,qdss-presets"); + qdss_addr_set->count /= sizeof(*qdss_addr_set->addr_tbl) / sizeof(u32); + + if (!qdss_addr_set->count) { + dprintk(CVP_CORE, "no elements in qdss reg set\n"); + return rc; + } + + qdss_addr_set->addr_tbl = devm_kzalloc(&pdev->dev, + qdss_addr_set->count * sizeof(*qdss_addr_set->addr_tbl), + GFP_KERNEL); + if (!qdss_addr_set->addr_tbl) { + dprintk(CVP_ERR, "%s Failed to alloc register table\n", + __func__); + rc = -ENOMEM; + goto err_qdss_addr_tbl; + } + + rc = of_property_read_u32_array(pdev->dev.of_node, "qcom,qdss-presets", + (u32 *)qdss_addr_set->addr_tbl, qdss_addr_set->count * 2); + if (rc) { + dprintk(CVP_ERR, "Failed to read qdss address table\n"); + msm_cvp_free_qdss_addr_table(res); + rc = -EINVAL; + goto err_qdss_addr_tbl; + } + + for (i = 0; i < qdss_addr_set->count; i++) { + dprintk(CVP_CORE, "qdss addr = %x, value = %x\n", + qdss_addr_set->addr_tbl[i].start, + qdss_addr_set->addr_tbl[i].size); + } +err_qdss_addr_tbl: + return rc; +} + +static int msm_cvp_load_subcache_info(struct msm_cvp_platform_resources *res) +{ + int rc = 0, num_subcaches = 0, c; + struct platform_device *pdev = res->pdev; + struct subcache_set *subcaches = &res->subcache_set; + + num_subcaches = of_property_count_strings(pdev->dev.of_node, + "cache-slice-names"); + if (num_subcaches <= 0) { + dprintk(CVP_CORE, "No subcaches found\n"); + goto err_load_subcache_table_fail; + } + + subcaches->subcache_tbl = devm_kzalloc(&pdev->dev, + sizeof(*subcaches->subcache_tbl) * num_subcaches, GFP_KERNEL); + if (!subcaches->subcache_tbl) { + dprintk(CVP_ERR, + "Failed to allocate memory for subcache tbl\n"); + rc = -ENOMEM; + goto err_load_subcache_table_fail; + } + + subcaches->count = num_subcaches; + dprintk(CVP_CORE, "Found %d subcaches\n", num_subcaches); + + for (c = 0; c < num_subcaches; ++c) { + struct subcache_info *vsc = &res->subcache_set.subcache_tbl[c]; + + of_property_read_string_index(pdev->dev.of_node, + "cache-slice-names", c, &vsc->name); + } + + res->sys_cache_present = true; + + return 0; + +err_load_subcache_table_fail: + res->sys_cache_present = false; + subcaches->count = 0; + subcaches->subcache_tbl = NULL; + + return rc; +} + +/** + * msm_cvp_load_u32_table() - load dtsi table entries + * @pdev: A pointer to the platform device. + * @of_node: A pointer to the device node. + * @table_name: A pointer to the dtsi table entry name. + * @struct_size: The size of the structure which is nothing but + * a single entry in the dtsi table. + * @table: A pointer to the table pointer which needs to be + * filled by the dtsi table entries. + * @num_elements: Number of elements pointer which needs to be filled + * with the number of elements in the table. + * + * This is a generic implementation to load single or multiple array + * table from dtsi. The array elements should be of size equal to u32. + * + * Return: Return '0' for success else appropriate error value. + */ +int msm_cvp_load_u32_table(struct platform_device *pdev, + struct device_node *of_node, char *table_name, int struct_size, + u32 **table, u32 *num_elements) +{ + int rc = 0, num_elemts = 0; + u32 *ptbl = NULL; + + if (!of_find_property(of_node, table_name, NULL)) { + dprintk(CVP_CORE, "%s not found\n", table_name); + return 0; + } + + num_elemts = get_u32_array_num_elements(of_node, table_name); + if (!num_elemts) { + dprintk(CVP_ERR, "no elements in %s\n", table_name); + return 0; + } + num_elemts /= struct_size / sizeof(u32); + + ptbl = devm_kzalloc(&pdev->dev, num_elemts * struct_size, GFP_KERNEL); + if (!ptbl) { + dprintk(CVP_ERR, "Failed to alloc table %s\n", table_name); + return -ENOMEM; + } + + if (of_property_read_u32_array(of_node, table_name, ptbl, + num_elemts * struct_size / sizeof(u32))) { + dprintk(CVP_ERR, "Failed to read %s\n", table_name); + return -EINVAL; + } + + *table = ptbl; + if (num_elements) + *num_elements = num_elemts; + + return rc; +} +EXPORT_SYMBOL(msm_cvp_load_u32_table); + +/* A comparator to compare loads (needed later on) */ +static int cmp(const void *a, const void *b) +{ + return ((struct allowed_clock_rates_table *)a)->clock_rate - + ((struct allowed_clock_rates_table *)b)->clock_rate; +} + +static int msm_cvp_load_allowed_clocks_table( + struct msm_cvp_platform_resources *res) +{ + int rc = 0; + struct platform_device *pdev = res->pdev; + + if (!of_find_property(pdev->dev.of_node, + "qcom,allowed-clock-rates", NULL)) { + dprintk(CVP_CORE, "qcom,allowed-clock-rates not found\n"); + return 0; + } + + rc = msm_cvp_load_u32_table(pdev, pdev->dev.of_node, + "qcom,allowed-clock-rates", + sizeof(*res->allowed_clks_tbl), + (u32 **)&res->allowed_clks_tbl, + &res->allowed_clks_tbl_size); + if (rc) { + dprintk(CVP_ERR, + "%s: failed to read allowed clocks table\n", __func__); + return rc; + } + + sort(res->allowed_clks_tbl, res->allowed_clks_tbl_size, + sizeof(*res->allowed_clks_tbl), cmp, NULL); + + return 0; +} + +static int msm_cvp_populate_mem_cdsp(struct device *dev, + struct msm_cvp_platform_resources *res) +{ + struct device_node *mem_node; + int ret; + + mem_node = of_parse_phandle(dev->of_node, "memory-region", 0); + if (mem_node) { + ret = of_reserved_mem_device_init_by_idx(dev, + dev->of_node, 0); + of_node_put(dev->of_node); + if (ret) { + dprintk(CVP_ERR, + "Failed to initialize reserved mem, ret %d\n", + ret); + return ret; + } + } + res->mem_cdsp.dev = dev; + + return 0; +} + +static int msm_cvp_populate_bus(struct device *dev, + struct msm_cvp_platform_resources *res) +{ + struct bus_set *buses = &res->bus_set; + const char *temp_name = NULL; + struct bus_info *bus = NULL, *temp_table; + u32 range[2]; + int rc = 0; + + temp_table = krealloc(buses->bus_tbl, sizeof(*temp_table) * + (buses->count + 1), GFP_KERNEL); + if (!temp_table) { + dprintk(CVP_ERR, "%s: Failed to allocate memory", __func__); + rc = -ENOMEM; + goto err_bus; + } + + buses->bus_tbl = temp_table; + bus = &buses->bus_tbl[buses->count]; + + memset(bus, 0x0, sizeof(struct bus_info)); + + rc = of_property_read_string(dev->of_node, "label", &temp_name); + if (rc) { + dprintk(CVP_ERR, "'label' not found in node\n"); + goto err_bus; + } + /* need a non-const version of name, hence copying it over */ + bus->name = devm_kstrdup(dev, temp_name, GFP_KERNEL); + if (!bus->name) { + rc = -ENOMEM; + goto err_bus; + } + + rc = of_property_read_u32(dev->of_node, "qcom,bus-master", + &bus->master); + if (rc) { + dprintk(CVP_ERR, "'qcom,bus-master' not found in node\n"); + goto err_bus; + } + + rc = of_property_read_u32(dev->of_node, "qcom,bus-slave", &bus->slave); + if (rc) { + dprintk(CVP_ERR, "'qcom,bus-slave' not found in node\n"); + goto err_bus; + } + + rc = of_property_read_string(dev->of_node, "qcom,bus-governor", + &bus->governor); + if (rc) { + rc = 0; + dprintk(CVP_CORE, + "'qcom,bus-governor' not found, default to performance governor\n"); + bus->governor = PERF_GOV; + } + + if (!strcmp(bus->governor, PERF_GOV)) + bus->is_prfm_gov_used = true; + + rc = of_property_read_u32_array(dev->of_node, "qcom,bus-range-kbps", + range, ARRAY_SIZE(range)); + if (rc) { + rc = 0; + dprintk(CVP_CORE, + "'qcom,range' not found defaulting to <0 INT_MAX>\n"); + range[0] = 0; + range[1] = INT_MAX; + } + + bus->range[0] = range[0]; /* min */ + bus->range[1] = range[1]; /* max */ + + buses->count++; + bus->dev = dev; + dprintk(CVP_CORE, "Found bus %s [%d->%d] with governor %s\n", + bus->name, bus->master, bus->slave, bus->governor); +err_bus: + return rc; +} + +static int msm_cvp_load_regulator_table( + struct msm_cvp_platform_resources *res) +{ + int rc = 0; + struct platform_device *pdev = res->pdev; + struct regulator_set *regulators = &res->regulator_set; + struct device_node *domains_parent_node = NULL; + struct property *domains_property = NULL; + int reg_count = 0; + + regulators->count = 0; + regulators->regulator_tbl = NULL; + + domains_parent_node = pdev->dev.of_node; + for_each_property_of_node(domains_parent_node, domains_property) { + const char *search_string = "-supply"; + char *supply; + bool matched = false; + + /* check if current property is possibly a regulator */ + supply = strnstr(domains_property->name, search_string, + strlen(domains_property->name) + 1); + matched = supply && (*(supply + strlen(search_string)) == '\0'); + if (!matched) + continue; + + reg_count++; + } + + regulators->regulator_tbl = devm_kzalloc(&pdev->dev, + sizeof(*regulators->regulator_tbl) * + reg_count, GFP_KERNEL); + + if (!regulators->regulator_tbl) { + rc = -ENOMEM; + dprintk(CVP_ERR, + "Failed to alloc memory for regulator table\n"); + goto err_reg_tbl_alloc; + } + + for_each_property_of_node(domains_parent_node, domains_property) { + const char *search_string = "-supply"; + char *supply; + bool matched = false; + struct device_node *regulator_node = NULL; + struct regulator_info *rinfo = NULL; + + /* check if current property is possibly a regulator */ + supply = strnstr(domains_property->name, search_string, + strlen(domains_property->name) + 1); + matched = supply && (supply[strlen(search_string)] == '\0'); + if (!matched) + continue; + + /* make sure prop isn't being misused */ + regulator_node = of_parse_phandle(domains_parent_node, + domains_property->name, 0); + if (IS_ERR(regulator_node)) { + dprintk(CVP_WARN, "%s is not a phandle\n", + domains_property->name); + continue; + } + regulators->count++; + + /* populate regulator info */ + rinfo = ®ulators->regulator_tbl[regulators->count - 1]; + rinfo->name = devm_kzalloc(&pdev->dev, + (supply - domains_property->name) + 1, GFP_KERNEL); + if (!rinfo->name) { + rc = -ENOMEM; + dprintk(CVP_ERR, + "Failed to alloc memory for regulator name\n"); + goto err_reg_name_alloc; + } + strlcpy(rinfo->name, domains_property->name, + (supply - domains_property->name) + 1); + + rinfo->has_hw_power_collapse = of_property_read_bool( + regulator_node, "qcom,support-hw-trigger"); + + dprintk(CVP_CORE, "Found regulator %s: h/w collapse = %s\n", + rinfo->name, + rinfo->has_hw_power_collapse ? "yes" : "no"); + } + + if (!regulators->count) + dprintk(CVP_CORE, "No regulators found"); + + return 0; + +err_reg_name_alloc: +err_reg_tbl_alloc: + msm_cvp_free_regulator_table(res); + return rc; +} + +static int msm_cvp_load_clock_table( + struct msm_cvp_platform_resources *res) +{ + int rc = 0, num_clocks = 0, c = 0; + struct platform_device *pdev = res->pdev; + int *clock_props = NULL; + struct clock_set *clocks = &res->clock_set; + + num_clocks = of_property_count_strings(pdev->dev.of_node, + "clock-names"); + if (num_clocks <= 0) { + dprintk(CVP_CORE, "No clocks found\n"); + clocks->count = 0; + rc = 0; + goto err_load_clk_table_fail; + } + + clock_props = devm_kzalloc(&pdev->dev, num_clocks * + sizeof(*clock_props), GFP_KERNEL); + if (!clock_props) { + dprintk(CVP_ERR, "No memory to read clock properties\n"); + rc = -ENOMEM; + goto err_load_clk_table_fail; + } + + rc = of_property_read_u32_array(pdev->dev.of_node, + "qcom,clock-configs", clock_props, + num_clocks); + if (rc) { + dprintk(CVP_ERR, "Failed to read clock properties: %d\n", rc); + goto err_load_clk_prop_fail; + } + + clocks->clock_tbl = devm_kzalloc(&pdev->dev, sizeof(*clocks->clock_tbl) + * num_clocks, GFP_KERNEL); + if (!clocks->clock_tbl) { + dprintk(CVP_ERR, "Failed to allocate memory for clock tbl\n"); + rc = -ENOMEM; + goto err_load_clk_prop_fail; + } + + clocks->count = num_clocks; + dprintk(CVP_CORE, "Found %d clocks\n", num_clocks); + + for (c = 0; c < num_clocks; ++c) { + struct clock_info *vc = &res->clock_set.clock_tbl[c]; + + of_property_read_string_index(pdev->dev.of_node, + "clock-names", c, &vc->name); + + if (clock_props[c] & CLOCK_PROP_HAS_SCALING) { + vc->has_scaling = true; + } else { + vc->count = 0; + vc->has_scaling = false; + } + + if (clock_props[c] & CLOCK_PROP_HAS_MEM_RETENTION) + vc->has_mem_retention = true; + else + vc->has_mem_retention = false; + + dprintk(CVP_CORE, "Found clock %s: scale-able = %s\n", vc->name, + vc->count ? "yes" : "no"); + } + + return 0; + +err_load_clk_prop_fail: +err_load_clk_table_fail: + return rc; +} + +#define MAX_CLK_RESETS 5 + +static int msm_cvp_load_reset_table( + struct msm_cvp_platform_resources *res) +{ + struct platform_device *pdev = res->pdev; + struct reset_set *rst = &res->reset_set; + int num_clocks = 0, c = 0, ret = 0; + int pwr_stats[MAX_CLK_RESETS]; + + num_clocks = of_property_count_strings(pdev->dev.of_node, + "reset-names"); + if (num_clocks <= 0 || num_clocks > MAX_CLK_RESETS) { + dprintk(CVP_ERR, "Num reset clocks out of range\n"); + rst->count = 0; + return 0; + } + + rst->reset_tbl = devm_kcalloc(&pdev->dev, num_clocks, + sizeof(*rst->reset_tbl), GFP_KERNEL); + if (!rst->reset_tbl) + return -ENOMEM; + + rst->count = num_clocks; + dprintk(CVP_CORE, "Found %d reset clocks\n", num_clocks); + ret = of_property_read_u32_array(pdev->dev.of_node, + "reset-power-status", pwr_stats, + num_clocks); + if (ret) { + dprintk(CVP_ERR, "Failed to read reset pwr state: %d\n", ret); + devm_kfree(&pdev->dev, rst->reset_tbl); + return ret; + } + + for (c = 0; c < num_clocks; ++c) { + struct reset_info *rc = &res->reset_set.reset_tbl[c]; + + of_property_read_string_index(pdev->dev.of_node, + "reset-names", c, &rc->name); + rc->required_state = pwr_stats[c]; + } + + return 0; +} + +static int find_key_value(struct msm_cvp_platform_data *platform_data, + const char *key) +{ + int i = 0; + struct msm_cvp_common_data *common_data = platform_data->common_data; + int size = platform_data->common_data_length; + + for (i = 0; i < size; i++) { + if (!strcmp(common_data[i].key, key)) + return common_data[i].value; + } + return 0; +} + +int cvp_read_platform_resources_from_drv_data( + struct msm_cvp_core *core) +{ + struct msm_cvp_platform_data *platform_data; + struct msm_cvp_platform_resources *res; + int rc = 0; + + if (!core || !core->platform_data) { + dprintk(CVP_ERR, "%s Invalid data\n", __func__); + return -ENOENT; + } + platform_data = core->platform_data; + res = &core->resources; + + res->sku_version = platform_data->sku_version; + + res->fw_name = "evass"; + + dprintk(CVP_CORE, "Firmware filename: %s\n", res->fw_name); + + res->auto_pil = find_key_value(platform_data, + "qcom,auto-pil"); + + res->max_load = find_key_value(platform_data, + "qcom,max-hw-load"); + + res->sw_power_collapsible = find_key_value(platform_data, + "qcom,sw-power-collapse"); + + res->never_unload_fw = find_key_value(platform_data, + "qcom,never-unload-fw"); + + res->debug_timeout = find_key_value(platform_data, + "qcom,debug-timeout"); + + res->pm_qos_latency_us = find_key_value(platform_data, + "qcom,pm-qos-latency-us"); + + res->max_secure_inst_count = find_key_value(platform_data, + "qcom,max-secure-instances"); + + res->thermal_mitigable = find_key_value(platform_data, + "qcom,enable-thermal-mitigation"); + res->msm_cvp_pwr_collapse_delay = find_key_value(platform_data, + "qcom,power-collapse-delay"); + res->msm_cvp_firmware_unload_delay = find_key_value(platform_data, + "qcom,fw-unload-delay"); + res->msm_cvp_hw_rsp_timeout = find_key_value(platform_data, + "qcom,hw-resp-timeout"); + res->msm_cvp_dsp_rsp_timeout = find_key_value(platform_data, + "qcom,dsp-resp-timeout"); + res->non_fatal_pagefaults = find_key_value(platform_data, + "qcom,domain-attr-non-fatal-faults"); + + res->vpu_ver = platform_data->vpu_ver; + res->ubwc_config = platform_data->ubwc_config; + return rc; + +} + +int cvp_read_platform_resources_from_dt( + struct msm_cvp_platform_resources *res) +{ + struct platform_device *pdev = res->pdev; + struct resource *kres = NULL; + int rc = 0; + uint32_t firmware_base = 0; + + if (!pdev->dev.of_node) { + dprintk(CVP_ERR, "DT node not found\n"); + return -ENOENT; + } + + INIT_LIST_HEAD(&res->context_banks); + + res->firmware_base = (phys_addr_t)firmware_base; + + kres = platform_get_resource(pdev, IORESOURCE_MEM, 0); + res->register_base = kres ? kres->start : -1; + res->register_size = kres ? (kres->end + 1 - kres->start) : -1; + + kres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + res->irq = kres ? kres->start : -1; + + rc = msm_cvp_load_subcache_info(res); + if (rc) + dprintk(CVP_WARN, "Failed to load subcache info: %d\n", rc); + + rc = msm_cvp_load_qdss_table(res); + if (rc) + dprintk(CVP_WARN, "Failed to load qdss reg table: %d\n", rc); + + rc = msm_cvp_load_reg_table(res); + if (rc) { + dprintk(CVP_ERR, "Failed to load reg table: %d\n", rc); + goto err_load_reg_table; + } + + rc = msm_cvp_load_regulator_table(res); + if (rc) { + dprintk(CVP_ERR, "Failed to load list of regulators %d\n", rc); + goto err_load_regulator_table; + } + + rc = msm_cvp_load_clock_table(res); + if (rc) { + dprintk(CVP_ERR, + "Failed to load clock table: %d\n", rc); + goto err_load_clock_table; + } + + rc = msm_cvp_load_allowed_clocks_table(res); + if (rc) { + dprintk(CVP_ERR, + "Failed to load allowed clocks table: %d\n", rc); + goto err_load_allowed_clocks_table; + } + + rc = msm_cvp_load_reset_table(res); + if (rc) { + dprintk(CVP_ERR, + "Failed to load reset table: %d\n", rc); + goto err_load_reset_table; + } + + res->use_non_secure_pil = of_property_read_bool(pdev->dev.of_node, + "qcom,use-non-secure-pil"); + + if (res->use_non_secure_pil || !is_iommu_present(res)) { + of_property_read_u32(pdev->dev.of_node, "qcom,fw-bias", + &firmware_base); + res->firmware_base = (phys_addr_t)firmware_base; + dprintk(CVP_CORE, + "Using fw-bias : %pa", &res->firmware_base); + } + +return rc; + +err_load_reset_table: + msm_cvp_free_allowed_clocks_table(res); +err_load_allowed_clocks_table: + msm_cvp_free_clock_table(res); +err_load_clock_table: + msm_cvp_free_regulator_table(res); +err_load_regulator_table: + msm_cvp_free_reg_table(res); +err_load_reg_table: + return rc; +} + +static int msm_cvp_setup_context_bank(struct msm_cvp_platform_resources *res, + struct context_bank_info *cb, struct device *dev) +{ + int rc = 0; + struct bus_type *bus; + + if (!dev || !cb || !res) { + dprintk(CVP_ERR, + "%s: Invalid Input params\n", __func__); + return -EINVAL; + } + cb->dev = dev; + + bus = cb->dev->bus; + if (IS_ERR_OR_NULL(bus)) { + dprintk(CVP_ERR, "%s - failed to get bus type\n", __func__); + rc = PTR_ERR(bus) ?: -ENODEV; + goto remove_cb; + } + + /* + * configure device segment size and segment boundary to ensure + * iommu mapping returns one mapping (which is required for partial + * cache operations) + */ + if (!dev->dma_parms) + dev->dma_parms = + devm_kzalloc(dev, sizeof(*dev->dma_parms), GFP_KERNEL); + dma_set_max_seg_size(dev, DMA_BIT_MASK(32)); + dma_set_seg_boundary(dev, DMA_BIT_MASK(64)); + + dprintk(CVP_CORE, "Attached %s and created mapping\n", dev_name(dev)); + dprintk(CVP_CORE, + "Context bank name:%s, buffer_type: %#x, is_secure: %d, address range start: %#x, size: %#x, dev: %pK", + cb->name, cb->buffer_type, cb->is_secure, cb->addr_range.start, + cb->addr_range.size, cb->dev); + + return rc; + +remove_cb: + return rc; +} + +int msm_cvp_smmu_fault_handler(struct iommu_domain *domain, + struct device *dev, unsigned long iova, int flags, void *token) +{ + struct msm_cvp_core *core = token; + struct msm_cvp_inst *inst; + u32 *pfaddr = &core->last_fault_addr; + + if (!domain || !core) { + dprintk(CVP_ERR, "%s - invalid param %pK %pK\n", + __func__, domain, core); + return -EINVAL; + } + + if (core->smmu_fault_handled) { + if (core->resources.non_fatal_pagefaults) { + WARN_ONCE(1, "%s: non-fatal pagefault address: %lx\n", + __func__, iova); + *pfaddr = (*pfaddr == 0) ? iova : (*pfaddr); + return 0; + } + } + + dprintk(CVP_ERR, "%s - faulting address: %lx\n", __func__, iova); + + mutex_lock(&core->lock); + list_for_each_entry(inst, &core->instances, list) { + msm_cvp_print_inst_bufs(inst); + } + core->smmu_fault_handled = true; + msm_cvp_noc_error_info(core); + mutex_unlock(&core->lock); + /* + * Return -EINVAL to elicit the default behaviour of smmu driver. + * If we return -ENOSYS, then smmu driver assumes page fault handler + * is not installed and prints a list of useful debug information like + * FAR, SID etc. This information is not printed if we return 0. + */ + return -EINVAL; +} + +static int msm_cvp_populate_context_bank(struct device *dev, + struct msm_cvp_core *core) +{ + int rc = 0; + struct context_bank_info *cb = NULL; + struct device_node *np = NULL; + + if (!dev || !core) { + dprintk(CVP_ERR, "%s - invalid inputs\n", __func__); + return -EINVAL; + } + + np = dev->of_node; + cb = devm_kzalloc(dev, sizeof(*cb), GFP_KERNEL); + if (!cb) { + dprintk(CVP_ERR, "%s - Failed to allocate cb\n", __func__); + return -ENOMEM; + } + + INIT_LIST_HEAD(&cb->list); + list_add_tail(&cb->list, &core->resources.context_banks); + + rc = of_property_read_string(np, "label", &cb->name); + if (rc) { + dprintk(CVP_CORE, + "Failed to read cb label from device tree\n"); + rc = 0; + } + + dprintk(CVP_CORE, "%s: context bank has name %s\n", __func__, cb->name); + rc = of_property_read_u32_array(np, "qcom,iommu-dma-addr-pool", + (u32 *)&cb->addr_range, 2); + if (rc) { + dprintk(CVP_ERR, + "Could not read addr pool for context bank : %s %d\n", + cb->name, rc); + goto err_setup_cb; + } + + cb->is_secure = of_property_read_bool(np, "qcom,iommu-vmid"); + dprintk(CVP_CORE, "context bank %s : secure = %d\n", + cb->name, cb->is_secure); + + /* setup buffer type for each sub device*/ + rc = of_property_read_u32(np, "buffer-types", &cb->buffer_type); + if (rc) { + dprintk(CVP_ERR, "failed to load buffer_type info %d\n", rc); + rc = -ENOENT; + goto err_setup_cb; + } + dprintk(CVP_CORE, + "context bank %s address start = %x address size = %x buffer_type = %x\n", + cb->name, cb->addr_range.start, + cb->addr_range.size, cb->buffer_type); + + cb->domain = iommu_get_domain_for_dev(dev); + if (IS_ERR_OR_NULL(cb->domain)) { + dprintk(CVP_ERR, "Create domain failed\n"); + rc = -ENODEV; + goto err_setup_cb; + } + + rc = msm_cvp_setup_context_bank(&core->resources, cb, dev); + if (rc) { + dprintk(CVP_ERR, "Cannot setup context bank %d\n", rc); + goto err_setup_cb; + } + + iommu_set_fault_handler(cb->domain, + msm_cvp_smmu_fault_handler, (void *)core); + + return 0; + +err_setup_cb: + list_del(&cb->list); + return rc; +} + +int cvp_read_context_bank_resources_from_dt(struct platform_device *pdev) +{ + struct msm_cvp_core *core; + int rc = 0; + + if (!pdev) { + dprintk(CVP_ERR, "Invalid platform device\n"); + return -EINVAL; + } else if (!pdev->dev.parent) { + dprintk(CVP_ERR, "Failed to find a parent for %s\n", + dev_name(&pdev->dev)); + return -ENODEV; + } + + core = dev_get_drvdata(pdev->dev.parent); + if (!core) { + dprintk(CVP_ERR, "Failed to find cookie in parent device %s", + dev_name(pdev->dev.parent)); + return -EINVAL; + } + + rc = msm_cvp_populate_context_bank(&pdev->dev, core); + if (rc) + dprintk(CVP_ERR, "Failed to probe context bank\n"); + else + dprintk(CVP_CORE, "Successfully probed context bank\n"); + + return rc; +} + +int cvp_read_bus_resources_from_dt(struct platform_device *pdev) +{ + struct msm_cvp_core *core; + + if (!pdev) { + dprintk(CVP_ERR, "Invalid platform device\n"); + return -EINVAL; + } else if (!pdev->dev.parent) { + dprintk(CVP_ERR, "Failed to find a parent for %s\n", + dev_name(&pdev->dev)); + return -ENODEV; + } + + core = dev_get_drvdata(pdev->dev.parent); + if (!core) { + dprintk(CVP_ERR, "Failed to find cookie in parent device %s", + dev_name(pdev->dev.parent)); + return -EINVAL; + } + + return msm_cvp_populate_bus(&pdev->dev, &core->resources); +} + +int cvp_read_mem_cdsp_resources_from_dt(struct platform_device *pdev) +{ + struct msm_cvp_core *core; + + if (!pdev) { + dprintk(CVP_ERR, "%s: invalid platform device\n", __func__); + return -EINVAL; + } else if (!pdev->dev.parent) { + dprintk(CVP_ERR, "Failed to find a parent for %s\n", + dev_name(&pdev->dev)); + return -ENODEV; + } + + core = dev_get_drvdata(pdev->dev.parent); + if (!core) { + dprintk(CVP_ERR, "Failed to find cookie in parent device %s", + dev_name(pdev->dev.parent)); + return -EINVAL; + } + + return msm_cvp_populate_mem_cdsp(&pdev->dev, &core->resources); +} diff --git a/msm/eva/msm_cvp_res_parse.h b/msm/eva/msm_cvp_res_parse.h new file mode 100644 index 0000000000..814ee94e81 --- /dev/null +++ b/msm/eva/msm_cvp_res_parse.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#ifndef __MSM_CVP_RES_PARSE_H__ +#define __MSM_CVP_RES_PARSE_H__ +#include +#include "msm_cvp_resources.h" +#include "msm_cvp_common.h" +void msm_cvp_free_platform_resources( + struct msm_cvp_platform_resources *res); + +int read_hfi_type(struct platform_device *pdev); + +int cvp_read_platform_resources_from_drv_data( + struct msm_cvp_core *core); +int cvp_read_platform_resources_from_dt( + struct msm_cvp_platform_resources *res); + +int cvp_read_context_bank_resources_from_dt(struct platform_device *pdev); + +int cvp_read_bus_resources_from_dt(struct platform_device *pdev); +int cvp_read_mem_cdsp_resources_from_dt(struct platform_device *pdev); + +int msm_cvp_load_u32_table(struct platform_device *pdev, + struct device_node *of_node, char *table_name, int struct_size, + u32 **table, u32 *num_elements); + +#endif diff --git a/msm/eva/msm_cvp_resources.h b/msm/eva/msm_cvp_resources.h new file mode 100644 index 0000000000..7ce228cbe3 --- /dev/null +++ b/msm/eva/msm_cvp_resources.h @@ -0,0 +1,185 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#ifndef __MSM_CVP_RESOURCES_H__ +#define __MSM_CVP_RESOURCES_H__ + +#include +#include +#include "msm_cvp_core.h" +#include + +struct reg_value_pair { + u32 reg; + u32 value; +}; + +struct reg_set { + struct reg_value_pair *reg_tbl; + int count; +}; + +struct addr_range { + u32 start; + u32 size; +}; + +struct addr_set { + struct addr_range *addr_tbl; + int count; +}; + +struct context_bank_info { + struct list_head list; + const char *name; + u32 buffer_type; + bool is_secure; + struct addr_range addr_range; + struct device *dev; + struct iommu_domain *domain; +}; + +struct regulator_info { + struct regulator *regulator; + bool has_hw_power_collapse; + char *name; +}; + +struct regulator_set { + struct regulator_info *regulator_tbl; + u32 count; +}; + +struct clock_info { + const char *name; + struct clk *clk; + u32 count; + bool has_scaling; + bool has_mem_retention; +}; + +struct clock_set { + struct clock_info *clock_tbl; + u32 count; +}; + +struct bus_info { + char *name; + int master; + int slave; + unsigned int range[2]; + const char *governor; + struct device *dev; + struct devfreq_dev_profile devfreq_prof; + struct devfreq *devfreq; + struct icc_path *client; + bool is_prfm_gov_used; +}; + +struct bus_set { + struct bus_info *bus_tbl; + u32 count; +}; + +enum power_state { + CVP_POWER_INIT, + CVP_POWER_ON, + CVP_POWER_OFF, + CVP_POWER_INVALID, +}; + +struct reset_info { + struct reset_control *rst; + enum power_state required_state; + const char *name; +}; + +struct reset_set { + struct reset_info *reset_tbl; + u32 count; +}; + +struct allowed_clock_rates_table { + u32 clock_rate; +}; + +struct clock_profile_entry { + u32 codec_mask; + u32 vpp_cycles; + u32 vsp_cycles; + u32 low_power_cycles; +}; + +struct clock_freq_table { + struct clock_profile_entry *clk_prof_entries; + u32 count; +}; + +struct subcache_info { + const char *name; + bool isactive; + bool isset; + struct llcc_slice_desc *subcache; +}; + +struct subcache_set { + struct subcache_info *subcache_tbl; + u32 count; +}; + +struct msm_cvp_mem_cdsp { + struct device *dev; +}; + +struct msm_cvp_platform_resources { + phys_addr_t firmware_base; + phys_addr_t register_base; + uint32_t register_size; + uint32_t irq; + uint32_t sku_version; + struct allowed_clock_rates_table *allowed_clks_tbl; + u32 allowed_clks_tbl_size; + struct clock_freq_table clock_freq_tbl; + bool sys_cache_present; + bool sys_cache_res_set; + struct subcache_set subcache_set; + struct reg_set reg_set; + struct addr_set qdss_addr_set; + uint32_t max_load; + struct platform_device *pdev; + struct regulator_set regulator_set; + struct clock_set clock_set; + struct bus_set bus_set; + struct reset_set reset_set; + bool use_non_secure_pil; + bool sw_power_collapsible; + bool auto_pil; + struct list_head context_banks; + bool thermal_mitigable; + const char *fw_name; + const char *hfi_version; + bool never_unload_fw; + bool debug_timeout; + uint32_t pm_qos_latency_us; + uint32_t max_inst_count; + uint32_t max_secure_inst_count; + int msm_cvp_hw_rsp_timeout; + int msm_cvp_dsp_rsp_timeout; + int msm_cvp_firmware_unload_delay; + uint32_t msm_cvp_pwr_collapse_delay; + bool non_fatal_pagefaults; + struct msm_cvp_mem_cdsp mem_cdsp; + uint32_t vpu_ver; + uint32_t fw_cycles; + struct msm_cvp_ubwc_config_data *ubwc_config; +}; + +static inline bool is_iommu_present(struct msm_cvp_platform_resources *res) +{ + return !list_empty(&res->context_banks); +} + +#endif + diff --git a/msm/eva/msm_cvp_synx.c b/msm/eva/msm_cvp_synx.c new file mode 100644 index 0000000000..a114ff6f9c --- /dev/null +++ b/msm/eva/msm_cvp_synx.c @@ -0,0 +1,240 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include "msm_cvp_common.h" +#include "cvp_hfi_api.h" +#include "msm_cvp_debug.h" +#include "msm_cvp_core.h" +#include "msm_cvp_dsp.h" + +void cvp_dump_fence_queue(struct msm_cvp_inst *inst) +{ + struct cvp_fence_queue *q; + struct cvp_fence_command *f; + struct synx_session ssid; + int i; + + q = &inst->fence_cmd_queue; + ssid = inst->synx_session_id; + mutex_lock(&q->lock); + dprintk(CVP_WARN, "inst %x fence q mode %d, ssid %d\n", + hash32_ptr(inst->session), q->mode, ssid.client_id); + + dprintk(CVP_WARN, "fence cmdq wait list:\n"); + list_for_each_entry(f, &q->wait_list, list) { + dprintk(CVP_WARN, "frame pkt type 0x%x\n", f->pkt->packet_type); + for (i = 0; i < f->output_index; i++) + dprintk(CVP_WARN, "idx %d client hdl %d, state %d\n", + i, f->synx[i], + synx_get_status(ssid, f->synx[i])); + + } + + dprintk(CVP_WARN, "fence cmdq schedule list:\n"); + list_for_each_entry(f, &q->sched_list, list) { + dprintk(CVP_WARN, "frame pkt type 0x%x\n", f->pkt->packet_type); + for (i = 0; i < f->output_index; i++) + dprintk(CVP_WARN, "idx %d client hdl %d, state %d\n", + i, f->synx[i], + synx_get_status(ssid, f->synx[i])); + + } + mutex_unlock(&q->lock); +} + +int cvp_import_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, + u32 *fence) +{ + int rc = 0; + int i; + struct cvp_fence_type *fs; + struct synx_import_params params; + s32 h_synx; + struct synx_session ssid; + + if (fc->signature != 0xFEEDFACE) { + dprintk(CVP_ERR, "%s Deprecated synx path\n", __func__); + return -EINVAL; + } + + fs = (struct cvp_fence_type *)fence; + ssid = inst->synx_session_id; + + for (i = 0; i < fc->num_fences; ++i) { + h_synx = fs[i].h_synx; + + if (h_synx) { + params.h_synx = h_synx; + params.secure_key = fs[i].secure_key; + params.new_h_synx = &fc->synx[i]; + + rc = synx_import(ssid, ¶ms); + if (rc) { + dprintk(CVP_ERR, + "%s: synx_import failed\n", + __func__); + return rc; + } + } + } + + return 0; +} + +int cvp_release_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc) +{ + int rc = 0; + int i; + s32 h_synx; + struct synx_session ssid; + + if (fc->signature != 0xFEEDFACE) { + dprintk(CVP_ERR, "%s deprecated synx_path\n", __func__); + return -EINVAL; + } + + ssid = inst->synx_session_id; + for (i = 0; i < fc->num_fences; ++i) { + h_synx = fc->synx[i]; + if (h_synx) { + rc = synx_release(ssid, h_synx); + if (rc) + dprintk(CVP_ERR, + "%s: synx_release %d failed\n", + __func__, i); + } + } + return rc; +} + +static int cvp_cancel_synx_impl(struct msm_cvp_inst *inst, + enum cvp_synx_type type, + struct cvp_fence_command *fc) +{ + int rc = 0; + int i; + int h_synx; + struct synx_session ssid; + int start = 0, end = 0; + int synx_state = SYNX_STATE_SIGNALED_CANCEL; + + ssid = inst->synx_session_id; + + if (type == CVP_INPUT_SYNX) { + start = 0; + end = fc->output_index; + } else if (type == CVP_OUTPUT_SYNX) { + start = fc->output_index; + end = fc->num_fences; + } else { + dprintk(CVP_ERR, "%s Incorrect synx type\n", __func__); + return -EINVAL; + } + + for (i = start; i < end; ++i) { + h_synx = fc->synx[i]; + if (h_synx) { + rc = synx_signal(ssid, h_synx, synx_state); + if (rc) { + dprintk(CVP_ERR, "%s: synx_signal %d failed\n", + __func__, i); + synx_state = SYNX_STATE_SIGNALED_ERROR; + } + } + } + + return rc; + + +} + +int cvp_cancel_synx(struct msm_cvp_inst *inst, enum cvp_synx_type type, + struct cvp_fence_command *fc) +{ + if (fc->signature != 0xFEEDFACE) { + dprintk(CVP_ERR, "%s deprecated synx path\n", __func__); + return -EINVAL; + } + + return cvp_cancel_synx_impl(inst, type, fc); +} + +static int cvp_wait_synx(struct synx_session ssid, u32 *synx, u32 num_synx, + u32 *synx_state) +{ + int i = 0, rc = 0; + unsigned long timeout_ms = 1000; + int h_synx; + + while (i < num_synx) { + h_synx = synx[i]; + if (h_synx) { + rc = synx_wait(ssid, h_synx, timeout_ms); + if (rc) { + *synx_state = synx_get_status(ssid, h_synx); + if (*synx_state == SYNX_STATE_SIGNALED_CANCEL) { + dprintk(CVP_SYNX, + "%s: synx_wait %d cancel %d state %d\n", + current->comm, i, rc, *synx_state); + } else { + dprintk(CVP_ERR, + "%s: synx_wait %d failed %d state %d\n", + current->comm, i, rc, *synx_state); + *synx_state = SYNX_STATE_SIGNALED_ERROR; + } + return rc; + } + } + ++i; + } + return rc; +} + +static int cvp_signal_synx(struct synx_session ssid, u32 *synx, u32 num_synx, + u32 synx_state) +{ + int i = 0, rc = 0; + int h_synx; + + while (i < num_synx) { + h_synx = synx[i]; + if (h_synx) { + rc = synx_signal(ssid, h_synx, synx_state); + if (rc) { + dprintk(CVP_ERR, "%s: synx_signal %d failed\n", + current->comm, i); + synx_state = SYNX_STATE_SIGNALED_ERROR; + } + } + ++i; + } + return rc; +} + +int cvp_synx_ops(struct msm_cvp_inst *inst, enum cvp_synx_type type, + struct cvp_fence_command *fc, u32 *synx_state) +{ + struct synx_session ssid; + + ssid = inst->synx_session_id; + + if (fc->signature != 0xFEEDFACE) { + dprintk(CVP_ERR, "%s deprecated synx, type %d\n", __func__); + return -EINVAL; + } + + if (type == CVP_INPUT_SYNX) { + return cvp_wait_synx(ssid, fc->synx, fc->output_index, + synx_state); + } else if (type == CVP_OUTPUT_SYNX) { + return cvp_signal_synx(ssid, &fc->synx[fc->output_index], + (fc->num_fences - fc->output_index), + *synx_state); + } else { + dprintk(CVP_ERR, "%s Incorrect SYNX type\n", __func__); + return -EINVAL; + } +} + diff --git a/msm/eva/msm_cvp_synx.h b/msm/eva/msm_cvp_synx.h new file mode 100644 index 0000000000..27c0052fa8 --- /dev/null +++ b/msm/eva/msm_cvp_synx.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#ifndef _MSM_CVP_SYNX_H_ +#define _MSM_CVP_SYNX_H_ + +#include +#include +#include "cvp_comm_def.h" + + +struct cvp_fence_queue { + struct mutex lock; + enum queue_state state; + enum op_mode mode; + struct list_head wait_list; + wait_queue_head_t wq; + struct list_head sched_list; +}; + +struct cvp_fence_type { + s32 h_synx; + u32 secure_key; +}; + +struct cvp_fence_command { + struct list_head list; + u64 frame_id; + enum op_mode mode; + u32 signature; + u32 num_fences; + u32 output_index; + u32 type; + u32 synx[MAX_HFI_FENCE_SIZE/2]; + struct cvp_hfi_cmd_session_hdr *pkt; +}; + +enum cvp_synx_type { + CVP_UINIT_SYNX, + CVP_INPUT_SYNX, + CVP_OUTPUT_SYNX, + CVP_INVALID_SYNX, +}; + +int cvp_import_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, + u32 *fence); +int cvp_release_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc); +int cvp_cancel_synx(struct msm_cvp_inst *inst, enum cvp_synx_type type, + struct cvp_fence_command *fc); +int cvp_synx_ops(struct msm_cvp_inst *inst, enum cvp_synx_type type, + struct cvp_fence_command *fc, u32 *synx_state); +void cvp_dump_fence_queue(struct msm_cvp_inst *inst); +#endif diff --git a/msm/eva/msm_smem.c b/msm/eva/msm_smem.c new file mode 100644 index 0000000000..22cc131ecd --- /dev/null +++ b/msm/eva/msm_smem.c @@ -0,0 +1,473 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "msm_cvp_core.h" +#include "msm_cvp_debug.h" +#include "msm_cvp_resources.h" + + +static int msm_dma_get_device_address(struct dma_buf *dbuf, u32 align, + dma_addr_t *iova, u32 flags, unsigned long ion_flags, + struct msm_cvp_platform_resources *res, + struct cvp_dma_mapping_info *mapping_info) +{ + int rc = 0; + struct dma_buf_attachment *attach; + struct sg_table *table = NULL; + struct context_bank_info *cb = NULL; + + if (!dbuf || !iova || !mapping_info) { + dprintk(CVP_ERR, "Invalid params: %pK, %pK, %pK\n", + dbuf, iova, mapping_info); + return -EINVAL; + } + + if (is_iommu_present(res)) { + cb = msm_cvp_smem_get_context_bank((flags & SMEM_SECURE), + res, ion_flags); + if (!cb) { + dprintk(CVP_ERR, + "%s: Failed to get context bank device\n", + __func__); + rc = -EIO; + goto mem_map_failed; + } + + /* Prepare a dma buf for dma on the given device */ + attach = dma_buf_attach(dbuf, cb->dev); + if (IS_ERR_OR_NULL(attach)) { + rc = PTR_ERR(attach) ?: -ENOMEM; + dprintk(CVP_ERR, "Failed to attach dmabuf\n"); + goto mem_buf_attach_failed; + } + + /* + * Get the scatterlist for the given attachment + * Mapping of sg is taken care by map attachment + */ + attach->dma_map_attrs = DMA_ATTR_DELAYED_UNMAP; + /* + * We do not need dma_map function to perform cache operations + * on the whole buffer size and hence pass skip sync flag. + * We do the required cache operations separately for the + * required buffer size + */ + attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC; + if (res->sys_cache_present) + attach->dma_map_attrs |= + DMA_ATTR_IOMMU_USE_UPSTREAM_HINT; + + table = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); + if (IS_ERR_OR_NULL(table)) { + rc = PTR_ERR(table) ?: -ENOMEM; + dprintk(CVP_ERR, "Failed to map table\n"); + goto mem_map_table_failed; + } + + if (table->sgl) { + *iova = table->sgl->dma_address; + } else { + dprintk(CVP_ERR, "sgl is NULL\n"); + rc = -ENOMEM; + goto mem_map_sg_failed; + } + + mapping_info->dev = cb->dev; + mapping_info->domain = cb->domain; + mapping_info->table = table; + mapping_info->attach = attach; + mapping_info->buf = dbuf; + mapping_info->cb_info = (void *)cb; + } else { + dprintk(CVP_MEM, "iommu not present, use phys mem addr\n"); + } + + return 0; +mem_map_sg_failed: + dma_buf_unmap_attachment(attach, table, DMA_BIDIRECTIONAL); +mem_map_table_failed: + dma_buf_detach(dbuf, attach); +mem_buf_attach_failed: +mem_map_failed: + return rc; +} + +static int msm_dma_put_device_address(u32 flags, + struct cvp_dma_mapping_info *mapping_info) +{ + int rc = 0; + + if (!mapping_info) { + dprintk(CVP_WARN, "Invalid mapping_info\n"); + return -EINVAL; + } + + if (!mapping_info->dev || !mapping_info->table || + !mapping_info->buf || !mapping_info->attach || + !mapping_info->cb_info) { + dprintk(CVP_WARN, "Invalid params\n"); + return -EINVAL; + } + + dma_buf_unmap_attachment(mapping_info->attach, + mapping_info->table, DMA_BIDIRECTIONAL); + dma_buf_detach(mapping_info->buf, mapping_info->attach); + + mapping_info->dev = NULL; + mapping_info->domain = NULL; + mapping_info->table = NULL; + mapping_info->attach = NULL; + mapping_info->buf = NULL; + mapping_info->cb_info = NULL; + + + return rc; +} + +struct dma_buf *msm_cvp_smem_get_dma_buf(int fd) +{ + struct dma_buf *dma_buf; + + dma_buf = dma_buf_get(fd); + if (IS_ERR_OR_NULL(dma_buf)) { + dprintk(CVP_ERR, "Failed to get dma_buf for %d, error %ld\n", + fd, PTR_ERR(dma_buf)); + dma_buf = NULL; + } + + return dma_buf; +} + +void msm_cvp_smem_put_dma_buf(void *dma_buf) +{ + if (!dma_buf) { + dprintk(CVP_ERR, "%s: NULL dma_buf\n", __func__); + return; + } + + dma_buf_put((struct dma_buf *)dma_buf); +} + +int msm_cvp_map_smem(struct msm_cvp_inst *inst, + struct msm_cvp_smem *smem, + const char *str) +{ + int rc = 0; + + dma_addr_t iova = 0; + u32 temp = 0; + u32 align = SZ_4K; + struct dma_buf *dma_buf; + unsigned long ion_flags = 0; + + if (!inst || !smem) { + dprintk(CVP_ERR, "%s: Invalid params: %pK %pK\n", + __func__, inst, smem); + return -EINVAL; + } + + dma_buf = smem->dma_buf; + rc = dma_buf_get_flags(dma_buf, &ion_flags); + if (rc) { + dprintk(CVP_ERR, "Failed to get dma buf flags: %d\n", rc); + goto exit; + } + if (ion_flags & ION_FLAG_CACHED) + smem->flags |= SMEM_CACHED; + + if (ion_flags & ION_FLAG_SECURE) + smem->flags |= SMEM_SECURE; + + rc = msm_dma_get_device_address(dma_buf, align, &iova, smem->flags, + ion_flags, &(inst->core->resources), + &smem->mapping_info); + if (rc) { + dprintk(CVP_ERR, "Failed to get device address: %d\n", rc); + goto exit; + } + temp = (u32)iova; + if ((dma_addr_t)temp != iova) { + dprintk(CVP_ERR, "iova(%pa) truncated to %#x", &iova, temp); + rc = -EINVAL; + goto exit; + } + + smem->size = dma_buf->size; + smem->device_addr = (u32)iova; + + print_smem(CVP_MEM, str, inst, smem); + return rc; +exit: + smem->device_addr = 0x0; + return rc; +} + +int msm_cvp_unmap_smem(struct msm_cvp_inst *inst, + struct msm_cvp_smem *smem, + const char *str) +{ + int rc = 0; + + if (!smem) { + dprintk(CVP_ERR, "%s: Invalid params: %pK\n", __func__, smem); + rc = -EINVAL; + goto exit; + } + + print_smem(CVP_MEM, str, inst, smem); + rc = msm_dma_put_device_address(smem->flags, &smem->mapping_info); + if (rc) { + dprintk(CVP_ERR, "Failed to put device address: %d\n", rc); + goto exit; + } + + smem->device_addr = 0x0; + +exit: + return rc; +} + +static int alloc_dma_mem(size_t size, u32 align, u32 flags, int map_kernel, + struct msm_cvp_platform_resources *res, struct msm_cvp_smem *mem) +{ + dma_addr_t iova = 0; + unsigned long heap_mask = 0; + int rc = 0; + int ion_flags = 0; + struct dma_buf *dbuf = NULL; + + if (!res) { + dprintk(CVP_ERR, "%s: NULL res\n", __func__); + return -EINVAL; + } + + align = ALIGN(align, SZ_4K); + size = ALIGN(size, SZ_4K); + + if (is_iommu_present(res)) { + if (flags & SMEM_ADSP) { + dprintk(CVP_MEM, "Allocating from ADSP heap\n"); + heap_mask = ION_HEAP(ION_ADSP_HEAP_ID); + } else { + heap_mask = ION_HEAP(ION_SYSTEM_HEAP_ID); + } + } else { + dprintk(CVP_MEM, + "allocate shared memory from adsp heap size %zx align %d\n", + size, align); + heap_mask = ION_HEAP(ION_ADSP_HEAP_ID); + } + + if (flags & SMEM_CACHED) + ion_flags |= ION_FLAG_CACHED; + + if (flags & SMEM_NON_PIXEL) + ion_flags |= ION_FLAG_CP_NON_PIXEL; + + if (flags & SMEM_SECURE) { + ion_flags |= ION_FLAG_SECURE; + heap_mask = ION_HEAP(ION_SECURE_HEAP_ID); + } + + dbuf = ion_alloc(size, heap_mask, ion_flags); + if (IS_ERR_OR_NULL(dbuf)) { + dprintk(CVP_ERR, + "Failed to allocate shared memory = %x bytes, %llx, %x\n", + size, heap_mask, ion_flags); + rc = -ENOMEM; + goto fail_shared_mem_alloc; + } + + mem->flags = flags; + mem->ion_flags = ion_flags; + mem->size = size; + mem->dma_buf = dbuf; + mem->kvaddr = NULL; + + rc = msm_dma_get_device_address(dbuf, align, &iova, flags, + ion_flags, res, &mem->mapping_info); + if (rc) { + dprintk(CVP_ERR, "Failed to get device address: %d\n", + rc); + goto fail_device_address; + } + mem->device_addr = (u32)iova; + if ((dma_addr_t)mem->device_addr != iova) { + dprintk(CVP_ERR, "iova(%pa) truncated to %#x", + &iova, mem->device_addr); + goto fail_device_address; + } + + if (map_kernel) { + dma_buf_begin_cpu_access(dbuf, DMA_BIDIRECTIONAL); + mem->kvaddr = dma_buf_vmap(dbuf); + if (!mem->kvaddr) { + dprintk(CVP_ERR, + "Failed to map shared mem in kernel\n"); + rc = -EIO; + goto fail_map; + } + } + + dprintk(CVP_MEM, + "%s: dma_buf = %pK, device_addr = %x, size = %d, kvaddr = %pK, ion_flags = %#x, flags = %#lx\n", + __func__, mem->dma_buf, mem->device_addr, mem->size, + mem->kvaddr, mem->ion_flags, mem->flags); + return rc; + +fail_map: + if (map_kernel) + dma_buf_end_cpu_access(dbuf, DMA_BIDIRECTIONAL); +fail_device_address: + dma_buf_put(dbuf); +fail_shared_mem_alloc: + return rc; +} + +static int free_dma_mem(struct msm_cvp_smem *mem) +{ + dprintk(CVP_MEM, + "%s: dma_buf = %pK, device_addr = %x, size = %d, kvaddr = %pK, ion_flags = %#x\n", + __func__, mem->dma_buf, mem->device_addr, mem->size, + mem->kvaddr, mem->ion_flags); + + if (mem->device_addr) { + msm_dma_put_device_address(mem->flags, &mem->mapping_info); + mem->device_addr = 0x0; + } + + if (mem->kvaddr) { + dma_buf_vunmap(mem->dma_buf, mem->kvaddr); + mem->kvaddr = NULL; + dma_buf_end_cpu_access(mem->dma_buf, DMA_BIDIRECTIONAL); + } + + if (mem->dma_buf) { + dma_buf_put(mem->dma_buf); + mem->dma_buf = NULL; + } + + return 0; +} + +int msm_cvp_smem_alloc(size_t size, u32 align, u32 flags, int map_kernel, + void *res, struct msm_cvp_smem *smem) +{ + int rc = 0; + + if (!smem || !size) { + dprintk(CVP_ERR, "%s: NULL smem or %d size\n", + __func__, (u32)size); + return -EINVAL; + } + + rc = alloc_dma_mem(size, align, flags, map_kernel, + (struct msm_cvp_platform_resources *)res, + smem); + + return rc; +} + +int msm_cvp_smem_free(struct msm_cvp_smem *smem) +{ + int rc = 0; + + if (!smem) { + dprintk(CVP_ERR, "NULL smem passed\n"); + return -EINVAL; + } + rc = free_dma_mem(smem); + + return rc; +}; + +int msm_cvp_smem_cache_operations(struct dma_buf *dbuf, + enum smem_cache_ops cache_op, unsigned long offset, unsigned long size) +{ + int rc = 0; + unsigned long flags = 0; + + if (!dbuf) { + dprintk(CVP_ERR, "%s: Invalid params\n", __func__); + return -EINVAL; + } + + /* Return if buffer doesn't support caching */ + rc = dma_buf_get_flags(dbuf, &flags); + if (rc) { + dprintk(CVP_ERR, "%s: dma_buf_get_flags failed, err %d\n", + __func__, rc); + return rc; + } else if (!(flags & ION_FLAG_CACHED)) { + return rc; + } + + switch (cache_op) { + case SMEM_CACHE_CLEAN: + case SMEM_CACHE_CLEAN_INVALIDATE: + rc = dma_buf_begin_cpu_access_partial(dbuf, DMA_BIDIRECTIONAL, + offset, size); + if (rc) + break; + rc = dma_buf_end_cpu_access_partial(dbuf, DMA_BIDIRECTIONAL, + offset, size); + break; + case SMEM_CACHE_INVALIDATE: + rc = dma_buf_begin_cpu_access_partial(dbuf, DMA_TO_DEVICE, + offset, size); + if (rc) + break; + rc = dma_buf_end_cpu_access_partial(dbuf, DMA_FROM_DEVICE, + offset, size); + break; + default: + dprintk(CVP_ERR, "%s: cache (%d) operation not supported\n", + __func__, cache_op); + rc = -EINVAL; + break; + } + + return rc; +} + +struct context_bank_info *msm_cvp_smem_get_context_bank(bool is_secure, + struct msm_cvp_platform_resources *res, unsigned long ion_flags) +{ + struct context_bank_info *cb = NULL, *match = NULL; + char *search_str; + char *non_secure_cb = "cvp_hlos"; + char *secure_nonpixel_cb = "cvp_sec_nonpixel"; + char *secure_pixel_cb = "cvp_sec_pixel"; + + if (ion_flags & ION_FLAG_CP_PIXEL) + search_str = secure_pixel_cb; + else if (ion_flags & ION_FLAG_CP_NON_PIXEL) + search_str = secure_nonpixel_cb; + else + search_str = non_secure_cb; + + list_for_each_entry(cb, &res->context_banks, list) { + if (cb->is_secure == is_secure && + !strcmp(search_str, cb->name)) { + match = cb; + break; + } + } + + if (!match) + dprintk(CVP_ERR, + "%s: cb not found for ion_flags %x, is_secure %d\n", + __func__, ion_flags, is_secure); + + return match; +} From 274090e4b39ebcf018aeb096138a11dd504afe02 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Wed, 15 Jul 2020 17:21:58 -0700 Subject: [PATCH 003/317] msm: eva: checkin readme for this prj checkin a readme file for this project Change-Id: I9738f45b7cb5caf220d12309495dd2adb2fadbd9 Signed-off-by: Yu SI --- readme.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 readme.txt diff --git a/readme.txt b/readme.txt new file mode 100644 index 0000000000..16c4423fe6 --- /dev/null +++ b/readme.txt @@ -0,0 +1,2 @@ +kernel driver component for EVA (engine for video analytics) +to be included in the vendor SI , and for EVA tech pack From c5c6c1545ced52e65fa4661499aca0a51ecf3ce6 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 22 Jul 2020 14:18:47 -0700 Subject: [PATCH 004/317] msm: eva: Build EVA driver in eCRM Enabling EVA build in CRM environment. The setup can be used to sanity check future changes. Change-Id: If18abf7212c768c07e550678109d90d0c8519478 Signed-off-by: George Shen --- Makefile | 4 + config/waipioeva.conf | 4 +- config/waipioevaconf.h | 2 +- include/uapi/eva/media/msm_cvp_private.h | 245 +++++++++++++++++++++++ msm/eva/msm_cvp.c | 2 +- readme.txt | 2 - 6 files changed, 253 insertions(+), 6 deletions(-) create mode 100644 include/uapi/eva/media/msm_cvp_private.h delete mode 100644 readme.txt diff --git a/Makefile b/Makefile index 3e80127286..dd0445d097 100644 --- a/Makefile +++ b/Makefile @@ -8,4 +8,8 @@ LINUXINCLUDE += -include $(srctree)/techpack/eva/config/waipioevaconf.h endif endif +LINUXINCLUDE += -I$(srctree)/techpack/eva/include \ + -I$(srctree)/techpack/eva/include/uapi \ + -I$(srctree)/techpack/eva/include/uapi/eva + obj-y +=msm/ diff --git a/config/waipioeva.conf b/config/waipioeva.conf index 1bfda5e8aa..0e2fa57323 100644 --- a/config/waipioeva.conf +++ b/config/waipioeva.conf @@ -1,5 +1,5 @@ ifeq ($(CONFIG_QGKI),y) -export CONFIG_MSM_EVA=n +export CONFIG_MSM_EVA=y else -export CONFIG_MSM_EVA=n +export CONFIG_MSM_EVA=m endif diff --git a/config/waipioevaconf.h b/config/waipioevaconf.h index 2ec1e53ade..8ead84b38b 100644 --- a/config/waipioevaconf.h +++ b/config/waipioevaconf.h @@ -3,4 +3,4 @@ * Copyright (c) 2020, The Linux Foundation. All rights reserved. */ -#define CONFIG_MSM_EVA 0 +#define CONFIG_MSM_EVA 1 diff --git a/include/uapi/eva/media/msm_cvp_private.h b/include/uapi/eva/media/msm_cvp_private.h new file mode 100644 index 0000000000..90046d9eb4 --- /dev/null +++ b/include/uapi/eva/media/msm_cvp_private.h @@ -0,0 +1,245 @@ +/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ +/* + * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + */ +#ifndef __MSM_CVP_PRIVATE_H__ +#define __MSM_CVP_PRIVATE_H__ + +#include + +/* Commands type */ +#define CVP_KMD_CMD_BASE 0x10000000 +#define CVP_KMD_CMD_START (CVP_KMD_CMD_BASE + 0x1000) + +/* + * userspace clients pass one of the below arguments type + * in struct cvp_kmd_arg (@type field). + */ + +/* + * CVP_KMD_GET_SESSION_INFO - this argument type is used to + * get the session information from driver. it passes + * struct cvp_kmd_session_info {} + */ +#define CVP_KMD_GET_SESSION_INFO (CVP_KMD_CMD_START + 1) + +/* + * CVP_KMD_REGISTER_BUFFER - this argument type is used to + * register the buffer to driver. it passes + * struct cvp_kmd_buffer {} + */ +#define CVP_KMD_REGISTER_BUFFER (CVP_KMD_CMD_START + 3) + +/* + * CVP_KMD_REGISTER_BUFFER - this argument type is used to + * unregister the buffer to driver. it passes + * struct cvp_kmd_buffer {} + */ +#define CVP_KMD_UNREGISTER_BUFFER (CVP_KMD_CMD_START + 4) + +#define CVP_KMD_UPDATE_POWER (CVP_KMD_CMD_START + 17) + +#define CVP_KMD_SEND_CMD_PKT (CVP_KMD_CMD_START + 64) + +#define CVP_KMD_RECEIVE_MSG_PKT (CVP_KMD_CMD_START + 65) + +#define CVP_KMD_SET_SYS_PROPERTY (CVP_KMD_CMD_START + 66) + +#define CVP_KMD_GET_SYS_PROPERTY (CVP_KMD_CMD_START + 67) + +#define CVP_KMD_SESSION_CONTROL (CVP_KMD_CMD_START + 68) + +#define CVP_KMD_SEND_FENCE_CMD_PKT (CVP_KMD_CMD_START + 69) + +#define CVP_KMD_FLUSH_ALL (CVP_KMD_CMD_START + 70) + +#define CVP_KMD_FLUSH_FRAME (CVP_KMD_CMD_START + 71) + +/* flags */ +#define CVP_KMD_FLAG_UNSECURE 0x00000000 +#define CVP_KMD_FLAG_SECURE 0x00000001 + +/* buffer type */ +#define CVP_KMD_BUFTYPE_INPUT 0x00000001 +#define CVP_KMD_BUFTYPE_OUTPUT 0x00000002 +#define CVP_KMD_BUFTYPE_INTERNAL_1 0x00000003 +#define CVP_KMD_BUFTYPE_INTERNAL_2 0x00000004 + + +/** + * struct cvp_kmd_session_info - session information + * @session_id: current session id + */ +struct cvp_kmd_session_info { + __u32 session_id; + __u32 reserved[10]; +}; + +/** + * struct cvp_kmd_buffer - buffer information to be registered + * @index: index of buffer + * @type: buffer type + * @fd: file descriptor of buffer + * @size: allocated size of buffer + * @offset: offset in fd from where usable data starts + * @pixelformat: fourcc format + * @flags: buffer flags + */ +struct cvp_kmd_buffer { + __u32 index; + __u32 type; + __u32 fd; + __u32 size; + __u32 offset; + __u32 pixelformat; + __u32 flags; + __u32 reserved[5]; +}; + +/** + * struct cvp_kmd_send_cmd - sending generic HFI command + * @cmd_address_fd: file descriptor of cmd_address + * @cmd_size: allocated size of buffer + */ +struct cvp_kmd_send_cmd { + __u32 cmd_address_fd; + __u32 cmd_size; + __u32 reserved[10]; +}; + +/** + * struct cvp_kmd_client_data - store generic client + * data + * @transactionid: transaction id + * @client_data1: client data to be used during callback + * @client_data2: client data to be used during callback + */ +struct cvp_kmd_client_data { + __u32 transactionid; + __u32 client_data1; + __u32 client_data2; +}; + + +#define MAX_HFI_PKT_SIZE 470 + +struct cvp_kmd_hfi_packet { + __u32 pkt_data[MAX_HFI_PKT_SIZE]; +}; + +#define CVP_KMD_PROP_HFI_VERSION 1 +#define CVP_KMD_PROP_SESSION_TYPE 2 +#define CVP_KMD_PROP_SESSION_KERNELMASK 3 +#define CVP_KMD_PROP_SESSION_PRIORITY 4 +#define CVP_KMD_PROP_SESSION_SECURITY 5 +#define CVP_KMD_PROP_SESSION_DSPMASK 6 + +#define CVP_KMD_PROP_PWR_FDU 0x10 +#define CVP_KMD_PROP_PWR_ICA 0x11 +#define CVP_KMD_PROP_PWR_OD 0x12 +#define CVP_KMD_PROP_PWR_MPU 0x13 +#define CVP_KMD_PROP_PWR_FW 0x14 +#define CVP_KMD_PROP_PWR_DDR 0x15 +#define CVP_KMD_PROP_PWR_SYSCACHE 0x16 +#define CVP_KMD_PROP_PWR_FDU_OP 0x17 +#define CVP_KMD_PROP_PWR_ICA_OP 0x18 +#define CVP_KMD_PROP_PWR_OD_OP 0x19 +#define CVP_KMD_PROP_PWR_MPU_OP 0x1A +#define CVP_KMD_PROP_PWR_FW_OP 0x1B +#define CVP_KMD_PROP_PWR_DDR_OP 0x1C +#define CVP_KMD_PROP_PWR_SYSCACHE_OP 0x1D + +#define MAX_KMD_PROP_NUM_PER_PACKET 8 +#define MAX_KMD_PROP_TYPE (CVP_KMD_PROP_PWR_SYSCACHE_OP + 1) + +struct cvp_kmd_sys_property { + __u32 prop_type; + __u32 data; +}; + +struct cvp_kmd_sys_properties { + __u32 prop_num; + struct cvp_kmd_sys_property prop_data[8]; +}; + +#define SESSION_CREATE 1 +#define SESSION_DELETE 2 +#define SESSION_START 3 +#define SESSION_STOP 4 +#define SESSION_INFO 5 + +struct cvp_kmd_session_control { + __u32 ctrl_type; + __u32 ctrl_data[8]; +}; + +#define MAX_HFI_FENCE_SIZE 16 +#define MAX_HFI_FENCE_OFFSET (MAX_HFI_PKT_SIZE-MAX_HFI_FENCE_SIZE) +struct cvp_kmd_hfi_fence_packet { + __u32 pkt_data[MAX_HFI_FENCE_OFFSET]; + __u32 fence_data[MAX_HFI_FENCE_SIZE]; + __u64 frame_id; +}; + +struct cvp_kmd_fence { + __s32 h_synx; + __u32 secure_key; +}; + +struct cvp_kmd_fence_ctrl { + __u32 magic; + __u32 reserved; + __u64 frame_id; + __u32 num_fences; + __u32 output_index; + struct cvp_kmd_fence fences[MAX_HFI_FENCE_SIZE/2]; +}; + +#define MAX_FENCE_DATA_SIZE (MAX_HFI_FENCE_SIZE + 6) + +struct cvp_kmd_hfi_synx_packet { + __u32 pkt_data[MAX_HFI_PKT_SIZE]; + union { + __u32 fence_data[MAX_FENCE_DATA_SIZE]; + struct cvp_kmd_fence_ctrl fc; + }; +}; + +/** + * struct cvp_kmd_arg + * + * @type: command type + * @buf_offset: offset to buffer list in the command + * @buf_num: number of buffers in the command + * @session: session information + * @req_power: power information + * @regbuf: buffer to be registered + * @unregbuf: buffer to be unregistered + * @send_cmd: sending generic HFI command + + * @hfi_pkt: HFI packet created by user library + * @sys_properties System properties read or set by user library + * @hfi_fence_pkt: HFI fence packet created by user library + */ +struct cvp_kmd_arg { + __u32 type; + __u32 buf_offset; + __u32 buf_num; + union cvp_data_t { + struct cvp_kmd_session_info session; + struct cvp_kmd_buffer regbuf; + struct cvp_kmd_buffer unregbuf; + struct cvp_kmd_send_cmd send_cmd; + struct cvp_kmd_hfi_packet hfi_pkt; + struct cvp_kmd_sys_properties sys_properties; + struct cvp_kmd_hfi_fence_packet hfi_fence_pkt; + struct cvp_kmd_hfi_synx_packet hfi_synx_pkt; + struct cvp_kmd_session_control session_ctrl; + __u64 frame_id; + } data; +}; + +struct cvp_kmd_request_power { + __u32 deprecated; +}; +#endif diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 9e8f9a4a41..c8ab19f2ae 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -1122,7 +1122,7 @@ static int msm_cvp_set_sysprop(struct msm_cvp_inst *inst, return -EINVAL; } - if (props->prop_num >= MAX_KMD_PROP_NUM) { + if (props->prop_num >= MAX_KMD_PROP_NUM_PER_PACKET) { dprintk(CVP_ERR, "Too many properties %d to set\n", props->prop_num); return -E2BIG; diff --git a/readme.txt b/readme.txt deleted file mode 100644 index 16c4423fe6..0000000000 --- a/readme.txt +++ /dev/null @@ -1,2 +0,0 @@ -kernel driver component for EVA (engine for video analytics) -to be included in the vendor SI , and for EVA tech pack From 34e78bca0cc92e75f99c7f91ee919c9dce039b7c Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 23 Jul 2020 14:39:15 -0700 Subject: [PATCH 005/317] msm: eva: Rename UAPI header From msm_cvp_private.h to msm_eva_private.h Change-Id: I22f428e774fc725e1a88968da823a29f0ce68ffa Signed-off-by: George Shen --- include/uapi/eva/media/{msm_cvp_private.h => msm_eva_private.h} | 0 msm/eva/cvp_private.h | 2 +- msm/eva/msm_cvp_buf.h | 2 +- msm/eva/msm_cvp_core.h | 2 +- msm/eva/msm_cvp_internal.h | 2 +- msm/eva/msm_cvp_synx.h | 2 +- 6 files changed, 5 insertions(+), 5 deletions(-) rename include/uapi/eva/media/{msm_cvp_private.h => msm_eva_private.h} (100%) diff --git a/include/uapi/eva/media/msm_cvp_private.h b/include/uapi/eva/media/msm_eva_private.h similarity index 100% rename from include/uapi/eva/media/msm_cvp_private.h rename to include/uapi/eva/media/msm_eva_private.h diff --git a/msm/eva/cvp_private.h b/msm/eva/cvp_private.h index e6b84e9d14..a6d63271c9 100644 --- a/msm/eva/cvp_private.h +++ b/msm/eva/cvp_private.h @@ -6,7 +6,7 @@ #ifndef _MSM_V4L2_PRIVATE_H_ #define _MSM_V4L2_PRIVATE_H_ -#include +#include #include "msm_cvp_debug.h" long cvp_unblocked_ioctl(struct file *filp, diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index a911745979..f3a5618552 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -12,7 +12,7 @@ #include #include #include -#include +#include #define MAX_FRAME_BUFFER_NUMS 30 #define MAX_DMABUF_NUMS 64 diff --git a/msm/eva/msm_cvp_core.h b/msm/eva/msm_cvp_core.h index 215b16df49..54a3882c2e 100644 --- a/msm/eva/msm_cvp_core.h +++ b/msm/eva/msm_cvp_core.h @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include "msm_cvp_buf.h" #include "msm_cvp_synx.h" diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index 86442666d3..41f2afb2d4 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -21,7 +21,7 @@ #include #include "msm_cvp_core.h" #include -#include +#include #include "cvp_hfi_api.h" #include diff --git a/msm/eva/msm_cvp_synx.h b/msm/eva/msm_cvp_synx.h index 27c0052fa8..e95418a65a 100644 --- a/msm/eva/msm_cvp_synx.h +++ b/msm/eva/msm_cvp_synx.h @@ -7,7 +7,7 @@ #define _MSM_CVP_SYNX_H_ #include -#include +#include #include "cvp_comm_def.h" From 0c218a6148e2b4f3b36d52f8fcbfb5e02836592e Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 6 Aug 2020 14:06:03 -0700 Subject: [PATCH 006/317] msm: eva: propagate tip of CVP driver to EVA Merge cvp driver to EVA Change-Id: I3fb962bfae750f49f821c16061bd78fa5425959e Signed-off-by: George Shen --- include/uapi/eva/media/msm_eva_private.h | 8 +- msm/Makefile | 3 +- msm/eva/cvp.c | 13 + msm/eva/cvp_core_hfi.h | 2 + msm/eva/cvp_fw_load.c | 166 ++++++++++ msm/eva/cvp_hfi.c | 184 ++++++----- msm/eva/cvp_hfi.h | 5 + msm/eva/cvp_hfi_api.h | 2 +- msm/eva/cvp_hfi_helper.h | 23 ++ msm/eva/cvp_hfi_io.h | 1 + msm/eva/hfi_response_handler.c | 10 +- msm/eva/msm_cvp.c | 377 +++++++++++++++++++---- msm/eva/msm_cvp.h | 1 + msm/eva/msm_cvp_buf.c | 7 +- msm/eva/msm_cvp_buf.h | 1 + msm/eva/msm_cvp_common.c | 12 +- msm/eva/msm_cvp_dsp.c | 310 ++++++++++++++++++- msm/eva/msm_cvp_dsp.h | 13 +- msm/eva/msm_cvp_internal.h | 22 +- msm/eva/msm_cvp_ioctl.c | 10 +- msm/eva/msm_cvp_res_parse.c | 23 ++ msm/eva/msm_cvp_resources.h | 2 + msm/eva/msm_cvp_synx.c | 35 ++- msm/eva/msm_cvp_synx.h | 2 +- msm/eva/msm_smem.c | 39 +++ 25 files changed, 1083 insertions(+), 188 deletions(-) create mode 100644 msm/eva/cvp_fw_load.c diff --git a/include/uapi/eva/media/msm_eva_private.h b/include/uapi/eva/media/msm_eva_private.h index 90046d9eb4..555e8b7598 100644 --- a/include/uapi/eva/media/msm_eva_private.h +++ b/include/uapi/eva/media/msm_eva_private.h @@ -148,9 +148,13 @@ struct cvp_kmd_hfi_packet { #define CVP_KMD_PROP_PWR_FW_OP 0x1B #define CVP_KMD_PROP_PWR_DDR_OP 0x1C #define CVP_KMD_PROP_PWR_SYSCACHE_OP 0x1D +#define CVP_KMD_PROP_PWR_FPS_FDU 0x1E +#define CVP_KMD_PROP_PWR_FPS_MPU 0x1F +#define CVP_KMD_PROP_PWR_FPS_OD 0x20 +#define CVP_KMD_PROP_PWR_FPS_ICA 0x21 #define MAX_KMD_PROP_NUM_PER_PACKET 8 -#define MAX_KMD_PROP_TYPE (CVP_KMD_PROP_PWR_SYSCACHE_OP + 1) +#define MAX_KMD_PROP_TYPE (CVP_KMD_PROP_PWR_FPS_ICA + 1) struct cvp_kmd_sys_property { __u32 prop_type; @@ -159,7 +163,7 @@ struct cvp_kmd_sys_property { struct cvp_kmd_sys_properties { __u32 prop_num; - struct cvp_kmd_sys_property prop_data[8]; + struct cvp_kmd_sys_property prop_data[MAX_KMD_PROP_NUM_PER_PACKET]; }; #define SESSION_CREATE 1 diff --git a/msm/Makefile b/msm/Makefile index bffc386392..8f1ec95c6f 100644 --- a/msm/Makefile +++ b/msm/Makefile @@ -18,7 +18,8 @@ msm-eva-objs := eva/cvp.o \ eva/msm_cvp_clocks.o\ eva/msm_cvp_dsp.o \ eva/msm_cvp_buf.o \ - eva/msm_cvp_synx.o + eva/msm_cvp_synx.o \ + eva/cvp_fw_load.o obj-$(CONFIG_MSM_EVA) := msm-eva.o diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index 2802932c17..0fdb9b7366 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -107,6 +107,17 @@ static int read_platform_resources(struct msm_cvp_core *core, return rc; } +static void init_cycle_info(struct cvp_cycle_info *info) +{ + memset(info->sum_fps, 0, HFI_MAX_HW_THREADS*sizeof(u32)); + memset(info->hi_ctrl_lim, 0, HFI_MAX_HW_THREADS*sizeof(u32)); + memset(info->lo_ctrl_lim, 0, HFI_MAX_HW_THREADS*sizeof(u32)); + memset(info->cycle, 0, + HFI_MAX_HW_THREADS*sizeof(struct cvp_cycle_stat)); + info->conf_freq = 0; + mutex_init(&info->lock); +} + static int msm_cvp_initialize_core(struct platform_device *pdev, struct msm_cvp_core *core) { @@ -132,6 +143,7 @@ static int msm_cvp_initialize_core(struct platform_device *pdev, INIT_DELAYED_WORK(&core->fw_unload_work, msm_cvp_fw_unload_handler); INIT_WORK(&core->ssr_work, msm_cvp_ssr_handler); + init_cycle_info(&core->dyn_clk); return rc; } @@ -490,6 +502,7 @@ static int msm_cvp_remove(struct platform_device *pdev) sysfs_remove_group(&pdev->dev.kobj, &msm_cvp_core_attr_group); dev_set_drvdata(&pdev->dev, NULL); mutex_destroy(&core->lock); + mutex_destroy(&core->dyn_clk.lock); kfree(core); return rc; } diff --git a/msm/eva/cvp_core_hfi.h b/msm/eva/cvp_core_hfi.h index 427f063503..7e8174a873 100644 --- a/msm/eva/cvp_core_hfi.h +++ b/msm/eva/cvp_core_hfi.h @@ -268,4 +268,6 @@ int cvp_iris_hfi_initialize(struct cvp_hfi_device *hdev, u32 device_id, struct msm_cvp_platform_resources *res, hfi_cmd_response_callback callback); +int load_cvp_fw_impl(struct iris_hfi_device *device); +int unload_cvp_fw_impl(struct iris_hfi_device *device); #endif diff --git a/msm/eva/cvp_fw_load.c b/msm/eva/cvp_fw_load.c new file mode 100644 index 0000000000..089966b0d9 --- /dev/null +++ b/msm/eva/cvp_fw_load.c @@ -0,0 +1,166 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include "msm_cvp_debug.h" +#include "cvp_comm_def.h" +#include "cvp_core_hfi.h" +#include "cvp_hfi.h" +#ifdef CVP_MDT_ENABLED +#include +#include +#include +#else +#include +#endif + +#define MAX_FIRMWARE_NAME_SIZE 128 + +#ifdef CVP_MDT_ENABLED +static int __load_fw_to_memory(struct platform_device *pdev, + const char *fw_name) +{ + int rc = 0; + const struct firmware *firmware = NULL; + char firmware_name[MAX_FIRMWARE_NAME_SIZE] = {0}; + struct device_node *node = NULL; + struct resource res = {0}; + phys_addr_t phys = 0; + size_t res_size = 0; + ssize_t fw_size = 0; + void *virt = NULL; + int pas_id = 0; + + if (!fw_name || !(*fw_name) || !pdev) { + dprintk(CVP_ERR, "%s: Invalid inputs\n", __func__); + return -EINVAL; + } + if (strlen(fw_name) >= MAX_FIRMWARE_NAME_SIZE - 4) { + dprintk(CVP_ERR, "%s: Invalid fw name\n", __func__); + return -EINVAL; + } + scnprintf(firmware_name, ARRAY_SIZE(firmware_name), "%s.mdt", fw_name); + + rc = of_property_read_u32(pdev->dev.of_node, "pas-id", &pas_id); + if (rc) { + dprintk(CVP_ERR, + "%s: error %d while reading DT for \"pas-id\"\n", + __func__, rc); + goto exit; + } + + node = of_parse_phandle(pdev->dev.of_node, "memory-region", 0); + if (!node) { + dprintk(CVP_ERR, + "%s: DT error getting \"memory-region\" property\n", + __func__); + return -EINVAL; + } + + rc = of_address_to_resource(node, 0, &res); + if (rc) { + dprintk(CVP_ERR, + "%s: error %d getting \"memory-region\" resource\n", + __func__, rc); + goto exit; + } + phys = res.start; + res_size = (size_t)resource_size(&res); + + rc = request_firmware(&firmware, firmware_name, &pdev->dev); + if (rc) { + dprintk(CVP_ERR, "%s: error %d requesting \"%s\"\n", + __func__, rc, firmware_name); + goto exit; + } + + fw_size = qcom_mdt_get_size(firmware); + if (fw_size < 0 || res_size < (size_t)fw_size) { + rc = -EINVAL; + dprintk(CVP_ERR, + "%s: Corrupted fw image. Alloc size: %lu, fw size: %ld", + __func__, res_size, fw_size); + goto exit; + } + + virt = memremap(phys, res_size, MEMREMAP_WC); + if (!virt) { + rc = -ENOMEM; + dprintk(CVP_ERR, "%s: unable to remap firmware memory\n", + __func__); + goto exit; + } + + rc = qcom_mdt_load(&pdev->dev, firmware, firmware_name, + pas_id, virt, phys, res_size, NULL); + if (rc) { + dprintk(CVP_ERR, "%s: error %d loading \"%s\"\n", + __func__, rc, firmware_name); + goto exit; + } + rc = qcom_scm_pas_auth_and_reset(pas_id); + if (rc) { + dprintk(CVP_ERR, "%s: error %d authenticating \"%s\"\n", + __func__, rc, firmware_name); + goto exit; + } + + memunmap(virt); + release_firmware(firmware); + dprintk(CVP_CORE, "%s: firmware \"%s\" loaded successfully\n", + __func__, firmware_name); + return pas_id; + +exit: + if (virt) + memunmap(virt); + if (firmware) + release_firmware(firmware); + return rc; +} +#endif + +int load_cvp_fw_impl(struct iris_hfi_device *device) +{ + int rc = 0; + + if (!device->resources.fw.cookie) { +#ifdef CVP_MDT_ENABLED + device->resources.fw.cookie = + __load_fw_to_memory(device->res->pdev, + device->res->fw_name); + if (device->resources.fw.cookie <= 0) { + dprintk(CVP_ERR, "Failed to download firmware\n"); + device->resources.fw.cookie = 0; + rc = -ENOMEM; + } +#else + device->resources.fw.cookie = + subsystem_get_with_fwname("evass", + device->res->fw_name); + if (IS_ERR_OR_NULL(device->resources.fw.cookie)) { + dprintk(CVP_ERR, "Failed to download firmware\n"); + device->resources.fw.cookie = NULL; + rc = -ENOMEM; + } +#endif + } + return rc; +} + +int unload_cvp_fw_impl(struct iris_hfi_device *device) +{ +#ifdef CVP_MDT_ENABLED + qcom_scm_pas_shutdown(device->resources.fw.cookie); + device->resources.fw.cookie = 0; +#else + subsystem_put(device->resources.fw.cookie); + device->resources.fw.cookie = NULL; +#endif + return 0; +} diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 10cd7b23c4..e627cef2ab 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include "hfi_packetization.h" @@ -304,6 +303,7 @@ static void power_off_iris2(struct iris_hfi_device *device); static int __set_ubwc_config(struct iris_hfi_device *device); static void __noc_error_info_iris2(struct iris_hfi_device *device); +static int __enable_hw_power_collapse(struct iris_hfi_device *device); static struct iris_hfi_vpu_ops iris2_ops = { .interrupt_init = interrupt_init_iris2, @@ -364,9 +364,34 @@ int get_hfi_version(void) return hfi->version; } -unsigned int get_msg_size(void) +unsigned int get_msg_size(struct cvp_hfi_msg_session_hdr *hdr) { - return sizeof(struct cvp_hfi_msg_session_hdr); + struct msm_cvp_core *core; + struct iris_hfi_device *device; + u32 minor_ver; + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (core) + device = core->device->hfi_device_data; + else + return 0; + + if (!device) { + dprintk(CVP_ERR, "%s: NULL device\n", __func__); + return 0; + } + + minor_ver = (device->version & HFI_VERSION_MINOR_MASK) >> + HFI_VERSION_MINOR_SHIFT; + + if (minor_ver < 2) + return sizeof(struct cvp_hfi_msg_session_hdr); + + if (hdr->packet_type == HFI_MSG_SESSION_CVP_FD) + return sizeof(struct cvp_hfi_msg_session_hdr_ext); + else + return sizeof(struct cvp_hfi_msg_session_hdr); + } unsigned int get_msg_session_id(void *msg) @@ -1102,8 +1127,31 @@ static int __tzbsp_set_cvp_state(enum tzbsp_subsys_state state) static inline int __boot_firmware(struct iris_hfi_device *device) { - int rc = 0; + int rc = 0, loop = 10; u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 1000; + u32 reg_gdsc; + + /* + * Hand off control of regulators to h/w _after_ enabling clocks. + * Note that the GDSC will turn off when switching from normal + * (s/w triggered) to fast (HW triggered) unless the h/w vote is + * present. Since Iris isn't up yet, the GDSC will be off briefly. + */ + if (__enable_hw_power_collapse(device)) + dprintk(CVP_ERR, "Failed to enabled inter-frame PC\n"); + + while (loop) { + reg_gdsc = __read_register(device, CVP_CC_MVS1_GDSCR); + if (reg_gdsc & 0x80000000) { + usleep_range(100, 200); + loop--; + } else { + break; + } + } + + if (!loop) + dprintk(CVP_ERR, "fail to power off CORE during resume\n"); ctrl_init_val = BIT(0); __write_register(device, CVP_CTRL_INIT, ctrl_init_val); @@ -1492,8 +1540,6 @@ static int __interface_dsp_queues_init(struct iris_hfi_device *dev) { int rc = 0; u32 i; - struct cvp_hfi_queue_table_header *q_tbl_hdr; - struct cvp_hfi_queue_header *q_hdr; struct cvp_iface_q_info *iface_q; int offset = 0; phys_addr_t fw_bias = 0; @@ -1552,43 +1598,11 @@ static int __interface_dsp_queues_init(struct iris_hfi_device *dev) iface_q->q_array.align_virtual_addr = kvaddr + offset; iface_q->q_array.mem_size = CVP_IFACEQ_QUEUE_SIZE; offset += iface_q->q_array.mem_size; - iface_q->q_hdr = CVP_IFACEQ_GET_QHDR_START_ADDR( - dev->dsp_iface_q_table.align_virtual_addr, i); - __set_queue_hdr_defaults(iface_q->q_hdr); spin_lock_init(&iface_q->hfi_lock); } - q_tbl_hdr = (struct cvp_hfi_queue_table_header *) - dev->dsp_iface_q_table.align_virtual_addr; - q_tbl_hdr->qtbl_version = 0; - q_tbl_hdr->device_addr = (void *)dev; - strlcpy(q_tbl_hdr->name, "msm_cvp", sizeof(q_tbl_hdr->name)); - q_tbl_hdr->qtbl_size = CVP_IFACEQ_TABLE_SIZE; - q_tbl_hdr->qtbl_qhdr0_offset = - sizeof(struct cvp_hfi_queue_table_header); - q_tbl_hdr->qtbl_qhdr_size = sizeof(struct cvp_hfi_queue_header); - q_tbl_hdr->qtbl_num_q = CVP_IFACEQ_NUMQ; - q_tbl_hdr->qtbl_num_active_q = CVP_IFACEQ_NUMQ; + cvp_dsp_init_hfi_queue_hdr(dev); - iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_CMDQ_IDX]; - q_hdr = iface_q->q_hdr; - q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; - q_hdr->qhdr_type |= HFI_Q_ID_HOST_TO_CTRL_CMD_Q; - - iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_MSGQ_IDX]; - q_hdr = iface_q->q_hdr; - q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; - q_hdr->qhdr_type |= HFI_Q_ID_CTRL_TO_HOST_MSG_Q; - - iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_DBGQ_IDX]; - q_hdr = iface_q->q_hdr; - q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; - q_hdr->qhdr_type |= HFI_Q_ID_CTRL_TO_HOST_DEBUG_Q; - /* - * Set receive request to zero on debug queue as there is no - * need of interrupt from cvp hardware for debug messages - */ - q_hdr->qhdr_rx_req = 0; return rc; fail_dma_map: @@ -1964,6 +1978,7 @@ static int __sys_set_power_control(struct iris_hfi_device *device, static int iris_hfi_core_init(void *device) { int rc = 0; + u32 ipcc_iova; struct cvp_hfi_cmd_sys_init_packet pkt; struct cvp_hfi_cmd_sys_get_property_packet version_pkt; struct iris_hfi_device *dev; @@ -2011,6 +2026,12 @@ static int iris_hfi_core_init(void *device) goto err_core_init; } + rc = msm_cvp_map_ipcc_regs(&ipcc_iova); + if (!rc) { + dprintk(CVP_CORE, "IPCC iova 0x%x\n", ipcc_iova); + __write_register(dev, CVP_MMAP_ADDR, ipcc_iova); + } + rc = __boot_firmware(dev); if (rc) { dprintk(CVP_ERR, "Failed to start core\n"); @@ -3350,7 +3371,7 @@ static int reset_ahb2axi_bridge(struct iris_hfi_device *device) } /* wait for deassert */ - usleep_range(400, 450); + usleep_range(1000, 1050); rc = __handle_reset_clk(device->res, i, DEASSERT, s); if (rc) { @@ -3625,11 +3646,6 @@ static void __deinit_resources(struct iris_hfi_device *device) device->sys_init_capabilities = NULL; } -static int __protect_cp_mem(struct iris_hfi_device *device) -{ - return device ? 0 : -EINVAL; -} - static int __disable_regulator(struct regulator_info *rinfo, struct iris_hfi_device *device) { @@ -4014,15 +4030,6 @@ static int __iris_power_on(struct iris_hfi_device *device) device->intr_status = 0; enable_irq(device->cvp_hal_data->irq); - /* - * Hand off control of regulators to h/w _after_ enabling clocks. - * Note that the GDSC will turn off when switching from normal - * (s/w triggered) to fast (HW triggered) unless the h/w vote is - * present. Since Iris isn't up yet, the GDSC will be off briefly. - */ - if (__enable_hw_power_collapse(device)) - dprintk(CVP_ERR, "Failed to enabled inter-frame PC\n"); - return rc; fail_enable_clks: @@ -4175,10 +4182,10 @@ static void power_off_iris2(struct iris_hfi_device *device) /* HPG 6.1.2 Step 6 */ __disable_unprepare_clks(device); - /* HPG 6.1.2 Step 7 & 8 */ - if (call_iris_op(device, reset_ahb2axi_bridge, device)) - dprintk(CVP_ERR, "Failed to reset ahb2axi\n"); - + /* + * HPG 6.1.2 Step 7 & 8 + * per new HPG update, core clock reset will be unnecessary + */ if (__unvote_buses(device)) dprintk(CVP_WARN, "Failed to unvote for buses\n"); @@ -4212,8 +4219,6 @@ static inline int __resume(struct iris_hfi_device *device) goto err_iris_power_on; } - - reg_gdsc = __read_register(device, CVP_CC_MVS1C_GDSCR); reg_cbcr = __read_register(device, CVP_CC_MVS1C_CBCR); if (!(reg_gdsc & 0x80000000) || (reg_cbcr & 0x80000000)) @@ -4228,6 +4233,7 @@ static inline int __resume(struct iris_hfi_device *device) } __setup_ucregion_memory_map(device); + /* Wait for boot completion */ rc = __boot_firmware(device); if (rc) { @@ -4293,31 +4299,13 @@ static int __load_fw(struct iris_hfi_device *device) if ((!device->res->use_non_secure_pil && !device->res->firmware_base) || device->res->use_non_secure_pil) { - if (!device->resources.fw.cookie) - device->resources.fw.cookie = - subsystem_get_with_fwname("evass", - device->res->fw_name); - - if (IS_ERR_OR_NULL(device->resources.fw.cookie)) { - dprintk(CVP_ERR, "Failed to download firmware\n"); - device->resources.fw.cookie = NULL; - rc = -ENOMEM; + rc = load_cvp_fw_impl(device); + if (rc) goto fail_load_fw; - } } - if (!device->res->firmware_base) { - rc = __protect_cp_mem(device); - if (rc) { - dprintk(CVP_ERR, "Failed to protect memory\n"); - goto fail_protect_mem; - } - } return rc; -fail_protect_mem: - if (device->resources.fw.cookie) - subsystem_put(device->resources.fw.cookie); - device->resources.fw.cookie = NULL; + fail_load_fw: call_iris_op(device, power_off, device); fail_iris_power_on: @@ -4336,10 +4324,9 @@ static void __unload_fw(struct iris_hfi_device *device) if (device->state != IRIS_STATE_DEINIT) flush_workqueue(device->iris_pm_workq); - subsystem_put(device->resources.fw.cookie); + unload_cvp_fw_impl(device); __interface_queues_release(device); call_iris_op(device, power_off, device); - device->resources.fw.cookie = NULL; __deinit_resources(device); dprintk(CVP_WARN, "Firmware unloaded\n"); @@ -4389,9 +4376,12 @@ static int iris_hfi_get_core_capabilities(void *dev) return 0; } +static u32 cvp_arp_test_regs[16]; +static u32 cvp_dma_test_regs[512]; + static void __noc_error_info_iris2(struct iris_hfi_device *device) { - u32 val = 0; + u32 val = 0, regi, i; val = __read_register(device, CVP_NOC_ERR_SWID_LOW_OFFS); dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_SWID_LOW: %#x\n", val); @@ -4446,6 +4436,32 @@ static void __noc_error_info_iris2(struct iris_hfi_device *device) dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG3_LOW: %#x\n", val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG3_HIGH: %#x\n", val); +#define CVP_SS_CLK_HALT 0x8 +#define CVP_SS_CLK_EN 0xC +#define CVP_SS_ARP_TEST_BUS_CONTROL 0x700 +#define CVP_SS_ARP_TEST_BUS_REGISTER 0x704 +#define CVP_DMA_TEST_BUS_CONTROL 0x66A0 +#define CVP_DMA_TEST_BUS_REGISTER 0x66A4 +#define CVP_VPU_WRAPPER_CORE_CONFIG 0xB0088 + __write_register(device, CVP_SS_CLK_HALT, 0); + __write_register(device, CVP_SS_CLK_EN, 0x3f); + __write_register(device, CVP_VPU_WRAPPER_CORE_CONFIG, 0); + + for (i = 0; i < 15; i++) { + regi = 0xC0000000 + i; + __write_register(device, CVP_SS_ARP_TEST_BUS_CONTROL, regi); + val = __read_register(device, CVP_SS_ARP_TEST_BUS_REGISTER); + cvp_arp_test_regs[i] = val; + dprintk(CVP_ERR, "ARP_CTL:%x - %x\n", regi, val); + } + + for (i = 0; i < 512; i++) { + regi = 0x40000000 + i; + __write_register(device, CVP_DMA_TEST_BUS_CONTROL, regi); + val = __read_register(device, CVP_DMA_TEST_BUS_REGISTER); + cvp_dma_test_regs[i] = val; + dprintk(CVP_ERR, "DMA_CTL:%x - %x\n", regi, val); + } } static int iris_hfi_noc_error_info(void *dev) diff --git a/msm/eva/cvp_hfi.h b/msm/eva/cvp_hfi.h index c7142dcc41..2959c72a4f 100644 --- a/msm/eva/cvp_hfi.h +++ b/msm/eva/cvp_hfi.h @@ -9,6 +9,7 @@ #include #include "cvp_hfi_helper.h" #include "cvp_hfi_api.h" +#include "cvp_comm_def.h" #define HFI_CMD_SESSION_CVP_START \ (HFI_DOMAIN_BASE_CVP + HFI_ARCH_COMMON_OFFSET + \ @@ -199,7 +200,11 @@ struct cvp_hal_session { }; struct msm_cvp_fw { +#ifdef CVP_MDT_ENABLED + int cookie; +#else void *cookie; +#endif }; int cvp_hfi_process_msg_packet(u32 device_id, diff --git a/msm/eva/cvp_hfi_api.h b/msm/eva/cvp_hfi_api.h index 585dad12d3..511d476eb4 100644 --- a/msm/eva/cvp_hfi_api.h +++ b/msm/eva/cvp_hfi_api.h @@ -369,7 +369,7 @@ void cvp_hfi_deinitialize(enum msm_cvp_hfi_type hfi_type, int get_pkt_index(struct cvp_hal_session_cmd_pkt *hdr); int get_signal_from_pkt_type(unsigned int type); int get_hfi_version(void); -unsigned int get_msg_size(void); +unsigned int get_msg_size(struct cvp_hfi_msg_session_hdr *hdr); unsigned int get_msg_session_id(void *msg); unsigned int get_msg_errorcode(void *msg); int get_msg_opconfigs(void *msg, unsigned int *session_id, diff --git a/msm/eva/cvp_hfi_helper.h b/msm/eva/cvp_hfi_helper.h index c9662ef9ab..ba0dbead15 100644 --- a/msm/eva/cvp_hfi_helper.h +++ b/msm/eva/cvp_hfi_helper.h @@ -336,6 +336,29 @@ struct cvp_hfi_msg_session_hdr { u32 stream_idx; } __packed; +#define HFI_MAX_HW_ACTIVATIONS_PER_FRAME (6) +#define HFI_MAX_HW_THREADS (4) + +enum hfi_hw_thread { + HFI_HW_FDU, + HFI_HW_MPU, + HFI_HW_OD, + HFI_HW_ICA +}; + +struct cvp_hfi_msg_session_hdr_ext { + u32 size; + u32 packet_type; + u32 session_id; + u32 error_type; + struct cvp_hfi_client client_data; + u32 stream_idx; + u32 busy_cycles; + u32 total_cycles; + u32 hw_cycles[HFI_MAX_HW_THREADS][HFI_MAX_HW_ACTIVATIONS_PER_FRAME]; + u32 fw_cycles[HFI_MAX_HW_ACTIVATIONS_PER_FRAME]; +} __packed; + struct cvp_hfi_buffer_mapping_type { u32 index; u32 device_addr; diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index fa8933f9cf..925cc2f3b4 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -220,4 +220,5 @@ #define CVP_CC_MVS0C_GDSCR (CVP_CC_BASE_OFFS + 0xBF8) #define CVP_CC_MVS1C_GDSCR (CVP_CC_BASE_OFFS + 0xC98) #define CVP_CC_MVS1C_CBCR (CVP_CC_BASE_OFFS + 0xCD4) +#define CVP_CC_MVS1_GDSCR (CVP_CC_BASE_OFFS + 0xD98) #endif diff --git a/msm/eva/hfi_response_handler.c b/msm/eva/hfi_response_handler.c index e9cadb0d42..548010863f 100644 --- a/msm/eva/hfi_response_handler.c +++ b/msm/eva/hfi_response_handler.c @@ -313,7 +313,7 @@ static int hfi_process_session_set_buf_done(u32 device_id, struct cvp_hfi_msg_session_hdr *pkt = (struct cvp_hfi_msg_session_hdr *)hdr; struct msm_cvp_cb_cmd_done cmd_done = {0}; - unsigned int pkt_size = get_msg_size(); + unsigned int pkt_size = get_msg_size(pkt); if (!pkt || pkt->size < pkt_size) { dprintk(CVP_ERR, "bad packet/packet size %d\n", @@ -367,7 +367,7 @@ static int hfi_process_session_rel_buf_done(u32 device_id, struct cvp_hfi_msg_session_hdr *pkt = (struct cvp_hfi_msg_session_hdr *)hdr; struct msm_cvp_cb_cmd_done cmd_done = {0}; - unsigned int pkt_size = get_msg_size(); + unsigned int pkt_size = get_msg_size(pkt); if (!pkt || pkt->size < pkt_size) { dprintk(CVP_ERR, "bad packet/packet size %d\n", @@ -393,6 +393,8 @@ static int hfi_process_session_cvp_operation_config(u32 device_id, { struct cvp_hfi_msg_session_op_cfg_packet *pkt = (struct cvp_hfi_msg_session_op_cfg_packet *)hdr; + struct cvp_hfi_msg_session_hdr *lhdr = + (struct cvp_hfi_msg_session_hdr *)hdr; struct msm_cvp_cb_cmd_done cmd_done = {0}; int signal; unsigned int conf_id, session_id, error_type; @@ -400,7 +402,7 @@ static int hfi_process_session_cvp_operation_config(u32 device_id, if (!pkt) { dprintk(CVP_ERR, "%s: invalid param\n", __func__); return -EINVAL; - } else if (pkt->size < get_msg_size()) { + } else if (pkt->size < get_msg_size(lhdr)) { dprintk(CVP_ERR, "%s: bad_pkt_size\n", __func__); return -E2BIG; @@ -514,7 +516,7 @@ static int hfi_process_session_cvp_msg(u32 device_id, return -ENOMEM; } - memcpy(&sess_msg->pkt, pkt, get_msg_size()); + memcpy(&sess_msg->pkt, pkt, get_msg_size(pkt)); dprintk(CVP_HFI, "%s: Received msg %x cmd_done.status=%d sessionid=%x\n", diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index c8ab19f2ae..75185b2ad7 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -111,12 +111,15 @@ static int cvp_wait_process_message(struct msm_cvp_inst *inst, goto exit; } - if (out) - memcpy(out, &msg->pkt, sizeof(struct cvp_hfi_msg_session_hdr)); + if (!out) { + kmem_cache_free(cvp_driver->msg_cache, msg); + goto exit; + } - kmem_cache_free(cvp_driver->msg_cache, msg); - hdr = (struct cvp_hfi_msg_session_hdr *)out; + hdr = (struct cvp_hfi_msg_session_hdr *)&msg->pkt; + memcpy(out, &msg->pkt, get_msg_size(hdr)); msm_cvp_unmap_frame(inst, hdr->client_data.kdata); + kmem_cache_free(cvp_driver->msg_cache, msg); exit: return rc; @@ -271,7 +274,7 @@ static bool cvp_fence_wait(struct cvp_fence_queue *q, f = list_first_entry(&q->wait_list, struct cvp_fence_command, list); list_del_init(&f->list); - list_add_tail(&q->sched_list, &f->list); + list_add_tail(&f->list, &q->sched_list); mutex_unlock(&q->lock); *fence = f; @@ -279,6 +282,166 @@ static bool cvp_fence_wait(struct cvp_fence_queue *q, return true; } +static int cvp_readjust_clock(struct msm_cvp_core *core, + u32 avg_cycles, enum hfi_hw_thread i) +{ + int rc = 0; + struct allowed_clock_rates_table *tbl = NULL; + unsigned int tbl_size = 0; + unsigned int cvp_min_rate = 0, cvp_max_rate = 0; + unsigned long tmp = core->curr_freq; + unsigned long lo_freq = 0; + u32 j; + + dprintk(CVP_PWR, + "%s:%d - %d - avg_cycles %u > hi_tresh %u\n", + __func__, __LINE__, i, avg_cycles, + core->dyn_clk.hi_ctrl_lim[i]); + + core->curr_freq = ((avg_cycles * core->dyn_clk.sum_fps[i]) << 1)/3; + dprintk(CVP_PWR, + "%s - cycles tot %u, avg %u. sum_fps %u, cur_freq %u\n", + __func__, + core->dyn_clk.cycle[i].total, + avg_cycles, + core->dyn_clk.sum_fps[i], + core->curr_freq); + + tbl = core->resources.allowed_clks_tbl; + tbl_size = core->resources.allowed_clks_tbl_size; + cvp_min_rate = tbl[0].clock_rate; + cvp_max_rate = tbl[tbl_size - 1].clock_rate; + + if (core->curr_freq > cvp_max_rate) { + core->curr_freq = cvp_max_rate; + lo_freq = (tbl_size > 1) ? + tbl[tbl_size - 2].clock_rate : + cvp_min_rate; + } else if (core->curr_freq <= cvp_min_rate) { + core->curr_freq = cvp_min_rate; + lo_freq = cvp_min_rate; + } else { + for (j = 1; j < tbl_size; j++) + if (core->curr_freq <= tbl[j].clock_rate) + break; + core->curr_freq = tbl[j].clock_rate; + lo_freq = tbl[j-1].clock_rate; + } + + dprintk(CVP_PWR, + "%s:%d - %d - Readjust to %u\n", + __func__, __LINE__, i, core->curr_freq); + rc = msm_cvp_set_clocks(core); + if (rc) { + dprintk(CVP_ERR, + "Failed to set clock rate %u: %d %s\n", + core->curr_freq, rc, __func__); + core->curr_freq = tmp; + } else { + lo_freq = (lo_freq < core->dyn_clk.conf_freq) ? + core->dyn_clk.conf_freq : lo_freq; + core->dyn_clk.hi_ctrl_lim[i] = core->dyn_clk.sum_fps[i] ? + ((core->curr_freq*3)>>1)/core->dyn_clk.sum_fps[i] : 0; + core->dyn_clk.lo_ctrl_lim[i] = + core->dyn_clk.sum_fps[i] ? + ((lo_freq*3)>>1)/core->dyn_clk.sum_fps[i] : 0; + + dprintk(CVP_PWR, + "%s - Readjust clk to %u. New lim [%d] hi %u lo %u\n", + __func__, core->curr_freq, i, + core->dyn_clk.hi_ctrl_lim[i], + core->dyn_clk.lo_ctrl_lim[i]); + } + + return rc; +} + +static int cvp_check_clock(struct msm_cvp_inst *inst, + struct cvp_hfi_msg_session_hdr_ext *hdr) +{ + int rc = 0; + u32 i, j; + u32 hw_cycles[HFI_MAX_HW_THREADS] = {0}; + u32 fw_cycles = 0; + struct msm_cvp_core *core = inst->core; + + for (i = 0; i < HFI_MAX_HW_ACTIVATIONS_PER_FRAME; ++i) + fw_cycles += hdr->fw_cycles[i]; + + for (i = 0; i < HFI_MAX_HW_THREADS; ++i) + for (j = 0; j < HFI_MAX_HW_ACTIVATIONS_PER_FRAME; ++j) + hw_cycles[i] += hdr->hw_cycles[i][j]; + + dprintk(CVP_PWR, "%s - cycles fw %u. FDU %d MPU %d ODU %d ICA %d\n", + __func__, fw_cycles, hw_cycles[0], + hw_cycles[1], hw_cycles[2], hw_cycles[3]); + + mutex_lock(&core->dyn_clk.lock); + for (i = 0; i < HFI_MAX_HW_THREADS; ++i) { + dprintk(CVP_PWR, "%s - %d: hw_cycles %u, tens_thresh %u\n", + __func__, i, hw_cycles[i], + core->dyn_clk.hi_ctrl_lim[i]); + if (core->dyn_clk.hi_ctrl_lim[i]) { + if (core->dyn_clk.cycle[i].size < CVP_CYCLE_STAT_SIZE) + core->dyn_clk.cycle[i].size++; + else + core->dyn_clk.cycle[i].total -= + core->dyn_clk.cycle[i].busy[ + core->dyn_clk.cycle[i].idx]; + if (hw_cycles[i]) { + core->dyn_clk.cycle[i].busy[ + core->dyn_clk.cycle[i].idx] + = hw_cycles[i] + fw_cycles; + core->dyn_clk.cycle[i].total + += hw_cycles[i] + fw_cycles; + dprintk(CVP_PWR, + "%s: busy (hw + fw) cycles = %u\n", + __func__, + core->dyn_clk.cycle[i].busy[ + core->dyn_clk.cycle[i].idx]); + dprintk(CVP_PWR, "total cycles %u\n", + core->dyn_clk.cycle[i].total); + } else { + core->dyn_clk.cycle[i].busy[ + core->dyn_clk.cycle[i].idx] = + hdr->busy_cycles; + core->dyn_clk.cycle[i].total += + hdr->busy_cycles; + dprintk(CVP_PWR, + "%s - busy cycles = %u total %u\n", + __func__, + core->dyn_clk.cycle[i].busy[ + core->dyn_clk.cycle[i].idx], + core->dyn_clk.cycle[i].total); + } + + core->dyn_clk.cycle[i].idx = + (core->dyn_clk.cycle[i].idx == + CVP_CYCLE_STAT_SIZE-1) ? + 0 : core->dyn_clk.cycle[i].idx+1; + + dprintk(CVP_PWR, "%s - %d: size %u, tens_thresh %u\n", + __func__, i, core->dyn_clk.cycle[i].size, + core->dyn_clk.hi_ctrl_lim[i]); + if (core->dyn_clk.cycle[i].size == CVP_CYCLE_STAT_SIZE + && core->dyn_clk.hi_ctrl_lim[i] != 0) { + u32 avg_cycles = + core->dyn_clk.cycle[i].total>>3; + if ((avg_cycles > core->dyn_clk.hi_ctrl_lim[i]) + || (avg_cycles <= + core->dyn_clk.lo_ctrl_lim[i])) { + rc = cvp_readjust_clock(core, + avg_cycles, + i); + } + } + } + } + mutex_unlock(&core->dyn_clk.lock); + + return rc; +} + static int cvp_fence_proc(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, struct cvp_hfi_cmd_session_hdr *pkt) @@ -290,7 +453,8 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, struct cvp_hfi_device *hdev; struct cvp_session_queue *sq; u32 hfi_err = HFI_ERR_NONE; - struct cvp_hfi_msg_session_hdr *hdr; + struct cvp_hfi_msg_session_hdr_ext hdr; + bool clock_check = false; dprintk(CVP_SYNX, "%s %s\n", current->comm, __func__); @@ -298,7 +462,8 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, sq = &inst->session_queue_fence; ktid = pkt->client_data.kdata; - if (cvp_synx_ops(inst, CVP_INPUT_SYNX, fc, &synx_state)) { + rc = cvp_synx_ops(inst, CVP_INPUT_SYNX, fc, &synx_state); + if (rc) { msm_cvp_unmap_frame(inst, pkt->client_data.kdata); goto exit; } @@ -314,9 +479,16 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, timeout = msecs_to_jiffies(CVP_MAX_WAIT_TIME); rc = cvp_wait_process_message(inst, sq, &ktid, timeout, - (struct cvp_kmd_hfi_packet *)pkt); - hdr = (struct cvp_hfi_msg_session_hdr *)pkt; - hfi_err = hdr->error_type; + (struct cvp_kmd_hfi_packet *)&hdr); + if (get_msg_size((struct cvp_hfi_msg_session_hdr *) &hdr) + == sizeof(struct cvp_hfi_msg_session_hdr_ext)) { + struct cvp_hfi_msg_session_hdr_ext *fhdr = + (struct cvp_hfi_msg_session_hdr_ext *)&hdr; + dprintk(CVP_HFI, "busy cycle 0x%x, total 0x%x\n", + fhdr->busy_cycles, fhdr->total_cycles); + clock_check = true; + } + hfi_err = hdr.error_type; if (rc) { dprintk(CVP_ERR, "%s %s: cvp_wait_process_message rc %d\n", current->comm, __func__, rc); @@ -339,19 +511,23 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, exit: rc = cvp_synx_ops(inst, CVP_OUTPUT_SYNX, fc, &synx_state); - + if (clock_check) + cvp_check_clock(inst, + (struct cvp_hfi_msg_session_hdr_ext *)&hdr); return rc; } static int cvp_alloc_fence_data(struct cvp_fence_command **f, u32 size) { struct cvp_fence_command *fcmd; + int alloc_size = sizeof(struct cvp_hfi_msg_session_hdr_ext); fcmd = kzalloc(sizeof(struct cvp_fence_command), GFP_KERNEL); if (!fcmd) return -ENOMEM; - fcmd->pkt = kzalloc(size, GFP_KERNEL); + alloc_size = (alloc_size >= size) ? alloc_size : size; + fcmd->pkt = kzalloc(alloc_size, GFP_KERNEL); if (!fcmd->pkt) { kfree(fcmd); return -ENOMEM; @@ -414,6 +590,7 @@ wait: mutex_lock(&q->lock); cvp_release_synx(inst, f); list_del_init(&f->list); + state = q->state; mutex_unlock(&q->lock); dprintk(CVP_SYNX, "%s done with %d ktid %llu frameID %llu rc %d\n", @@ -421,6 +598,9 @@ wait: cvp_free_fence_data(f); + if (rc && state != QUEUE_ACTIVE) + goto exit; + goto wait; exit: @@ -587,7 +767,7 @@ static void aggregate_power_update(struct msm_cvp_core *core, } else { i = 1; } - dprintk(CVP_PROF, "pwrUpdate %pK fdu %u od %u mpu %u ica %u\n", + dprintk(CVP_PROF, "pwrUpdate fdu %u od %u mpu %u ica %u\n", inst->prop.fdu_cycles, inst->prop.od_cycles, inst->prop.mpu_cycles, @@ -629,6 +809,21 @@ static void aggregate_power_update(struct msm_cvp_core *core, op_bw_max[i] = (op_bw_max[i] >= inst->prop.ddr_op_bw) ? op_bw_max[i] : inst->prop.ddr_op_bw; + + dprintk(CVP_PWR, "%s:%d - fps fdu %d mpu %d od %d ica %d\n", + __func__, __LINE__, + inst->prop.fps[HFI_HW_FDU], inst->prop.fps[HFI_HW_MPU], + inst->prop.fps[HFI_HW_OD], inst->prop.fps[HFI_HW_ICA]); + core->dyn_clk.sum_fps[HFI_HW_FDU] += inst->prop.fps[HFI_HW_FDU]; + core->dyn_clk.sum_fps[HFI_HW_MPU] += inst->prop.fps[HFI_HW_MPU]; + core->dyn_clk.sum_fps[HFI_HW_OD] += inst->prop.fps[HFI_HW_OD]; + core->dyn_clk.sum_fps[HFI_HW_ICA] += inst->prop.fps[HFI_HW_ICA]; + dprintk(CVP_PWR, "%s:%d - sum_fps fdu %d mpu %d od %d ica %d\n", + __func__, __LINE__, + core->dyn_clk.sum_fps[HFI_HW_FDU], + core->dyn_clk.sum_fps[HFI_HW_MPU], + core->dyn_clk.sum_fps[HFI_HW_OD], + core->dyn_clk.sum_fps[HFI_HW_ICA]); } for (i = 0; i < 2; i++) { @@ -680,6 +875,7 @@ static int adjust_bw_freqs(void) struct cvp_power_level rt_pwr = {0}, nrt_pwr = {0}; unsigned long tmp, core_sum, op_core_sum, bw_sum; int i, rc = 0; + unsigned long ctrl_freq; core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); @@ -714,7 +910,7 @@ static int adjust_bw_freqs(void) if (core_sum > cvp_max_rate) { core_sum = cvp_max_rate; - } else if (core_sum < cvp_min_rate) { + } else if (core_sum <= cvp_min_rate) { core_sum = cvp_min_rate; } else { for (i = 1; i < tbl_size; i++) @@ -745,6 +941,18 @@ static int adjust_bw_freqs(void) core->curr_freq = tmp; return rc; } + + ctrl_freq = (core->curr_freq*3)>>1; + mutex_lock(&core->dyn_clk.lock); + core->dyn_clk.conf_freq = core->curr_freq; + for (i = 0; i < HFI_MAX_HW_THREADS; ++i) { + core->dyn_clk.hi_ctrl_lim[i] = core->dyn_clk.sum_fps[i] ? + ctrl_freq/core->dyn_clk.sum_fps[i] : 0; + core->dyn_clk.lo_ctrl_lim[i] = + core->dyn_clk.hi_ctrl_lim[i]; + } + mutex_unlock(&core->dyn_clk.lock); + hdev->clk_freq = core->curr_freq; rc = icc_set_bw(bus->client, bw_sum, 0); if (rc) @@ -1122,7 +1330,7 @@ static int msm_cvp_set_sysprop(struct msm_cvp_inst *inst, return -EINVAL; } - if (props->prop_num >= MAX_KMD_PROP_NUM_PER_PACKET) { + if (props->prop_num > MAX_KMD_PROP_NUM_PER_PACKET) { dprintk(CVP_ERR, "Too many properties %d to set\n", props->prop_num); return -E2BIG; @@ -1194,6 +1402,18 @@ static int msm_cvp_set_sysprop(struct msm_cvp_inst *inst, case CVP_KMD_PROP_PWR_SYSCACHE_OP: session_prop->ddr_op_cache = prop_array[i].data; break; + case CVP_KMD_PROP_PWR_FPS_FDU: + session_prop->fps[HFI_HW_FDU] = prop_array[i].data; + break; + case CVP_KMD_PROP_PWR_FPS_MPU: + session_prop->fps[HFI_HW_MPU] = prop_array[i].data; + break; + case CVP_KMD_PROP_PWR_FPS_OD: + session_prop->fps[HFI_HW_OD] = prop_array[i].data; + break; + case CVP_KMD_PROP_PWR_FPS_ICA: + session_prop->fps[HFI_HW_ICA] = prop_array[i].data; + break; default: dprintk(CVP_ERR, "unrecognized sys property to set %d\n", @@ -1275,10 +1495,8 @@ static int cvp_drain_fence_sched_list(struct msm_cvp_inst *inst) mutex_lock(&q->lock); list_for_each_entry(f, &q->sched_list, list) { ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1); - dprintk(CVP_SYNX, "%s: frame %llu is in sched_list\n", - __func__, ktid); - dprintk(CVP_SYNX, "%s: frameID %llu is in sched_list\n", - __func__, f->frame_id); + dprintk(CVP_SYNX, "%s: frame %llu %llu is in sched_list\n", + __func__, ktid, f->frame_id); ++count; } mutex_unlock(&q->lock); @@ -1310,14 +1528,71 @@ retry: return rc; } +static void cvp_clean_fence_queue(struct msm_cvp_inst *inst, int synx_state) +{ + struct cvp_fence_queue *q; + struct cvp_fence_command *f, *d; + u64 ktid; + + q = &inst->fence_cmd_queue; + + mutex_lock(&q->lock); + q->mode = OP_DRAINING; + + list_for_each_entry_safe(f, d, &q->wait_list, list) { + ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1); + + dprintk(CVP_SYNX, "%s: (%#x) flush frame %llu %llu wait_list\n", + __func__, hash32_ptr(inst->session), ktid, f->frame_id); + + list_del_init(&f->list); + msm_cvp_unmap_frame(inst, f->pkt->client_data.kdata); + cvp_cancel_synx(inst, CVP_OUTPUT_SYNX, f, synx_state); + cvp_release_synx(inst, f); + cvp_free_fence_data(f); + } + + list_for_each_entry(f, &q->sched_list, list) { + ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1); + + dprintk(CVP_SYNX, "%s: (%#x)flush frame %llu %llu sched_list\n", + __func__, hash32_ptr(inst->session), ktid, f->frame_id); + cvp_cancel_synx(inst, CVP_INPUT_SYNX, f, synx_state); + } + + mutex_unlock(&q->lock); +} + +int cvp_stop_clean_fence_queue(struct msm_cvp_inst *inst) +{ + struct cvp_fence_queue *q; + u32 count = 0, max_retries = 100; + + cvp_clean_fence_queue(inst, SYNX_STATE_SIGNALED_ERROR); + cvp_fence_thread_stop(inst); + + /* Waiting for all output synx sent */ + q = &inst->fence_cmd_queue; +retry: + mutex_lock(&q->lock); + if (list_empty(&q->sched_list)) { + mutex_unlock(&q->lock); + return 0; + } + mutex_unlock(&q->lock); + usleep_range(500, 1000); + if (++count > max_retries) + return -EBUSY; + + goto retry; +} + static int cvp_flush_all(struct msm_cvp_inst *inst) { int rc = 0; struct msm_cvp_inst *s; struct cvp_fence_queue *q; - struct cvp_fence_command *f, *d; struct cvp_hfi_device *hdev; - u64 ktid; if (!inst || !inst->core) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); @@ -1328,40 +1603,15 @@ static int cvp_flush_all(struct msm_cvp_inst *inst) if (!s) return -ECONNRESET; + dprintk(CVP_SESS, "session %llx (%#x)flush all starts\n", + inst, hash32_ptr(inst->session)); q = &inst->fence_cmd_queue; hdev = inst->core->device; - mutex_lock(&q->lock); - q->mode = OP_DRAINING; + cvp_clean_fence_queue(inst, SYNX_STATE_SIGNALED_CANCEL); - list_for_each_entry_safe(f, d, &q->wait_list, list) { - ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1); - - dprintk(CVP_SESS, "%s: flush frame %llu from wait_list\n", - __func__, ktid); - dprintk(CVP_SESS, "%s: flush frameID %llu from wait_list\n", - __func__, f->frame_id); - - list_del_init(&f->list); - msm_cvp_unmap_frame(inst, f->pkt->client_data.kdata); - cvp_cancel_synx(inst, CVP_OUTPUT_SYNX, f); - cvp_release_synx(inst, f); - cvp_free_fence_data(f); - } - - list_for_each_entry(f, &q->sched_list, list) { - ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1); - - dprintk(CVP_SESS, "%s: flush frame %llu from sched_list\n", - __func__, ktid); - dprintk(CVP_SESS, "%s: flush frameID %llu from sched_list\n", - __func__, f->frame_id); - cvp_cancel_synx(inst, CVP_INPUT_SYNX, f); - } - - mutex_unlock(&q->lock); - - dprintk(CVP_SESS, "%s: send flush to fw\n", __func__); + dprintk(CVP_SESS, "%s: (%#x) send flush to fw\n", + __func__, hash32_ptr(inst->session)); /* Send flush to FW */ rc = call_hfi_op(hdev, session_flush, (void *)inst->session); @@ -1377,7 +1627,8 @@ static int cvp_flush_all(struct msm_cvp_inst *inst) dprintk(CVP_WARN, "%s: wait for signal failed, rc %d\n", __func__, rc); - dprintk(CVP_SESS, "%s: received flush from fw\n", __func__); + dprintk(CVP_SESS, "%s: (%#x) received flush from fw\n", + __func__, hash32_ptr(inst->session)); exit: rc = cvp_drain_fence_sched_list(inst); @@ -1440,6 +1691,8 @@ static int cvp_flush_frame(struct msm_cvp_inst *inst, u64 frame_id) if (!s) return -ECONNRESET; + dprintk(CVP_SESS, "Session %llx, flush frame with id %llu\n", + inst, frame_id); q = &inst->fence_cmd_queue; mutex_lock(&q->lock); @@ -1453,14 +1706,13 @@ static int cvp_flush_frame(struct msm_cvp_inst *inst, u64 frame_id) ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1); - dprintk(CVP_SESS, "%s: flush frame %llu from wait_list\n", - __func__, ktid); - dprintk(CVP_SESS, "%s: flush frameID %llu from wait_list\n", - __func__, f->frame_id); + dprintk(CVP_SYNX, "%s: flush frame %llu %llu from wait_list\n", + __func__, ktid, f->frame_id); list_del_init(&f->list); msm_cvp_unmap_frame(inst, f->pkt->client_data.kdata); - cvp_cancel_synx(inst, CVP_OUTPUT_SYNX, f); + cvp_cancel_synx(inst, CVP_OUTPUT_SYNX, f, + SYNX_STATE_SIGNALED_CANCEL); cvp_release_synx(inst, f); cvp_free_fence_data(f); } @@ -1471,11 +1723,10 @@ static int cvp_flush_frame(struct msm_cvp_inst *inst, u64 frame_id) ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1); - dprintk(CVP_SESS, "%s: flush frame %llu from sched_list\n", - __func__, ktid); - dprintk(CVP_SESS, "%s: flush frameID %llu from sched_list\n", - __func__, f->frame_id); - cvp_cancel_synx(inst, CVP_INPUT_SYNX, f); + dprintk(CVP_SYNX, "%s: flush frame %llu %llu from sched_list\n", + __func__, ktid, f->frame_id); + cvp_cancel_synx(inst, CVP_INPUT_SYNX, f, + SYNX_STATE_SIGNALED_CANCEL); } mutex_unlock(&q->lock); @@ -1640,7 +1891,7 @@ int msm_cvp_session_init(struct msm_cvp_inst *inst) inst->prop.priority = 0; inst->prop.is_secure = 0; inst->prop.dsp_mask = 0; - inst->prop.fthread_nr = 2; + inst->prop.fthread_nr = 3; return rc; } diff --git a/msm/eva/msm_cvp.h b/msm/eva/msm_cvp.h index 5875b631c1..b21864b46f 100644 --- a/msm/eva/msm_cvp.h +++ b/msm/eva/msm_cvp.h @@ -33,4 +33,5 @@ int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct cvp_kmd_arg *arg); int msm_cvp_session_init(struct msm_cvp_inst *inst); int msm_cvp_session_deinit(struct msm_cvp_inst *inst); int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst); +int cvp_stop_clean_fence_queue(struct msm_cvp_inst *inst); #endif diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index f67c2a25f7..ac56cd2689 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -498,6 +498,10 @@ static void msm_cvp_unmap_frame_buf(struct msm_cvp_inst *inst, } else if (atomic_dec_and_test(&smem->refcount)) { clear_bit(smem->bitmap_index, &inst->dma_cache.usage_bitmap); + dprintk(CVP_MEM, "smem %x %d iova %#x to be reused\n", + hash32_ptr(inst->session), + smem->size, + smem->device_addr); } } @@ -515,7 +519,8 @@ void msm_cvp_unmap_frame(struct msm_cvp_inst *inst, u64 ktid) } ktid &= (FENCE_BIT - 1); - dprintk(CVP_MEM, "%s: unmap frame %llu\n", __func__, ktid); + dprintk(CVP_MEM, "%s: (%#x) unmap frame %llu\n", + __func__, hash32_ptr(inst->session), ktid); found = false; mutex_lock(&inst->frames.lock); diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index f3a5618552..39ecb24424 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -166,6 +166,7 @@ int msm_cvp_smem_cache_operations(struct dma_buf *dbuf, enum smem_cache_ops cache_op, unsigned long offset, unsigned long size); +int msm_cvp_map_ipcc_regs(u32 *iova); /* CVP driver internal buffer management functions*/ struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 446a90d06f..66107472ef 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -8,7 +8,9 @@ #include #include #include +#ifndef CVP_MDT_ENABLED #include +#endif #include #include "msm_cvp_common.h" #include "cvp_hfi_api.h" @@ -402,6 +404,8 @@ int wait_for_sess_signal_receipt(struct msm_cvp_inst *inst, call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data); dump_hfi_queue(hdev->hfi_device_data); rc = -EIO; + } else if (inst->state == MSM_CVP_CORE_INVALID) { + rc = -ECONNRESET; } else { rc = 0; } @@ -623,11 +627,13 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) struct msm_cvp_core *core = NULL; struct cvp_hfi_device *hdev = NULL; struct msm_cvp_inst *inst = NULL; - int rc = 0; + int i, rc = 0; unsigned long flags = 0; enum cvp_core_state cur_state; +#ifndef CVP_MDT_ENABLED subsystem_crashed("evass"); +#endif if (!response) { dprintk(CVP_ERR, "Failed to get valid response for sys error\n"); @@ -663,6 +669,10 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) inst->cur_cmd_type, inst->state); if (inst->state != MSM_CVP_CORE_INVALID) { change_cvp_inst_state(inst, MSM_CVP_CORE_INVALID); + if (cvp_stop_clean_fence_queue(inst)) + dprintk(CVP_ERR, "Failed to clean fences\n"); + for (i = 0; i < ARRAY_SIZE(inst->completions); i++) + complete(&inst->completions[i]); spin_lock_irqsave(&inst->event_handler.lock, flags); inst->event_handler.event = CVP_SSR_EVENT; spin_unlock_irqrestore( diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index ae39770344..e9e76afe08 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -17,6 +17,8 @@ static int dspVMperm[DSP_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC, PERM_READ | PERM_WRITE | PERM_EXEC }; static int hlosVMperm[HLOS_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC }; +static int cvp_reinit_dsp(void); + static int cvp_dsp_send_cmd(struct cvp_dsp_cmd_msg *cmd, uint32_t len) { int rc = 0; @@ -40,7 +42,8 @@ exit: return rc; } -static int cvp_dsp_send_cmd_sync(struct cvp_dsp_cmd_msg *cmd, uint32_t len) +static int cvp_dsp_send_cmd_sync(struct cvp_dsp_cmd_msg *cmd, + uint32_t len, struct cvp_dsp_rsp_msg *rsp) { int rc = 0; struct cvp_dsp_apps *me = &gfa_cv; @@ -63,12 +66,15 @@ static int cvp_dsp_send_cmd_sync(struct cvp_dsp_cmd_msg *cmd, uint32_t len) } exit: + rsp->ret = me->pending_dsp2cpu_rsp.ret; + rsp->dsp_state = me->pending_dsp2cpu_rsp.dsp_state; me->pending_dsp2cpu_rsp.type = CVP_INVALID_RPMSG_TYPE; return rc; } static int cvp_dsp_send_cmd_hfi_queue(phys_addr_t *phys_addr, - uint32_t size_in_bytes) + uint32_t size_in_bytes, + struct cvp_dsp_rsp_msg *rsp) { int rc = 0; struct cvp_dsp_cmd_msg cmd; @@ -88,7 +94,7 @@ static int cvp_dsp_send_cmd_hfi_queue(phys_addr_t *phys_addr, "%s: address of buffer, PA=0x%pK size_buff=%d ddr_type=%d\n", __func__, phys_addr, size_in_bytes, cmd.ddr_type); - rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg)); + rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg), rsp); if (rc) { dprintk(CVP_ERR, "%s: cvp_dsp_send_cmd failed rc = %d\n", @@ -224,6 +230,8 @@ int cvp_dsp_suspend(uint32_t session_flag) int rc = 0; struct cvp_dsp_cmd_msg cmd; struct cvp_dsp_apps *me = &gfa_cv; + struct cvp_dsp_rsp_msg rsp; + bool retried = false; cmd.type = CPU2DSP_SUSPEND; @@ -231,8 +239,11 @@ int cvp_dsp_suspend(uint32_t session_flag) if (me->state != DSP_READY) goto exit; +retry: /* Use cvp_dsp_send_cmd_sync after dsp driver is ready */ - rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg)); + rc = cvp_dsp_send_cmd_sync(&cmd, + sizeof(struct cvp_dsp_cmd_msg), + &rsp); if (rc) { dprintk(CVP_ERR, "%s: cvp_dsp_send_cmd failed rc = %d\n", @@ -240,8 +251,31 @@ int cvp_dsp_suspend(uint32_t session_flag) goto exit; } - me->state = DSP_SUSPEND; + if (rsp.ret == CPU2DSP_EUNAVAILABLE) + goto fatal_exit; + if (rsp.ret == CPU2DSP_EFATAL) { + if (!retried) { + mutex_unlock(&me->lock); + retried = true; + rc = cvp_reinit_dsp(); + mutex_lock(&me->lock); + if (rc) + goto fatal_exit; + else + goto retry; + } else { + goto fatal_exit; + } + } + + me->state = DSP_SUSPEND; + goto exit; + +fatal_exit: + me->state = DSP_INVALID; + cvp_hyp_assign_from_dsp(); + rc = -ENOTSUPP; exit: mutex_unlock(&me->lock); return rc; @@ -252,6 +286,7 @@ int cvp_dsp_resume(uint32_t session_flag) int rc = 0; struct cvp_dsp_cmd_msg cmd; struct cvp_dsp_apps *me = &gfa_cv; + struct cvp_dsp_rsp_msg rsp; cmd.type = CPU2DSP_RESUME; @@ -260,7 +295,9 @@ int cvp_dsp_resume(uint32_t session_flag) goto exit; /* Use cvp_dsp_send_cmd_sync after dsp driver is ready */ - rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg)); + rc = cvp_dsp_send_cmd_sync(&cmd, + sizeof(struct cvp_dsp_cmd_msg), + &rsp); if (rc) { dprintk(CVP_ERR, "%s: cvp_dsp_send_cmd failed rc = %d\n", @@ -280,6 +317,7 @@ int cvp_dsp_shutdown(uint32_t session_flag) struct cvp_dsp_apps *me = &gfa_cv; int rc = 0; struct cvp_dsp_cmd_msg cmd; + struct cvp_dsp_rsp_msg rsp; cmd.type = CPU2DSP_SHUTDOWN; @@ -288,7 +326,7 @@ int cvp_dsp_shutdown(uint32_t session_flag) goto exit; me->state = DSP_INACTIVE; - rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg)); + rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg), &rsp); if (rc) { dprintk(CVP_ERR, "%s: cvp_dsp_send_cmd failed with rc = %d\n", @@ -312,6 +350,8 @@ int cvp_dsp_register_buffer(uint32_t session_id, uint32_t buff_fd, struct cvp_dsp_cmd_msg cmd; int rc; struct cvp_dsp_apps *me = &gfa_cv; + struct cvp_dsp_rsp_msg rsp; + bool retried = false; cmd.type = CPU2DSP_REGISTER_BUFFER; cmd.session_id = session_id; @@ -330,12 +370,43 @@ int cvp_dsp_register_buffer(uint32_t session_id, uint32_t buff_fd, __func__, cmd.buff_size, cmd.session_id); mutex_lock(&me->lock); - rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg)); +retry: + rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg), &rsp); if (rc) { dprintk(CVP_ERR, "%s send failed rc = %d\n", __func__, rc); goto exit; } + if (rsp.ret == CPU2DSP_EFAIL || rsp.ret == CPU2DSP_EUNSUPPORTED) { + dprintk(CVP_WARN, "%s, DSP return err %d\n", __func__, rsp.ret); + rc = -EINVAL; + goto exit; + } + + if (rsp.ret == CPU2DSP_EUNAVAILABLE) + goto fatal_exit; + + if (rsp.ret == CPU2DSP_EFATAL) { + if (!retried) { + mutex_unlock(&me->lock); + retried = true; + rc = cvp_reinit_dsp(); + mutex_lock(&me->lock); + if (rc) + goto fatal_exit; + else + goto retry; + } else { + goto fatal_exit; + } + } + + goto exit; + +fatal_exit: + me->state = DSP_INVALID; + cvp_hyp_assign_from_dsp(); + rc = -ENOTSUPP; exit: mutex_unlock(&me->lock); return rc; @@ -349,6 +420,8 @@ int cvp_dsp_deregister_buffer(uint32_t session_id, uint32_t buff_fd, struct cvp_dsp_cmd_msg cmd; int rc; struct cvp_dsp_apps *me = &gfa_cv; + struct cvp_dsp_rsp_msg rsp; + bool retried = false; cmd.type = CPU2DSP_DEREGISTER_BUFFER; cmd.session_id = session_id; @@ -367,12 +440,43 @@ int cvp_dsp_deregister_buffer(uint32_t session_id, uint32_t buff_fd, __func__, cmd.buff_size, cmd.session_id); mutex_lock(&me->lock); - rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg)); +retry: + rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg), &rsp); if (rc) { dprintk(CVP_ERR, "%s send failed rc = %d\n", __func__, rc); goto exit; } + if (rsp.ret == CPU2DSP_EFAIL || rsp.ret == CPU2DSP_EUNSUPPORTED) { + dprintk(CVP_WARN, "%s, DSP return err %d\n", __func__, rsp.ret); + rc = -EINVAL; + goto exit; + } + + if (rsp.ret == CPU2DSP_EUNAVAILABLE) + goto fatal_exit; + + if (rsp.ret == CPU2DSP_EFATAL) { + if (!retried) { + mutex_unlock(&me->lock); + retried = true; + rc = cvp_reinit_dsp(); + mutex_lock(&me->lock); + if (rc) + goto fatal_exit; + else + goto retry; + } else { + goto fatal_exit; + } + } + + goto exit; + +fatal_exit: + me->state = DSP_INVALID; + cvp_hyp_assign_from_dsp(); + rc = -ENOTSUPP; exit: mutex_unlock(&me->lock); return rc; @@ -393,11 +497,156 @@ static struct rpmsg_driver cvp_dsp_rpmsg_client = { }, }; +static void cvp_dsp_set_queue_hdr_defaults(struct cvp_hfi_queue_header *q_hdr) +{ + q_hdr->qhdr_status = 0x1; + q_hdr->qhdr_type = CVP_IFACEQ_DFLT_QHDR; + q_hdr->qhdr_q_size = CVP_IFACEQ_QUEUE_SIZE / 4; + q_hdr->qhdr_pkt_size = 0; + q_hdr->qhdr_rx_wm = 0x1; + q_hdr->qhdr_tx_wm = 0x1; + q_hdr->qhdr_rx_req = 0x1; + q_hdr->qhdr_tx_req = 0x0; + q_hdr->qhdr_rx_irq_status = 0x0; + q_hdr->qhdr_tx_irq_status = 0x0; + q_hdr->qhdr_read_idx = 0x0; + q_hdr->qhdr_write_idx = 0x0; +} + +void cvp_dsp_init_hfi_queue_hdr(struct iris_hfi_device *device) +{ + u32 i; + struct cvp_hfi_queue_table_header *q_tbl_hdr; + struct cvp_hfi_queue_header *q_hdr; + struct cvp_iface_q_info *iface_q; + + for (i = 0; i < CVP_IFACEQ_NUMQ; i++) { + iface_q = &device->dsp_iface_queues[i]; + iface_q->q_hdr = CVP_IFACEQ_GET_QHDR_START_ADDR( + device->dsp_iface_q_table.align_virtual_addr, i); + cvp_dsp_set_queue_hdr_defaults(iface_q->q_hdr); + } + q_tbl_hdr = (struct cvp_hfi_queue_table_header *) + device->dsp_iface_q_table.align_virtual_addr; + q_tbl_hdr->qtbl_version = 0; + q_tbl_hdr->device_addr = (void *)device; + strlcpy(q_tbl_hdr->name, "msm_cvp", sizeof(q_tbl_hdr->name)); + q_tbl_hdr->qtbl_size = CVP_IFACEQ_TABLE_SIZE; + q_tbl_hdr->qtbl_qhdr0_offset = + sizeof(struct cvp_hfi_queue_table_header); + q_tbl_hdr->qtbl_qhdr_size = sizeof(struct cvp_hfi_queue_header); + q_tbl_hdr->qtbl_num_q = CVP_IFACEQ_NUMQ; + q_tbl_hdr->qtbl_num_active_q = CVP_IFACEQ_NUMQ; + + iface_q = &device->dsp_iface_queues[CVP_IFACEQ_CMDQ_IDX]; + q_hdr = iface_q->q_hdr; + q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; + q_hdr->qhdr_type |= HFI_Q_ID_HOST_TO_CTRL_CMD_Q; + + iface_q = &device->dsp_iface_queues[CVP_IFACEQ_MSGQ_IDX]; + q_hdr = iface_q->q_hdr; + q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; + q_hdr->qhdr_type |= HFI_Q_ID_CTRL_TO_HOST_MSG_Q; + + iface_q = &device->dsp_iface_queues[CVP_IFACEQ_DBGQ_IDX]; + q_hdr = iface_q->q_hdr; + q_hdr->qhdr_start_addr = iface_q->q_array.align_device_addr; + q_hdr->qhdr_type |= HFI_Q_ID_CTRL_TO_HOST_DEBUG_Q; + /* + * Set receive request to zero on debug queue as there is no + * need of interrupt from cvp hardware for debug messages + */ + q_hdr->qhdr_rx_req = 0; +} + +static int __reinit_dsp(void) +{ + int rc; + uint32_t flag = 0; + uint64_t addr; + uint32_t size; + struct cvp_dsp_apps *me = &gfa_cv; + struct cvp_dsp_rsp_msg rsp; + struct msm_cvp_core *core; + struct iris_hfi_device *device; + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (core && core->device) + device = core->device->hfi_device_data; + else + return -EINVAL; + + if (!device) { + dprintk(CVP_ERR, "%s: NULL device\n", __func__); + return -EINVAL; + } + + /* Force shutdown DSP */ + rc = cvp_dsp_shutdown(flag); + if (rc) + return rc; + + /* Resend HFI queue */ + mutex_lock(&me->lock); + if (!device->dsp_iface_q_table.align_virtual_addr) { + dprintk(CVP_ERR, "%s: DSP HFI queue released\n", __func__); + rc = -EINVAL; + goto exit; + } + + addr = (uint64_t)device->dsp_iface_q_table.mem_data.dma_handle; + size = device->dsp_iface_q_table.mem_data.size; + + if (!addr || !size) { + dprintk(CVP_DSP, "%s: HFI queue is not ready\n", __func__); + goto exit; + } + + rc = cvp_hyp_assign_to_dsp(addr, size); + if (rc) { + dprintk(CVP_ERR, "%s: cvp_hyp_assign_to_dsp. rc=%d\n", + __func__, rc); + goto exit; + } + + rc = cvp_dsp_send_cmd_hfi_queue((phys_addr_t *)addr, size, &rsp); + if (rc) { + dprintk(CVP_WARN, "%s: Send HFI Queue failed rc = %d\n", + __func__, rc); + + goto exit; + } + if (rsp.ret) { + dprintk(CVP_ERR, "%s: DSP error %d %d\n", __func__, + rsp.ret, rsp.dsp_state); + rc = -ENODEV; + } +exit: + mutex_unlock(&me->lock); + return rc; +} + +static int cvp_reinit_dsp(void) +{ + int rc; + struct cvp_dsp_apps *me = &gfa_cv; + + rc = __reinit_dsp(); + if (rc) { + mutex_lock(&me->lock); + me->state = DSP_INVALID; + cvp_hyp_assign_from_dsp(); + mutex_unlock(&me->lock); + } + return rc; +} + void cvp_dsp_send_hfi_queue(void) { struct msm_cvp_core *core; struct iris_hfi_device *device; struct cvp_dsp_apps *me = &gfa_cv; + struct cvp_dsp_rsp_msg rsp; uint64_t addr; uint32_t size; int rc; @@ -418,6 +667,13 @@ void cvp_dsp_send_hfi_queue(void) mutex_lock(&device->lock); mutex_lock(&me->lock); + if (!device->dsp_iface_q_table.align_virtual_addr) { + dprintk(CVP_ERR, "%s: DSP HFI queue released\n", __func__); + mutex_unlock(&me->lock); + mutex_unlock(&device->lock); + return; + } + addr = (uint64_t)device->dsp_iface_q_table.mem_data.dma_handle; size = device->dsp_iface_q_table.mem_data.size; @@ -436,7 +692,13 @@ void cvp_dsp_send_hfi_queue(void) goto exit; } - rc = cvp_dsp_send_cmd_hfi_queue((phys_addr_t *)addr, size); + if (me->state == DSP_PROBED) { + cvp_dsp_init_hfi_queue_hdr(device); + dprintk(CVP_WARN, + "%s: Done init of HFI queue headers\n", __func__); + } + + rc = cvp_dsp_send_cmd_hfi_queue((phys_addr_t *)addr, size, &rsp); if (rc) { dprintk(CVP_WARN, "%s: Send HFI Queue failed rc = %d\n", __func__, rc); @@ -444,6 +706,30 @@ void cvp_dsp_send_hfi_queue(void) goto exit; } + if (rsp.ret == CPU2DSP_EUNSUPPORTED) { + dprintk(CVP_WARN, "%s unsupported cmd %d\n", + __func__, rsp.type); + goto exit; + } + + if (rsp.ret == CPU2DSP_EFATAL || rsp.ret == CPU2DSP_EUNAVAILABLE) { + dprintk(CVP_ERR, "%s fatal error returned %d\n", + __func__, rsp.dsp_state); + me->state = DSP_INVALID; + cvp_hyp_assign_from_dsp(); + goto exit; + } else if (rsp.ret == CPU2DSP_EINVALSTATE) { + dprintk(CVP_ERR, "%s dsp invalid state %d\n", + __func__, rsp.dsp_state); + mutex_unlock(&me->lock); + if (cvp_reinit_dsp()) { + dprintk(CVP_ERR, "%s reinit dsp fail\n", __func__); + mutex_unlock(&device->lock); + return; + } + mutex_lock(&me->lock); + } + dprintk(CVP_DSP, "%s: dsp initialized\n", __func__); me->state = DSP_READY; @@ -498,8 +784,10 @@ wait_dsp: switch (me->pending_dsp2cpu_cmd.type) { case DSP2CPU_POWERON: { - if (me->state == DSP_READY) + if (me->state == DSP_READY) { + cmd.ret = 0; break; + } mutex_unlock(&me->lock); old_state = me->state; diff --git a/msm/eva/msm_cvp_dsp.h b/msm/eva/msm_cvp_dsp.h index 0ea8b690f5..da926c0cf1 100644 --- a/msm/eva/msm_cvp_dsp.h +++ b/msm/eva/msm_cvp_dsp.h @@ -24,6 +24,16 @@ int cvp_dsp_device_init(void); void cvp_dsp_device_exit(void); void cvp_dsp_send_hfi_queue(void); +void cvp_dsp_init_hfi_queue_hdr(struct iris_hfi_device *device); + +enum CPU2DSP_STATUS { + CPU2DSP_SUCCESS = 0, + CPU2DSP_EFAIL = 1, + CPU2DSP_EFATAL = 2, + CPU2DSP_EUNAVAILABLE = 3, + CPU2DSP_EINVALSTATE = 4, + CPU2DSP_EUNSUPPORTED = 5, +}; enum CVP_DSP_COMMAND { CPU2DSP_SEND_HFI_QUEUE = 0, @@ -58,7 +68,8 @@ struct cvp_dsp_cmd_msg { struct cvp_dsp_rsp_msg { uint32_t type; int32_t ret; - uint32_t reserved[CVP_DSP_MAX_RESERVED]; + uint32_t dsp_state; + uint32_t reserved[CVP_DSP_MAX_RESERVED - 1]; }; struct cvp_dsp2cpu_cmd_msg { diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index 41f2afb2d4..f58b2cbc37 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -23,6 +23,7 @@ #include #include #include "cvp_hfi_api.h" +#include "cvp_hfi_helper.h" #include #define MAX_SUPPORTED_INSTANCES 16 @@ -192,7 +193,7 @@ enum msm_cvp_modes { struct cvp_session_msg { struct list_head node; - struct cvp_hfi_msg_session_hdr pkt; + struct cvp_hfi_msg_session_hdr_ext pkt; }; struct cvp_session_queue { @@ -203,6 +204,23 @@ struct cvp_session_queue { wait_queue_head_t wq; }; +#define CVP_CYCLE_STAT_SIZE 8 +struct cvp_cycle_stat { + u32 busy[CVP_CYCLE_STAT_SIZE]; + u32 total; + u32 idx; + u32 size; +}; + +struct cvp_cycle_info { + u32 sum_fps[HFI_MAX_HW_THREADS]; + u32 hi_ctrl_lim[HFI_MAX_HW_THREADS]; + u32 lo_ctrl_lim[HFI_MAX_HW_THREADS]; + struct cvp_cycle_stat cycle[HFI_MAX_HW_THREADS]; + unsigned long conf_freq; + struct mutex lock; +}; + struct cvp_session_prop { u32 type; u32 kernel_mask; @@ -224,6 +242,7 @@ struct cvp_session_prop { u32 ddr_op_bw; u32 ddr_cache; u32 ddr_op_cache; + u32 fps[HFI_MAX_HW_THREADS]; }; enum cvp_event_t { @@ -265,6 +284,7 @@ struct msm_cvp_core { u32 last_fault_addr; bool trigger_ssr; unsigned long curr_freq; + struct cvp_cycle_info dyn_clk; atomic64_t kernel_trans_id; }; diff --git a/msm/eva/msm_cvp_ioctl.c b/msm/eva/msm_cvp_ioctl.c index 47a3f6e834..d9277343a9 100644 --- a/msm/eva/msm_cvp_ioctl.c +++ b/msm/eva/msm_cvp_ioctl.c @@ -10,6 +10,9 @@ static int _get_pkt_hdr_from_user(struct cvp_kmd_arg __user *up, struct cvp_hal_session_cmd_pkt *pkt_hdr) { struct cvp_kmd_hfi_packet *u; + struct cvp_hfi_msg_session_hdr *hdr; + + hdr = (struct cvp_hfi_msg_session_hdr *)pkt_hdr; u = &up->data.hfi_pkt; @@ -33,7 +36,7 @@ static int _get_pkt_hdr_from_user(struct cvp_kmd_arg __user *up, return 0; set_default_pkt_hdr: - pkt_hdr->size = get_msg_size(); + pkt_hdr->size = get_msg_size(hdr); return 0; } @@ -451,7 +454,7 @@ static int _put_user_session_info( static int convert_to_user(struct cvp_kmd_arg *kp, unsigned long arg) { int rc = 0; - int i, size = get_msg_size() >> 2; + int i, size; struct cvp_kmd_arg __user *up = (struct cvp_kmd_arg *)arg; struct cvp_hal_session_cmd_pkt pkt_hdr; @@ -467,9 +470,12 @@ static int convert_to_user(struct cvp_kmd_arg *kp, unsigned long arg) case CVP_KMD_RECEIVE_MSG_PKT: { struct cvp_kmd_hfi_packet *k, *u; + struct cvp_hfi_msg_session_hdr *hdr; k = &kp->data.hfi_pkt; u = &up->data.hfi_pkt; + hdr = (struct cvp_hfi_msg_session_hdr *)k; + size = get_msg_size(hdr) >> 2; for (i = 0; i < size; i++) if (put_user(k->pkt_data[i], &u->pkt_data[i])) return -EFAULT; diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index 59fc1d3bfa..2ff704c8ca 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -115,6 +115,25 @@ void msm_cvp_free_platform_resources( msm_cvp_free_bus_vectors(res); } +static int msm_cvp_load_ipcc_regs(struct msm_cvp_platform_resources *res) +{ + int ret = 0; + unsigned int reg_config[2]; + struct platform_device *pdev = res->pdev; + + ret = of_property_read_u32_array(pdev->dev.of_node, "qcom,ipcc-reg", + reg_config, 2); + if (ret) { + dprintk(CVP_ERR, "Failed to read ipcc reg: %d\n", ret); + return ret; + } + + res->ipcc_reg_base = reg_config[0]; + res->ipcc_reg_size = reg_config[1]; + + return ret; +} + static int msm_cvp_load_reg_table(struct msm_cvp_platform_resources *res) { struct reg_set *reg_set; @@ -783,6 +802,10 @@ int cvp_read_platform_resources_from_dt( goto err_load_reg_table; } + rc = msm_cvp_load_ipcc_regs(res); + if (rc) + dprintk(CVP_ERR, "Failed to load IPCC regs: %d\n", rc); + rc = msm_cvp_load_regulator_table(res); if (rc) { dprintk(CVP_ERR, "Failed to load list of regulators %d\n", rc); diff --git a/msm/eva/msm_cvp_resources.h b/msm/eva/msm_cvp_resources.h index 7ce228cbe3..ad254fb87f 100644 --- a/msm/eva/msm_cvp_resources.h +++ b/msm/eva/msm_cvp_resources.h @@ -136,7 +136,9 @@ struct msm_cvp_mem_cdsp { struct msm_cvp_platform_resources { phys_addr_t firmware_base; phys_addr_t register_base; + phys_addr_t ipcc_reg_base; uint32_t register_size; + uint32_t ipcc_reg_size; uint32_t irq; uint32_t sku_version; struct allowed_clock_rates_table *allowed_clks_tbl; diff --git a/msm/eva/msm_cvp_synx.c b/msm/eva/msm_cvp_synx.c index a114ff6f9c..f70fb40130 100644 --- a/msm/eva/msm_cvp_synx.c +++ b/msm/eva/msm_cvp_synx.c @@ -73,8 +73,8 @@ int cvp_import_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, rc = synx_import(ssid, ¶ms); if (rc) { dprintk(CVP_ERR, - "%s: synx_import failed\n", - __func__); + "%s: %d synx_import failed\n", + __func__, h_synx); return rc; } } @@ -102,8 +102,8 @@ int cvp_release_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc) rc = synx_release(ssid, h_synx); if (rc) dprintk(CVP_ERR, - "%s: synx_release %d failed\n", - __func__, i); + "%s: synx_release %d, %d failed\n", + __func__, h_synx, i); } } return rc; @@ -111,14 +111,14 @@ int cvp_release_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc) static int cvp_cancel_synx_impl(struct msm_cvp_inst *inst, enum cvp_synx_type type, - struct cvp_fence_command *fc) + struct cvp_fence_command *fc, + int synx_state) { int rc = 0; int i; int h_synx; struct synx_session ssid; int start = 0, end = 0; - int synx_state = SYNX_STATE_SIGNALED_CANCEL; ssid = inst->synx_session_id; @@ -137,11 +137,12 @@ static int cvp_cancel_synx_impl(struct msm_cvp_inst *inst, h_synx = fc->synx[i]; if (h_synx) { rc = synx_signal(ssid, h_synx, synx_state); - if (rc) { - dprintk(CVP_ERR, "%s: synx_signal %d failed\n", - __func__, i); - synx_state = SYNX_STATE_SIGNALED_ERROR; - } + dprintk(CVP_SYNX, "Cancel synx %d session %llx\n", + h_synx, inst); + if (rc) + dprintk(CVP_ERR, + "%s: synx_signal %d %d %d failed\n", + __func__, h_synx, i, synx_state); } } @@ -151,14 +152,14 @@ static int cvp_cancel_synx_impl(struct msm_cvp_inst *inst, } int cvp_cancel_synx(struct msm_cvp_inst *inst, enum cvp_synx_type type, - struct cvp_fence_command *fc) + struct cvp_fence_command *fc, int synx_state) { if (fc->signature != 0xFEEDFACE) { dprintk(CVP_ERR, "%s deprecated synx path\n", __func__); return -EINVAL; } - return cvp_cancel_synx_impl(inst, type, fc); + return cvp_cancel_synx_impl(inst, type, fc, synx_state); } static int cvp_wait_synx(struct synx_session ssid, u32 *synx, u32 num_synx, @@ -186,6 +187,8 @@ static int cvp_wait_synx(struct synx_session ssid, u32 *synx, u32 num_synx, } return rc; } + dprintk(CVP_SYNX, "Wait synx %d returned succes\n", + h_synx); } ++i; } @@ -203,10 +206,12 @@ static int cvp_signal_synx(struct synx_session ssid, u32 *synx, u32 num_synx, if (h_synx) { rc = synx_signal(ssid, h_synx, synx_state); if (rc) { - dprintk(CVP_ERR, "%s: synx_signal %d failed\n", - current->comm, i); + dprintk(CVP_ERR, + "%s: synx_signal %d %d failed\n", + current->comm, h_synx, i); synx_state = SYNX_STATE_SIGNALED_ERROR; } + dprintk(CVP_SYNX, "Signaled synx %d\n", h_synx); } ++i; } diff --git a/msm/eva/msm_cvp_synx.h b/msm/eva/msm_cvp_synx.h index e95418a65a..3e2fcce514 100644 --- a/msm/eva/msm_cvp_synx.h +++ b/msm/eva/msm_cvp_synx.h @@ -48,7 +48,7 @@ int cvp_import_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, u32 *fence); int cvp_release_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc); int cvp_cancel_synx(struct msm_cvp_inst *inst, enum cvp_synx_type type, - struct cvp_fence_command *fc); + struct cvp_fence_command *fc, int synx_state); int cvp_synx_ops(struct msm_cvp_inst *inst, enum cvp_synx_type type, struct cvp_fence_command *fc, u32 *synx_state); void cvp_dump_fence_queue(struct msm_cvp_inst *inst); diff --git a/msm/eva/msm_smem.c b/msm/eva/msm_smem.c index 22cc131ecd..8080191518 100644 --- a/msm/eva/msm_smem.c +++ b/msm/eva/msm_smem.c @@ -14,6 +14,7 @@ #include "msm_cvp_core.h" #include "msm_cvp_debug.h" #include "msm_cvp_resources.h" +#include "cvp_core_hfi.h" static int msm_dma_get_device_address(struct dma_buf *dbuf, u32 align, @@ -471,3 +472,41 @@ struct context_bank_info *msm_cvp_smem_get_context_bank(bool is_secure, return match; } + +int msm_cvp_map_ipcc_regs(u32 *iova) +{ + struct context_bank_info *cb; + struct msm_cvp_core *core; + struct cvp_hfi_device *hfi_ops; + struct iris_hfi_device *dev = NULL; + phys_addr_t paddr; + u32 size; + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (core) { + hfi_ops = core->device; + if (hfi_ops) + dev = hfi_ops->hfi_device_data; + } + + if (!dev) + return -EINVAL; + + paddr = dev->res->ipcc_reg_base; + size = dev->res->ipcc_reg_size; + + if (!paddr || !size) + return -EINVAL; + + cb = msm_cvp_smem_get_context_bank(false, dev->res, 0); + if (!cb) { + dprintk(CVP_ERR, "%s: fail to get context bank\n", __func__); + return -EINVAL; + } + *iova = dma_map_resource(cb->dev, paddr, size, DMA_BIDIRECTIONAL, 0); + if (*iova == DMA_MAPPING_ERROR) { + dprintk(CVP_WARN, "%s: fail to map IPCC regs\n", __func__); + return -EFAULT; + } + return 0; +} From 16527cad452021918b457d603f9469bd0702a549 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 2 Sep 2020 22:47:56 -0700 Subject: [PATCH 007/317] msm: eva: Merge Lahaina changes changes from gerrits: 3302597 3292606 3313485 3315054 3303642 Change-Id: I7d481ced38963396255435ddb968017f79bfbe12 Signed-off-by: George Shen --- msm/eva/cvp.c | 4 +-- msm/eva/cvp_hfi.c | 31 ++++++++++++++++++- msm/eva/msm_cvp.c | 16 +++++----- msm/eva/msm_cvp_buf.c | 61 ++++++++++++++++++++++++++------------ msm/eva/msm_cvp_common.c | 3 +- msm/eva/msm_cvp_debug.c | 2 +- msm/eva/msm_cvp_internal.h | 2 +- msm/eva/msm_cvp_platform.c | 8 +++-- 8 files changed, 90 insertions(+), 37 deletions(-) diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index 0fdb9b7366..cf3e4b530d 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -115,7 +115,6 @@ static void init_cycle_info(struct cvp_cycle_info *info) memset(info->cycle, 0, HFI_MAX_HW_THREADS*sizeof(struct cvp_cycle_stat)); info->conf_freq = 0; - mutex_init(&info->lock); } static int msm_cvp_initialize_core(struct platform_device *pdev, @@ -134,6 +133,7 @@ static int msm_cvp_initialize_core(struct platform_device *pdev, INIT_LIST_HEAD(&core->instances); mutex_init(&core->lock); + mutex_init(&core->clk_lock); core->state = CVP_CORE_UNINIT; for (i = SYS_MSG_INDEX(SYS_MSG_START); @@ -502,7 +502,7 @@ static int msm_cvp_remove(struct platform_device *pdev) sysfs_remove_group(&pdev->dev.kobj, &msm_cvp_core_attr_group); dev_set_drvdata(&pdev->dev, NULL); mutex_destroy(&core->lock); - mutex_destroy(&core->dyn_clk.lock); + mutex_destroy(&core->clk_lock); kfree(core); return rc; } diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index e627cef2ab..377a6d9bb2 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -4379,6 +4379,35 @@ static int iris_hfi_get_core_capabilities(void *dev) static u32 cvp_arp_test_regs[16]; static u32 cvp_dma_test_regs[512]; +static const char * const mid_names[16] = { + "CVP_FW", + "ARP_DATA", + "CVP_OD_NON_PIXEL", + "CVP_OD_ORIG_PIXEL", + "CVP_OD_WR_PIXEL", + "CVP_MPU_ORIG_PIXEL", + "CVP_MPU_REF_PIXEL", + "CVP_MPU_NON_PIXEL", + "CVP_MPU_DFS", + "CVP_FDU_NON_PIXEL", + "CVP_FDU_PIXEL", + "CVP_ICA_PIXEL", + "Invalid", + "Invalid", + "Invalid", + "Invalid" +}; + +static void __print_reg_details(u32 val) +{ + u32 mid, sid; + + mid = (val >> 5) & 0xF; + sid = (val >> 2) & 0x7; + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG3_LOW: %#x\n", val); + dprintk(CVP_ERR, "Sub-client:%s, SID: %d\n", mid_names[mid], sid); +} + static void __noc_error_info_iris2(struct iris_hfi_device *device) { u32 val = 0, regi, i; @@ -4433,7 +4462,7 @@ static void __noc_error_info_iris2(struct iris_hfi_device *device) val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_HIGH: %#x\n", val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG3_LOW: %#x\n", val); + __print_reg_details(val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG3_HIGH: %#x\n", val); #define CVP_SS_CLK_HALT 0x8 diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 75185b2ad7..af99aec42a 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -182,9 +182,7 @@ static int msm_cvp_session_process_hfi( dprintk(CVP_ERR, "%s incorrect packet %d, %x\n", __func__, in_pkt->pkt_data[0], in_pkt->pkt_data[1]); - offset = in_offset; - buf_num = in_buf_num; - signal = HAL_NO_RESP; + goto exit; } else { offset = cvp_hfi_defs[pkt_idx].buf_offset; buf_num = cvp_hfi_defs[pkt_idx].buf_num; @@ -376,7 +374,7 @@ static int cvp_check_clock(struct msm_cvp_inst *inst, __func__, fw_cycles, hw_cycles[0], hw_cycles[1], hw_cycles[2], hw_cycles[3]); - mutex_lock(&core->dyn_clk.lock); + mutex_lock(&core->clk_lock); for (i = 0; i < HFI_MAX_HW_THREADS; ++i) { dprintk(CVP_PWR, "%s - %d: hw_cycles %u, tens_thresh %u\n", __func__, i, hw_cycles[i], @@ -437,7 +435,7 @@ static int cvp_check_clock(struct msm_cvp_inst *inst, } } } - mutex_unlock(&core->dyn_clk.lock); + mutex_unlock(&core->clk_lock); return rc; } @@ -861,6 +859,8 @@ static void aggregate_power_update(struct msm_cvp_core *core, * Clock vote from realtime session will be hard request. If aggregated * session clock request exceeds max limit, the function will return * error. + * + * Ensure caller acquires clk_lock! */ static int adjust_bw_freqs(void) { @@ -943,7 +943,6 @@ static int adjust_bw_freqs(void) } ctrl_freq = (core->curr_freq*3)>>1; - mutex_lock(&core->dyn_clk.lock); core->dyn_clk.conf_freq = core->curr_freq; for (i = 0; i < HFI_MAX_HW_THREADS; ++i) { core->dyn_clk.hi_ctrl_lim[i] = core->dyn_clk.sum_fps[i] ? @@ -951,7 +950,6 @@ static int adjust_bw_freqs(void) core->dyn_clk.lo_ctrl_lim[i] = core->dyn_clk.hi_ctrl_lim[i]; } - mutex_unlock(&core->dyn_clk.lock); hdev->clk_freq = core->curr_freq; rc = icc_set_bw(bus->client, bw_sum, 0); @@ -980,9 +978,9 @@ static int msm_cvp_update_power(struct msm_cvp_inst *inst) inst->cur_cmd_type = CVP_KMD_UPDATE_POWER; core = inst->core; - mutex_lock(&core->lock); + mutex_lock(&core->clk_lock); rc = adjust_bw_freqs(); - mutex_unlock(&core->lock); + mutex_unlock(&core->clk_lock); inst->cur_cmd_type = 0; cvp_put_inst(s); diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index ac56cd2689..f52a7af0b1 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -9,6 +9,23 @@ #include "msm_cvp_core.h" #include "msm_cvp_dsp.h" +#define CLEAR_USE_BITMAP(idx, inst) \ + do { \ + clear_bit(idx, &inst->dma_cache.usage_bitmap); \ + dprintk(CVP_MEM, "clear %x bit %d dma_cache bitmap 0x%llx\n", \ + hash32_ptr(inst->session), smem->bitmap_index, \ + inst->dma_cache.usage_bitmap); \ + } while (0) + +#define SET_USE_BITMAP(idx, inst) \ + do { \ + set_bit(idx, &inst->dma_cache.usage_bitmap); \ + dprintk(CVP_MEM, "Set %x bit %d dma_cache bitmap 0x%llx\n", \ + hash32_ptr(inst->session), idx, \ + inst->dma_cache.usage_bitmap); \ + } while (0) + + void print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, struct msm_cvp_smem *smem) { @@ -16,9 +33,11 @@ void print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, return; if (smem->dma_buf) { - dprintk(tag, "%s: %x : %s size %d flags %#x iova %#x", str, - hash32_ptr(inst->session), smem->dma_buf->name, - smem->size, smem->flags, smem->device_addr); + dprintk(tag, + "%s: %x : %s size %d flags %#x iova %#x idx %d ref %d", + str, hash32_ptr(inst->session), smem->dma_buf->name, + smem->size, smem->flags, smem->device_addr, + smem->bitmap_index, smem->refcount); } } @@ -126,7 +145,7 @@ int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct cvp_kmd_buffer *buf) smem->dma_buf = dma_buf; smem->bitmap_index = MAX_DMABUF_NUMS; - dprintk(CVP_DSP, "%s: dma_buf = %llx\n", __func__, dma_buf); + dprintk(CVP_MEM, "%s: dma_buf = %llx\n", __func__, dma_buf); rc = msm_cvp_map_smem(inst, smem, "map dsp"); if (rc) { print_client_buffer(CVP_ERR, "map failed", inst, buf); @@ -274,7 +293,7 @@ static struct msm_cvp_smem *msm_cvp_session_find_smem(struct msm_cvp_inst *inst, mutex_lock(&inst->dma_cache.lock); for (i = 0; i < inst->dma_cache.nr; i++) if (inst->dma_cache.entries[i]->dma_buf == dma_buf) { - set_bit(i, &inst->dma_cache.usage_bitmap); + SET_USE_BITMAP(i, inst); smem = inst->dma_cache.entries[i]; smem->bitmap_index = i; atomic_inc(&smem->refcount); @@ -303,7 +322,7 @@ static int msm_cvp_session_add_smem(struct msm_cvp_inst *inst, mutex_lock(&inst->dma_cache.lock); if (inst->dma_cache.nr < MAX_DMABUF_NUMS) { inst->dma_cache.entries[inst->dma_cache.nr] = smem; - set_bit(inst->dma_cache.nr, &inst->dma_cache.usage_bitmap); + SET_USE_BITMAP(inst->dma_cache.nr, inst); smem->bitmap_index = inst->dma_cache.nr; inst->dma_cache.nr++; i = smem->bitmap_index; @@ -318,7 +337,7 @@ static int msm_cvp_session_add_smem(struct msm_cvp_inst *inst, inst->dma_cache.entries[i] = smem; smem->bitmap_index = i; - set_bit(i, &inst->dma_cache.usage_bitmap); + SET_USE_BITMAP(i, inst); } else { dprintk(CVP_WARN, "%s: not enough memory\n", __func__); mutex_unlock(&inst->dma_cache.lock); @@ -495,13 +514,14 @@ static void msm_cvp_unmap_frame_buf(struct msm_cvp_inst *inst, dma_buf_put(smem->dma_buf); kmem_cache_free(cvp_driver->smem_cache, smem); buf->smem = NULL; - } else if (atomic_dec_and_test(&smem->refcount)) { - clear_bit(smem->bitmap_index, - &inst->dma_cache.usage_bitmap); - dprintk(CVP_MEM, "smem %x %d iova %#x to be reused\n", - hash32_ptr(inst->session), - smem->size, - smem->device_addr); + } else { + mutex_lock(&inst->dma_cache.lock); + if (atomic_dec_and_test(&smem->refcount)) { + CLEAR_USE_BITMAP(smem->bitmap_index, inst); + print_smem(CVP_MEM, "Map dereference", + inst, smem); + } + mutex_unlock(&inst->dma_cache.lock); } } @@ -550,7 +570,7 @@ int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, struct msm_cvp_smem *smem = NULL; if (!offset || !buf_num) - return 0; + return rc; cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; ktid = cmd_hdr->client_data.kdata & (FENCE_BIT - 1); @@ -574,10 +594,13 @@ int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, cvp_driver->smem_cache, smem); pbuf->smem = NULL; - } else if (atomic_dec_and_test( - &smem->refcount)) { - clear_bit(smem->bitmap_index, - &inst->dma_cache.usage_bitmap); + } else { + mutex_lock(&inst->dma_cache.lock); + if (atomic_dec_and_test(&smem->refcount)) + CLEAR_USE_BITMAP( + smem->bitmap_index, + inst); + mutex_unlock(&inst->dma_cache.lock); } kmem_cache_free(cvp_driver->buf_cache, pbuf); diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 66107472ef..3be1ce61b9 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -1611,7 +1611,8 @@ int cvp_comm_set_arp_buffers(struct msm_cvp_inst *inst) return rc; error: - cvp_release_arp_buffers(inst); + if (rc != -ENOMEM) + cvp_release_arp_buffers(inst); return rc; } diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 64f882a5d1..cf203a1ef1 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -22,7 +22,7 @@ int msm_cvp_fw_debug_mode = 1; int msm_cvp_fw_low_power_mode = 1; bool msm_cvp_fw_coverage = !true; bool msm_cvp_thermal_mitigation_disabled = !true; -bool msm_cvp_cacheop_disabled = true; +bool msm_cvp_cacheop_disabled = !true; int msm_cvp_clock_voting = !1; bool msm_cvp_syscache_disable = !true; bool msm_cvp_dsp_disable = !true; diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index f58b2cbc37..0e044db578 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -218,7 +218,6 @@ struct cvp_cycle_info { u32 lo_ctrl_lim[HFI_MAX_HW_THREADS]; struct cvp_cycle_stat cycle[HFI_MAX_HW_THREADS]; unsigned long conf_freq; - struct mutex lock; }; struct cvp_session_prop { @@ -263,6 +262,7 @@ struct cvp_session_event { struct msm_cvp_core { struct list_head list; struct mutex lock; + struct mutex clk_lock; int id; dev_t dev_num; struct cdev cdev; diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index bc9d55fe93..47dd14a59e 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -215,7 +215,7 @@ void *cvp_get_drv_data(struct device *dev) driver_data = (struct msm_cvp_platform_data *)match->data; - if (!strcmp(match->compatible, "qcom,kona-cvp")) { + if (!strcmp(match->compatible, "qcom,lahaina-cvp")) { ddr_type = of_fdt_get_ddrtype(); if (ddr_type == -ENOENT) { dprintk(CVP_ERR, @@ -224,9 +224,11 @@ void *cvp_get_drv_data(struct device *dev) if (driver_data->ubwc_config && (ddr_type == DDR_TYPE_LPDDR4 || - ddr_type == DDR_TYPE_LPDDR4X || - ddr_type == DDR_TYPE_LPDDR4Y)) + ddr_type == DDR_TYPE_LPDDR4X)) driver_data->ubwc_config->highest_bank_bit = 15; + dprintk(CVP_CORE, "DDR Type 0x%x hbb 0x%x\n", + ddr_type, driver_data->ubwc_config ? + driver_data->ubwc_config->highest_bank_bit : -1); } exit: return driver_data; From 10b7267132e87fd3ef1691cb79939e5a769a5818 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 10 Sep 2020 11:36:58 -0700 Subject: [PATCH 008/317] msm: eva: Snapshot of eva driver compiled in LKP Port EVA driver to LKP. Change-Id: If258891dd5adef096c28eaded36b4529750b9359 Signed-off-by: George Shen --- Kbuild | 15 ++++++++++++ Makefile | 23 +++++++++--------- msm/eva/cvp_fw_load.c | 22 ----------------- msm/eva/cvp_hfi.c | 14 +++++------ msm/eva/cvp_hfi.h | 4 ---- msm/eva/msm_cvp_common.c | 3 --- msm/eva/msm_cvp_debug.c | 52 +++++++++++++++++----------------------- msm/eva/msm_cvp_ioctl.c | 1 + msm/eva/msm_smem.c | 4 ++-- 9 files changed, 58 insertions(+), 80 deletions(-) create mode 100644 Kbuild diff --git a/Kbuild b/Kbuild new file mode 100644 index 0000000000..dd0445d097 --- /dev/null +++ b/Kbuild @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0-only + +# auto-detect subdirs +ifneq ($(CONFIG_ARCH_QTI_VM), y) +ifeq ($(CONFIG_ARCH_LAHAINA), y) +include $(srctree)/techpack/eva/config/waipioeva.conf +LINUXINCLUDE += -include $(srctree)/techpack/eva/config/waipioevaconf.h +endif +endif + +LINUXINCLUDE += -I$(srctree)/techpack/eva/include \ + -I$(srctree)/techpack/eva/include/uapi \ + -I$(srctree)/techpack/eva/include/uapi/eva + +obj-y +=msm/ diff --git a/Makefile b/Makefile index dd0445d097..89c01aca34 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,14 @@ -# SPDX-License-Identifier: GPL-2.0-only +KBUILD_OPTIONS+= EVA_ROOT=$(KERNEL_SRC)/$(M) -# auto-detect subdirs -ifneq ($(CONFIG_ARCH_QTI_VM), y) -ifeq ($(CONFIG_ARCH_LAHAINA), y) -include $(srctree)/techpack/eva/config/waipioeva.conf -LINUXINCLUDE += -include $(srctree)/techpack/eva/config/waipioevaconf.h -endif -endif +all: + $(MAKE) -C $(KERNEL_SRC) M=$(M) modules $(KBUILD_OPTIONS) -LINUXINCLUDE += -I$(srctree)/techpack/eva/include \ - -I$(srctree)/techpack/eva/include/uapi \ - -I$(srctree)/techpack/eva/include/uapi/eva +modules_install: + $(MAKE) M=$(M) -C $(KERNEL_SRC) modules_install -obj-y +=msm/ +%: + $(MAKE) -C $(KERNEL_SRC) M=$(M) $@ $(KBUILD_OPTIONS) + +clean: + rm -f *.o *.ko *.mod.c *.mod.o *~ .*.cmd Module.symvers + rm -rf .tmp_versions diff --git a/msm/eva/cvp_fw_load.c b/msm/eva/cvp_fw_load.c index 089966b0d9..a97c592d58 100644 --- a/msm/eva/cvp_fw_load.c +++ b/msm/eva/cvp_fw_load.c @@ -11,17 +11,12 @@ #include "cvp_comm_def.h" #include "cvp_core_hfi.h" #include "cvp_hfi.h" -#ifdef CVP_MDT_ENABLED #include #include #include -#else -#include -#endif #define MAX_FIRMWARE_NAME_SIZE 128 -#ifdef CVP_MDT_ENABLED static int __load_fw_to_memory(struct platform_device *pdev, const char *fw_name) { @@ -123,14 +118,12 @@ exit: release_firmware(firmware); return rc; } -#endif int load_cvp_fw_impl(struct iris_hfi_device *device) { int rc = 0; if (!device->resources.fw.cookie) { -#ifdef CVP_MDT_ENABLED device->resources.fw.cookie = __load_fw_to_memory(device->res->pdev, device->res->fw_name); @@ -139,28 +132,13 @@ int load_cvp_fw_impl(struct iris_hfi_device *device) device->resources.fw.cookie = 0; rc = -ENOMEM; } -#else - device->resources.fw.cookie = - subsystem_get_with_fwname("evass", - device->res->fw_name); - if (IS_ERR_OR_NULL(device->resources.fw.cookie)) { - dprintk(CVP_ERR, "Failed to download firmware\n"); - device->resources.fw.cookie = NULL; - rc = -ENOMEM; - } -#endif } return rc; } int unload_cvp_fw_impl(struct iris_hfi_device *device) { -#ifdef CVP_MDT_ENABLED qcom_scm_pas_shutdown(device->resources.fw.cookie); device->resources.fw.cookie = 0; -#else - subsystem_put(device->resources.fw.cookie); - device->resources.fw.cookie = NULL; -#endif return 0; } diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 377a6d9bb2..ec3225fffb 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -2065,7 +2065,7 @@ static int iris_hfi_core_init(void *device) __sys_set_idle_indicator(device, true); if (dev->res->pm_qos_latency_us) - pm_qos_add_request(&dev->qos, PM_QOS_CPU_DMA_LATENCY, + cpu_latency_qos_add_request(&dev->qos, dev->res->pm_qos_latency_us); mutex_unlock(&dev->lock); @@ -2099,8 +2099,8 @@ static int iris_hfi_core_release(void *dev) mutex_lock(&device->lock); dprintk(CVP_WARN, "Core releasing\n"); if (device->res->pm_qos_latency_us && - pm_qos_request_active(&device->qos)) - pm_qos_remove_request(&device->qos); + cpu_latency_qos_request_active(&device->qos)) + cpu_latency_qos_remove_request(&device->qos); __resume(device); __set_state(device, IRIS_STATE_DEINIT); @@ -3185,7 +3185,7 @@ static int __init_regs_and_interrupts(struct iris_hfi_device *device, hal->irq = res->irq; hal->firmware_base = res->firmware_base; - hal->register_base = devm_ioremap_nocache(&res->pdev->dev, + hal->register_base = devm_ioremap(&res->pdev->dev, res->register_base, res->register_size); hal->register_size = res->register_size; if (!hal->register_base) { @@ -4074,8 +4074,8 @@ static inline int __suspend(struct iris_hfi_device *device) dprintk(CVP_PWR, "Entering suspend\n"); if (device->res->pm_qos_latency_us && - pm_qos_request_active(&device->qos)) - pm_qos_remove_request(&device->qos); + cpu_latency_qos_request_active(&device->qos)) + cpu_latency_qos_remove_request(&device->qos); rc = __tzbsp_set_cvp_state(TZ_SUBSYS_STATE_SUSPEND); if (rc) { @@ -4248,7 +4248,7 @@ static inline int __resume(struct iris_hfi_device *device) __set_threshold_registers(device); if (device->res->pm_qos_latency_us) - pm_qos_add_request(&device->qos, PM_QOS_CPU_DMA_LATENCY, + cpu_latency_qos_add_request(&device->qos, device->res->pm_qos_latency_us); __sys_set_debug(device, msm_cvp_fw_debug); diff --git a/msm/eva/cvp_hfi.h b/msm/eva/cvp_hfi.h index 2959c72a4f..bbaebd883f 100644 --- a/msm/eva/cvp_hfi.h +++ b/msm/eva/cvp_hfi.h @@ -200,11 +200,7 @@ struct cvp_hal_session { }; struct msm_cvp_fw { -#ifdef CVP_MDT_ENABLED int cookie; -#else - void *cookie; -#endif }; int cvp_hfi_process_msg_packet(u32 device_id, diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 3be1ce61b9..7185195635 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -631,9 +631,6 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) unsigned long flags = 0; enum cvp_core_state cur_state; -#ifndef CVP_MDT_ENABLED - subsystem_crashed("evass"); -#endif if (!response) { dprintk(CVP_ERR, "Failed to get valid response for sys error\n"); diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index cf203a1ef1..2404504951 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -21,6 +21,7 @@ int msm_cvp_fw_debug = 0x18; int msm_cvp_fw_debug_mode = 1; int msm_cvp_fw_low_power_mode = 1; bool msm_cvp_fw_coverage = !true; +bool msm_cvp_cacheop_enabled = true; bool msm_cvp_thermal_mitigation_disabled = !true; bool msm_cvp_cacheop_disabled = !true; int msm_cvp_clock_voting = !1; @@ -229,8 +230,7 @@ DEFINE_DEBUGFS_ATTRIBUTE(cvp_pwr_fops, cvp_power_get, cvp_power_set, "%llu\n"); struct dentry *msm_cvp_debugfs_init_drv(void) { - bool ok = false; - struct dentry *dir = NULL; + struct dentry *dir = NULL, *f; dir = debugfs_create_dir("msm_cvp", NULL); if (IS_ERR_OR_NULL(dir)) { @@ -238,35 +238,26 @@ struct dentry *msm_cvp_debugfs_init_drv(void) goto failed_create_dir; } -#define __debugfs_create(__type, __name, __value) ({ \ - struct dentry *f = debugfs_create_##__type(__name, 0644, \ - dir, __value); \ - if (IS_ERR_OR_NULL(f)) { \ - dprintk(CVP_ERR, "Failed creating debugfs file '%pd/%s'\n", \ - dir, __name); \ - f = NULL; \ - } \ - f; \ -}) - - ok = - __debugfs_create(x32, "debug_level", &msm_cvp_debug) && - __debugfs_create(x32, "fw_level", &msm_cvp_fw_debug) && - __debugfs_create(u32, "fw_debug_mode", &msm_cvp_fw_debug_mode) && - __debugfs_create(bool, "fw_coverage", &msm_cvp_fw_coverage) && - __debugfs_create(u32, "fw_low_power_mode", - &msm_cvp_fw_low_power_mode) && - __debugfs_create(u32, "debug_output", &msm_cvp_debug_out) && - __debugfs_create(bool, "disable_thermal_mitigation", - &msm_cvp_thermal_mitigation_disabled) && - __debugfs_create(bool, "disable_cacheop", - &msm_cvp_cacheop_disabled) && - __debugfs_create(bool, "disable_cvp_syscache", + debugfs_create_x32("debug_level", 0644, dir, &msm_cvp_debug); + debugfs_create_x32("fw_level", 0644, dir, &msm_cvp_fw_debug); + debugfs_create_u32("fw_debug_mode", 0644, dir, &msm_cvp_fw_debug_mode); + debugfs_create_u32("fw_low_power_mode", 0644, dir, + &msm_cvp_fw_low_power_mode); + debugfs_create_u32("debug_output", 0644, dir, &msm_cvp_debug_out); + f = debugfs_create_bool("fw_coverage", 0644, dir, &msm_cvp_fw_coverage); + if (IS_ERR_OR_NULL(f)) + goto failed_create_dir; + f = debugfs_create_bool("disable_thermal_mitigation", 0644, dir, + &msm_cvp_thermal_mitigation_disabled); + if (IS_ERR_OR_NULL(f)) + goto failed_create_dir; + f = debugfs_create_bool("enable_cacheop", 0644, dir, + &msm_cvp_cacheop_enabled); + if (IS_ERR_OR_NULL(f)) + goto failed_create_dir; + f = debugfs_create_bool("disable_cvp_syscache", 0644, dir, &msm_cvp_syscache_disable); - -#undef __debugfs_create - - if (!ok) + if (IS_ERR_OR_NULL(f)) goto failed_create_dir; debugfs_create_file("cvp_power", 0644, dir, NULL, &cvp_pwr_fops); @@ -277,6 +268,7 @@ failed_create_dir: if (dir) debugfs_remove_recursive(cvp_driver->debugfs_root); + dprintk(CVP_WARN, "Failed to create debugfs\n"); return NULL; } diff --git a/msm/eva/msm_cvp_ioctl.c b/msm/eva/msm_cvp_ioctl.c index d9277343a9..74d58146c9 100644 --- a/msm/eva/msm_cvp_ioctl.c +++ b/msm/eva/msm_cvp_ioctl.c @@ -3,6 +3,7 @@ * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ +#include #include "cvp_private.h" #include "cvp_hfi_api.h" diff --git a/msm/eva/msm_smem.c b/msm/eva/msm_smem.c index 8080191518..6e3efc276e 100644 --- a/msm/eva/msm_smem.c +++ b/msm/eva/msm_smem.c @@ -283,8 +283,8 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, int map_kernel, dbuf = ion_alloc(size, heap_mask, ion_flags); if (IS_ERR_OR_NULL(dbuf)) { dprintk(CVP_ERR, - "Failed to allocate shared memory = %x bytes, %llx, %x\n", - size, heap_mask, ion_flags); + "Failed to allocate shared memory = %x bytes, %llx, %x %x\n", + size, heap_mask, ion_flags, PTR_ERR(dbuf)); rc = -ENOMEM; goto fail_shared_mem_alloc; } From 5f1c0b90c374829d64d7a73c8516031aa4629f0b Mon Sep 17 00:00:00 2001 From: Yu SI Date: Fri, 25 Sep 2020 18:35:11 -0700 Subject: [PATCH 009/317] msm: eva: rename cvp to eva for private h and such renamed cvp to eva for msm_eva_private.h and other source and header depending on this file Change-Id: I987cfedca62c82e5e26af230b4f36c84f1318a95 Signed-off-by: Yu SI --- include/uapi/eva/media/msm_eva_private.h | 172 +++++++++++------------ msm/eva/cvp_hfi.c | 4 +- msm/eva/cvp_hfi_api.h | 2 +- msm/eva/hfi_packetization.c | 4 +- msm/eva/hfi_packetization.h | 4 +- msm/eva/msm_cvp.c | 158 ++++++++++----------- msm/eva/msm_cvp.h | 6 +- msm/eva/msm_cvp_buf.c | 22 +-- msm/eva/msm_cvp_buf.h | 14 +- msm/eva/msm_cvp_core.c | 2 +- msm/eva/msm_cvp_core.h | 2 +- msm/eva/msm_cvp_ioctl.c | 168 +++++++++++----------- 12 files changed, 279 insertions(+), 279 deletions(-) diff --git a/include/uapi/eva/media/msm_eva_private.h b/include/uapi/eva/media/msm_eva_private.h index 555e8b7598..6876e0bb1b 100644 --- a/include/uapi/eva/media/msm_eva_private.h +++ b/include/uapi/eva/media/msm_eva_private.h @@ -2,81 +2,81 @@ /* * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. */ -#ifndef __MSM_CVP_PRIVATE_H__ -#define __MSM_CVP_PRIVATE_H__ +#ifndef __MSM_EVA_PRIVATE_H__ +#define __MSM_EVA_PRIVATE_H__ #include /* Commands type */ -#define CVP_KMD_CMD_BASE 0x10000000 -#define CVP_KMD_CMD_START (CVP_KMD_CMD_BASE + 0x1000) +#define EVA_KMD_CMD_BASE 0x10000000 +#define EVA_KMD_CMD_START (EVA_KMD_CMD_BASE + 0x1000) /* * userspace clients pass one of the below arguments type - * in struct cvp_kmd_arg (@type field). + * in struct eva_kmd_arg (@type field). */ /* - * CVP_KMD_GET_SESSION_INFO - this argument type is used to + * EVA_KMD_GET_SESSION_INFO - this argument type is used to * get the session information from driver. it passes - * struct cvp_kmd_session_info {} + * struct eva_kmd_session_info {} */ -#define CVP_KMD_GET_SESSION_INFO (CVP_KMD_CMD_START + 1) +#define EVA_KMD_GET_SESSION_INFO (EVA_KMD_CMD_START + 1) /* - * CVP_KMD_REGISTER_BUFFER - this argument type is used to + * EVA_KMD_REGISTER_BUFFER - this argument type is used to * register the buffer to driver. it passes - * struct cvp_kmd_buffer {} + * struct eva_kmd_buffer {} */ -#define CVP_KMD_REGISTER_BUFFER (CVP_KMD_CMD_START + 3) +#define EVA_KMD_REGISTER_BUFFER (EVA_KMD_CMD_START + 3) /* - * CVP_KMD_REGISTER_BUFFER - this argument type is used to + * EVA_KMD_REGISTER_BUFFER - this argument type is used to * unregister the buffer to driver. it passes - * struct cvp_kmd_buffer {} + * struct eva_kmd_buffer {} */ -#define CVP_KMD_UNREGISTER_BUFFER (CVP_KMD_CMD_START + 4) +#define EVA_KMD_UNREGISTER_BUFFER (EVA_KMD_CMD_START + 4) -#define CVP_KMD_UPDATE_POWER (CVP_KMD_CMD_START + 17) +#define EVA_KMD_UPDATE_POWER (EVA_KMD_CMD_START + 17) -#define CVP_KMD_SEND_CMD_PKT (CVP_KMD_CMD_START + 64) +#define EVA_KMD_SEND_CMD_PKT (EVA_KMD_CMD_START + 64) -#define CVP_KMD_RECEIVE_MSG_PKT (CVP_KMD_CMD_START + 65) +#define EVA_KMD_RECEIVE_MSG_PKT (EVA_KMD_CMD_START + 65) -#define CVP_KMD_SET_SYS_PROPERTY (CVP_KMD_CMD_START + 66) +#define EVA_KMD_SET_SYS_PROPERTY (EVA_KMD_CMD_START + 66) -#define CVP_KMD_GET_SYS_PROPERTY (CVP_KMD_CMD_START + 67) +#define EVA_KMD_GET_SYS_PROPERTY (EVA_KMD_CMD_START + 67) -#define CVP_KMD_SESSION_CONTROL (CVP_KMD_CMD_START + 68) +#define EVA_KMD_SESSION_CONTROL (EVA_KMD_CMD_START + 68) -#define CVP_KMD_SEND_FENCE_CMD_PKT (CVP_KMD_CMD_START + 69) +#define EVA_KMD_SEND_FENCE_CMD_PKT (EVA_KMD_CMD_START + 69) -#define CVP_KMD_FLUSH_ALL (CVP_KMD_CMD_START + 70) +#define EVA_KMD_FLUSH_ALL (EVA_KMD_CMD_START + 70) -#define CVP_KMD_FLUSH_FRAME (CVP_KMD_CMD_START + 71) +#define EVA_KMD_FLUSH_FRAME (EVA_KMD_CMD_START + 71) /* flags */ -#define CVP_KMD_FLAG_UNSECURE 0x00000000 -#define CVP_KMD_FLAG_SECURE 0x00000001 +#define EVA_KMD_FLAG_UNSECURE 0x00000000 +#define EVA_KMD_FLAG_SECURE 0x00000001 /* buffer type */ -#define CVP_KMD_BUFTYPE_INPUT 0x00000001 -#define CVP_KMD_BUFTYPE_OUTPUT 0x00000002 -#define CVP_KMD_BUFTYPE_INTERNAL_1 0x00000003 -#define CVP_KMD_BUFTYPE_INTERNAL_2 0x00000004 +#define EVA_KMD_BUFTYPE_INPUT 0x00000001 +#define EVA_KMD_BUFTYPE_OUTPUT 0x00000002 +#define EVA_KMD_BUFTYPE_INTERNAL_1 0x00000003 +#define EVA_KMD_BUFTYPE_INTERNAL_2 0x00000004 /** - * struct cvp_kmd_session_info - session information + * struct eva_kmd_session_info - session information * @session_id: current session id */ -struct cvp_kmd_session_info { +struct eva_kmd_session_info { __u32 session_id; __u32 reserved[10]; }; /** - * struct cvp_kmd_buffer - buffer information to be registered + * struct eva_kmd_buffer - buffer information to be registered * @index: index of buffer * @type: buffer type * @fd: file descriptor of buffer @@ -85,7 +85,7 @@ struct cvp_kmd_session_info { * @pixelformat: fourcc format * @flags: buffer flags */ -struct cvp_kmd_buffer { +struct eva_kmd_buffer { __u32 index; __u32 type; __u32 fd; @@ -97,24 +97,24 @@ struct cvp_kmd_buffer { }; /** - * struct cvp_kmd_send_cmd - sending generic HFI command + * struct eva_kmd_send_cmd - sending generic HFI command * @cmd_address_fd: file descriptor of cmd_address * @cmd_size: allocated size of buffer */ -struct cvp_kmd_send_cmd { +struct eva_kmd_send_cmd { __u32 cmd_address_fd; __u32 cmd_size; __u32 reserved[10]; }; /** - * struct cvp_kmd_client_data - store generic client + * struct eva_kmd_client_data - store generic client * data * @transactionid: transaction id * @client_data1: client data to be used during callback * @client_data2: client data to be used during callback */ -struct cvp_kmd_client_data { +struct eva_kmd_client_data { __u32 transactionid; __u32 client_data1; __u32 client_data2; @@ -123,47 +123,47 @@ struct cvp_kmd_client_data { #define MAX_HFI_PKT_SIZE 470 -struct cvp_kmd_hfi_packet { +struct eva_kmd_hfi_packet { __u32 pkt_data[MAX_HFI_PKT_SIZE]; }; -#define CVP_KMD_PROP_HFI_VERSION 1 -#define CVP_KMD_PROP_SESSION_TYPE 2 -#define CVP_KMD_PROP_SESSION_KERNELMASK 3 -#define CVP_KMD_PROP_SESSION_PRIORITY 4 -#define CVP_KMD_PROP_SESSION_SECURITY 5 -#define CVP_KMD_PROP_SESSION_DSPMASK 6 +#define EVA_KMD_PROP_HFI_VERSION 1 +#define EVA_KMD_PROP_SESSION_TYPE 2 +#define EVA_KMD_PROP_SESSION_KERNELMASK 3 +#define EVA_KMD_PROP_SESSION_PRIORITY 4 +#define EVA_KMD_PROP_SESSION_SECURITY 5 +#define EVA_KMD_PROP_SESSION_DSPMASK 6 -#define CVP_KMD_PROP_PWR_FDU 0x10 -#define CVP_KMD_PROP_PWR_ICA 0x11 -#define CVP_KMD_PROP_PWR_OD 0x12 -#define CVP_KMD_PROP_PWR_MPU 0x13 -#define CVP_KMD_PROP_PWR_FW 0x14 -#define CVP_KMD_PROP_PWR_DDR 0x15 -#define CVP_KMD_PROP_PWR_SYSCACHE 0x16 -#define CVP_KMD_PROP_PWR_FDU_OP 0x17 -#define CVP_KMD_PROP_PWR_ICA_OP 0x18 -#define CVP_KMD_PROP_PWR_OD_OP 0x19 -#define CVP_KMD_PROP_PWR_MPU_OP 0x1A -#define CVP_KMD_PROP_PWR_FW_OP 0x1B -#define CVP_KMD_PROP_PWR_DDR_OP 0x1C -#define CVP_KMD_PROP_PWR_SYSCACHE_OP 0x1D -#define CVP_KMD_PROP_PWR_FPS_FDU 0x1E -#define CVP_KMD_PROP_PWR_FPS_MPU 0x1F -#define CVP_KMD_PROP_PWR_FPS_OD 0x20 -#define CVP_KMD_PROP_PWR_FPS_ICA 0x21 +#define EVA_KMD_PROP_PWR_FDU 0x10 +#define EVA_KMD_PROP_PWR_ICA 0x11 +#define EVA_KMD_PROP_PWR_OD 0x12 +#define EVA_KMD_PROP_PWR_MPU 0x13 +#define EVA_KMD_PROP_PWR_FW 0x14 +#define EVA_KMD_PROP_PWR_DDR 0x15 +#define EVA_KMD_PROP_PWR_SYSCACHE 0x16 +#define EVA_KMD_PROP_PWR_FDU_OP 0x17 +#define EVA_KMD_PROP_PWR_ICA_OP 0x18 +#define EVA_KMD_PROP_PWR_OD_OP 0x19 +#define EVA_KMD_PROP_PWR_MPU_OP 0x1A +#define EVA_KMD_PROP_PWR_FW_OP 0x1B +#define EVA_KMD_PROP_PWR_DDR_OP 0x1C +#define EVA_KMD_PROP_PWR_SYSCACHE_OP 0x1D +#define EVA_KMD_PROP_PWR_FPS_FDU 0x1E +#define EVA_KMD_PROP_PWR_FPS_MPU 0x1F +#define EVA_KMD_PROP_PWR_FPS_OD 0x20 +#define EVA_KMD_PROP_PWR_FPS_ICA 0x21 #define MAX_KMD_PROP_NUM_PER_PACKET 8 -#define MAX_KMD_PROP_TYPE (CVP_KMD_PROP_PWR_FPS_ICA + 1) +#define MAX_KMD_PROP_TYPE (EVA_KMD_PROP_PWR_FPS_ICA + 1) -struct cvp_kmd_sys_property { +struct eva_kmd_sys_property { __u32 prop_type; __u32 data; }; -struct cvp_kmd_sys_properties { +struct eva_kmd_sys_properties { __u32 prop_num; - struct cvp_kmd_sys_property prop_data[MAX_KMD_PROP_NUM_PER_PACKET]; + struct eva_kmd_sys_property prop_data[MAX_KMD_PROP_NUM_PER_PACKET]; }; #define SESSION_CREATE 1 @@ -172,45 +172,45 @@ struct cvp_kmd_sys_properties { #define SESSION_STOP 4 #define SESSION_INFO 5 -struct cvp_kmd_session_control { +struct eva_kmd_session_control { __u32 ctrl_type; __u32 ctrl_data[8]; }; #define MAX_HFI_FENCE_SIZE 16 #define MAX_HFI_FENCE_OFFSET (MAX_HFI_PKT_SIZE-MAX_HFI_FENCE_SIZE) -struct cvp_kmd_hfi_fence_packet { +struct eva_kmd_hfi_fence_packet { __u32 pkt_data[MAX_HFI_FENCE_OFFSET]; __u32 fence_data[MAX_HFI_FENCE_SIZE]; __u64 frame_id; }; -struct cvp_kmd_fence { +struct eva_kmd_fence { __s32 h_synx; __u32 secure_key; }; -struct cvp_kmd_fence_ctrl { +struct eva_kmd_fence_ctrl { __u32 magic; __u32 reserved; __u64 frame_id; __u32 num_fences; __u32 output_index; - struct cvp_kmd_fence fences[MAX_HFI_FENCE_SIZE/2]; + struct eva_kmd_fence fences[MAX_HFI_FENCE_SIZE/2]; }; #define MAX_FENCE_DATA_SIZE (MAX_HFI_FENCE_SIZE + 6) -struct cvp_kmd_hfi_synx_packet { +struct eva_kmd_hfi_synx_packet { __u32 pkt_data[MAX_HFI_PKT_SIZE]; union { __u32 fence_data[MAX_FENCE_DATA_SIZE]; - struct cvp_kmd_fence_ctrl fc; + struct eva_kmd_fence_ctrl fc; }; }; /** - * struct cvp_kmd_arg + * struct eva_kmd_arg * * @type: command type * @buf_offset: offset to buffer list in the command @@ -225,25 +225,25 @@ struct cvp_kmd_hfi_synx_packet { * @sys_properties System properties read or set by user library * @hfi_fence_pkt: HFI fence packet created by user library */ -struct cvp_kmd_arg { +struct eva_kmd_arg { __u32 type; __u32 buf_offset; __u32 buf_num; - union cvp_data_t { - struct cvp_kmd_session_info session; - struct cvp_kmd_buffer regbuf; - struct cvp_kmd_buffer unregbuf; - struct cvp_kmd_send_cmd send_cmd; - struct cvp_kmd_hfi_packet hfi_pkt; - struct cvp_kmd_sys_properties sys_properties; - struct cvp_kmd_hfi_fence_packet hfi_fence_pkt; - struct cvp_kmd_hfi_synx_packet hfi_synx_pkt; - struct cvp_kmd_session_control session_ctrl; + union eva_data_t { + struct eva_kmd_session_info session; + struct eva_kmd_buffer regbuf; + struct eva_kmd_buffer unregbuf; + struct eva_kmd_send_cmd send_cmd; + struct eva_kmd_hfi_packet hfi_pkt; + struct eva_kmd_sys_properties sys_properties; + struct eva_kmd_hfi_fence_packet hfi_fence_pkt; + struct eva_kmd_hfi_synx_packet hfi_synx_pkt; + struct eva_kmd_session_control session_ctrl; __u64 frame_id; } data; }; -struct cvp_kmd_request_power { +struct eva_kmd_request_power { __u32 deprecated; }; #endif diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index ec3225fffb..4fffc176b9 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -2438,10 +2438,10 @@ err_create_pkt: } static int iris_hfi_session_send(void *sess, - struct cvp_kmd_hfi_packet *in_pkt) + struct eva_kmd_hfi_packet *in_pkt) { int rc = 0; - struct cvp_kmd_hfi_packet pkt; + struct eva_kmd_hfi_packet pkt; struct cvp_hal_session *session = sess; struct iris_hfi_device *device; diff --git a/msm/eva/cvp_hfi_api.h b/msm/eva/cvp_hfi_api.h index 511d476eb4..2d8d2fad3e 100644 --- a/msm/eva/cvp_hfi_api.h +++ b/msm/eva/cvp_hfi_api.h @@ -340,7 +340,7 @@ struct cvp_hfi_device { int (*session_abort)(void *session); int (*session_set_buffers)(void *sess, u32 iova, u32 size); int (*session_release_buffers)(void *sess); - int (*session_send)(void *sess, struct cvp_kmd_hfi_packet *in_pkt); + int (*session_send)(void *sess, struct eva_kmd_hfi_packet *in_pkt); int (*session_flush)(void *sess); int (*scale_clocks)(void *dev, u32 freq); int (*vote_bus)(void *dev, struct cvp_bus_vote_data *data, diff --git a/msm/eva/hfi_packetization.c b/msm/eva/hfi_packetization.c index 107e2d744f..2d1149131b 100644 --- a/msm/eva/hfi_packetization.c +++ b/msm/eva/hfi_packetization.c @@ -340,9 +340,9 @@ int cvp_create_pkt_cmd_session_release_buffers( } int cvp_create_pkt_cmd_session_send( - struct cvp_kmd_hfi_packet *out_pkt, + struct eva_kmd_hfi_packet *out_pkt, struct cvp_hal_session *session, - struct cvp_kmd_hfi_packet *in_pkt) + struct eva_kmd_hfi_packet *in_pkt) { int def_idx; struct cvp_hal_session_cmd_pkt *ptr = diff --git a/msm/eva/hfi_packetization.h b/msm/eva/hfi_packetization.h index 757fe7b96a..05c7be1305 100644 --- a/msm/eva/hfi_packetization.h +++ b/msm/eva/hfi_packetization.h @@ -65,9 +65,9 @@ struct cvp_hfi_packetization_ops { struct cvp_hfi_cmd_session_sync_process_packet *pkt, struct cvp_hal_session *session); int (*session_send)( - struct cvp_kmd_hfi_packet *out_pkt, + struct eva_kmd_hfi_packet *out_pkt, struct cvp_hal_session *session, - struct cvp_kmd_hfi_packet *in_pkt); + struct eva_kmd_hfi_packet *in_pkt); }; struct cvp_hfi_packetization_ops *cvp_hfi_get_pkt_ops_handle( diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index af99aec42a..4ab44e226b 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -15,7 +15,7 @@ struct cvp_power_level { }; static int msm_cvp_get_session_info(struct msm_cvp_inst *inst, - struct cvp_kmd_session_info *session) + struct eva_kmd_session_info *session) { int rc = 0; struct msm_cvp_inst *s; @@ -29,7 +29,7 @@ static int msm_cvp_get_session_info(struct msm_cvp_inst *inst, if (!s) return -ECONNRESET; - s->cur_cmd_type = CVP_KMD_GET_SESSION_INFO; + s->cur_cmd_type = EVA_KMD_GET_SESSION_INFO; session->session_id = hash32_ptr(inst->session); dprintk(CVP_SESS, "%s: id 0x%x\n", __func__, session->session_id); @@ -84,7 +84,7 @@ static bool cvp_msg_pending(struct cvp_session_queue *sq, static int cvp_wait_process_message(struct msm_cvp_inst *inst, struct cvp_session_queue *sq, u64 *ktid, unsigned long timeout, - struct cvp_kmd_hfi_packet *out) + struct eva_kmd_hfi_packet *out) { struct cvp_session_msg *msg = NULL; struct cvp_hfi_msg_session_hdr *hdr; @@ -126,7 +126,7 @@ exit: } static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst, - struct cvp_kmd_hfi_packet *out_pkt) + struct eva_kmd_hfi_packet *out_pkt) { unsigned long wait_time; struct cvp_session_queue *sq; @@ -142,7 +142,7 @@ static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst, if (!s) return -ECONNRESET; - s->cur_cmd_type = CVP_KMD_RECEIVE_MSG_PKT; + s->cur_cmd_type = EVA_KMD_RECEIVE_MSG_PKT; wait_time = msecs_to_jiffies(CVP_MAX_WAIT_TIME); sq = &inst->session_queue; @@ -155,7 +155,7 @@ static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst, static int msm_cvp_session_process_hfi( struct msm_cvp_inst *inst, - struct cvp_kmd_hfi_packet *in_pkt, + struct eva_kmd_hfi_packet *in_pkt, unsigned int in_offset, unsigned int in_buf_num) { @@ -174,7 +174,7 @@ static int msm_cvp_session_process_hfi( if (!s) return -ECONNRESET; - inst->cur_cmd_type = CVP_KMD_SEND_CMD_PKT; + inst->cur_cmd_type = EVA_KMD_SEND_CMD_PKT; hdev = inst->core->device; pkt_idx = get_pkt_index((struct cvp_hal_session_cmd_pkt *)in_pkt); @@ -467,7 +467,7 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, } rc = call_hfi_op(hdev, session_send, (void *)inst->session, - (struct cvp_kmd_hfi_packet *)pkt); + (struct eva_kmd_hfi_packet *)pkt); if (rc) { dprintk(CVP_ERR, "%s %s: Failed in call_hfi_op %d, %x\n", current->comm, __func__, pkt->size, pkt->packet_type); @@ -477,7 +477,7 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, timeout = msecs_to_jiffies(CVP_MAX_WAIT_TIME); rc = cvp_wait_process_message(inst, sq, &ktid, timeout, - (struct cvp_kmd_hfi_packet *)&hdr); + (struct eva_kmd_hfi_packet *)&hdr); if (get_msg_size((struct cvp_hfi_msg_session_hdr *) &hdr) == sizeof(struct cvp_hfi_msg_session_hdr_ext)) { struct cvp_hfi_msg_session_hdr_ext *fhdr = @@ -608,13 +608,13 @@ exit: } static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst, - struct cvp_kmd_arg *arg) + struct eva_kmd_arg *arg) { int rc = 0; int idx; - struct cvp_kmd_hfi_fence_packet *fence_pkt; - struct cvp_kmd_hfi_synx_packet *synx_pkt; - struct cvp_kmd_fence_ctrl *kfc; + struct eva_kmd_hfi_fence_packet *fence_pkt; + struct eva_kmd_hfi_synx_packet *synx_pkt; + struct eva_kmd_fence_ctrl *kfc; struct cvp_hfi_cmd_session_hdr *pkt; unsigned int offset, buf_num, in_offset, in_buf_num; struct msm_cvp_inst *s; @@ -669,7 +669,7 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst, dprintk(CVP_ERR, "Incorrect buf num and offset in cmd\n"); goto exit; } - rc = msm_cvp_map_frame(inst, (struct cvp_kmd_hfi_packet *)pkt, offset, + rc = msm_cvp_map_frame(inst, (struct eva_kmd_hfi_packet *)pkt, offset, buf_num); if (rc) goto exit; @@ -975,7 +975,7 @@ static int msm_cvp_update_power(struct msm_cvp_inst *inst) if (!s) return -ECONNRESET; - inst->cur_cmd_type = CVP_KMD_UPDATE_POWER; + inst->cur_cmd_type = EVA_KMD_UPDATE_POWER; core = inst->core; mutex_lock(&core->clk_lock); @@ -988,7 +988,7 @@ static int msm_cvp_update_power(struct msm_cvp_inst *inst) } static int msm_cvp_register_buffer(struct msm_cvp_inst *inst, - struct cvp_kmd_buffer *buf) + struct eva_kmd_buffer *buf) { struct cvp_hfi_device *hdev; struct cvp_hal_session *session; @@ -1007,7 +1007,7 @@ static int msm_cvp_register_buffer(struct msm_cvp_inst *inst, if (!s) return -ECONNRESET; - inst->cur_cmd_type = CVP_KMD_REGISTER_BUFFER; + inst->cur_cmd_type = EVA_KMD_REGISTER_BUFFER; session = (struct cvp_hal_session *)inst->session; if (!session) { dprintk(CVP_ERR, "%s: invalid session\n", __func__); @@ -1025,7 +1025,7 @@ exit: } static int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst, - struct cvp_kmd_buffer *buf) + struct eva_kmd_buffer *buf) { struct msm_cvp_inst *s; int rc = 0; @@ -1042,7 +1042,7 @@ static int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst, if (!s) return -ECONNRESET; - inst->cur_cmd_type = CVP_KMD_UNREGISTER_BUFFER; + inst->cur_cmd_type = EVA_KMD_UNREGISTER_BUFFER; print_client_buffer(CVP_HFI, "unregister", inst, buf); rc = msm_cvp_unmap_buf_dsp(inst, buf); @@ -1180,7 +1180,7 @@ static int cvp_fence_thread_stop(struct msm_cvp_inst *inst) } static int msm_cvp_session_start(struct msm_cvp_inst *inst, - struct cvp_kmd_arg *arg) + struct eva_kmd_arg *arg) { struct cvp_session_queue *sq; @@ -1199,10 +1199,10 @@ static int msm_cvp_session_start(struct msm_cvp_inst *inst, } static int msm_cvp_session_stop(struct msm_cvp_inst *inst, - struct cvp_kmd_arg *arg) + struct eva_kmd_arg *arg) { struct cvp_session_queue *sq; - struct cvp_kmd_session_control *sc = &arg->data.session_ctrl; + struct eva_kmd_session_control *sc = &arg->data.session_ctrl; sq = &inst->session_queue; @@ -1250,9 +1250,9 @@ int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst) } static int msm_cvp_session_ctrl(struct msm_cvp_inst *inst, - struct cvp_kmd_arg *arg) + struct eva_kmd_arg *arg) { - struct cvp_kmd_session_control *ctrl = &arg->data.session_ctrl; + struct eva_kmd_session_control *ctrl = &arg->data.session_ctrl; int rc = 0; unsigned int ctrl_type; @@ -1284,9 +1284,9 @@ static int msm_cvp_session_ctrl(struct msm_cvp_inst *inst, } static int msm_cvp_get_sysprop(struct msm_cvp_inst *inst, - struct cvp_kmd_arg *arg) + struct eva_kmd_arg *arg) { - struct cvp_kmd_sys_properties *props = &arg->data.sys_properties; + struct eva_kmd_sys_properties *props = &arg->data.sys_properties; struct cvp_hfi_device *hdev; struct iris_hfi_device *hfi; int i, rc = 0; @@ -1301,7 +1301,7 @@ static int msm_cvp_get_sysprop(struct msm_cvp_inst *inst, for (i = 0; i < props->prop_num; i++) { switch (props->prop_data[i].prop_type) { - case CVP_KMD_PROP_HFI_VERSION: + case EVA_KMD_PROP_HFI_VERSION: { props->prop_data[i].data = hfi->version; break; @@ -1316,10 +1316,10 @@ static int msm_cvp_get_sysprop(struct msm_cvp_inst *inst, } static int msm_cvp_set_sysprop(struct msm_cvp_inst *inst, - struct cvp_kmd_arg *arg) + struct eva_kmd_arg *arg) { - struct cvp_kmd_sys_properties *props = &arg->data.sys_properties; - struct cvp_kmd_sys_property *prop_array; + struct eva_kmd_sys_properties *props = &arg->data.sys_properties; + struct eva_kmd_sys_property *prop_array; struct cvp_session_prop *session_prop; int i, rc = 0; @@ -1339,77 +1339,77 @@ static int msm_cvp_set_sysprop(struct msm_cvp_inst *inst, for (i = 0; i < props->prop_num; i++) { switch (prop_array[i].prop_type) { - case CVP_KMD_PROP_SESSION_TYPE: + case EVA_KMD_PROP_SESSION_TYPE: session_prop->type = prop_array[i].data; break; - case CVP_KMD_PROP_SESSION_KERNELMASK: + case EVA_KMD_PROP_SESSION_KERNELMASK: session_prop->kernel_mask = prop_array[i].data; break; - case CVP_KMD_PROP_SESSION_PRIORITY: + case EVA_KMD_PROP_SESSION_PRIORITY: session_prop->priority = prop_array[i].data; break; - case CVP_KMD_PROP_SESSION_SECURITY: + case EVA_KMD_PROP_SESSION_SECURITY: session_prop->is_secure = prop_array[i].data; break; - case CVP_KMD_PROP_SESSION_DSPMASK: + case EVA_KMD_PROP_SESSION_DSPMASK: session_prop->dsp_mask = prop_array[i].data; break; - case CVP_KMD_PROP_PWR_FDU: + case EVA_KMD_PROP_PWR_FDU: session_prop->fdu_cycles = prop_array[i].data; break; - case CVP_KMD_PROP_PWR_ICA: + case EVA_KMD_PROP_PWR_ICA: session_prop->ica_cycles = div_by_1dot5(prop_array[i].data); break; - case CVP_KMD_PROP_PWR_OD: + case EVA_KMD_PROP_PWR_OD: session_prop->od_cycles = prop_array[i].data; break; - case CVP_KMD_PROP_PWR_MPU: + case EVA_KMD_PROP_PWR_MPU: session_prop->mpu_cycles = prop_array[i].data; break; - case CVP_KMD_PROP_PWR_FW: + case EVA_KMD_PROP_PWR_FW: session_prop->fw_cycles = div_by_1dot5(prop_array[i].data); break; - case CVP_KMD_PROP_PWR_DDR: + case EVA_KMD_PROP_PWR_DDR: session_prop->ddr_bw = prop_array[i].data; break; - case CVP_KMD_PROP_PWR_SYSCACHE: + case EVA_KMD_PROP_PWR_SYSCACHE: session_prop->ddr_cache = prop_array[i].data; break; - case CVP_KMD_PROP_PWR_FDU_OP: + case EVA_KMD_PROP_PWR_FDU_OP: session_prop->fdu_op_cycles = prop_array[i].data; break; - case CVP_KMD_PROP_PWR_ICA_OP: + case EVA_KMD_PROP_PWR_ICA_OP: session_prop->ica_op_cycles = div_by_1dot5(prop_array[i].data); break; - case CVP_KMD_PROP_PWR_OD_OP: + case EVA_KMD_PROP_PWR_OD_OP: session_prop->od_op_cycles = prop_array[i].data; break; - case CVP_KMD_PROP_PWR_MPU_OP: + case EVA_KMD_PROP_PWR_MPU_OP: session_prop->mpu_op_cycles = prop_array[i].data; break; - case CVP_KMD_PROP_PWR_FW_OP: + case EVA_KMD_PROP_PWR_FW_OP: session_prop->fw_op_cycles = div_by_1dot5(prop_array[i].data); break; - case CVP_KMD_PROP_PWR_DDR_OP: + case EVA_KMD_PROP_PWR_DDR_OP: session_prop->ddr_op_bw = prop_array[i].data; break; - case CVP_KMD_PROP_PWR_SYSCACHE_OP: + case EVA_KMD_PROP_PWR_SYSCACHE_OP: session_prop->ddr_op_cache = prop_array[i].data; break; - case CVP_KMD_PROP_PWR_FPS_FDU: + case EVA_KMD_PROP_PWR_FPS_FDU: session_prop->fps[HFI_HW_FDU] = prop_array[i].data; break; - case CVP_KMD_PROP_PWR_FPS_MPU: + case EVA_KMD_PROP_PWR_FPS_MPU: session_prop->fps[HFI_HW_MPU] = prop_array[i].data; break; - case CVP_KMD_PROP_PWR_FPS_OD: + case EVA_KMD_PROP_PWR_FPS_OD: session_prop->fps[HFI_HW_OD] = prop_array[i].data; break; - case CVP_KMD_PROP_PWR_FPS_ICA: + case EVA_KMD_PROP_PWR_FPS_ICA: session_prop->fps[HFI_HW_ICA] = prop_array[i].data; break; default: @@ -1740,7 +1740,7 @@ static int cvp_flush_frame(struct msm_cvp_inst *inst, u64 frame_id) return rc; } -int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct cvp_kmd_arg *arg) +int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct eva_kmd_arg *arg) { int rc = 0; @@ -1750,9 +1750,9 @@ int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct cvp_kmd_arg *arg) } dprintk(CVP_HFI, "%s: arg->type = %x", __func__, arg->type); - if (arg->type != CVP_KMD_SESSION_CONTROL && - arg->type != CVP_KMD_SET_SYS_PROPERTY && - arg->type != CVP_KMD_GET_SYS_PROPERTY) { + if (arg->type != EVA_KMD_SESSION_CONTROL && + arg->type != EVA_KMD_SET_SYS_PROPERTY && + arg->type != EVA_KMD_GET_SYS_PROPERTY) { rc = session_state_check_init(inst); if (rc) { @@ -1764,69 +1764,69 @@ int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct cvp_kmd_arg *arg) } switch (arg->type) { - case CVP_KMD_GET_SESSION_INFO: + case EVA_KMD_GET_SESSION_INFO: { - struct cvp_kmd_session_info *session = - (struct cvp_kmd_session_info *)&arg->data.session; + struct eva_kmd_session_info *session = + (struct eva_kmd_session_info *)&arg->data.session; rc = msm_cvp_get_session_info(inst, session); break; } - case CVP_KMD_UPDATE_POWER: + case EVA_KMD_UPDATE_POWER: { rc = msm_cvp_update_power(inst); break; } - case CVP_KMD_REGISTER_BUFFER: + case EVA_KMD_REGISTER_BUFFER: { - struct cvp_kmd_buffer *buf = - (struct cvp_kmd_buffer *)&arg->data.regbuf; + struct eva_kmd_buffer *buf = + (struct eva_kmd_buffer *)&arg->data.regbuf; rc = msm_cvp_register_buffer(inst, buf); break; } - case CVP_KMD_UNREGISTER_BUFFER: + case EVA_KMD_UNREGISTER_BUFFER: { - struct cvp_kmd_buffer *buf = - (struct cvp_kmd_buffer *)&arg->data.unregbuf; + struct eva_kmd_buffer *buf = + (struct eva_kmd_buffer *)&arg->data.unregbuf; rc = msm_cvp_unregister_buffer(inst, buf); break; } - case CVP_KMD_RECEIVE_MSG_PKT: + case EVA_KMD_RECEIVE_MSG_PKT: { - struct cvp_kmd_hfi_packet *out_pkt = - (struct cvp_kmd_hfi_packet *)&arg->data.hfi_pkt; + struct eva_kmd_hfi_packet *out_pkt = + (struct eva_kmd_hfi_packet *)&arg->data.hfi_pkt; rc = msm_cvp_session_receive_hfi(inst, out_pkt); break; } - case CVP_KMD_SEND_CMD_PKT: + case EVA_KMD_SEND_CMD_PKT: { - struct cvp_kmd_hfi_packet *in_pkt = - (struct cvp_kmd_hfi_packet *)&arg->data.hfi_pkt; + struct eva_kmd_hfi_packet *in_pkt = + (struct eva_kmd_hfi_packet *)&arg->data.hfi_pkt; rc = msm_cvp_session_process_hfi(inst, in_pkt, arg->buf_offset, arg->buf_num); break; } - case CVP_KMD_SEND_FENCE_CMD_PKT: + case EVA_KMD_SEND_FENCE_CMD_PKT: { rc = msm_cvp_session_process_hfi_fence(inst, arg); break; } - case CVP_KMD_SESSION_CONTROL: + case EVA_KMD_SESSION_CONTROL: rc = msm_cvp_session_ctrl(inst, arg); break; - case CVP_KMD_GET_SYS_PROPERTY: + case EVA_KMD_GET_SYS_PROPERTY: rc = msm_cvp_get_sysprop(inst, arg); break; - case CVP_KMD_SET_SYS_PROPERTY: + case EVA_KMD_SET_SYS_PROPERTY: rc = msm_cvp_set_sysprop(inst, arg); break; - case CVP_KMD_FLUSH_ALL: + case EVA_KMD_FLUSH_ALL: rc = cvp_flush_all(inst); break; - case CVP_KMD_FLUSH_FRAME: + case EVA_KMD_FLUSH_FRAME: rc = cvp_flush_frame(inst, arg->data.frame_id); break; default: diff --git a/msm/eva/msm_cvp.h b/msm/eva/msm_cvp.h index b21864b46f..5750026b42 100644 --- a/msm/eva/msm_cvp.h +++ b/msm/eva/msm_cvp.h @@ -16,20 +16,20 @@ static inline bool is_buf_param_valid(u32 buf_num, u32 offset) { int max_buf_num; - max_buf_num = sizeof(struct cvp_kmd_hfi_packet) / + max_buf_num = sizeof(struct eva_kmd_hfi_packet) / sizeof(struct cvp_buf_type); if (buf_num > max_buf_num) return false; if ((offset + buf_num * sizeof(struct cvp_buf_type)) > - sizeof(struct cvp_kmd_hfi_packet)) + sizeof(struct eva_kmd_hfi_packet)) return false; return true; } -int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct cvp_kmd_arg *arg); +int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct eva_kmd_arg *arg); int msm_cvp_session_init(struct msm_cvp_inst *inst); int msm_cvp_session_deinit(struct msm_cvp_inst *inst); int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst); diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index f52a7af0b1..f6153a2e8f 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -69,7 +69,7 @@ void print_cvp_buffer(u32 tag, const char *str, struct msm_cvp_inst *inst, } void print_client_buffer(u32 tag, const char *str, - struct msm_cvp_inst *inst, struct cvp_kmd_buffer *cbuf) + struct msm_cvp_inst *inst, struct eva_kmd_buffer *cbuf) { if (!(tag & msm_cvp_debug) || !inst || !cbuf) return; @@ -80,7 +80,7 @@ void print_client_buffer(u32 tag, const char *str, cbuf->offset, cbuf->size, cbuf->type, cbuf->flags); } -int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct cvp_kmd_buffer *buf) +int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) { int rc = 0; bool found = false; @@ -193,7 +193,7 @@ exit: return rc; } -int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, struct cvp_kmd_buffer *buf) +int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) { int rc = 0; bool found; @@ -265,10 +265,10 @@ void msm_cvp_cache_operations(struct msm_cvp_smem *smem, u32 type, } switch (type) { - case CVP_KMD_BUFTYPE_INPUT: + case EVA_KMD_BUFTYPE_INPUT: cache_op = SMEM_CACHE_CLEAN; break; - case CVP_KMD_BUFTYPE_OUTPUT: + case EVA_KMD_BUFTYPE_OUTPUT: cache_op = SMEM_CACHE_INVALIDATE; break; default: @@ -485,7 +485,7 @@ u32 msm_cvp_map_frame_buf(struct msm_cvp_inst *inst, frame->nr++; - type = CVP_KMD_BUFTYPE_INPUT | CVP_KMD_BUFTYPE_OUTPUT; + type = EVA_KMD_BUFTYPE_INPUT | EVA_KMD_BUFTYPE_OUTPUT; msm_cvp_cache_operations(smem, type, buf->offset, buf->size); iova = smem->device_addr + buf->offset; @@ -501,7 +501,7 @@ static void msm_cvp_unmap_frame_buf(struct msm_cvp_inst *inst, struct msm_cvp_smem *smem = NULL; struct cvp_internal_buf *buf; - type = CVP_KMD_BUFTYPE_OUTPUT; + type = EVA_KMD_BUFTYPE_OUTPUT; for (i = 0; i < frame->nr; ++i) { buf = &frame->bufs[i]; @@ -560,7 +560,7 @@ void msm_cvp_unmap_frame(struct msm_cvp_inst *inst, u64 ktid) } int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, - struct cvp_kmd_hfi_packet *in_pkt, + struct eva_kmd_hfi_packet *in_pkt, unsigned int offset, unsigned int buf_num) { struct cvp_hfi_cmd_session_hdr *cmd_hdr; @@ -611,7 +611,7 @@ int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, } int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst, - struct cvp_kmd_hfi_packet *in_pkt, + struct eva_kmd_hfi_packet *in_pkt, unsigned int offset, unsigned int buf_num) { struct cvp_hfi_cmd_session_hdr *cmd_hdr; @@ -660,7 +660,7 @@ int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst, } int msm_cvp_map_user_persist(struct msm_cvp_inst *inst, - struct cvp_kmd_hfi_packet *in_pkt, + struct eva_kmd_hfi_packet *in_pkt, unsigned int offset, unsigned int buf_num) { struct cvp_buf_type *buf; @@ -691,7 +691,7 @@ int msm_cvp_map_user_persist(struct msm_cvp_inst *inst, } int msm_cvp_map_frame(struct msm_cvp_inst *inst, - struct cvp_kmd_hfi_packet *in_pkt, + struct eva_kmd_hfi_packet *in_pkt, unsigned int offset, unsigned int buf_num) { struct cvp_buf_type *buf; diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index 39ecb24424..b663605851 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -142,7 +142,7 @@ void print_cvp_buffer(u32 tag, const char *str, struct cvp_internal_buf *cbuf); void print_client_buffer(u32 tag, const char *str, struct msm_cvp_inst *inst, - struct cvp_kmd_buffer *cbuf); + struct eva_kmd_buffer *cbuf); void print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, struct msm_cvp_smem *smem); @@ -173,25 +173,25 @@ struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, u32 buffer_size); int cvp_release_arp_buffers(struct msm_cvp_inst *inst); int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, - struct cvp_kmd_buffer *buf); + struct eva_kmd_buffer *buf); int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, - struct cvp_kmd_buffer *buf); + struct eva_kmd_buffer *buf); void msm_cvp_cache_operations(struct msm_cvp_smem *smem, u32 type, u32 offset, u32 size); u32 msm_cvp_map_frame_buf(struct msm_cvp_inst *inst, struct cvp_buf_type *buf, struct msm_cvp_frame *frame); int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst, - struct cvp_kmd_hfi_packet *in_pkt, + struct eva_kmd_hfi_packet *in_pkt, unsigned int offset, unsigned int buf_num); int msm_cvp_map_user_persist(struct msm_cvp_inst *inst, - struct cvp_kmd_hfi_packet *in_pkt, + struct eva_kmd_hfi_packet *in_pkt, unsigned int offset, unsigned int buf_num); int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, - struct cvp_kmd_hfi_packet *in_pkt, + struct eva_kmd_hfi_packet *in_pkt, unsigned int offset, unsigned int buf_num); int msm_cvp_map_frame(struct msm_cvp_inst *inst, - struct cvp_kmd_hfi_packet *in_pkt, + struct eva_kmd_hfi_packet *in_pkt, unsigned int offset, unsigned int buf_num); void msm_cvp_unmap_frame(struct msm_cvp_inst *inst, u64 ktid); int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst); diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 72315f6e9a..4b3d2ccce6 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -34,7 +34,7 @@ int msm_cvp_poll(void *instance, struct file *filp, EXPORT_SYMBOL(msm_cvp_poll); int msm_cvp_private(void *cvp_inst, unsigned int cmd, - struct cvp_kmd_arg *arg) + struct eva_kmd_arg *arg) { int rc = 0; struct msm_cvp_inst *inst = (struct msm_cvp_inst *)cvp_inst; diff --git a/msm/eva/msm_cvp_core.h b/msm/eva/msm_cvp_core.h index 54a3882c2e..0208dd8c04 100644 --- a/msm/eva/msm_cvp_core.h +++ b/msm/eva/msm_cvp_core.h @@ -35,6 +35,6 @@ int msm_cvp_suspend(int core_id); int msm_cvp_poll(void *instance, struct file *filp, struct poll_table_struct *pt); int msm_cvp_private(void *cvp_inst, unsigned int cmd, - struct cvp_kmd_arg *arg); + struct eva_kmd_arg *arg); #endif diff --git a/msm/eva/msm_cvp_ioctl.c b/msm/eva/msm_cvp_ioctl.c index 74d58146c9..f01c4eb4ce 100644 --- a/msm/eva/msm_cvp_ioctl.c +++ b/msm/eva/msm_cvp_ioctl.c @@ -7,10 +7,10 @@ #include "cvp_private.h" #include "cvp_hfi_api.h" -static int _get_pkt_hdr_from_user(struct cvp_kmd_arg __user *up, +static int _get_pkt_hdr_from_user(struct eva_kmd_arg __user *up, struct cvp_hal_session_cmd_pkt *pkt_hdr) { - struct cvp_kmd_hfi_packet *u; + struct eva_kmd_hfi_packet *u; struct cvp_hfi_msg_session_hdr *hdr; hdr = (struct cvp_hfi_msg_session_hdr *)pkt_hdr; @@ -41,10 +41,10 @@ set_default_pkt_hdr: return 0; } -static int _get_fence_pkt_hdr_from_user(struct cvp_kmd_arg __user *up, +static int _get_fence_pkt_hdr_from_user(struct eva_kmd_arg __user *up, struct cvp_hal_session_cmd_pkt *pkt_hdr) { - struct cvp_kmd_hfi_synx_packet __user *u; + struct eva_kmd_hfi_synx_packet __user *u; u = &up->data.hfi_synx_pkt; @@ -61,11 +61,11 @@ static int _get_fence_pkt_hdr_from_user(struct cvp_kmd_arg __user *up, } /* Size is in unit of u32 */ -static int _copy_pkt_from_user(struct cvp_kmd_arg *kp, - struct cvp_kmd_arg __user *up, +static int _copy_pkt_from_user(struct eva_kmd_arg *kp, + struct eva_kmd_arg __user *up, unsigned int size) { - struct cvp_kmd_hfi_packet *k, *u; + struct eva_kmd_hfi_packet *k, *u; int i; k = &kp->data.hfi_pkt; @@ -78,8 +78,8 @@ static int _copy_pkt_from_user(struct cvp_kmd_arg *kp, } static int _copy_synx_data_from_user( - struct cvp_kmd_hfi_synx_packet *k, - struct cvp_kmd_hfi_synx_packet __user *u) + struct eva_kmd_hfi_synx_packet *k, + struct eva_kmd_hfi_synx_packet __user *u) { int i; @@ -93,8 +93,8 @@ static int _copy_synx_data_from_user( /* Size is in unit of u32 */ static int _copy_fence_data_from_user_deprecate( - struct cvp_kmd_hfi_fence_packet *k, - struct cvp_kmd_hfi_fence_packet __user *u) + struct eva_kmd_hfi_fence_packet *k, + struct eva_kmd_hfi_fence_packet __user *u) { int i; @@ -111,11 +111,11 @@ static int _copy_fence_data_from_user_deprecate( return 0; } -static int _copy_fence_pkt_from_user(struct cvp_kmd_arg *kp, - struct cvp_kmd_arg __user *up) -{ struct cvp_kmd_hfi_synx_packet *k; - struct cvp_kmd_hfi_synx_packet __user *u; - struct cvp_kmd_hfi_fence_packet __user *u1; +static int _copy_fence_pkt_from_user(struct eva_kmd_arg *kp, + struct eva_kmd_arg __user *up) +{ struct eva_kmd_hfi_synx_packet *k; + struct eva_kmd_hfi_synx_packet __user *u; + struct eva_kmd_hfi_fence_packet __user *u1; int i; k = &kp->data.hfi_synx_pkt; @@ -133,11 +133,11 @@ static int _copy_fence_pkt_from_user(struct cvp_kmd_arg *kp, return _copy_synx_data_from_user(k, u); else return _copy_fence_data_from_user_deprecate( - (struct cvp_kmd_hfi_fence_packet *)k, u1); + (struct eva_kmd_hfi_fence_packet *)k, u1); } -static int _copy_frameid_from_user(struct cvp_kmd_arg *kp, - struct cvp_kmd_arg __user *up) +static int _copy_frameid_from_user(struct eva_kmd_arg *kp, + struct eva_kmd_arg __user *up) { if (get_user(kp->data.frame_id, &up->data.frame_id)) { dprintk(CVP_ERR, "Failed to get frame id from user\n"); @@ -147,10 +147,10 @@ static int _copy_frameid_from_user(struct cvp_kmd_arg *kp, return 0; } -static int _copy_sysprop_from_user(struct cvp_kmd_arg *kp, - struct cvp_kmd_arg __user *up) +static int _copy_sysprop_from_user(struct eva_kmd_arg *kp, + struct eva_kmd_arg __user *up) { - struct cvp_kmd_sys_properties *k, *u; + struct eva_kmd_sys_properties *k, *u; k = &kp->data.sys_properties; u = &up->data.sys_properties; @@ -164,14 +164,14 @@ static int _copy_sysprop_from_user(struct cvp_kmd_arg *kp, } return _copy_pkt_from_user(kp, up, - (k->prop_num*((sizeof(struct cvp_kmd_sys_property)>>2)+1))); + (k->prop_num*((sizeof(struct eva_kmd_sys_property)>>2)+1))); } -static int _copy_pkt_to_user(struct cvp_kmd_arg *kp, - struct cvp_kmd_arg __user *up, +static int _copy_pkt_to_user(struct eva_kmd_arg *kp, + struct eva_kmd_arg __user *up, unsigned int size) { - struct cvp_kmd_hfi_packet *k, *u; + struct eva_kmd_hfi_packet *k, *u; int i; k = &kp->data.hfi_pkt; @@ -183,11 +183,11 @@ static int _copy_pkt_to_user(struct cvp_kmd_arg *kp, return 0; } -static int _copy_fence_pkt_to_user(struct cvp_kmd_arg *kp, - struct cvp_kmd_arg __user *up) +static int _copy_fence_pkt_to_user(struct eva_kmd_arg *kp, + struct eva_kmd_arg __user *up) { - struct cvp_kmd_hfi_synx_packet *k; - struct cvp_kmd_hfi_synx_packet __user *u; + struct eva_kmd_hfi_synx_packet *k; + struct eva_kmd_hfi_synx_packet __user *u; int i; k = &kp->data.hfi_synx_pkt; @@ -200,11 +200,11 @@ static int _copy_fence_pkt_to_user(struct cvp_kmd_arg *kp, return 0; } -static int _copy_sysprop_to_user(struct cvp_kmd_arg *kp, - struct cvp_kmd_arg __user *up) +static int _copy_sysprop_to_user(struct eva_kmd_arg *kp, + struct eva_kmd_arg __user *up) { - struct cvp_kmd_sys_properties *k; - struct cvp_kmd_sys_properties __user *u; + struct eva_kmd_sys_properties *k; + struct eva_kmd_sys_properties __user *u; int i; k = &kp->data.sys_properties; @@ -218,9 +218,9 @@ static int _copy_sysprop_to_user(struct cvp_kmd_arg *kp, } -static void print_hfi_short(struct cvp_kmd_arg __user *up) +static void print_hfi_short(struct eva_kmd_arg __user *up) { - struct cvp_kmd_hfi_packet *pkt; + struct eva_kmd_hfi_packet *pkt; unsigned int words[5]; pkt = &up->data.hfi_pkt; @@ -236,8 +236,8 @@ static void print_hfi_short(struct cvp_kmd_arg __user *up) } static int _copy_session_ctrl_to_user( - struct cvp_kmd_session_control *k, - struct cvp_kmd_session_control *u) + struct eva_kmd_session_control *k, + struct eva_kmd_session_control *u) { int i; @@ -250,8 +250,8 @@ static int _copy_session_ctrl_to_user( } static int _get_session_ctrl_from_user( - struct cvp_kmd_session_control *k, - struct cvp_kmd_session_control *u) + struct eva_kmd_session_control *k, + struct eva_kmd_session_control *u) { int i; @@ -265,8 +265,8 @@ static int _get_session_ctrl_from_user( } static int _get_session_info_from_user( - struct cvp_kmd_session_info *k, - struct cvp_kmd_session_info __user *u) + struct eva_kmd_session_info *k, + struct eva_kmd_session_info __user *u) { int i; @@ -279,13 +279,13 @@ static int _get_session_info_from_user( return 0; } -static int convert_from_user(struct cvp_kmd_arg *kp, +static int convert_from_user(struct eva_kmd_arg *kp, unsigned long arg, struct msm_cvp_inst *inst) { int rc = 0; int i; - struct cvp_kmd_arg __user *up = (struct cvp_kmd_arg *)arg; + struct eva_kmd_arg __user *up = (struct eva_kmd_arg *)arg; struct cvp_hal_session_cmd_pkt pkt_hdr; int pkt_idx; @@ -304,10 +304,10 @@ static int convert_from_user(struct cvp_kmd_arg *kp, return -EFAULT; switch (kp->type) { - case CVP_KMD_GET_SESSION_INFO: + case EVA_KMD_GET_SESSION_INFO: { - struct cvp_kmd_session_info *k; - struct cvp_kmd_session_info __user *u; + struct eva_kmd_session_info *k; + struct eva_kmd_session_info __user *u; k = &kp->data.session; u = &up->data.session; @@ -318,9 +318,9 @@ static int convert_from_user(struct cvp_kmd_arg *kp, break; } - case CVP_KMD_REGISTER_BUFFER: + case EVA_KMD_REGISTER_BUFFER: { - struct cvp_kmd_buffer *k, *u; + struct eva_kmd_buffer *k, *u; k = &kp->data.regbuf; u = &up->data.regbuf; @@ -337,9 +337,9 @@ static int convert_from_user(struct cvp_kmd_arg *kp, return -EFAULT; break; } - case CVP_KMD_UNREGISTER_BUFFER: + case EVA_KMD_UNREGISTER_BUFFER: { - struct cvp_kmd_buffer *k, *u; + struct eva_kmd_buffer *k, *u; k = &kp->data.unregbuf; u = &up->data.unregbuf; @@ -356,7 +356,7 @@ static int convert_from_user(struct cvp_kmd_arg *kp, return -EFAULT; break; } - case CVP_KMD_SEND_CMD_PKT: + case EVA_KMD_SEND_CMD_PKT: { if (_get_pkt_hdr_from_user(up, &pkt_hdr)) { dprintk(CVP_ERR, "Invalid syscall: %x, %x, %x\n", @@ -367,7 +367,7 @@ static int convert_from_user(struct cvp_kmd_arg *kp, rc = _copy_pkt_from_user(kp, up, (pkt_hdr.size >> 2)); break; } - case CVP_KMD_SEND_FENCE_CMD_PKT: + case EVA_KMD_SEND_FENCE_CMD_PKT: { if (_get_fence_pkt_hdr_from_user(up, &pkt_hdr)) { dprintk(CVP_ERR, "Invalid syscall: %x, %x, %x\n", @@ -389,11 +389,11 @@ static int convert_from_user(struct cvp_kmd_arg *kp, rc = _copy_fence_pkt_from_user(kp, up); break; } - case CVP_KMD_RECEIVE_MSG_PKT: + case EVA_KMD_RECEIVE_MSG_PKT: break; - case CVP_KMD_SESSION_CONTROL: + case EVA_KMD_SESSION_CONTROL: { - struct cvp_kmd_session_control *k, *u; + struct eva_kmd_session_control *k, *u; k = &kp->data.session_ctrl; u = &up->data.session_ctrl; @@ -401,7 +401,7 @@ static int convert_from_user(struct cvp_kmd_arg *kp, rc = _get_session_ctrl_from_user(k, u); break; } - case CVP_KMD_GET_SYS_PROPERTY: + case EVA_KMD_GET_SYS_PROPERTY: { if (_copy_sysprop_from_user(kp, up)) { dprintk(CVP_ERR, "Failed to get sysprop from user\n"); @@ -409,7 +409,7 @@ static int convert_from_user(struct cvp_kmd_arg *kp, } break; } - case CVP_KMD_SET_SYS_PROPERTY: + case EVA_KMD_SET_SYS_PROPERTY: { if (_copy_sysprop_from_user(kp, up)) { dprintk(CVP_ERR, "Failed to set sysprop from user\n"); @@ -417,10 +417,10 @@ static int convert_from_user(struct cvp_kmd_arg *kp, } break; } - case CVP_KMD_FLUSH_ALL: - case CVP_KMD_UPDATE_POWER: + case EVA_KMD_FLUSH_ALL: + case EVA_KMD_UPDATE_POWER: break; - case CVP_KMD_FLUSH_FRAME: + case EVA_KMD_FLUSH_FRAME: { if (_copy_frameid_from_user(kp, up)) return -EFAULT; @@ -437,8 +437,8 @@ static int convert_from_user(struct cvp_kmd_arg *kp, } static int _put_user_session_info( - struct cvp_kmd_session_info *k, - struct cvp_kmd_session_info __user *u) + struct eva_kmd_session_info *k, + struct eva_kmd_session_info __user *u) { int i; @@ -452,11 +452,11 @@ static int _put_user_session_info( return 0; } -static int convert_to_user(struct cvp_kmd_arg *kp, unsigned long arg) +static int convert_to_user(struct eva_kmd_arg *kp, unsigned long arg) { int rc = 0; int i, size; - struct cvp_kmd_arg __user *up = (struct cvp_kmd_arg *)arg; + struct eva_kmd_arg __user *up = (struct eva_kmd_arg *)arg; struct cvp_hal_session_cmd_pkt pkt_hdr; if (!kp || !up) { @@ -468,9 +468,9 @@ static int convert_to_user(struct cvp_kmd_arg *kp, unsigned long arg) return -EFAULT; switch (kp->type) { - case CVP_KMD_RECEIVE_MSG_PKT: + case EVA_KMD_RECEIVE_MSG_PKT: { - struct cvp_kmd_hfi_packet *k, *u; + struct eva_kmd_hfi_packet *k, *u; struct cvp_hfi_msg_session_hdr *hdr; k = &kp->data.hfi_pkt; @@ -482,10 +482,10 @@ static int convert_to_user(struct cvp_kmd_arg *kp, unsigned long arg) return -EFAULT; break; } - case CVP_KMD_GET_SESSION_INFO: + case EVA_KMD_GET_SESSION_INFO: { - struct cvp_kmd_session_info *k; - struct cvp_kmd_session_info __user *u; + struct eva_kmd_session_info *k; + struct eva_kmd_session_info __user *u; k = &kp->data.session; u = &up->data.session; @@ -496,9 +496,9 @@ static int convert_to_user(struct cvp_kmd_arg *kp, unsigned long arg) break; } - case CVP_KMD_REGISTER_BUFFER: + case EVA_KMD_REGISTER_BUFFER: { - struct cvp_kmd_buffer *k, *u; + struct eva_kmd_buffer *k, *u; k = &kp->data.regbuf; u = &up->data.regbuf; @@ -515,9 +515,9 @@ static int convert_to_user(struct cvp_kmd_arg *kp, unsigned long arg) return -EFAULT; break; } - case CVP_KMD_UNREGISTER_BUFFER: + case EVA_KMD_UNREGISTER_BUFFER: { - struct cvp_kmd_buffer *k, *u; + struct eva_kmd_buffer *k, *u; k = &kp->data.unregbuf; u = &up->data.unregbuf; @@ -534,7 +534,7 @@ static int convert_to_user(struct cvp_kmd_arg *kp, unsigned long arg) return -EFAULT; break; } - case CVP_KMD_SEND_CMD_PKT: + case EVA_KMD_SEND_CMD_PKT: { if (_get_pkt_hdr_from_user(up, &pkt_hdr)) return -EFAULT; @@ -544,7 +544,7 @@ static int convert_to_user(struct cvp_kmd_arg *kp, unsigned long arg) rc = _copy_pkt_to_user(kp, up, (pkt_hdr.size >> 2)); break; } - case CVP_KMD_SEND_FENCE_CMD_PKT: + case EVA_KMD_SEND_FENCE_CMD_PKT: { if (_get_fence_pkt_hdr_from_user(up, &pkt_hdr)) return -EFAULT; @@ -555,16 +555,16 @@ static int convert_to_user(struct cvp_kmd_arg *kp, unsigned long arg) rc = _copy_fence_pkt_to_user(kp, up); break; } - case CVP_KMD_SESSION_CONTROL: + case EVA_KMD_SESSION_CONTROL: { - struct cvp_kmd_session_control *k, *u; + struct eva_kmd_session_control *k, *u; k = &kp->data.session_ctrl; u = &up->data.session_ctrl; rc = _copy_session_ctrl_to_user(k, u); break; } - case CVP_KMD_GET_SYS_PROPERTY: + case EVA_KMD_GET_SYS_PROPERTY: { if (_copy_sysprop_to_user(kp, up)) { dprintk(CVP_ERR, "Fail to copy sysprop to user\n"); @@ -572,10 +572,10 @@ static int convert_to_user(struct cvp_kmd_arg *kp, unsigned long arg) } break; } - case CVP_KMD_FLUSH_ALL: - case CVP_KMD_FLUSH_FRAME: - case CVP_KMD_SET_SYS_PROPERTY: - case CVP_KMD_UPDATE_POWER: + case EVA_KMD_FLUSH_ALL: + case EVA_KMD_FLUSH_FRAME: + case EVA_KMD_SET_SYS_PROPERTY: + case EVA_KMD_UPDATE_POWER: break; default: dprintk(CVP_ERR, "%s: unknown cmd type 0x%x\n", @@ -591,7 +591,7 @@ static long cvp_ioctl(struct msm_cvp_inst *inst, unsigned int cmd, unsigned long arg) { int rc; - struct cvp_kmd_arg *karg; + struct eva_kmd_arg *karg; if (!inst) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); From 5f9634ab481676d7ebb7790701a596a65b19c09e Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 6 Oct 2020 16:53:12 -0700 Subject: [PATCH 010/317] msm: eva: Removes dma-coherent-hint Deprecate dma-coherent-hint usage in io-coherency support. Change-Id: Iffe58cb7ad79b60e0b7cf8235cfdc4195307059c Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 4fffc176b9..31381f7280 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1357,6 +1357,7 @@ static int __iface_cmdq_write_relaxed(struct iris_hfi_device *device, struct cvp_iface_q_info *q_info; struct cvp_hal_cmd_pkt_hdr *cmd_packet; int result = -E2BIG; + struct dma_buf *dbuf; if (!device || !pkt) { dprintk(CVP_ERR, "Invalid Params\n"); @@ -1365,6 +1366,9 @@ static int __iface_cmdq_write_relaxed(struct iris_hfi_device *device, __strict_check(device); + dbuf = device->iface_q_table.mem_data.dma_buf; + dma_buf_begin_cpu_access(dbuf, DMA_BIDIRECTIONAL); + if (!__core_in_valid_state(device)) { dprintk(CVP_ERR, "%s - fw not in init state\n", __func__); result = -EINVAL; @@ -1410,6 +1414,7 @@ static int __iface_cmdq_write_relaxed(struct iris_hfi_device *device, err_q_write: err_q_null: + dma_buf_end_cpu_access(dbuf, DMA_BIDIRECTIONAL); return result; } @@ -2956,6 +2961,7 @@ static int __response_handler(struct iris_hfi_device *device) int packet_count = 0; u8 *raw_packet = NULL; bool requeue_pm_work = true; + struct dma_buf *dbuf_sfr, *dbuf_hfi; if (!device || device->state != IRIS_STATE_INIT) return 0; @@ -2971,6 +2977,10 @@ static int __response_handler(struct iris_hfi_device *device) return 0; } + dbuf_sfr = device->sfr.mem_data.dma_buf; + dbuf_hfi = device->iface_q_table.mem_data.dma_buf; + dma_buf_begin_cpu_access(dbuf_sfr, DMA_BIDIRECTIONAL); + dma_buf_begin_cpu_access(dbuf_hfi, DMA_BIDIRECTIONAL); if (device->intr_status & CVP_FATAL_INTR_BMSK) { struct cvp_hfi_sfr_struct *vsfr = (struct cvp_hfi_sfr_struct *) device->sfr.align_virtual_addr; @@ -3073,7 +3083,8 @@ static int __response_handler(struct iris_hfi_device *device) exit: __flush_debug_queue(device, raw_packet); - + dma_buf_end_cpu_access(dbuf_hfi, DMA_BIDIRECTIONAL); + dma_buf_end_cpu_access(dbuf_sfr, DMA_BIDIRECTIONAL); return packet_count; } From 928365194bd6a06abf5e467e996d1f02edd84af1 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 21 Oct 2020 14:16:59 -0700 Subject: [PATCH 011/317] msm: eva: Initial migration to new dma-buf API Per Waipio requirement. Change-Id: Ic501909c93e9c12cb873458f47f7f86e598f16b0 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 12 ------------ msm/eva/msm_cvp_buf.c | 4 ++-- msm/eva/msm_cvp_buf.h | 1 + msm/eva/msm_smem.c | 11 +++++++---- 4 files changed, 10 insertions(+), 18 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 31381f7280..019ece7616 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1357,7 +1357,6 @@ static int __iface_cmdq_write_relaxed(struct iris_hfi_device *device, struct cvp_iface_q_info *q_info; struct cvp_hal_cmd_pkt_hdr *cmd_packet; int result = -E2BIG; - struct dma_buf *dbuf; if (!device || !pkt) { dprintk(CVP_ERR, "Invalid Params\n"); @@ -1366,9 +1365,6 @@ static int __iface_cmdq_write_relaxed(struct iris_hfi_device *device, __strict_check(device); - dbuf = device->iface_q_table.mem_data.dma_buf; - dma_buf_begin_cpu_access(dbuf, DMA_BIDIRECTIONAL); - if (!__core_in_valid_state(device)) { dprintk(CVP_ERR, "%s - fw not in init state\n", __func__); result = -EINVAL; @@ -1414,7 +1410,6 @@ static int __iface_cmdq_write_relaxed(struct iris_hfi_device *device, err_q_write: err_q_null: - dma_buf_end_cpu_access(dbuf, DMA_BIDIRECTIONAL); return result; } @@ -2961,7 +2956,6 @@ static int __response_handler(struct iris_hfi_device *device) int packet_count = 0; u8 *raw_packet = NULL; bool requeue_pm_work = true; - struct dma_buf *dbuf_sfr, *dbuf_hfi; if (!device || device->state != IRIS_STATE_INIT) return 0; @@ -2977,10 +2971,6 @@ static int __response_handler(struct iris_hfi_device *device) return 0; } - dbuf_sfr = device->sfr.mem_data.dma_buf; - dbuf_hfi = device->iface_q_table.mem_data.dma_buf; - dma_buf_begin_cpu_access(dbuf_sfr, DMA_BIDIRECTIONAL); - dma_buf_begin_cpu_access(dbuf_hfi, DMA_BIDIRECTIONAL); if (device->intr_status & CVP_FATAL_INTR_BMSK) { struct cvp_hfi_sfr_struct *vsfr = (struct cvp_hfi_sfr_struct *) device->sfr.align_virtual_addr; @@ -3083,8 +3073,6 @@ static int __response_handler(struct iris_hfi_device *device) exit: __flush_debug_queue(device, raw_packet); - dma_buf_end_cpu_access(dbuf_hfi, DMA_BIDIRECTIONAL); - dma_buf_end_cpu_access(dbuf_sfr, DMA_BIDIRECTIONAL); return packet_count; } diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index f6153a2e8f..340f110062 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -511,7 +511,7 @@ static void msm_cvp_unmap_frame_buf(struct msm_cvp_inst *inst, if (smem->bitmap_index >= MAX_DMABUF_NUMS) { /* smem not in dmamap cache */ msm_cvp_unmap_smem(inst, smem, "unmap cpu"); - dma_buf_put(smem->dma_buf); + dma_heap_buffer_free(smem->dma_buf); kmem_cache_free(cvp_driver->smem_cache, smem); buf->smem = NULL; } else { @@ -589,7 +589,7 @@ int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, /* smem not in dmamap cache */ msm_cvp_unmap_smem(inst, smem, "unmap cpu"); - dma_buf_put(smem->dma_buf); + dma_heap_buffer_free(smem->dma_buf); kmem_cache_free( cvp_driver->smem_cache, smem); diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index b663605851..6efba2e293 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/msm/eva/msm_smem.c b/msm/eva/msm_smem.c index 6e3efc276e..6fe57762c4 100644 --- a/msm/eva/msm_smem.c +++ b/msm/eva/msm_smem.c @@ -4,6 +4,7 @@ */ #include +#include #include #include #include @@ -156,7 +157,7 @@ void msm_cvp_smem_put_dma_buf(void *dma_buf) return; } - dma_buf_put((struct dma_buf *)dma_buf); + dma_heap_buffer_free((struct dma_buf *)dma_buf); } int msm_cvp_map_smem(struct msm_cvp_inst *inst, @@ -246,6 +247,7 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, int map_kernel, int rc = 0; int ion_flags = 0; struct dma_buf *dbuf = NULL; + struct dma_heap *heap; if (!res) { dprintk(CVP_ERR, "%s: NULL res\n", __func__); @@ -280,7 +282,8 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, int map_kernel, heap_mask = ION_HEAP(ION_SECURE_HEAP_ID); } - dbuf = ion_alloc(size, heap_mask, ion_flags); + heap = dma_heap_find("qcom,system"); + dbuf = dma_heap_buffer_alloc(heap, size, 0, 0); if (IS_ERR_OR_NULL(dbuf)) { dprintk(CVP_ERR, "Failed to allocate shared memory = %x bytes, %llx, %x %x\n", @@ -330,7 +333,7 @@ fail_map: if (map_kernel) dma_buf_end_cpu_access(dbuf, DMA_BIDIRECTIONAL); fail_device_address: - dma_buf_put(dbuf); + dma_heap_buffer_free(dbuf); fail_shared_mem_alloc: return rc; } @@ -354,7 +357,7 @@ static int free_dma_mem(struct msm_cvp_smem *mem) } if (mem->dma_buf) { - dma_buf_put(mem->dma_buf); + dma_heap_buffer_free(mem->dma_buf); mem->dma_buf = NULL; } From f525c41b2a48d5fbe8ba57f44de1bb56b21f3006 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 22 Oct 2020 13:28:29 -0700 Subject: [PATCH 012/317] msm: eva: Update Kbuild to build eva for Waipio Remove target specific build restrictions. Change-Id: I31d282e6ff74d6126462509516b1ac7eca31ab39 Signed-off-by: George Shen --- Kbuild | 2 -- 1 file changed, 2 deletions(-) diff --git a/Kbuild b/Kbuild index dd0445d097..d9ec3f084e 100644 --- a/Kbuild +++ b/Kbuild @@ -2,11 +2,9 @@ # auto-detect subdirs ifneq ($(CONFIG_ARCH_QTI_VM), y) -ifeq ($(CONFIG_ARCH_LAHAINA), y) include $(srctree)/techpack/eva/config/waipioeva.conf LINUXINCLUDE += -include $(srctree)/techpack/eva/config/waipioevaconf.h endif -endif LINUXINCLUDE += -I$(srctree)/techpack/eva/include \ -I$(srctree)/techpack/eva/include/uapi \ From 8b8da9ccf5cf0759012c732754bbf241071c87fa Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 27 Oct 2020 00:46:53 -0700 Subject: [PATCH 013/317] msm: eva: Add Waipio platform properties Add EVA 3.0 (Engine for Visual Analytics) platform info. Change-Id: I35fe2a8cdf0a249bbb69d205e2da2aaf98d0a104 Signed-off-by: George Shen --- msm/eva/msm_cvp_platform.c | 85 ++++++-------------------------------- 1 file changed, 12 insertions(+), 73 deletions(-) diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 47dd14a59e..8a4f7b5937 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -46,14 +46,18 @@ static struct msm_cvp_common_data default_common_data[] = { }, }; -static struct msm_cvp_common_data sm8250_common_data[] = { +static struct msm_cvp_common_data sm8450_common_data[] = { + { + .key = "qcom,auto-pil", + .value = 0, + }, { .key = "qcom,never-unload-fw", .value = 1, }, { .key = "qcom,sw-power-collapse", - .value = 1, + .value = 0, }, { .key = "qcom,domain-attr-non-fatal-faults", @@ -97,60 +101,6 @@ static struct msm_cvp_common_data sm8250_common_data[] = { } }; -static struct msm_cvp_common_data sm8350_common_data[] = { - { - .key = "qcom,auto-pil", - .value = 1, - }, - { - .key = "qcom,never-unload-fw", - .value = 1, - }, - { - .key = "qcom,sw-power-collapse", - .value = 1, - }, - { - .key = "qcom,domain-attr-non-fatal-faults", - .value = 1, - }, - { - .key = "qcom,max-secure-instances", - .value = 2, /* - * As per design driver allows 3rd - * instance as well since the secure - * flags were updated later for the - * current instance. Hence total - * secure sessions would be - * max-secure-instances + 1. - */ - }, - { - .key = "qcom,max-hw-load", - .value = 3916800, /* - * 1920x1088/256 MBs@480fps. It is less - * any other usecases (ex: - * 3840x2160@120fps, 4096x2160@96ps, - * 7680x4320@30fps) - */ - }, - { - .key = "qcom,power-collapse-delay", - .value = 3000, - }, - { - .key = "qcom,hw-resp-timeout", - .value = 2000, - }, - { - .key = "qcom,dsp-resp-timeout", - .value = 1000 - }, - { - .key = "qcom,debug-timeout", - .value = 0, - } -}; /* Default UBWC config for LPDDR5 */ @@ -167,30 +117,19 @@ static struct msm_cvp_platform_data default_data = { .ubwc_config = 0x0, }; -static struct msm_cvp_platform_data sm8250_data = { - .common_data = sm8250_common_data, - .common_data_length = ARRAY_SIZE(sm8250_common_data), +static struct msm_cvp_platform_data sm8450_data = { + .common_data = sm8450_common_data, + .common_data_length = ARRAY_SIZE(sm8450_common_data), .sku_version = 0, .vpu_ver = VPU_VERSION_5, .ubwc_config = kona_ubwc_data, }; -static struct msm_cvp_platform_data sm8350_data = { - .common_data = sm8350_common_data, - .common_data_length = ARRAY_SIZE(sm8350_common_data), - .sku_version = 0, - .vpu_ver = VPU_VERSION_5, - .ubwc_config = kona_ubwc_data, -}; static const struct of_device_id msm_cvp_dt_match[] = { { - .compatible = "qcom,lahaina-cvp", - .data = &sm8350_data, - }, - { - .compatible = "qcom,kona-cvp", - .data = &sm8250_data, + .compatible = "qcom,waipio-cvp", + .data = &sm8450_data, }, {}, }; @@ -215,7 +154,7 @@ void *cvp_get_drv_data(struct device *dev) driver_data = (struct msm_cvp_platform_data *)match->data; - if (!strcmp(match->compatible, "qcom,lahaina-cvp")) { + if (!strcmp(match->compatible, "qcom,waipio-cvp")) { ddr_type = of_fdt_get_ddrtype(); if (ddr_type == -ENOENT) { dprintk(CVP_ERR, From d15b45260857c11662bdd5322124851f584a8ef1 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Tue, 17 Nov 2020 19:45:48 -0800 Subject: [PATCH 014/317] msm: cvp: set clock src rate instead of clock rate multiplied by factor before set to clock source Change-Id: I647c7f706bc0576b646cf6432445ff0b6406bd20 Signed-off-by: Yu SI --- msm/eva/cvp_hfi.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 019ece7616..912d88aac2 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1286,6 +1286,9 @@ static int __set_clocks(struct iris_hfi_device *device, u32 freq) { struct clock_info *cl; int rc = 0; + int factorsrc2clk = 3; // ratio factor for clock source : clk + + dprintk(CVP_PWR, "%s: entering with freq : %ld\n", __func__, freq); iris_hfi_for_each_clock(device, cl) { if (cl->has_scaling) {/* has_scaling */ @@ -1293,6 +1296,9 @@ static int __set_clocks(struct iris_hfi_device *device, u32 freq) if (msm_cvp_clock_voting) freq = msm_cvp_clock_voting; + freq = freq * factorsrc2clk; + dprintk(CVP_PWR, "%s: clock source rate set to: %ld\n", __func__, freq); + rc = clk_set_rate(cl->clk, freq); if (rc) { dprintk(CVP_ERR, From d0e7cd2a5032c1f260404a67dd86c804445b7d96 Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 11 Dec 2020 21:29:05 -0800 Subject: [PATCH 015/317] msm: eva: Fix a compiler error of typecasting Fix session id type casting issue Change-Id: Ic7a61a38cbb2bd884c10e4b58a579357ce444ee1 Signed-off-by: George Shen --- msm/eva/hfi_response_handler.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/msm/eva/hfi_response_handler.c b/msm/eva/hfi_response_handler.c index 548010863f..1b88c9bf97 100644 --- a/msm/eva/hfi_response_handler.c +++ b/msm/eva/hfi_response_handler.c @@ -486,7 +486,7 @@ static int hfi_process_session_cvp_msg(u32 device_id, struct cvp_session_msg *sess_msg; struct msm_cvp_inst *inst = NULL; struct msm_cvp_core *core; - void *session_id; + unsigned int session_id; struct cvp_session_queue *sq; if (!pkt) { @@ -496,9 +496,9 @@ static int hfi_process_session_cvp_msg(u32 device_id, dprintk(CVP_ERR, "%s: bad_pkt_size %d\n", __func__, pkt->size); return -E2BIG; } - session_id = (void *)(uintptr_t)get_msg_session_id(pkt); + session_id = get_msg_session_id(pkt); core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); - inst = cvp_get_inst_from_id(core, (unsigned int)session_id); + inst = cvp_get_inst_from_id(core, session_id); if (!inst) { dprintk(CVP_ERR, "%s: invalid session\n", __func__); From f998ae1909d77e76fc6e34c74dd420007d02b035 Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 15 Dec 2020 15:02:30 -0800 Subject: [PATCH 016/317] msm: eva: make ARP buffer non-secure temporarily Will remap to secure CB after hyp_assign becomes available. Change-Id: I17a2e00a8e6ea6a45754c69db8638370da035f28 Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 4 +++- msm/eva/msm_cvp_internal.h | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 340f110062..994fa43353 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -854,7 +854,9 @@ struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, return NULL; /* PERSIST buffer requires secure mapping */ - smem_flags |= SMEM_SECURE | SMEM_NON_PIXEL; + /* Disable and wait for hyp_assign available + * smem_flags |= SMEM_SECURE | SMEM_NON_PIXEL; + */ buf = kmem_cache_zalloc(cvp_driver->buf_cache, GFP_KERNEL); if (!buf) { diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index 0e044db578..1d53e0a5d8 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -45,7 +45,7 @@ #define SYS_MSG_INDEX(__msg) (__msg - SYS_MSG_START) #define SESSION_MSG_INDEX(__msg) (__msg - SESSION_MSG_START) -#define ARP_BUF_SIZE 0x100000 +#define ARP_BUF_SIZE 0x300000 #define CVP_RT_PRIO_THRESHOLD 1 From d31519435845c0e2da427829b08dfc3dab3ee709 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Wed, 2 Dec 2020 18:24:45 -0800 Subject: [PATCH 017/317] msm: eva: build script as DLKM for Vendor SI added mk and Kbuild script to support building eva as external module for Vendor SI Change-Id: I96bfe0c5260264c40755b337dfe8b8522e966022 Signed-off-by: Yu SI --- Android.mk | 22 ++++++++++++++++++++++ Kbuild | 4 ++++ eva_kernel_board.mk | 6 ++++++ eva_kernel_product.mk | 1 + msm/Kbuild | 30 ++++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+) create mode 100644 Android.mk create mode 100644 eva_kernel_board.mk create mode 100644 eva_kernel_product.mk create mode 100644 msm/Kbuild diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000000..46548065d4 --- /dev/null +++ b/Android.mk @@ -0,0 +1,22 @@ +ifneq ($(TARGET_PRODUCT), qssi) +ifeq ($(call is-board-platform-in-list, $(TARGET_BOARD_PLATFORM)),true) + +# Test dlkm +DLKM_DIR := device/qcom/common/dlkm + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) +# For incremental compilation +LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/**/*) $(wildcard $(LOCAL_PATH)/*) +# LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/msm/eva/*) +LOCAL_MODULE := msm-eva.ko +LOCAL_MODULE_KBUILD_NAME := msm/msm-eva.ko +LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) +# Include msm-eva.ko in the /vendor/lib/modules +# BOARD_VENDOR_KERNEL_MODULES += $(LOCAL_MODULE_PATH)/$(LOCAL_MODULE) +LOCAL_ADDITIONAL_DEPENDENCY := synx-driver.ko +include $(DLKM_DIR)/Build_external_kernelmodule.mk + +endif # End of check for board platform +endif # End of check for target product \ No newline at end of file diff --git a/Kbuild b/Kbuild index d9ec3f084e..79dc821c04 100644 --- a/Kbuild +++ b/Kbuild @@ -1,6 +1,9 @@ # SPDX-License-Identifier: GPL-2.0-only +CONFIG_BUILD_VENDORSI := true + # auto-detect subdirs +ifneq ($(CONFIG_BUILD_VENDORSI), true) ifneq ($(CONFIG_ARCH_QTI_VM), y) include $(srctree)/techpack/eva/config/waipioeva.conf LINUXINCLUDE += -include $(srctree)/techpack/eva/config/waipioevaconf.h @@ -9,5 +12,6 @@ endif LINUXINCLUDE += -I$(srctree)/techpack/eva/include \ -I$(srctree)/techpack/eva/include/uapi \ -I$(srctree)/techpack/eva/include/uapi/eva +endif obj-y +=msm/ diff --git a/eva_kernel_board.mk b/eva_kernel_board.mk new file mode 100644 index 0000000000..d23cf37402 --- /dev/null +++ b/eva_kernel_board.mk @@ -0,0 +1,6 @@ +# Build eva kernel driver +ifneq ($(TARGET_BOARD_AUTO),true) +ifeq ($(call is-board-platform-in-list,$(TARGET_BOARD_PLATFORM)),true) +BOARD_VENDOR_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/msm-eva.ko +endif +endif \ No newline at end of file diff --git a/eva_kernel_product.mk b/eva_kernel_product.mk new file mode 100644 index 0000000000..da7ee60cb0 --- /dev/null +++ b/eva_kernel_product.mk @@ -0,0 +1 @@ +PRODUCT_PACKAGES += msm-eva.ko diff --git a/msm/Kbuild b/msm/Kbuild new file mode 100644 index 0000000000..a4754e1d87 --- /dev/null +++ b/msm/Kbuild @@ -0,0 +1,30 @@ +LINUXINCLUDE += -I$(EVA_ROOT)/include \ + -I$(EVA_ROOT)/include/uapi \ + -I$(EVA_ROOT)/include/uapi/eva + +#srctree is /kernel_platform/common/ + +#ccflags-m not working, why? +ccflags-y += -I$(srctree)/techpack/eva/msm/eva/ \ + -I$(srctree)/drivers/media/platform/msm/synx/ + +msm-eva-objs := eva/cvp.o \ + eva/msm_cvp_ioctl.o \ + eva/msm_cvp_platform.o \ + eva/msm_cvp_common.o \ + eva/msm_cvp_core.o \ + eva/msm_cvp.o \ + eva/msm_smem.o \ + eva/msm_cvp_debug.o \ + eva/msm_cvp_res_parse.o \ + eva/cvp_hfi.o \ + eva/hfi_response_handler.o \ + eva/hfi_packetization.o \ + eva/cvp_core_hfi.o \ + eva/msm_cvp_clocks.o\ + eva/msm_cvp_dsp.o \ + eva/msm_cvp_buf.o \ + eva/msm_cvp_synx.o \ + eva/cvp_fw_load.o +obj-m += msm-eva.o + From e96edf5d62b045640c870a63dc2b7f6a0e67558f Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 8 Jan 2021 09:51:00 -0800 Subject: [PATCH 018/317] msm: eva: Enable auto-pil Enable auto pil and all debug loggings for bring up. Change-Id: I14e56e0f13269db78ef9a8e6bc63619d90dd62bc Signed-off-by: George Shen --- msm/eva/msm_cvp_debug.c | 2 +- msm/eva/msm_cvp_platform.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 2404504951..17924e7196 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -11,7 +11,7 @@ #define CREATE_TRACE_POINTS #define MAX_SSR_STRING_LEN 10 -int msm_cvp_debug = CVP_ERR | CVP_WARN | CVP_FW; +int msm_cvp_debug = CVP_ERR | CVP_WARN | CVP_FW | CVP_DBG; EXPORT_SYMBOL(msm_cvp_debug); int msm_cvp_debug_out = CVP_OUT_PRINTK; diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 8a4f7b5937..efc64f0e05 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -49,7 +49,7 @@ static struct msm_cvp_common_data default_common_data[] = { static struct msm_cvp_common_data sm8450_common_data[] = { { .key = "qcom,auto-pil", - .value = 0, + .value = 1, }, { .key = "qcom,never-unload-fw", From 085cc3a1a8a8ebcff8ea549528217dbf88b628ee Mon Sep 17 00:00:00 2001 From: Yu SI Date: Mon, 11 Jan 2021 18:13:05 -0800 Subject: [PATCH 019/317] msm: eva: feature related Waipio eva driver change Feature related Waipio_EVA_driver_code changes Change-Id: I49955d8b33d8c2e668555ac2a1795ea8d5710442 Signed-off-by: Yu SI --- msm/eva/cvp_hfi.c | 66 +++++++++++++++++++++++++++------- msm/eva/cvp_hfi.h | 56 ++++++++++++++++++++++++++--- msm/eva/cvp_hfi_api.h | 21 ++++++----- msm/eva/cvp_hfi_helper.h | 2 +- msm/eva/hfi_response_handler.c | 12 ++++++- msm/eva/msm_cvp.c | 8 +++-- msm/eva/msm_cvp_buf.h | 2 +- msm/eva/msm_cvp_common.c | 11 ++++-- msm/eva/msm_cvp_core.c | 4 +-- msm/eva/msm_cvp_internal.h | 6 ++-- msm/eva/msm_cvp_synx.c | 2 +- 11 files changed, 150 insertions(+), 40 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 912d88aac2..7eab779952 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -51,24 +51,59 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[] = { .resp = HAL_NO_RESP, }, { - .size = HFI_DME_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_DME_CONFIG, + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_WARP_NCC_CONFIG, .buf_offset = 0, .buf_num = 0, - .resp = HAL_SESSION_DME_CONFIG_CMD_DONE, + .resp = HAL_SESSION_WARP_NCC_CONFIG_CMD_DONE, }, { - .size = HFI_DME_BASIC_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_DME_BASIC_CONFIG, + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_WARP_NCC_FRAME, .buf_offset = 0, .buf_num = 0, - .resp = HAL_SESSION_DME_BASIC_CONFIG_CMD_DONE, + .resp = HAL_NO_RESP, }, { - .size = HFI_DME_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_DME_FRAME, - .buf_offset = HFI_DME_FRAME_BUFFERS_OFFSET, - .buf_num = HFI_DME_BUF_NUM, + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_WARP_CONFIG, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_SESSION_WARP_CONFIG_CMD_DONE, + }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_WARP_DS_PARAMS, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_SESSION_WARP_DS_PARAMS_CMD_DONE, + }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_WARP_FRAME, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_DMM_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DMM_CONFIG, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_SESSION_DMM_CONFIG_CMD_DONE, + }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_DMM_PARAMS, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_SESSION_DMM_PARAMS_CMD_DONE, + }, + { + .size = HFI_DMM_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DMM_FRAME, + .buf_offset = HFI_DMM_FRAME_BUFFERS_OFFSET, + .buf_num = HFI_DMM_BUF_NUM, .resp = HAL_NO_RESP, }, { @@ -2909,7 +2944,9 @@ static void **get_session_id(struct msm_cvp_cb_info *info) case HAL_SESSION_REGISTER_BUFFER_DONE: case HAL_SESSION_UNREGISTER_BUFFER_DONE: case HAL_SESSION_DFS_CONFIG_CMD_DONE: - case HAL_SESSION_DME_CONFIG_CMD_DONE: + case HAL_SESSION_DMM_CONFIG_CMD_DONE: + case HAL_SESSION_WARP_CONFIG_CMD_DONE: + case HAL_SESSION_WARP_NCC_CONFIG_CMD_DONE: case HAL_SESSION_TME_CONFIG_CMD_DONE: case HAL_SESSION_ODT_CONFIG_CMD_DONE: case HAL_SESSION_OD_CONFIG_CMD_DONE: @@ -2919,9 +2956,12 @@ static void **get_session_id(struct msm_cvp_cb_info *info) case HAL_SESSION_DCM_CONFIG_CMD_DONE: case HAL_SESSION_DC_CONFIG_CMD_DONE: case HAL_SESSION_PYS_HCD_CONFIG_CMD_DONE: - case HAL_SESSION_DME_BASIC_CONFIG_CMD_DONE: + case HAL_SESSION_DMM_PARAMS_CMD_DONE: + case HAL_SESSION_WARP_DS_PARAMS_CMD_DONE: case HAL_SESSION_DFS_FRAME_CMD_DONE: - case HAL_SESSION_DME_FRAME_CMD_DONE: + case HAL_SESSION_DMM_FRAME_CMD_DONE: + case HAL_SESSION_WARP_FRAME_CMD_DONE: + case HAL_SESSION_WARP_NCC_FRAME_CMD_DONE: case HAL_SESSION_ICA_FRAME_CMD_DONE: case HAL_SESSION_FD_FRAME_CMD_DONE: case HAL_SESSION_PERSIST_SET_DONE: diff --git a/msm/eva/cvp_hfi.h b/msm/eva/cvp_hfi.h index bbaebd883f..ee43ff41e8 100644 --- a/msm/eva/cvp_hfi.h +++ b/msm/eva/cvp_hfi.h @@ -99,8 +99,39 @@ (HFI_CMD_SESSION_CVP_START + 0x054) #define HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS\ (HFI_CMD_SESSION_CVP_START + 0x055) -#define HFI_CMD_SESSION_CVP_FLUSH\ +#define HFI_CMD_SESSION_CVP_RELEASE_MODEL_BUFFERS\ + (HFI_CMD_SESSION_CVP_START + 0x056) +#define HFI_CMD_SESSION_CVP_SGM_DFS_CONFIG\ (HFI_CMD_SESSION_CVP_START + 0x057) +#define HFI_CMD_SESSION_CVP_SGM_DFS_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x058) +#define HFI_CMD_SESSION_CVP_SGM_OF_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x059) +#define HFI_CMD_SESSION_CVP_SGM_OF_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x05A) +#define HFI_CMD_SESSION_CVP_GCE_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x05B) +#define HFI_CMD_SESSION_CVP_GCE_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x05C) +#define HFI_CMD_SESSION_CVP_WARP_NCC_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x05D) +#define HFI_CMD_SESSION_CVP_WARP_NCC_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x05E) +#define HFI_CMD_SESSION_CVP_DMM_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x05F) +#define HFI_CMD_SESSION_CVP_DMM_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x060) +#define HFI_CMD_SESSION_CVP_FLUSH\ + (HFI_CMD_SESSION_CVP_START + 0x061) +#define HFI_CMD_SESSION_CVP_WARP_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x062) +#define HFI_CMD_SESSION_CVP_WARP_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x063) +#define HFI_CMD_SESSION_CVP_DMM_PARAMS\ + (HFI_CMD_SESSION_CVP_START + 0x064) +#define HFI_CMD_SESSION_CVP_WARP_DS_PARAMS\ + (HFI_CMD_SESSION_CVP_START + 0x065) + #define HFI_CMD_SESSION_CVP_ICA_FRAME\ (HFI_CMD_SESSION_CVP_START + 0x100) #define HFI_CMD_SESSION_CVP_ICA_CONFIG\ @@ -147,10 +178,27 @@ (HFI_MSG_SESSION_CVP_START + 0x037) #define HFI_MSG_SESSION_CVP_RELEASE_PERSIST_BUFFERS\ (HFI_MSG_SESSION_CVP_START + 0x038) -#define HFI_MSG_SESSION_CVP_FLUSH_DEPRECATE\ - (HFI_CMD_SESSION_CVP_START + 0x03A) -#define HFI_MSG_SESSION_CVP_FLUSH\ +#define HFI_MSG_SESSION_CVP_RELEASE_MODEL_BUFFERS\ + (HFI_MSG_SESSION_CVP_START + 0x039) +#define HFI_MSG_SESSION_CVP_SGM_OF\ (HFI_MSG_SESSION_CVP_START + 0x03A) +#define HFI_MSG_SESSION_CVP_GCE\ + (HFI_MSG_SESSION_CVP_START + 0x03B) +#define HFI_MSG_SESSION_CVP_WARP_NCC\ + (HFI_MSG_SESSION_CVP_START + 0x03C) +#define HFI_MSG_SESSION_CVP_DMM\ + (HFI_MSG_SESSION_CVP_START + 0x03D) +#define HFI_MSG_SESSION_CVP_SGM_DFS\ + (HFI_MSG_SESSION_CVP_START + 0x03E) +#define HFI_MSG_SESSION_CVP_WARP\ + (HFI_MSG_SESSION_CVP_START + 0x03F) +#define HFI_MSG_SESSION_CVP_DMM_PARAMS\ + (HFI_MSG_SESSION_CVP_START + 0x040) +#define HFI_MSG_SESSION_CVP_WARP_DS_PARAMS\ + (HFI_MSG_SESSION_CVP_START + 0x041) + +#define HFI_MSG_SESSION_CVP_FLUSH\ + (HFI_MSG_SESSION_CVP_START + 0x004A) #define CVP_IFACEQ_MAX_PKT_SIZE 1024 #define CVP_IFACEQ_MED_PKT_SIZE 768 diff --git a/msm/eva/cvp_hfi_api.h b/msm/eva/cvp_hfi_api.h index 2d8d2fad3e..6960b5ffb3 100644 --- a/msm/eva/cvp_hfi_api.h +++ b/msm/eva/cvp_hfi_api.h @@ -35,11 +35,11 @@ #define HFI_DFS_FRAME_BUFFERS_OFFSET 8 #define HFI_DFS_BUF_NUM 4 -#define HFI_DME_CONFIG_CMD_SIZE 194 -#define HFI_DME_BASIC_CONFIG_CMD_SIZE 51 -#define HFI_DME_FRAME_CMD_SIZE 28 -#define HFI_DME_FRAME_BUFFERS_OFFSET 12 -#define HFI_DME_BUF_NUM 8 +#define HFI_DMM_CONFIG_CMD_SIZE 194 +#define HFI_DMM_BASIC_CONFIG_CMD_SIZE 51 +#define HFI_DMM_FRAME_CMD_SIZE 28 +#define HFI_DMM_FRAME_BUFFERS_OFFSET 12 +#define HFI_DMM_BUF_NUM 8 #define HFI_PERSIST_CMD_SIZE 11 #define HFI_PERSIST_BUFFERS_OFFSET 7 @@ -212,9 +212,14 @@ enum hal_command_response { HAL_SESSION_RELEASE_RESOURCE_DONE, HAL_SESSION_DFS_CONFIG_CMD_DONE, HAL_SESSION_DFS_FRAME_CMD_DONE, - HAL_SESSION_DME_CONFIG_CMD_DONE, - HAL_SESSION_DME_BASIC_CONFIG_CMD_DONE, - HAL_SESSION_DME_FRAME_CMD_DONE, + HAL_SESSION_DMM_CONFIG_CMD_DONE, + HAL_SESSION_DMM_PARAMS_CMD_DONE, + HAL_SESSION_DMM_FRAME_CMD_DONE, + HAL_SESSION_WARP_CONFIG_CMD_DONE, + HAL_SESSION_WARP_DS_PARAMS_CMD_DONE, + HAL_SESSION_WARP_FRAME_CMD_DONE, + HAL_SESSION_WARP_NCC_CONFIG_CMD_DONE, + HAL_SESSION_WARP_NCC_FRAME_CMD_DONE, HAL_SESSION_TME_CONFIG_CMD_DONE, HAL_SESSION_ODT_CONFIG_CMD_DONE, HAL_SESSION_OD_CONFIG_CMD_DONE, diff --git a/msm/eva/cvp_hfi_helper.h b/msm/eva/cvp_hfi_helper.h index ba0dbead15..6f48b2f2d0 100644 --- a/msm/eva/cvp_hfi_helper.h +++ b/msm/eva/cvp_hfi_helper.h @@ -224,7 +224,7 @@ struct cvp_hfi_cmd_sys_get_property_packet { enum HFI_SESSION_TYPE { HFI_SESSION_CV = 1, - HFI_SESSION_DME, + HFI_SESSION_DMM, HFI_SESSION_ODT, HFI_SESSION_FD }; diff --git a/msm/eva/hfi_response_handler.c b/msm/eva/hfi_response_handler.c index 1b88c9bf97..c2c553cf74 100644 --- a/msm/eva/hfi_response_handler.c +++ b/msm/eva/hfi_response_handler.c @@ -429,6 +429,12 @@ static int hfi_process_session_cvp_operation_config(u32 device_id, else if (pkt->packet_type == HFI_MSG_SESSION_CVP_SET_MODEL_BUFFERS) signal = get_signal_from_pkt_type( HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS); + else if (pkt->packet_type == HFI_MSG_SESSION_CVP_DMM_PARAMS) + signal = get_signal_from_pkt_type( + HFI_CMD_SESSION_CVP_DMM_PARAMS); + else if (pkt->packet_type == HFI_MSG_SESSION_CVP_WARP_DS_PARAMS) + signal = get_signal_from_pkt_type( + HFI_CMD_SESSION_CVP_WARP_DS_PARAMS); else signal = get_signal_from_pkt_type(conf_id); @@ -657,12 +663,16 @@ int cvp_hfi_process_msg_packet(u32 device_id, void *hdr, case HFI_MSG_SESSION_CVP_SET_PERSIST_BUFFERS: case HFI_MSG_SESSION_CVP_RELEASE_PERSIST_BUFFERS: case HFI_MSG_SESSION_CVP_SET_MODEL_BUFFERS: + case HFI_MSG_SESSION_CVP_DMM_PARAMS: + case HFI_MSG_SESSION_CVP_WARP_DS_PARAMS: pkt_func = (pkt_func_def)hfi_process_session_cvp_operation_config; break; case HFI_MSG_SESSION_CVP_DS: case HFI_MSG_SESSION_CVP_DFS: - case HFI_MSG_SESSION_CVP_DME: + case HFI_MSG_SESSION_CVP_DMM: + case HFI_MSG_SESSION_CVP_WARP: + case HFI_MSG_SESSION_CVP_WARP_NCC: case HFI_MSG_SESSION_CVP_FD: pkt_func = (pkt_func_def)hfi_process_session_cvp_msg; break; diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 4ab44e226b..f4c773e74e 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -211,7 +211,9 @@ static int msm_cvp_session_process_hfi( } pkt_type = in_pkt->pkt_data[1]; if (pkt_type == HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS || - pkt_type == HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS) + pkt_type == HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS || + pkt_type == HFI_CMD_SESSION_CVP_DMM_PARAMS || + pkt_type == HFI_CMD_SESSION_CVP_WARP_DS_PARAMS) rc = msm_cvp_map_user_persist(inst, in_pkt, offset, buf_num); else if (pkt_type == HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS) rc = msm_cvp_mark_user_persist(inst, in_pkt, offset, buf_num); @@ -651,7 +653,7 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst, pkt = (struct cvp_hfi_cmd_session_hdr *)&fence_pkt->pkt_data; idx = get_pkt_index((struct cvp_hal_session_cmd_pkt *)pkt); - if (idx < 0 || pkt->size > MAX_HFI_FENCE_OFFSET) { + if (idx < 0 || (pkt->size > MAX_HFI_FENCE_OFFSET * sizeof(unsigned int))) { dprintk(CVP_ERR, "%s incorrect packet %d %#x\n", __func__, pkt->size, pkt->packet_type); goto exit; @@ -1883,7 +1885,7 @@ int msm_cvp_session_init(struct msm_cvp_inst *inst) inst->prop.type = HFI_SESSION_CV; if (inst->session_type == MSM_CVP_KERNEL) - inst->prop.type = HFI_SESSION_DME; + inst->prop.type = HFI_SESSION_DMM; inst->prop.kernel_mask = 0xFFFFFFFF; inst->prop.priority = 0; diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index 6efba2e293..681673b716 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -15,7 +15,7 @@ #include #include -#define MAX_FRAME_BUFFER_NUMS 30 +#define MAX_FRAME_BUFFER_NUMS 48 #define MAX_DMABUF_NUMS 64 struct msm_cvp_inst; diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 7185195635..1e67249153 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -794,9 +794,14 @@ void cvp_handle_cmd_response(enum hal_command_response cmd, void *data) break; case HAL_SESSION_DFS_CONFIG_CMD_DONE: case HAL_SESSION_DFS_FRAME_CMD_DONE: - case HAL_SESSION_DME_CONFIG_CMD_DONE: - case HAL_SESSION_DME_BASIC_CONFIG_CMD_DONE: - case HAL_SESSION_DME_FRAME_CMD_DONE: + case HAL_SESSION_DMM_CONFIG_CMD_DONE: + case HAL_SESSION_DMM_PARAMS_CMD_DONE: + case HAL_SESSION_DMM_FRAME_CMD_DONE: + case HAL_SESSION_WARP_CONFIG_CMD_DONE: + case HAL_SESSION_WARP_DS_PARAMS_CMD_DONE: + case HAL_SESSION_WARP_FRAME_CMD_DONE: + case HAL_SESSION_WARP_NCC_CONFIG_CMD_DONE: + case HAL_SESSION_WARP_NCC_FRAME_CMD_DONE: case HAL_SESSION_PERSIST_SET_DONE: case HAL_SESSION_PERSIST_REL_DONE: case HAL_SESSION_TME_CONFIG_CMD_DONE: diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 4b3d2ccce6..a52327ff92 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -19,11 +19,11 @@ #define MAX_EVENTS 30 #define NUM_CYCLES16X16_HCD_FRAME 95 -#define NUM_CYCLES16X16_DME_FRAME 600 +#define NUM_CYCLES16X16_DMM_FRAME 600 #define NUM_CYCLES16X16_NCC_FRAME 400 #define NUM_CYCLES16X16_DS_FRAME 80 #define NUM_CYCLESFW_FRAME 1680000 -#define NUM_DME_MAX_FEATURE_POINTS 500 +#define NUM_DMM_MAX_FEATURE_POINTS 500 #define CYCLES_MARGIN_IN_POWEROF2 3 int msm_cvp_poll(void *instance, struct file *filp, diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index 1d53e0a5d8..b5bbce357e 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -34,9 +34,9 @@ #define FENCE_WAIT_SIGNAL_RETRY_TIMES 20 #define FENCE_BIT (1ULL << 63) -#define FENCE_DME_ICA_ENABLED_IDX 0 -#define FENCE_DME_DS_IDX 1 -#define FENCE_DME_OUTPUT_IDX 7 +#define FENCE_DMM_ICA_ENABLED_IDX 0 +#define FENCE_DMM_DS_IDX 1 +#define FENCE_DMM_OUTPUT_IDX 7 #define SYS_MSG_START HAL_SYS_INIT_DONE #define SYS_MSG_END HAL_SYS_ERROR diff --git a/msm/eva/msm_cvp_synx.c b/msm/eva/msm_cvp_synx.c index f70fb40130..eb1f6b3e4d 100644 --- a/msm/eva/msm_cvp_synx.c +++ b/msm/eva/msm_cvp_synx.c @@ -166,7 +166,7 @@ static int cvp_wait_synx(struct synx_session ssid, u32 *synx, u32 num_synx, u32 *synx_state) { int i = 0, rc = 0; - unsigned long timeout_ms = 1000; + unsigned long timeout_ms = 2000; //1000; int h_synx; while (i < num_synx) { From 0e7e863a3c995dfcff7b0e5d20a6223bc6cda439 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Fri, 15 Jan 2021 14:08:01 -0800 Subject: [PATCH 020/317] msm: eva: rm HFI_MSG_SESSION_CVP_FLUSH_DEPRECATE remove deprecated flag HFI_MSG_SESSION_CVP_FLUSH_DEPRECATE Change-Id: If3f53ce768050f541ec4d241ba1fdc0980891db7 Signed-off-by: Yu SI --- msm/eva/hfi_response_handler.c | 1 - 1 file changed, 1 deletion(-) diff --git a/msm/eva/hfi_response_handler.c b/msm/eva/hfi_response_handler.c index c2c553cf74..8dac742e41 100644 --- a/msm/eva/hfi_response_handler.c +++ b/msm/eva/hfi_response_handler.c @@ -656,7 +656,6 @@ int cvp_hfi_process_msg_packet(u32 device_id, void *hdr, pkt_func = (pkt_func_def)hfi_process_session_abort_done; break; case HFI_MSG_SESSION_CVP_FLUSH: - case HFI_MSG_SESSION_CVP_FLUSH_DEPRECATE: pkt_func = (pkt_func_def)hfi_process_session_flush_done; break; case HFI_MSG_SESSION_CVP_OPERATION_CONFIG: From 67c58f3214c94fe378ea7d38926a075940f9cab3 Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 15 Jan 2021 17:01:12 -0800 Subject: [PATCH 021/317] msm: eva: Disable hw controled power collapse Update EVA CC register offset and disable power collapse. Change-Id: I142053666e80c24ce1b12a4566b28638c615ec9b Signed-off-by: George Shen --- msm/eva/cvp_hfi_io.h | 9 ++++----- msm/eva/msm_cvp_debug.c | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index 925cc2f3b4..d4d55fb38a 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -216,9 +216,8 @@ #define CVP_AON_WRAPPER_MVP_NOC_LPI_CONTROL (CVP_AON_BASE_OFFS) #define CVP_AON_WRAPPER_MVP_NOC_LPI_STATUS (CVP_AON_BASE_OFFS + 0x4) -#define CVP_CC_BASE_OFFS 0x000F0000 -#define CVP_CC_MVS0C_GDSCR (CVP_CC_BASE_OFFS + 0xBF8) -#define CVP_CC_MVS1C_GDSCR (CVP_CC_BASE_OFFS + 0xC98) -#define CVP_CC_MVS1C_CBCR (CVP_CC_BASE_OFFS + 0xCD4) -#define CVP_CC_MVS1_GDSCR (CVP_CC_BASE_OFFS + 0xD98) +#define CVP_CC_BASE_OFFS 0x000F8000 +#define CVP_CC_MVS1C_GDSCR (CVP_CC_BASE_OFFS + 0x74) +#define CVP_CC_MVS1C_CBCR (CVP_CC_BASE_OFFS + 0x8C) +#define CVP_CC_MVS1_GDSCR (CVP_CC_BASE_OFFS + 0xC0) #endif diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 17924e7196..ff7280d917 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -19,7 +19,7 @@ EXPORT_SYMBOL(msm_cvp_debug_out); int msm_cvp_fw_debug = 0x18; int msm_cvp_fw_debug_mode = 1; -int msm_cvp_fw_low_power_mode = 1; +int msm_cvp_fw_low_power_mode = !1; bool msm_cvp_fw_coverage = !true; bool msm_cvp_cacheop_enabled = true; bool msm_cvp_thermal_mitigation_disabled = !true; From f3d06c8ef365317ce603f398f6b64ac8d98550d1 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 18 Jan 2021 09:15:25 -0800 Subject: [PATCH 022/317] msm: eva: New DSP driver interface New CPU-DSP interface aims to replace reverse RPC in DSP EVA applications. Change-Id: I4225dfa0b1acf8015a763263520442712e571851 Signed-off-by: George Shen --- msm/eva/cvp.c | 12 +- msm/eva/msm_cvp_buf.c | 327 +++++++++++ msm/eva/msm_cvp_buf.h | 17 +- msm/eva/msm_cvp_dsp.c | 1025 ++++++++++++++++++++++++++++++++++- msm/eva/msm_cvp_dsp.h | 117 +++- msm/eva/msm_cvp_platform.c | 6 +- msm/eva/msm_cvp_res_parse.c | 3 + msm/eva/msm_cvp_resources.h | 1 + msm/eva/msm_smem.c | 7 + 9 files changed, 1485 insertions(+), 30 deletions(-) diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index cf3e4b530d..797c5c3dfe 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -37,7 +37,7 @@ static int cvp_open(struct inode *inode, struct file *filp) struct msm_cvp_core, cdev); struct msm_cvp_inst *inst; - dprintk(CVP_SESS, "%s: Enter\n", __func__); + dprintk(CVP_SESS, "%s: core->id: %d\n", __func__, core->id); inst = msm_cvp_open(core->id, MSM_CVP_USER); if (!inst) { @@ -416,9 +416,13 @@ static int msm_probe_cvp_device(struct platform_device *pdev) atomic64_set(&core->kernel_trans_id, 0); - rc = cvp_dsp_device_init(); - if (rc) - dprintk(CVP_WARN, "Failed to initialize DSP driver\n"); + if (core->resources.dsp_enabled) { + rc = cvp_dsp_device_init(); + if (rc) + dprintk(CVP_WARN, "Failed to initialize DSP driver\n"); + } else { + dprintk(CVP_DSP, "DSP interface not enabled\n"); + } return rc; diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 994fa43353..785acd8b5c 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -3,6 +3,12 @@ * Copyright (c) 2020, The Linux Foundation. All rights reserved. */ +#include +#include +#include +#include +#include +#include #include "msm_cvp_common.h" #include "cvp_hfi_api.h" #include "msm_cvp_debug.h" @@ -251,6 +257,232 @@ int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) return rc; } +static struct file *msm_cvp_fget(unsigned int fd, struct task_struct *task, + fmode_t mask, unsigned int refs) +{ + struct files_struct *files = task->files; + struct file *file; + + rcu_read_lock(); +loop: + file = fcheck_files(files, fd); + if (file) { + /* File object ref couldn't be taken. + * dup2() atomicity guarantee is the reason + * we loop to catch the new file (or NULL pointer) + */ + if (file->f_mode & mask) + file = NULL; + else if (!get_file_rcu_many(file, refs)) + goto loop; + } + rcu_read_unlock(); + + return file; +} + +static struct dma_buf *cvp_dma_buf_get(struct file *file, int fd, + struct task_struct *task) +{ + if (file->f_op != gfa_cv.dmabuf_f_op) { + dprintk(CVP_WARN, "fd doesn't refer to dma_buf\n"); + return ERR_PTR(-EINVAL); + } + + return file->private_data; +} + +int msm_cvp_map_buf_dsp_new(struct msm_cvp_inst *inst, + struct eva_kmd_buffer *buf, + int32_t pid, uint32_t *iova) +{ + int rc = 0; + bool found = false; + struct cvp_internal_buf *cbuf; + struct msm_cvp_smem *smem = NULL; + struct cvp_hal_session *session; + struct dma_buf *dma_buf = NULL; + + struct pid *pid_s; + struct task_struct *task; + struct file *file; + + if (!inst || !inst->core || !buf) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + if (buf->fd < 0) { + dprintk(CVP_ERR, "%s: Invalid fd = %d", __func__, buf->fd); + return 0; + } + + if (buf->offset) { + dprintk(CVP_ERR, + "%s: offset is deprecated, set to 0.\n", + __func__); + return -EINVAL; + } + + session = (struct cvp_hal_session *)inst->session; + + mutex_lock(&inst->cvpdspbufs.lock); + list_for_each_entry(cbuf, &inst->cvpdspbufs.list, list) { + if (cbuf->fd == buf->fd) { + if (cbuf->size != buf->size) { + dprintk(CVP_ERR, "%s: buf size mismatch\n", + __func__); + mutex_unlock(&inst->cvpdspbufs.lock); + return -EINVAL; + } + found = true; + break; + } + } + mutex_unlock(&inst->cvpdspbufs.lock); + if (found) { + print_internal_buffer(CVP_ERR, "duplicate", inst, cbuf); + return -EINVAL; + } + + pid_s = find_get_pid(pid); + if (pid_s == NULL) { + dprintk(CVP_WARN, "%s incorrect pid\n", __func__); + return -EINVAL; + } + dprintk(CVP_WARN, "%s get pid_s 0x%x from pidA 0x%x\n", __func__, pid_s, pid); + /* task = get_pid_task(pid, PIDTYPE_PID); */ + task = get_pid_task(pid_s, PIDTYPE_TGID); + + if (!task) + dprintk(CVP_WARN, "%s task doesn't exist\n", __func__); + file = msm_cvp_fget(buf->fd, task, FMODE_PATH, 1); + if (file == NULL) { + dprintk(CVP_WARN, "%s fail to get file from fd\n", __func__); + put_task_struct(task); + return -EINVAL; + } + + //entry->file = file; + dma_buf = cvp_dma_buf_get( + file, + buf->fd, + task); + if (dma_buf == ERR_PTR(-EINVAL)) { + dprintk(CVP_ERR, "%s: Invalid fd = %d", __func__, buf->fd); + fput(file); + put_task_struct(task); + return -EINVAL; + } + + dprintk(CVP_WARN, "dma_buf from internal %llu\n", dma_buf); + /* to unmap dsp buf, below sequence is required + * fput(file); + * dma_buf_put(dma_buf); + * put_task_struct(task); + */ + + if (!dma_buf) { + dprintk(CVP_ERR, "%s: Invalid fd = %d", __func__, buf->fd); + return 0; + } + + cbuf = kmem_cache_zalloc(cvp_driver->buf_cache, GFP_KERNEL); + if (!cbuf) + return -ENOMEM; + + smem = kmem_cache_zalloc(cvp_driver->smem_cache, GFP_KERNEL); + if (!smem) { + kmem_cache_free(cvp_driver->buf_cache, cbuf); + return -ENOMEM; + } + + smem->dma_buf = dma_buf; + smem->bitmap_index = MAX_DMABUF_NUMS; + dprintk(CVP_DSP, "%s: dma_buf = %llx\n", __func__, dma_buf); + rc = msm_cvp_map_smem(inst, smem, "map dsp"); + if (rc) { + print_client_buffer(CVP_ERR, "map failed", inst, buf); + goto exit; + } + + cbuf->smem = smem; + cbuf->fd = buf->fd; + cbuf->size = buf->size; + cbuf->offset = buf->offset; + cbuf->ownership = CLIENT; + cbuf->index = buf->index; + + *iova = (uint32_t)smem->device_addr; + + dprintk(CVP_DSP, "%s: buf->fd %d, device_addr = %llx\n", + __func__, buf->fd, (uint32_t)smem->device_addr); + + mutex_lock(&inst->cvpdspbufs.lock); + list_add_tail(&cbuf->list, &inst->cvpdspbufs.list); + mutex_unlock(&inst->cvpdspbufs.lock); + + return rc; + +exit: + if (smem->device_addr) { + msm_cvp_unmap_smem(inst, smem, "unmap dsp"); + msm_cvp_smem_put_dma_buf(smem->dma_buf); + } + kmem_cache_free(cvp_driver->buf_cache, cbuf); + cbuf = NULL; + kmem_cache_free(cvp_driver->smem_cache, smem); + smem = NULL; + return rc; +} + +int msm_cvp_unmap_buf_dsp_new(struct msm_cvp_inst *inst, + struct eva_kmd_buffer *buf) +{ + int rc = 0; + bool found; + struct cvp_internal_buf *cbuf; + struct cvp_hal_session *session; + + if (!inst || !inst->core || !buf) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + session = (struct cvp_hal_session *)inst->session; + if (!session) { + dprintk(CVP_ERR, "%s: invalid session\n", __func__); + return -EINVAL; + } + + mutex_lock(&inst->cvpdspbufs.lock); + found = false; + list_for_each_entry(cbuf, &inst->cvpdspbufs.list, list) { + if (cbuf->fd == buf->fd) { + found = true; + break; + } + } + mutex_unlock(&inst->cvpdspbufs.lock); + if (!found) { + print_client_buffer(CVP_ERR, "invalid", inst, buf); + return -EINVAL; + } + + if (cbuf->smem->device_addr) { + msm_cvp_unmap_smem(inst, cbuf->smem, "unmap dsp"); + msm_cvp_smem_put_dma_buf(cbuf->smem->dma_buf); + } + + mutex_lock(&inst->cvpdspbufs.lock); + list_del(&cbuf->list); + mutex_unlock(&inst->cvpdspbufs.lock); + + kmem_cache_free(cvp_driver->smem_cache, cbuf->smem); + kmem_cache_free(cvp_driver->buf_cache, cbuf); + return rc; +} + void msm_cvp_cache_operations(struct msm_cvp_smem *smem, u32 type, u32 offset, u32 size) { @@ -964,3 +1196,98 @@ int cvp_release_arp_buffers(struct msm_cvp_inst *inst) return rc; } +int cvp_allocate_dsp_bufs(struct msm_cvp_inst *inst, + struct cvp_internal_buf *buf, + u32 buffer_size, + u32 secure_type) +{ + u32 smem_flags = SMEM_UNCACHED; + int rc = 0; + + if (!inst) { + dprintk(CVP_ERR, "%s Invalid input\n", __func__); + return -EINVAL; + } + + if (!buf) + return -EINVAL; + + if (!buffer_size) + return -EINVAL; + + switch (secure_type) { + case 0: + break; + case 1: + smem_flags |= SMEM_SECURE | SMEM_PIXEL; + break; + case 2: + smem_flags |= SMEM_SECURE | SMEM_NON_PIXEL; + break; + default: + dprintk(CVP_ERR, "%s Invalid secure_type %d\n", + __func__, secure_type); + return -EINVAL; + } + + dprintk(CVP_ERR, "%s smem_flags 0x%x\n", __func__, smem_flags); + buf->smem = kmem_cache_zalloc(cvp_driver->smem_cache, GFP_KERNEL); + if (!buf->smem) { + dprintk(CVP_ERR, "%s Out of memory\n", __func__); + goto fail_kzalloc_smem_cache; + } + + rc = msm_cvp_smem_alloc(buffer_size, 1, smem_flags, 0, + &(inst->core->resources), buf->smem); + if (rc) { + dprintk(CVP_ERR, "Failed to allocate ARP memory\n"); + goto err_no_mem; + } + + dprintk(CVP_ERR, "%s dma_buf %pK\n", __func__, buf->smem->dma_buf); + + buf->size = buf->smem->size; + buf->type = HFI_BUFFER_INTERNAL_PERSIST_1; + buf->ownership = CLIENT; + + return rc; + +err_no_mem: + kmem_cache_free(cvp_driver->smem_cache, buf->smem); +fail_kzalloc_smem_cache: + return rc; +} + +int cvp_release_dsp_buffers(struct msm_cvp_inst *inst, + struct cvp_internal_buf *buf) +{ + struct msm_cvp_smem *smem; + int rc = 0; + + if (!inst) { + dprintk(CVP_ERR, "Invalid instance pointer = %pK\n", inst); + return -EINVAL; + } + + if (!buf) { + dprintk(CVP_ERR, "Invalid buffer pointer = %pK\n", inst); + return -EINVAL; + } + + smem = buf->smem; + if (!smem) { + dprintk(CVP_ERR, "%s invalid smem\n", __func__); + return -EINVAL; + } + + if (buf->ownership == CLIENT) { + dprintk(CVP_MEM, + "%s: %x : fd %x %s size %d", + "free dsp buf", hash32_ptr(inst->session), buf->fd, + smem->dma_buf->name, buf->size); + msm_cvp_smem_free(smem); + kmem_cache_free(cvp_driver->smem_cache, smem); + } + + return rc; +} diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index 681673b716..c46d4177af 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -15,7 +15,7 @@ #include #include -#define MAX_FRAME_BUFFER_NUMS 48 +#define MAX_FRAME_BUFFER_NUMS 30 #define MAX_DMABUF_NUMS 64 struct msm_cvp_inst; @@ -33,7 +33,8 @@ enum smem_prop { SMEM_CACHED = 0x2, SMEM_SECURE = 0x4, SMEM_ADSP = 0x8, - SMEM_NON_PIXEL = 0x10 + SMEM_NON_PIXEL = 0x10, + SMEM_PIXEL = 0x20 }; struct msm_cvp_list { @@ -177,6 +178,12 @@ int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf); int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf); +int msm_cvp_map_buf_dsp_new(struct msm_cvp_inst *inst, + struct eva_kmd_buffer *buf, + int32_t pid, + uint32_t *iova); +int msm_cvp_unmap_buf_dsp_new(struct msm_cvp_inst *inst, + struct eva_kmd_buffer *buf); void msm_cvp_cache_operations(struct msm_cvp_smem *smem, u32 type, u32 offset, u32 size); u32 msm_cvp_map_frame_buf(struct msm_cvp_inst *inst, @@ -197,4 +204,10 @@ int msm_cvp_map_frame(struct msm_cvp_inst *inst, void msm_cvp_unmap_frame(struct msm_cvp_inst *inst, u64 ktid); int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst); void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst); +int cvp_allocate_dsp_bufs(struct msm_cvp_inst *inst, + struct cvp_internal_buf *buf, + u32 buffer_size, + u32 secure_type); +int cvp_release_dsp_buffers(struct msm_cvp_inst *inst, + struct cvp_internal_buf *buf); #endif diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index e9e76afe08..3ee71d7991 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -7,8 +7,9 @@ #include #include #include -#include "msm_cvp_dsp.h" -#include "msm_cvp_internal.h" +#include "msm_cvp_core.h" +#include "msm_cvp.h" +#include "cvp_hfi.h" struct cvp_dsp_apps gfa_cv; static int hlosVM[HLOS_VM_NUM] = {VMID_HLOS}; @@ -204,9 +205,11 @@ static int cvp_dsp_rpmsg_callback(struct rpmsg_device *rpdev, } else if (rsp->type < CVP_DSP_MAX_CMD && len == sizeof(struct cvp_dsp2cpu_cmd_msg)) { if (me->pending_dsp2cpu_cmd.type != CVP_INVALID_RPMSG_TYPE) { - dprintk(CVP_ERR, "%s: DSP2CPU cmd:%d pending %d\n", + dprintk(CVP_ERR, + "%s: DSP2CPU cmd:%d pending %d %d expect %d\n", __func__, rsp->type, - me->pending_dsp2cpu_cmd.type); + me->pending_dsp2cpu_cmd.type, len, + sizeof(struct cvp_dsp2cpu_cmd_msg)); goto exit; } memcpy(&me->pending_dsp2cpu_cmd, rsp, @@ -286,29 +289,19 @@ int cvp_dsp_resume(uint32_t session_flag) int rc = 0; struct cvp_dsp_cmd_msg cmd; struct cvp_dsp_apps *me = &gfa_cv; - struct cvp_dsp_rsp_msg rsp; cmd.type = CPU2DSP_RESUME; - mutex_lock(&me->lock); + /* + * Deadlock against DSP2CPU_CREATE_SESSION in dsp_thread + * Probably get rid of this entirely as discussed before + */ if (me->state != DSP_SUSPEND) goto exit; - /* Use cvp_dsp_send_cmd_sync after dsp driver is ready */ - rc = cvp_dsp_send_cmd_sync(&cmd, - sizeof(struct cvp_dsp_cmd_msg), - &rsp); - if (rc) { - dprintk(CVP_ERR, - "%s: cvp_dsp_send_cmd failed rc = %d\n", - __func__, rc); - goto exit; - } - me->state = DSP_READY; exit: - mutex_unlock(&me->lock); return rc; } @@ -641,12 +634,280 @@ static int cvp_reinit_dsp(void) return rc; } +#ifdef FASTRPC_DRIVER_AVAILABLE +static struct cvp_dsp_fastrpc_driver_entry *cvp_find_fastrpc_node_with_handle( + uint32_t handle) +{ + struct cvp_dsp_apps *me = &gfa_cv; + struct list_head *ptr = NULL, *next = NULL; + struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; + + mutex_lock(&me->fastrpc_driver_list.lock); + list_for_each_safe(ptr, next, &me->fastrpc_driver_list.list) { + frpc_node = list_entry(ptr, + struct cvp_dsp_fastrpc_driver_entry, list); + if (handle == frpc_node->handle) { + dprintk(CVP_DSP, "Find frpc_node with handle 0x%x\n", + handle); + break; + } + } + mutex_unlock(&me->fastrpc_driver_list.lock); + + return frpc_node; +} + +static void eva_fastrpc_driver_unregister(struct msm_cvp_inst *inst, + uint32_t handle, + bool force_exit); + +static int cvp_fastrpc_probe(struct fastrpc_device *rpc_dev) +{ + struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; + + dprintk(CVP_DSP, "%s fastrpc probe handle 0x%x\n", + __func__, rpc_dev->handle); + + frpc_node = cvp_find_fastrpc_node_with_handle(rpc_dev->handle); + if (frpc_node) { + frpc_node->cvp_fastrpc_device = rpc_dev; + // static structure with signal and pid + complete(&frpc_node->fastrpc_probe_completion); + } + + return 0; +} + +static int cvp_fastrpc_callback(struct fastrpc_device *rpc_dev, + enum fastrpc_driver_status fastrpc_proc_num) +{ + dprintk(CVP_DSP, "%s handle 0x%x, proc %d\n", __func__, + rpc_dev->handle, fastrpc_proc_num); + + /* fastrpc drive down when process gone + * any handling can happen here, such as + * eva_fastrpc_driver_unregister(rpc_dev->handle, true); + */ + + return 0; +} + + +static struct fastrpc_driver cvp_fastrpc_client = { + .probe = cvp_fastrpc_probe, + .callback = cvp_fastrpc_callback, + .driver = { + .name = "qcom,fastcv", + }, +}; + + +static int eva_fastrpc_dev_map_dma(struct fastrpc_device *frpc_device, + struct cvp_internal_buf *buf, + uint32_t dsp_remote_map, + uint64_t *v_dsp_addr) +{ + struct fastrpc_dev_map_dma frpc_map_buf = {0}; + int rc = 0; + + if (dsp_remote_map == 1) { + frpc_map_buf.buf = buf->smem->dma_buf; + frpc_map_buf.size = buf->smem->size; + frpc_map_buf.attrs = 0; + + dprintk(CVP_DSP, + "%s frpc_map_buf size %d, dma_buf %pK, map %pK, 0x%x\n", + __func__, frpc_map_buf.size, frpc_map_buf.buf, + &frpc_map_buf, (unsigned long)&frpc_map_buf); + rc = fastrpc_driver_invoke(frpc_device, FASTRPC_DEV_MAP_DMA, + (unsigned long)(&frpc_map_buf)); + if (rc) { + dprintk(CVP_ERR, + "%s Failed to map buffer 0x%x\n", __func__, rc); + return rc; + } + buf->fd = (s32)frpc_map_buf.v_dsp_addr; + *v_dsp_addr = frpc_map_buf.v_dsp_addr; + } else { + dprintk(CVP_DSP, "%s Buffer not mapped to dsp\n", __func__); + buf->fd = 0; + } + + return rc; +} + +static int eva_fastrpc_dev_unmap_dma(struct fastrpc_device *frpc_device, + struct cvp_internal_buf *buf) +{ + struct fastrpc_dev_unmap_dma frpc_unmap_buf = {0}; + int rc = 0; + + /* Only if buffer is mapped to dsp */ + if (buf->fd != 0) { + frpc_unmap_buf.buf = buf->smem->dma_buf; + rc = fastrpc_driver_invoke(frpc_device, FASTRPC_DEV_UNMAP_DMA, + (unsigned long)(&frpc_unmap_buf)); + if (rc) { + dprintk(CVP_ERR, "%s Failed to unmap buffer 0x%x\n", + __func__, rc); + return rc; + } + } else { + dprintk(CVP_DSP, "%s buffer not mapped to dsp\n", __func__); + } + + return rc; +} + +static int eva_fastrpc_driver_register(uint32_t handle) +{ + struct cvp_dsp_apps *me = &gfa_cv; + int rc = 0; + //struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; + struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; + + frpc_node = cvp_find_fastrpc_node_with_handle(handle); + + if (frpc_node == NULL) { + frpc_node = kzalloc(sizeof(*frpc_node), GFP_KERNEL); + if (!frpc_node) { + dprintk(CVP_DSP, "%s allocate frpc node fail\n", + __func__); + return -EINVAL; + } + + memset(frpc_node, 0, sizeof(*frpc_node)); + + /* Init completion */ + init_completion(&frpc_node->fastrpc_probe_completion); + + mutex_lock(&me->fastrpc_driver_list.lock); + dprintk(CVP_DSP, "Add frpc node 0x%x to list\n", frpc_node); + list_add_tail(&frpc_node->list, &me->fastrpc_driver_list.list); + mutex_unlock(&me->fastrpc_driver_list.lock); + + /* register fastrpc device to this session */ + frpc_node->handle = handle; + frpc_node->cvp_fastrpc_driver = cvp_fastrpc_client; + frpc_node->cvp_fastrpc_driver.handle = handle; + rc = fastrpc_driver_register(&frpc_node->cvp_fastrpc_driver); + if (rc) { + dprintk(CVP_ERR, "%s fastrpc driver reg fail err %d\n", + __func__, rc); + goto fail_fastrpc_driver_register; + } + + /* signal wait reuse dsp timeout setup for now */ + if (!wait_for_completion_timeout( + &frpc_node->fastrpc_probe_completion, + msecs_to_jiffies(CVP_DSP_RESPONSE_TIMEOUT))) { + dprintk(CVP_ERR, "%s fastrpc driver_register timeout\n", + __func__); + goto fail_fastrpc_driver_timeout; + } + + /* initialize dspbuf list */ + INIT_MSM_CVP_LIST(&frpc_node->dspbufs); + } + + frpc_node->session_cnt++; + + return rc; + +fail_fastrpc_driver_timeout: + /* remove list if this is the last session */ + mutex_lock(&me->fastrpc_driver_list.lock); + list_del(&frpc_node->list); + mutex_unlock(&me->fastrpc_driver_list.lock); + fastrpc_driver_unregister(&frpc_node->cvp_fastrpc_driver); +fail_fastrpc_driver_register: + kfree(frpc_node); + return -EINVAL; +} + +static void eva_fastrpc_driver_unregister(struct msm_cvp_inst *inst, + uint32_t handle, + bool force_exit) +{ + struct cvp_dsp_apps *me = &gfa_cv; + struct list_head *ptr = NULL, *next = NULL; + struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; + struct msm_cvp_list *buf_list = NULL; + struct cvp_internal_buf *buf = NULL; + struct fastrpc_device *frpc_device = NULL; + struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; + int rc = 0; + + dprintk(CVP_DSP, "%s Unregister fastrpc driver handle 0x%x, force %d\n", + __func__, handle, (uint32_t)force_exit); + + /* Foundd fastrpc node */ + frpc_node = cvp_find_fastrpc_node_with_handle(dsp2cpu_cmd->pid); + + if (frpc_node == NULL) + return; + + frpc_node->session_cnt--; + + if ((frpc_node->session_cnt == 0) || force_exit) { + dprintk(CVP_DSP, "%s session cnt %d, force %d\n", + __func__, frpc_node->session_cnt, (uint32_t)force_exit); + //Free any left over buffers + ptr = NULL; + next = NULL; + buf_list = &frpc_node->dspbufs; + mutex_lock(&buf_list->lock); + list_for_each_safe(ptr, next, &buf_list->list) { + buf = list_entry(ptr, struct cvp_internal_buf, list); + + if (!buf->smem) { + dprintk(CVP_DSP, "%s Empyt smem\n", __func__); + list_del(&buf->list); + kfree(buf); + continue; + } + + rc = eva_fastrpc_dev_unmap_dma(frpc_device, buf); + if (rc) { + dprintk(CVP_ERR, + "%s Fail to unmap buffer 0x%x\n", + __func__, rc); + continue; + } + + rc = cvp_release_dsp_buffers(inst, buf); + if (rc) { + dprintk(CVP_ERR, + "%s Fail to free buffer 0x%x\n", + __func__, rc); + continue; + } + + list_del(&buf->list); + kfree(buf); + } + mutex_unlock(&buf_list->lock); + + DEINIT_MSM_CVP_LIST(&frpc_node->dspbufs); + + /* remove list if this is the last session */ + mutex_lock(&me->fastrpc_driver_list.lock); + list_del(&frpc_node->list); + mutex_unlock(&me->fastrpc_driver_list.lock); + + fastrpc_driver_unregister(&frpc_node->cvp_fastrpc_driver); + kfree(frpc_node); + } +} + +#endif + void cvp_dsp_send_hfi_queue(void) { struct msm_cvp_core *core; struct iris_hfi_device *device; struct cvp_dsp_apps *me = &gfa_cv; - struct cvp_dsp_rsp_msg rsp; + struct cvp_dsp_rsp_msg rsp = {0}; uint64_t addr; uint32_t size; int rc; @@ -737,6 +998,686 @@ exit: mutex_unlock(&me->lock); mutex_unlock(&device->lock); } +/* 32 or 64 bit CPU Side Ptr <-> 2 32 bit DSP Pointers. Dirty Fix. */ +static void *ptr_dsp2cpu(uint32_t session_cpu_high, uint32_t session_cpu_low) +{ + void *inst; + + if ((session_cpu_high == 0) && (sizeof(void *) == BITPTRSIZE32)) { + inst = (void *)((uintptr_t)session_cpu_low); + } else if ((session_cpu_high != 0) && (sizeof(void *) == BITPTRSIZE64)) { + inst = (void *)((uintptr_t)(((uint64_t)session_cpu_high) << 32 + | session_cpu_low)); + } else { + dprintk(CVP_ERR, + "%s Invalid _cpu_high = 0x%x _cpu_low = 0x%x\n", + __func__, session_cpu_high, session_cpu_low); + inst = NULL; + } + return inst; +} + +static void print_power(const struct eva_power_req *pwr_req) +{ + if (pwr_req) { + dprintk(CVP_DSP, "Clock: Fdu %d Ica %d Od %d Mpu %d Fw %d", + pwr_req->clock_fdu, pwr_req->clock_ica, + pwr_req->clock_od, pwr_req->clock_mpu, + pwr_req->clock_fw); + dprintk(CVP_DSP, "OpClock: Fdu %d Ica %d Od %d Mpu %d Fw %d", + pwr_req->op_clock_fdu, pwr_req->op_clock_ica, + pwr_req->op_clock_od, pwr_req->op_clock_mpu, + pwr_req->op_clock_fw); + dprintk(CVP_DSP, "Actual Bw: Ddr %d, SysCache %d", + pwr_req->bw_ddr, pwr_req->bw_sys_cache); + dprintk(CVP_DSP, "OpBw: Ddr %d, SysCache %d", + pwr_req->op_bw_ddr, pwr_req->op_bw_sys_cache); + } +} + +static int msm_cvp_register_buffer_dsp(struct msm_cvp_inst *inst, + struct eva_kmd_buffer *buf, + int32_t pid, + uint32_t *iova) +{ + struct cvp_hfi_device *hdev; + struct cvp_hal_session *session; + struct msm_cvp_inst *s; + int rc = 0; + + if (!inst || !inst->core || !buf) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + if (!buf->index) + return 0; + + s = cvp_get_inst_validate(inst->core, inst); + if (!s) + return -ECONNRESET; + + inst->cur_cmd_type = EVA_KMD_REGISTER_BUFFER; + session = (struct cvp_hal_session *)inst->session; + if (!session) { + dprintk(CVP_ERR, "%s: invalid session\n", __func__); + rc = -EINVAL; + goto exit; + } + hdev = inst->core->device; + print_client_buffer(CVP_HFI, "register", inst, buf); + + rc = msm_cvp_map_buf_dsp_new(inst, buf, pid, iova); + dprintk(CVP_DSP, "%s: fd %d, iova 0x%x\n", __func__, buf->fd, *iova); + +exit: + inst->cur_cmd_type = 0; + cvp_put_inst(s); + return rc; +} + +static int msm_cvp_unregister_buffer_dsp(struct msm_cvp_inst *inst, + struct eva_kmd_buffer *buf) +{ + struct msm_cvp_inst *s; + int rc = 0; + + if (!inst || !inst->core || !buf) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + if (!buf->index) + return 0; + + s = cvp_get_inst_validate(inst->core, inst); + if (!s) + return -ECONNRESET; + + inst->cur_cmd_type = EVA_KMD_UNREGISTER_BUFFER; + print_client_buffer(CVP_HFI, "unregister", inst, buf); + + rc = msm_cvp_unmap_buf_dsp_new(inst, buf); + inst->cur_cmd_type = 0; + cvp_put_inst(s); + return rc; +} + +static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) +{ + struct cvp_dsp_apps *me = &gfa_cv; + struct msm_cvp_inst *inst = NULL; + uint64_t inst_handle = 0; + struct eva_kmd_arg *kmd; + struct eva_kmd_sys_properties *sys_prop = NULL; + struct eva_kmd_session_control *sys_ctrl = NULL; + int rc = 0; + struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; + + cmd->ret = 0; + + dprintk(CVP_DSP, + "%s sess Type %d Mask %d Prio %d Sec %d pid 0x%x\n", + __func__, dsp2cpu_cmd->session_type, + dsp2cpu_cmd->kernel_mask, + dsp2cpu_cmd->session_prio, + dsp2cpu_cmd->is_secure, + dsp2cpu_cmd->pid); + + kmd = kzalloc(sizeof(*kmd), GFP_KERNEL); + if (!kmd) { + dprintk(CVP_ERR, "%s kzalloc failure\n", __func__); + goto fail_frpc_driver_reg; + } + +#ifdef FASTRPC_DRIVER_AVAILABLE + rc = eva_fastrpc_driver_register(dsp2cpu_cmd->pid); +#endif + if (rc) { + dprintk(CVP_ERR, "%s Register fastrpc driver fail\n", __func__); + goto fail_frpc_driver_reg; + } + + inst = msm_cvp_open(MSM_CORE_CVP, MSM_CVP_USER); + if (!inst) { + dprintk(CVP_ERR, "%s Failed create instance\n", __func__); + goto fail_msm_cvp_open; + } + + kmd->type = EVA_KMD_SET_SYS_PROPERTY; + sys_prop = (struct eva_kmd_sys_properties *)&kmd->data.sys_properties; + sys_prop->prop_num = 5; + + sys_prop->prop_data[0].prop_type = EVA_KMD_PROP_SESSION_KERNELMASK; + sys_prop->prop_data[0].data = dsp2cpu_cmd->kernel_mask; + sys_prop->prop_data[1].prop_type = EVA_KMD_PROP_SESSION_TYPE; + sys_prop->prop_data[1].data = dsp2cpu_cmd->session_type; + sys_prop->prop_data[2].prop_type = EVA_KMD_PROP_SESSION_PRIORITY; + sys_prop->prop_data[2].data = dsp2cpu_cmd->session_prio; + sys_prop->prop_data[3].prop_type = EVA_KMD_PROP_SESSION_SECURITY; + sys_prop->prop_data[3].data = dsp2cpu_cmd->is_secure; + sys_prop->prop_data[4].prop_type = EVA_KMD_PROP_SESSION_DSPMASK; + sys_prop->prop_data[4].data = dsp2cpu_cmd->dsp_access_mask; + + rc = msm_cvp_handle_syscall(inst, kmd); + if (rc) { + dprintk(CVP_ERR, "%s Failed to set sys property\n", __func__); + goto fail_set_sys_property; + } + dprintk(CVP_DSP, "%s set sys property done\n", __func__); + + + /* EVA_KMD_SESSION_CONTROL from DSP */ + memset(kmd, 0, sizeof(struct eva_kmd_arg)); + kmd->type = EVA_KMD_SESSION_CONTROL; + sys_ctrl = (struct eva_kmd_session_control *)&kmd->data.session_ctrl; + sys_ctrl->ctrl_type = SESSION_CREATE; + + rc = msm_cvp_handle_syscall(inst, kmd); + if (rc) { + dprintk(CVP_ERR, "Warning: send Session Create failed\n"); + goto fail_session_create; + } + dprintk(CVP_DSP, "%s send Session Create done\n", __func__); + + + /* Get session id */ + memset(kmd, 0, sizeof(struct eva_kmd_arg)); + kmd->type = EVA_KMD_GET_SESSION_INFO; + rc = msm_cvp_handle_syscall(inst, kmd); + if (rc) { + dprintk(CVP_ERR, "Warning: get session index failed\n"); + goto fail_get_session_info; + } + cmd->session_id = kmd->data.session.session_id; + + inst_handle = (uint64_t)inst; + cmd->session_cpu_high = (uint32_t)((inst_handle & HIGH32) >> 32); + cmd->session_cpu_low = (uint32_t)(inst_handle & LOW32); + + dprintk(CVP_DSP, + "%s CREATE_SESS id 0x%x, cpu_low 0x%x, cpu_high 0x%x\n", + __func__, cmd->session_id, cmd->session_cpu_low, + cmd->session_cpu_high); + + kfree(kmd); + return; + +fail_get_session_info: +fail_session_create: +fail_set_sys_property: +fail_msm_cvp_open: + /* unregister fastrpc driver */ +fail_frpc_driver_reg: + cmd->ret = -1; + kfree(kmd); +} + +static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) +{ + struct cvp_dsp_apps *me = &gfa_cv; + struct msm_cvp_inst *inst; + struct eva_kmd_arg *kmd; + struct eva_kmd_session_control *sys_ctrl; + int rc; + struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; + + cmd->ret = 0; + + dprintk(CVP_DSP, + "%s sess id 0x%x low 0x%x high 0x%x, pid 0x%x\n", + __func__, dsp2cpu_cmd->session_id, + dsp2cpu_cmd->session_cpu_low, + dsp2cpu_cmd->session_cpu_high, + dsp2cpu_cmd->pid); + + kmd = kzalloc(sizeof(*kmd), GFP_KERNEL); + if (!kmd) { + dprintk(CVP_ERR, "%s kzalloc failure\n", __func__); + cmd->ret = -1; + return; + } + + inst = (struct msm_cvp_inst *)ptr_dsp2cpu( + dsp2cpu_cmd->session_cpu_high, + dsp2cpu_cmd->session_cpu_low); + +#ifdef FASTRPC_DRIVER_AVAILABLE + /* unregister fastrpc driver */ + eva_fastrpc_driver_unregister(inst, dsp2cpu_cmd->pid, false); +#endif + + kmd->type = EVA_KMD_SESSION_CONTROL; + sys_ctrl = (struct eva_kmd_session_control *)&kmd->data.session_ctrl; + + /* Session delete does nothing here */ + sys_ctrl->ctrl_type = SESSION_DELETE; + + rc = msm_cvp_handle_syscall(inst, kmd); + if (rc) { + dprintk(CVP_ERR, "Warning: send Delete Session failed\n"); + cmd->ret = -1; + goto dsp_fail_delete; + } + + rc = msm_cvp_close(inst); + if (rc) { + dprintk(CVP_ERR, "Warning: Failed to close cvp instance\n"); + cmd->ret = -1; + goto dsp_fail_delete; + } + + dprintk(CVP_DSP, "%s DSP2CPU_DETELE_SESSION Done\n", __func__); +dsp_fail_delete: + kfree(kmd); +} + +static void __dsp_cvp_power_req(struct cvp_dsp_cmd_msg *cmd) +{ + struct cvp_dsp_apps *me = &gfa_cv; + struct msm_cvp_inst *inst; + struct eva_kmd_arg *kmd; + struct eva_kmd_sys_properties *sys_prop; + int rc; + struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; + + cmd->ret = 0; + dprintk(CVP_DSP, + "%s sess id 0x%x, low 0x%x, high 0x%x\n", + __func__, dsp2cpu_cmd->session_id, + dsp2cpu_cmd->session_cpu_low, + dsp2cpu_cmd->session_cpu_high); + + kmd = kzalloc(sizeof(*kmd), GFP_KERNEL); + if (!kmd) { + dprintk(CVP_ERR, "%s kzalloc failure\n", __func__); + cmd->ret = -1; + return; + } + + inst = (struct msm_cvp_inst *)ptr_dsp2cpu( + dsp2cpu_cmd->session_cpu_high, + dsp2cpu_cmd->session_cpu_low); + + print_power(&dsp2cpu_cmd->power_req); + + /* EVA_KMD_SET_SYS_PROPERTY + * Total 14 properties, 8 max once + * Need to do 2 rounds + */ + kmd->type = EVA_KMD_SET_SYS_PROPERTY; + sys_prop = (struct eva_kmd_sys_properties *)&kmd->data.sys_properties; + sys_prop->prop_num = 7; + + sys_prop->prop_data[0].prop_type = EVA_KMD_PROP_PWR_FDU; + sys_prop->prop_data[0].data = + dsp2cpu_cmd->power_req.clock_fdu; + sys_prop->prop_data[1].prop_type = EVA_KMD_PROP_PWR_ICA; + sys_prop->prop_data[1].data = + dsp2cpu_cmd->power_req.clock_ica; + sys_prop->prop_data[2].prop_type = EVA_KMD_PROP_PWR_OD; + sys_prop->prop_data[2].data = + dsp2cpu_cmd->power_req.clock_od; + sys_prop->prop_data[3].prop_type = EVA_KMD_PROP_PWR_MPU; + sys_prop->prop_data[3].data = + dsp2cpu_cmd->power_req.clock_mpu; + sys_prop->prop_data[4].prop_type = EVA_KMD_PROP_PWR_FW; + sys_prop->prop_data[4].data = + dsp2cpu_cmd->power_req.clock_fw; + sys_prop->prop_data[5].prop_type = EVA_KMD_PROP_PWR_DDR; + sys_prop->prop_data[5].data = + dsp2cpu_cmd->power_req.bw_ddr; + sys_prop->prop_data[6].prop_type = EVA_KMD_PROP_PWR_SYSCACHE; + sys_prop->prop_data[6].data = + dsp2cpu_cmd->power_req.bw_sys_cache; + + rc = msm_cvp_handle_syscall(inst, kmd); + if (rc) { + dprintk(CVP_ERR, "%s Failed to set sys property\n", __func__); + cmd->ret = -1; + goto dsp_fail_power_req; + } + dprintk(CVP_DSP, "%s set sys property done part 1\n", __func__); + + /* EVA_KMD_SET_SYS_PROPERTY Round 2 */ + memset(kmd, 0, sizeof(struct eva_kmd_arg)); + kmd->type = EVA_KMD_SET_SYS_PROPERTY; + sys_prop = (struct eva_kmd_sys_properties *)&kmd->data.sys_properties; + sys_prop->prop_num = 7; + + sys_prop->prop_data[0].prop_type = EVA_KMD_PROP_PWR_FDU_OP; + sys_prop->prop_data[0].data = + dsp2cpu_cmd->power_req.op_clock_fdu; + sys_prop->prop_data[1].prop_type = EVA_KMD_PROP_PWR_ICA_OP; + sys_prop->prop_data[1].data = + dsp2cpu_cmd->power_req.op_clock_ica; + sys_prop->prop_data[2].prop_type = EVA_KMD_PROP_PWR_OD_OP; + sys_prop->prop_data[2].data = + dsp2cpu_cmd->power_req.op_clock_od; + sys_prop->prop_data[3].prop_type = EVA_KMD_PROP_PWR_MPU_OP; + sys_prop->prop_data[3].data = + dsp2cpu_cmd->power_req.op_clock_mpu; + sys_prop->prop_data[4].prop_type = EVA_KMD_PROP_PWR_FW_OP; + sys_prop->prop_data[4].data = + dsp2cpu_cmd->power_req.op_clock_fw; + sys_prop->prop_data[5].prop_type = EVA_KMD_PROP_PWR_DDR_OP; + sys_prop->prop_data[5].data = + dsp2cpu_cmd->power_req.op_bw_ddr; + sys_prop->prop_data[6].prop_type = EVA_KMD_PROP_PWR_SYSCACHE_OP; + sys_prop->prop_data[6].data = + dsp2cpu_cmd->power_req.op_bw_sys_cache; + + rc = msm_cvp_handle_syscall(inst, kmd); + if (rc) { + dprintk(CVP_ERR, "%s Failed to set sys property\n", __func__); + cmd->ret = -1; + goto dsp_fail_power_req; + } + dprintk(CVP_DSP, "%s set sys property done part 2\n", __func__); + + memset(kmd, 0, sizeof(struct eva_kmd_arg)); + kmd->type = EVA_KMD_UPDATE_POWER; + rc = msm_cvp_handle_syscall(inst, kmd); + if (rc) { + /* May need to define more error types + * Check UMD implementation here: + * https://opengrok.qualcomm.com/source/xref/LA.UM.9.14/vendor/qcom/proprietary/cv-noship/cvp/cpurev/src/cvpcpuRev_skel_imp_cvp2.cpp#380 + */ + dprintk(CVP_ERR, "%s Failed to send update power numbers\n", __func__); + cmd->ret = -1; + goto dsp_fail_power_req; + } + + dprintk(CVP_DSP, "%s DSP2CPU_POWER_REQUEST Done\n", __func__); +dsp_fail_power_req: + kfree(kmd); +} + +static void __dsp_cvp_buf_register(struct cvp_dsp_cmd_msg *cmd) +{ + struct cvp_dsp_apps *me = &gfa_cv; + struct msm_cvp_inst *inst; + struct eva_kmd_arg *kmd; + struct eva_kmd_buffer *kmd_buf; + int rc; + struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; + + cmd->ret = 0; + + dprintk(CVP_DSP, + "%s sess id 0x%x, low 0x%x, high 0x%x, pid 0x%x\n", + __func__, dsp2cpu_cmd->session_id, + dsp2cpu_cmd->session_cpu_low, + dsp2cpu_cmd->session_cpu_high, + dsp2cpu_cmd->pid); + + kmd = kzalloc(sizeof(*kmd), GFP_KERNEL); + if (!kmd) { + dprintk(CVP_ERR, "%s kzalloc failure\n", __func__); + cmd->ret = -1; + return; + } + + inst = (struct msm_cvp_inst *)ptr_dsp2cpu( + dsp2cpu_cmd->session_cpu_high, + dsp2cpu_cmd->session_cpu_low); + + kmd->type = EVA_KMD_REGISTER_BUFFER; + kmd_buf = (struct eva_kmd_buffer *)&(kmd->data.regbuf); + kmd_buf->type = EVA_KMD_BUFTYPE_INPUT; + kmd_buf->index = dsp2cpu_cmd->sbuf.index; + kmd_buf->fd = dsp2cpu_cmd->sbuf.fd; + kmd_buf->size = dsp2cpu_cmd->sbuf.size; + kmd_buf->offset = dsp2cpu_cmd->sbuf.offset; + kmd_buf->pixelformat = 0; + kmd_buf->flags = EVA_KMD_FLAG_UNSECURE; + + rc = msm_cvp_register_buffer_dsp(inst, kmd_buf, + dsp2cpu_cmd->pid, &cmd->sbuf.iova); + if (rc) { + dprintk(CVP_ERR, "%s Failed to register buffer\n", __func__); + cmd->ret = -1; + goto dsp_fail_buf_reg; + } + dprintk(CVP_DSP, "%s register buffer done\n", __func__); + + cmd->sbuf.size = kmd_buf->size; + cmd->sbuf.fd = kmd_buf->fd; + cmd->sbuf.index = kmd_buf->index; + cmd->sbuf.offset = kmd_buf->offset; + dprintk(CVP_DSP, "%s: fd %d, iova 0x%x\n", __func__, + cmd->sbuf.fd, cmd->sbuf.iova); +dsp_fail_buf_reg: + kfree(kmd); +} + +static void __dsp_cvp_buf_deregister(struct cvp_dsp_cmd_msg *cmd) +{ + struct cvp_dsp_apps *me = &gfa_cv; + struct msm_cvp_inst *inst; + struct eva_kmd_arg *kmd; + struct eva_kmd_buffer *kmd_buf; + int rc; + struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; + + cmd->ret = 0; + + dprintk(CVP_DSP, + "%s : sess id 0x%x, low 0x%x, high 0x%x, pid 0x%x\n", + __func__, dsp2cpu_cmd->session_id, + dsp2cpu_cmd->session_cpu_low, + dsp2cpu_cmd->session_cpu_high, + dsp2cpu_cmd->pid); + + kmd = kzalloc(sizeof(*kmd), GFP_KERNEL); + if (!kmd) { + dprintk(CVP_ERR, "%s kzalloc failure\n", __func__); + cmd->ret = -1; + return; + } + + inst = (struct msm_cvp_inst *)ptr_dsp2cpu( + dsp2cpu_cmd->session_cpu_high, + dsp2cpu_cmd->session_cpu_low); + + kmd->type = EVA_KMD_UNREGISTER_BUFFER; + kmd_buf = (struct eva_kmd_buffer *)&(kmd->data.regbuf); + kmd_buf->type = EVA_KMD_UNREGISTER_BUFFER; + + kmd_buf->type = EVA_KMD_BUFTYPE_INPUT; + kmd_buf->index = dsp2cpu_cmd->sbuf.index; + kmd_buf->fd = dsp2cpu_cmd->sbuf.fd; + kmd_buf->size = dsp2cpu_cmd->sbuf.size; + kmd_buf->offset = dsp2cpu_cmd->sbuf.offset; + kmd_buf->pixelformat = 0; + kmd_buf->flags = EVA_KMD_FLAG_UNSECURE; + + rc = msm_cvp_unregister_buffer_dsp(inst, kmd_buf); + if (rc) { + dprintk(CVP_ERR, "%s Failed to deregister buffer\n", __func__); + cmd->ret = -1; + goto fail_dsp_buf_dereg; + } + + dprintk(CVP_DSP, "%s deregister buffer done\n", __func__); +fail_dsp_buf_dereg: + kfree(kmd); +} + +static void __dsp_cvp_mem_alloc(struct cvp_dsp_cmd_msg *cmd) +{ + struct cvp_dsp_apps *me = &gfa_cv; + struct msm_cvp_inst *inst; + int rc; + struct cvp_internal_buf *buf = NULL; + struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; + uint64_t v_dsp_addr = 0; + +#ifdef FASTRPC_DRIVER_AVAILABLE + struct fastrpc_device *frpc_device = NULL; + struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; + struct msm_cvp_list *buf_list = NULL; +#endif + + cmd->ret = 0; + + dprintk(CVP_DSP, + "%s sess id 0x%x, low 0x%x, high 0x%x, pid 0x%x\n", + __func__, dsp2cpu_cmd->session_id, + dsp2cpu_cmd->session_cpu_low, + dsp2cpu_cmd->session_cpu_high, + dsp2cpu_cmd->pid); + +#ifdef FASTRPC_DRIVER_AVAILABLE + frpc_node = cvp_find_fastrpc_node_with_handle(dsp2cpu_cmd->pid); + if (!frpc_node) { + dprintk(CVP_ERR, "%s Failed to find fastrpc node 0x%x\n", + __func__, dsp2cpu_cmd->pid); + goto fail_fastrpc_node; + } + frpc_device = frpc_node->cvp_fastrpc_device; +#endif + + inst = (struct msm_cvp_inst *)ptr_dsp2cpu( + dsp2cpu_cmd->session_cpu_high, + dsp2cpu_cmd->session_cpu_low); + + buf = kzalloc(sizeof(*buf), GFP_KERNEL); + if (!buf) + goto fail_kzalloc_buf; + + rc = cvp_allocate_dsp_bufs(inst, buf, + dsp2cpu_cmd->sbuf.size, + dsp2cpu_cmd->sbuf.type); + if (rc != 0) + goto fail_allocate_dsp_buf; + +#ifdef FASTRPC_DRIVER_AVAILABLE + rc = eva_fastrpc_dev_map_dma(frpc_device, buf, + dsp2cpu_cmd->sbuf.dsp_remote_map, + &v_dsp_addr); +#endif + if (rc) { + dprintk(CVP_ERR, "%s Failed to map buffer 0x%x\n", __func__, + rc); + goto fail_fastrpc_dev_map_dma; + } +#ifdef FASTRPC_DRIVER_AVAILABLE + buf_list = &frpc_node->dspbufs; + mutex_lock(&buf_list->lock); + list_add_tail(&buf->list, &buf_list->list); + mutex_unlock(&buf_list->lock); +#endif + dprintk(CVP_DSP, "%s allocate buffer done, addr 0x%llx\n", + __func__, v_dsp_addr); + + cmd->sbuf.size = buf->smem->size; + cmd->sbuf.fd = buf->fd; + cmd->sbuf.offset = 0; + cmd->sbuf.iova = buf->smem->device_addr; + cmd->sbuf.v_dsp_addr = v_dsp_addr; + dprintk(CVP_DSP, "%s: size %d, iova 0x%x, v_dsp_addr 0x%llx\n", + __func__, cmd->sbuf.size, cmd->sbuf.iova, + cmd->sbuf.v_dsp_addr); + + return; + +fail_fastrpc_dev_map_dma: + cvp_release_dsp_buffers(inst, buf); +fail_allocate_dsp_buf: + kfree(buf); +fail_kzalloc_buf: +#ifdef FASTRPC_DRIVER_AVAILABLE +fail_fastrpc_node: +#endif + cmd->ret = -1; + return; + +} + +static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) +{ +#ifdef FASTRPC_DRIVER_AVAILABLE + struct cvp_dsp_apps *me = &gfa_cv; + struct msm_cvp_inst *inst; + int rc; + struct cvp_internal_buf *buf = NULL; + struct list_head *ptr = NULL, *next = NULL; + struct msm_cvp_list *buf_list = NULL; + struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; + + struct fastrpc_device *frpc_device = NULL; + struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; + + cmd->ret = 0; + + dprintk(CVP_DSP, + "%s sess id 0x%x, low 0x%x, high 0x%x, pid 0x%x\n", + __func__, dsp2cpu_cmd->session_id, + dsp2cpu_cmd->session_cpu_low, + dsp2cpu_cmd->session_cpu_high, + dsp2cpu_cmd->pid); + + inst = (struct msm_cvp_inst *)ptr_dsp2cpu( + dsp2cpu_cmd->session_cpu_high, + dsp2cpu_cmd->session_cpu_low); + + frpc_node = cvp_find_fastrpc_node_with_handle(dsp2cpu_cmd->pid); + if (!frpc_node) { + dprintk(CVP_ERR, "%s Failed to find fastrpc node 0x%x\n", + __func__, dsp2cpu_cmd->pid); + cmd->ret = -1; + return; + } + frpc_device = frpc_node->cvp_fastrpc_device; + + buf_list = &frpc_node->dspbufs; + mutex_lock(&buf_list->lock); + list_for_each_safe(ptr, next, &buf_list->list) { + buf = list_entry(ptr, struct cvp_internal_buf, list); + dprintk(CVP_DSP, "fd in list 0x%x, fd from dsp 0x%x\n", + buf->fd, dsp2cpu_cmd->sbuf.fd); + + if (!buf->smem) { + dprintk(CVP_DSP, "Empyt smem\n"); + continue; + } + + /* Verify with device addr */ + if (buf->smem->device_addr == dsp2cpu_cmd->sbuf.iova) { + dprintk(CVP_DSP, "%s find device addr 0x%x\n", + __func__, buf->smem->device_addr); + + rc = eva_fastrpc_dev_unmap_dma(frpc_device, buf); + if (rc) { + dprintk(CVP_ERR, + "%s Failed to unmap buffer 0x%x\n", + __func__, rc); + cmd->ret = -1; + goto fail_fastrpc_dev_unmap_dma; + } + + rc = cvp_release_dsp_buffers(inst, buf); + if (rc) { + dprintk(CVP_ERR, + "%s Failed to free buffer 0x%x\n", + __func__, rc); + cmd->ret = -1; + goto fail_release_buf; + } + + list_del(&buf->list); + + kfree(buf); + break; + } + } + +fail_release_buf: +fail_fastrpc_dev_unmap_dma: + mutex_unlock(&buf_list->lock); +#endif +} static int cvp_dsp_thread(void *data) { @@ -811,6 +1752,48 @@ wait_dsp: cmd.ret = 0; break; } + case DSP2CPU_CREATE_SESSION: + { + __dsp_cvp_sess_create(&cmd); + + break; + } + case DSP2CPU_DETELE_SESSION: + { + __dsp_cvp_sess_delete(&cmd); + + break; + } + case DSP2CPU_POWER_REQUEST: + { + __dsp_cvp_power_req(&cmd); + + break; + } + case DSP2CPU_REGISTER_BUFFER: + { + __dsp_cvp_buf_register(&cmd); + + break; + } + case DSP2CPU_DEREGISTER_BUFFER: + { + __dsp_cvp_buf_deregister(&cmd); + + break; + } + case DSP2CPU_MEM_ALLOC: + { + __dsp_cvp_mem_alloc(&cmd); + + break; + } + case DSP2CPU_MEM_FREE: + { + __dsp_cvp_mem_free(&cmd); + + break; + } default: dprintk(CVP_ERR, "unrecognaized dsp cmds: %d\n", me->pending_dsp2cpu_cmd.type); @@ -848,6 +1831,8 @@ int cvp_dsp_device_init(void) me->pending_dsp2cpu_cmd.type = CVP_INVALID_RPMSG_TYPE; me->pending_dsp2cpu_rsp.type = CVP_INVALID_RPMSG_TYPE; + INIT_MSM_CVP_LIST(&me->fastrpc_driver_list); + rc = register_rpmsg_driver(&cvp_dsp_rpmsg_client); if (rc) { dprintk(CVP_ERR, @@ -879,6 +1864,8 @@ void cvp_dsp_device_exit(void) me->state = DSP_INVALID; mutex_unlock(&me->lock); + DEINIT_MSM_CVP_LIST(&me->fastrpc_driver_list); + for (i = 0; i <= CPU2DSP_MAX_CMD; i++) complete_all(&me->completions[i]); diff --git a/msm/eva/msm_cvp_dsp.h b/msm/eva/msm_cvp_dsp.h index da926c0cf1..fd58f9a267 100644 --- a/msm/eva/msm_cvp_dsp.h +++ b/msm/eva/msm_cvp_dsp.h @@ -10,6 +10,16 @@ #include "msm_cvp_debug.h" #include "cvp_core_hfi.h" +#include +#include + +/*#define FASTRPC_DRIVER_AVAILABLE*/ + +#ifdef FASTRPC_DRIVER_AVAILABLE +#include +#endif + + #define CVP_APPS_DSP_GLINK_GUID "cvp-glink-apps-dsp" #define CVP_APPS_DSP_SMD_GUID "cvp-smd-apps-dsp" @@ -20,6 +30,17 @@ #define CVP_DSP2CPU_RESERVED 8 #define CVP_DSP_RESPONSE_TIMEOUT 300 #define CVP_INVALID_RPMSG_TYPE 0xBADDFACE +#define MAX_FRAME_BUF_NUM 16 + +#define BITPTRSIZE32 (4) +#define BITPTRSIZE64 (8) +#define HIGH32 (0xFFFFFFFF00000000LL) +#define LOW32 (0xFFFFFFFFLL) + + +/* Supports up to 8 DSP sessions in 4 processes */ +#define MAX_FASTRPC_DRIVER_NUM (4) +#define MAX_DSP_SESSION_NUM (8) int cvp_dsp_device_init(void); void cvp_dsp_device_exit(void); @@ -42,10 +63,56 @@ enum CVP_DSP_COMMAND { CPU2DSP_SHUTDOWN = 3, CPU2DSP_REGISTER_BUFFER = 4, CPU2DSP_DEREGISTER_BUFFER = 5, - CPU2DSP_MAX_CMD = 6, - DSP2CPU_POWERON = 6, - DSP2CPU_POWEROFF = 7, - CVP_DSP_MAX_CMD = 8, + CPU2DSP_INIT = 6, + CPU2DSP_SET_DEBUG_LEVEL = 7, + CPU2DSP_MAX_CMD = 8, + DSP2CPU_POWERON = 11, + DSP2CPU_POWEROFF = 12, + DSP2CPU_CREATE_SESSION = 13, + DSP2CPU_DETELE_SESSION = 14, + DSP2CPU_POWER_REQUEST = 15, + DSP2CPU_POWER_CANCEL = 16, + DSP2CPU_REGISTER_BUFFER = 17, + DSP2CPU_DEREGISTER_BUFFER = 18, + DSP2CPU_MEM_ALLOC = 19, + DSP2CPU_MEM_FREE = 20, + CVP_DSP_MAX_CMD = 21, +}; + +enum eva_dsp_debug_level { + EVA_PORT_INFO_ON = 0, + EVA_PORT_DEBUG_ON = 1, + EVA_QDI_INFO_ON = 2, + EVA_QDI_DEBUG_ON = 3, + EVA_MEM_DEBUG_ON = 4 +}; + +struct eva_power_req { + uint32_t clock_fdu; + uint32_t clock_ica; + uint32_t clock_od; + uint32_t clock_mpu; + uint32_t clock_fw; + uint32_t bw_ddr; + uint32_t bw_sys_cache; + uint32_t op_clock_fdu; + uint32_t op_clock_ica; + uint32_t op_clock_od; + uint32_t op_clock_mpu; + uint32_t op_clock_fw; + uint32_t op_bw_ddr; + uint32_t op_bw_sys_cache; +}; + +struct eva_mem_remote { + uint32_t type; + uint32_t size; + uint32_t fd; + uint32_t offset; + uint32_t index; + uint32_t iova; + uint32_t dsp_remote_map; + uint64_t v_dsp_addr; }; struct cvp_dsp_cmd_msg { @@ -61,6 +128,15 @@ struct cvp_dsp_cmd_msg { uint32_t buff_fd; uint32_t buff_offset; uint32_t buff_fd_size; + + uint32_t eva_dsp_debug_level; + + /* Create Session */ + uint32_t session_cpu_low; + uint32_t session_cpu_high; + + struct eva_mem_remote sbuf; + uint32_t reserved1; uint32_t reserved2; }; @@ -76,9 +152,38 @@ struct cvp_dsp2cpu_cmd_msg { uint32_t type; uint32_t ver; uint32_t len; + + /* Create Session */ + uint32_t session_type; + uint32_t kernel_mask; + uint32_t session_prio; + uint32_t is_secure; + uint32_t dsp_access_mask; + + uint32_t session_id; + uint32_t session_cpu_low; + uint32_t session_cpu_high; + int32_t pid; + struct eva_power_req power_req; + struct eva_mem_remote sbuf; + uint32_t data[CVP_DSP2CPU_RESERVED]; }; +struct cvp_dsp_fastrpc_driver_entry { + struct list_head list; + uint32_t handle; + uint32_t session_cnt; +#ifdef FASTRPC_DRIVER_AVAILABLE + struct fastrpc_driver cvp_fastrpc_driver; + struct fastrpc_device *cvp_fastrpc_device; +#endif + struct completion fastrpc_probe_completion; + struct msm_cvp_list dspbufs; + /* all dsp sessions list */ + struct msm_cvp_list dsp_session; +}; + struct cvp_dsp_apps { struct mutex lock; struct rpmsg_device *chan; @@ -90,6 +195,10 @@ struct cvp_dsp_apps { struct cvp_dsp2cpu_cmd_msg pending_dsp2cpu_cmd; struct cvp_dsp_rsp_msg pending_dsp2cpu_rsp; struct task_struct *dsp_thread; + /* dsp buffer mapping, set of dma function pointer */ + const struct file_operations *dmabuf_f_op; + uint32_t buf_num; + struct msm_cvp_list fastrpc_driver_list; }; extern struct cvp_dsp_apps gfa_cv; diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index efc64f0e05..4cc0a02404 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -93,11 +93,15 @@ static struct msm_cvp_common_data sm8450_common_data[] = { }, { .key = "qcom,dsp-resp-timeout", - .value = 1000 + .value = 1000, }, { .key = "qcom,debug-timeout", .value = 0, + }, + { + .key = "qcom,dsp-enabled", + .value = 0, } }; diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index 2ff704c8ca..c46ea1924b 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -727,6 +727,9 @@ int cvp_read_platform_resources_from_drv_data( res->auto_pil = find_key_value(platform_data, "qcom,auto-pil"); + res->dsp_enabled = find_key_value(platform_data, + "qcom,dsp-enabled"); + res->max_load = find_key_value(platform_data, "qcom,max-hw-load"); diff --git a/msm/eva/msm_cvp_resources.h b/msm/eva/msm_cvp_resources.h index ad254fb87f..3686bf0d2e 100644 --- a/msm/eva/msm_cvp_resources.h +++ b/msm/eva/msm_cvp_resources.h @@ -158,6 +158,7 @@ struct msm_cvp_platform_resources { bool use_non_secure_pil; bool sw_power_collapsible; bool auto_pil; + bool dsp_enabled; struct list_head context_banks; bool thermal_mitigable; const char *fw_name; diff --git a/msm/eva/msm_smem.c b/msm/eva/msm_smem.c index 6fe57762c4..86937f927e 100644 --- a/msm/eva/msm_smem.c +++ b/msm/eva/msm_smem.c @@ -16,6 +16,7 @@ #include "msm_cvp_debug.h" #include "msm_cvp_resources.h" #include "cvp_core_hfi.h" +#include "msm_cvp_dsp.h" static int msm_dma_get_device_address(struct dma_buf *dbuf, u32 align, @@ -277,6 +278,9 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, int map_kernel, if (flags & SMEM_NON_PIXEL) ion_flags |= ION_FLAG_CP_NON_PIXEL; + if (flags & SMEM_PIXEL) + ion_flags |= ION_FLAG_CP_PIXEL; + if (flags & SMEM_SECURE) { ion_flags |= ION_FLAG_SECURE; heap_mask = ION_HEAP(ION_SECURE_HEAP_ID); @@ -292,6 +296,9 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, int map_kernel, goto fail_shared_mem_alloc; } + if (!gfa_cv.dmabuf_f_op) + gfa_cv.dmabuf_f_op = (const struct file_operations *)dbuf->file->f_op; + mem->flags = flags; mem->ion_flags = ion_flags; mem->size = size; From 38aededca59569ece1d5ee6fc4290ea8f5af2994 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Thu, 21 Jan 2021 11:08:30 -0800 Subject: [PATCH 023/317] msm: eva: temp workaround to pass pid compilation commented pid to pass compilation due to missing symbol in whitelist Change-Id: I9607d649d7f6f1ae1eab01ec80cb9b020b4b2697 Signed-off-by: Yu SI --- msm/eva/msm_cvp_buf.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 785acd8b5c..7e41df0a65 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -303,8 +303,8 @@ int msm_cvp_map_buf_dsp_new(struct msm_cvp_inst *inst, struct cvp_hal_session *session; struct dma_buf *dma_buf = NULL; - struct pid *pid_s; - struct task_struct *task; + struct pid *pid_s = NULL; + struct task_struct *task = NULL; struct file *file; if (!inst || !inst->core || !buf) { @@ -345,14 +345,18 @@ int msm_cvp_map_buf_dsp_new(struct msm_cvp_inst *inst, return -EINVAL; } - pid_s = find_get_pid(pid); + // Temp workaround : commented for passing compilation due to missing dependency in AU whitelist +// pid_s = find_get_pid(pid); + + if (pid_s == NULL) { dprintk(CVP_WARN, "%s incorrect pid\n", __func__); return -EINVAL; } dprintk(CVP_WARN, "%s get pid_s 0x%x from pidA 0x%x\n", __func__, pid_s, pid); /* task = get_pid_task(pid, PIDTYPE_PID); */ - task = get_pid_task(pid_s, PIDTYPE_TGID); + // Temp workaround : commented for passing compilation due to missing dependency in AU whitelist +// task = get_pid_task(pid_s, PIDTYPE_TGID); if (!task) dprintk(CVP_WARN, "%s task doesn't exist\n", __func__); From d83b8480a6b95b930ce9ff751fc7557244b65554 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 21 Jan 2021 16:27:05 -0800 Subject: [PATCH 024/317] msm: eva: Support session creation via device node Support creating eva session via device node "boot". It helps pre-silicon and kbdev based EVA bring up test. Change-Id: I66f4ccf730817afd8f00f8ffeb286c7d89a69a65 Signed-off-by: George Shen --- msm/eva/cvp.c | 20 ++++++++++++++++++++ msm/eva/msm_cvp.c | 5 +---- msm/eva/msm_cvp.h | 1 + 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index 797c5c3dfe..e3303f070b 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -25,6 +25,7 @@ #include "cvp_private.h" #include "msm_cvp_clocks.h" #include "msm_cvp_dsp.h" +#include "msm_cvp.h" #define CLASS_NAME "cvp" #define DRIVER_NAME "cvp" @@ -272,6 +273,25 @@ static ssize_t boot_store(struct device *dev, "Failed to close cvp instance\n"); return rc; } + } else if ((val == 2) && booted) { + struct msm_cvp_inst *inst; + + inst = msm_cvp_open(MSM_CORE_CVP, MSM_CVP_USER); + if (!inst) { + dprintk(CVP_ERR, + "Failed to create eva instance\n"); + return -ENOMEM; + } + rc = msm_cvp_session_create(inst); + if (rc) + dprintk(CVP_ERR, "Failed to create eva session\n"); + + rc = msm_cvp_close(inst); + if (rc) { + dprintk(CVP_ERR, + "Failed to close eva instance\n"); + return rc; + } } booted = 1; return count; diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index f4c773e74e..85c1a2932b 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -1053,7 +1053,7 @@ static int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst, return rc; } -static int msm_cvp_session_create(struct msm_cvp_inst *inst) +int msm_cvp_session_create(struct msm_cvp_inst *inst) { int rc = 0; struct synx_initialization_params params; @@ -1884,9 +1884,6 @@ int msm_cvp_session_init(struct msm_cvp_inst *inst) inst->clk_data.sys_cache_bw = 1000; inst->prop.type = HFI_SESSION_CV; - if (inst->session_type == MSM_CVP_KERNEL) - inst->prop.type = HFI_SESSION_DMM; - inst->prop.kernel_mask = 0xFFFFFFFF; inst->prop.priority = 0; inst->prop.is_secure = 0; diff --git a/msm/eva/msm_cvp.h b/msm/eva/msm_cvp.h index 5750026b42..494c6eccda 100644 --- a/msm/eva/msm_cvp.h +++ b/msm/eva/msm_cvp.h @@ -33,5 +33,6 @@ int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct eva_kmd_arg *arg); int msm_cvp_session_init(struct msm_cvp_inst *inst); int msm_cvp_session_deinit(struct msm_cvp_inst *inst); int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst); +int msm_cvp_session_create(struct msm_cvp_inst *inst); int cvp_stop_clean_fence_queue(struct msm_cvp_inst *inst); #endif From d356d6fe7a74fc32dee54df5a192c08038d662bf Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 25 Jan 2021 19:57:35 -0800 Subject: [PATCH 025/317] msm: eva: Enable secure ARP Allocate secure buffer in kernel. Change-Id: I9f4411b45fe6cd2795da78ce2aee08ab1ea92973 Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 12 +++++------- msm/eva/msm_smem.c | 31 +++++++++++-------------------- 2 files changed, 16 insertions(+), 27 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 7e41df0a65..c61c5054df 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -345,8 +345,7 @@ int msm_cvp_map_buf_dsp_new(struct msm_cvp_inst *inst, return -EINVAL; } - // Temp workaround : commented for passing compilation due to missing dependency in AU whitelist -// pid_s = find_get_pid(pid); + pid_s = find_get_pid(pid); if (pid_s == NULL) { @@ -355,8 +354,7 @@ int msm_cvp_map_buf_dsp_new(struct msm_cvp_inst *inst, } dprintk(CVP_WARN, "%s get pid_s 0x%x from pidA 0x%x\n", __func__, pid_s, pid); /* task = get_pid_task(pid, PIDTYPE_PID); */ - // Temp workaround : commented for passing compilation due to missing dependency in AU whitelist -// task = get_pid_task(pid_s, PIDTYPE_TGID); + task = get_pid_task(pid_s, PIDTYPE_TGID); if (!task) dprintk(CVP_WARN, "%s task doesn't exist\n", __func__); @@ -1089,10 +1087,10 @@ struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, if (!buffer_size) return NULL; - /* PERSIST buffer requires secure mapping */ - /* Disable and wait for hyp_assign available - * smem_flags |= SMEM_SECURE | SMEM_NON_PIXEL; + /* PERSIST buffer requires secure mapping + * Disable and wait for hyp_assign available */ + smem_flags |= SMEM_SECURE | SMEM_NON_PIXEL; buf = kmem_cache_zalloc(cvp_driver->buf_cache, GFP_KERNEL); if (!buf) { diff --git a/msm/eva/msm_smem.c b/msm/eva/msm_smem.c index 86937f927e..b401a45561 100644 --- a/msm/eva/msm_smem.c +++ b/msm/eva/msm_smem.c @@ -244,7 +244,6 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, int map_kernel, struct msm_cvp_platform_resources *res, struct msm_cvp_smem *mem) { dma_addr_t iova = 0; - unsigned long heap_mask = 0; int rc = 0; int ion_flags = 0; struct dma_buf *dbuf = NULL; @@ -259,39 +258,31 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, int map_kernel, size = ALIGN(size, SZ_4K); if (is_iommu_present(res)) { - if (flags & SMEM_ADSP) { - dprintk(CVP_MEM, "Allocating from ADSP heap\n"); - heap_mask = ION_HEAP(ION_ADSP_HEAP_ID); - } else { - heap_mask = ION_HEAP(ION_SYSTEM_HEAP_ID); - } + heap = dma_heap_find("qcom,system"); + dprintk(CVP_MEM, "%s size %zx align %d flag %d\n", + __func__, size, align, flags); } else { - dprintk(CVP_MEM, - "allocate shared memory from adsp heap size %zx align %d\n", + dprintk(CVP_ERR, + "No IOMMU CB: allocate shared memory heap size %zx align %d\n", size, align); - heap_mask = ION_HEAP(ION_ADSP_HEAP_ID); } if (flags & SMEM_CACHED) ion_flags |= ION_FLAG_CACHED; - if (flags & SMEM_NON_PIXEL) + if (flags & SMEM_NON_PIXEL) { + heap = dma_heap_find("qcom,secure-non-pixel"); ion_flags |= ION_FLAG_CP_NON_PIXEL; - - if (flags & SMEM_PIXEL) + } else if (flags & SMEM_PIXEL) { + heap = dma_heap_find("qcom,secure-pixel"); ion_flags |= ION_FLAG_CP_PIXEL; - - if (flags & SMEM_SECURE) { - ion_flags |= ION_FLAG_SECURE; - heap_mask = ION_HEAP(ION_SECURE_HEAP_ID); } - heap = dma_heap_find("qcom,system"); dbuf = dma_heap_buffer_alloc(heap, size, 0, 0); if (IS_ERR_OR_NULL(dbuf)) { dprintk(CVP_ERR, - "Failed to allocate shared memory = %x bytes, %llx, %x %x\n", - size, heap_mask, ion_flags, PTR_ERR(dbuf)); + "Failed to allocate shared memory = %x bytes, %x %x\n", + size, ion_flags, PTR_ERR(dbuf)); rc = -ENOMEM; goto fail_shared_mem_alloc; } From bd3feaf6b0042bc86a0773d1414849c28fe8523d Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 2 Feb 2021 19:25:41 -0800 Subject: [PATCH 026/317] msm: eva: Update EVA IOMMU fault handler return Changes return value from -EINVAL to -ENOSYS to print debugging info. Change-Id: Ic80fa6a348eb132aa7c215eedd6c43ffeec8c818 Signed-off-by: George Shen --- msm/eva/msm_cvp_res_parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index c46ea1924b..4a9d87e278 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -941,7 +941,7 @@ int msm_cvp_smmu_fault_handler(struct iommu_domain *domain, * is not installed and prints a list of useful debug information like * FAR, SID etc. This information is not printed if we return 0. */ - return -EINVAL; + return -ENOSYS; } static int msm_cvp_populate_context_bank(struct device *dev, From 5af2b7ae7706ebf96a55eb439e01c5e596ddb02f Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 4 Feb 2021 12:22:12 -0800 Subject: [PATCH 027/317] msm: eva: Support Optical Flow in kernel Add OF related command type for error checks. Clean up un-used signals. Change-Id: I2489f3fc87feb86468b24659e6752b130e2cc54d Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 30 +++++++++++++++++++++++------- msm/eva/cvp_hfi_api.h | 7 +------ msm/eva/hfi_response_handler.c | 1 + msm/eva/msm_cvp_common.c | 7 +------ msm/eva/msm_cvp_debug.h | 2 +- msm/eva/msm_cvp_synx.c | 2 +- 6 files changed, 28 insertions(+), 21 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 7eab779952..c6e69b9f0b 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -50,6 +50,20 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[] = { .buf_num = HFI_DFS_BUF_NUM, .resp = HAL_NO_RESP, }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_SGM_OF_CONFIG, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_SESSION_SGM_OF_CONFIG_CMD_DONE, + }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_SGM_OF_FRAME, + .buf_offset = 0, + .buf_num = 0, + .resp = HAL_NO_RESP, + }, { .size = 0xFFFFFFFF, .type = HFI_CMD_SESSION_CVP_WARP_NCC_CONFIG, @@ -2947,6 +2961,7 @@ static void **get_session_id(struct msm_cvp_cb_info *info) case HAL_SESSION_DMM_CONFIG_CMD_DONE: case HAL_SESSION_WARP_CONFIG_CMD_DONE: case HAL_SESSION_WARP_NCC_CONFIG_CMD_DONE: + case HAL_SESSION_SGM_OF_CONFIG_CMD_DONE: case HAL_SESSION_TME_CONFIG_CMD_DONE: case HAL_SESSION_ODT_CONFIG_CMD_DONE: case HAL_SESSION_OD_CONFIG_CMD_DONE: @@ -2958,12 +2973,6 @@ static void **get_session_id(struct msm_cvp_cb_info *info) case HAL_SESSION_PYS_HCD_CONFIG_CMD_DONE: case HAL_SESSION_DMM_PARAMS_CMD_DONE: case HAL_SESSION_WARP_DS_PARAMS_CMD_DONE: - case HAL_SESSION_DFS_FRAME_CMD_DONE: - case HAL_SESSION_DMM_FRAME_CMD_DONE: - case HAL_SESSION_WARP_FRAME_CMD_DONE: - case HAL_SESSION_WARP_NCC_FRAME_CMD_DONE: - case HAL_SESSION_ICA_FRAME_CMD_DONE: - case HAL_SESSION_FD_FRAME_CMD_DONE: case HAL_SESSION_PERSIST_SET_DONE: case HAL_SESSION_PERSIST_REL_DONE: case HAL_SESSION_FD_CONFIG_CMD_DONE: @@ -3128,6 +3137,7 @@ static void iris_hfi_core_work_handler(struct work_struct *work) struct iris_hfi_device *device; int num_responses = 0, i = 0; u32 intr_status; + static bool warning_on = true; core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); if (core) @@ -3139,10 +3149,16 @@ static void iris_hfi_core_work_handler(struct work_struct *work) if (!__core_in_valid_state(device)) { - dprintk(CVP_WARN, "%s - Core not in init state\n", __func__); + if (warning_on) { + dprintk(CVP_WARN, "%s Core not in init state\n", + __func__); + warning_on = false; + } goto err_no_work; } + warning_on = true; + if (!device->callback) { dprintk(CVP_ERR, "No interrupt callback function: %pK\n", device); diff --git a/msm/eva/cvp_hfi_api.h b/msm/eva/cvp_hfi_api.h index 6960b5ffb3..983326f459 100644 --- a/msm/eva/cvp_hfi_api.h +++ b/msm/eva/cvp_hfi_api.h @@ -210,16 +210,13 @@ enum hal_command_response { HAL_SESSION_REGISTER_BUFFER_DONE, HAL_SESSION_UNREGISTER_BUFFER_DONE, HAL_SESSION_RELEASE_RESOURCE_DONE, + HAL_SESSION_SGM_OF_CONFIG_CMD_DONE, HAL_SESSION_DFS_CONFIG_CMD_DONE, - HAL_SESSION_DFS_FRAME_CMD_DONE, HAL_SESSION_DMM_CONFIG_CMD_DONE, HAL_SESSION_DMM_PARAMS_CMD_DONE, - HAL_SESSION_DMM_FRAME_CMD_DONE, HAL_SESSION_WARP_CONFIG_CMD_DONE, HAL_SESSION_WARP_DS_PARAMS_CMD_DONE, - HAL_SESSION_WARP_FRAME_CMD_DONE, HAL_SESSION_WARP_NCC_CONFIG_CMD_DONE, - HAL_SESSION_WARP_NCC_FRAME_CMD_DONE, HAL_SESSION_TME_CONFIG_CMD_DONE, HAL_SESSION_ODT_CONFIG_CMD_DONE, HAL_SESSION_OD_CONFIG_CMD_DONE, @@ -233,8 +230,6 @@ enum hal_command_response { HAL_SESSION_PERSIST_SET_DONE, HAL_SESSION_PERSIST_REL_DONE, HAL_SESSION_MODEL_BUF_CMD_DONE, - HAL_SESSION_ICA_FRAME_CMD_DONE, - HAL_SESSION_FD_FRAME_CMD_DONE, HAL_SESSION_PROPERTY_INFO, HAL_SESSION_ERROR, HAL_RESPONSE_UNUSED = 0x10000000, diff --git a/msm/eva/hfi_response_handler.c b/msm/eva/hfi_response_handler.c index 8dac742e41..74a8f6093b 100644 --- a/msm/eva/hfi_response_handler.c +++ b/msm/eva/hfi_response_handler.c @@ -673,6 +673,7 @@ int cvp_hfi_process_msg_packet(u32 device_id, void *hdr, case HFI_MSG_SESSION_CVP_WARP: case HFI_MSG_SESSION_CVP_WARP_NCC: case HFI_MSG_SESSION_CVP_FD: + case HFI_MSG_SESSION_CVP_SGM_OF: pkt_func = (pkt_func_def)hfi_process_session_cvp_msg; break; default: diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 1e67249153..1579adad39 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -792,16 +792,13 @@ void cvp_handle_cmd_response(enum hal_command_response cmd, void *data) case HAL_SESSION_RELEASE_BUFFER_DONE: handle_session_release_buf_done(cmd, data); break; + case HAL_SESSION_SGM_OF_CONFIG_CMD_DONE: case HAL_SESSION_DFS_CONFIG_CMD_DONE: - case HAL_SESSION_DFS_FRAME_CMD_DONE: case HAL_SESSION_DMM_CONFIG_CMD_DONE: case HAL_SESSION_DMM_PARAMS_CMD_DONE: - case HAL_SESSION_DMM_FRAME_CMD_DONE: case HAL_SESSION_WARP_CONFIG_CMD_DONE: case HAL_SESSION_WARP_DS_PARAMS_CMD_DONE: - case HAL_SESSION_WARP_FRAME_CMD_DONE: case HAL_SESSION_WARP_NCC_CONFIG_CMD_DONE: - case HAL_SESSION_WARP_NCC_FRAME_CMD_DONE: case HAL_SESSION_PERSIST_SET_DONE: case HAL_SESSION_PERSIST_REL_DONE: case HAL_SESSION_TME_CONFIG_CMD_DONE: @@ -815,8 +812,6 @@ void cvp_handle_cmd_response(enum hal_command_response cmd, void *data) case HAL_SESSION_PYS_HCD_CONFIG_CMD_DONE: case HAL_SESSION_FD_CONFIG_CMD_DONE: case HAL_SESSION_MODEL_BUF_CMD_DONE: - case HAL_SESSION_ICA_FRAME_CMD_DONE: - case HAL_SESSION_FD_FRAME_CMD_DONE: cvp_handle_session_cmd_done(cmd, data); break; default: diff --git a/msm/eva/msm_cvp_debug.h b/msm/eva/msm_cvp_debug.h index 05f60007d1..d3e804a3d0 100644 --- a/msm/eva/msm_cvp_debug.h +++ b/msm/eva/msm_cvp_debug.h @@ -38,7 +38,7 @@ enum cvp_msg_prio { CVP_SESS = 0x002000, CVP_HFI = 0x004000, CVP_DBG = CVP_MEM | CVP_SYNX | CVP_CORE | CVP_REG | - CVP_PWR | CVP_DSP | CVP_SESS | CVP_HFI, + CVP_PWR | CVP_DSP | CVP_SESS | CVP_HFI | CVP_PKT, }; enum cvp_msg_out { diff --git a/msm/eva/msm_cvp_synx.c b/msm/eva/msm_cvp_synx.c index eb1f6b3e4d..07f294f8c2 100644 --- a/msm/eva/msm_cvp_synx.c +++ b/msm/eva/msm_cvp_synx.c @@ -166,7 +166,7 @@ static int cvp_wait_synx(struct synx_session ssid, u32 *synx, u32 num_synx, u32 *synx_state) { int i = 0, rc = 0; - unsigned long timeout_ms = 2000; //1000; + unsigned long timeout_ms = 2000; int h_synx; while (i < num_synx) { From b4179128026b9f13a139076bc1d3f0eab7e6adf2 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 8 Feb 2021 15:56:24 -0800 Subject: [PATCH 028/317] msm: eva: Update rpmsg cdsp edge name Needs to use correct edge for CPU to CDSP glink. Change-Id: Ie9117453454e13830987202d3629855b3c81c811 Signed-off-by: George Shen --- msm/eva/msm_cvp_core.h | 5 +++++ msm/eva/msm_cvp_dsp.c | 24 +++++++++++++++++------- msm/eva/msm_cvp_platform.c | 5 ----- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/msm/eva/msm_cvp_core.h b/msm/eva/msm_cvp_core.h index 0208dd8c04..b94447c60e 100644 --- a/msm/eva/msm_cvp_core.h +++ b/msm/eva/msm_cvp_core.h @@ -16,6 +16,11 @@ #include "msm_cvp_buf.h" #include "msm_cvp_synx.h" +#define DDR_TYPE_LPDDR4 0x6 +#define DDR_TYPE_LPDDR4X 0x7 +#define DDR_TYPE_LPDDR4Y 0x8 +#define DDR_TYPE_LPDDR5 0x9 + enum core_id { MSM_CORE_CVP = 0, MSM_CVP_CORES_MAX, diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 3ee71d7991..7e2ad4b62f 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -85,10 +85,11 @@ static int cvp_dsp_send_cmd_hfi_queue(phys_addr_t *phys_addr, cmd.msg_ptr_len = size_in_bytes; cmd.ddr_type = of_fdt_get_ddrtype(); if (cmd.ddr_type < 0) { - dprintk(CVP_ERR, - "%s: Incorrect DDR type value %d\n", - __func__, cmd.ddr_type); - return -EINVAL; + dprintk(CVP_WARN, + "%s: Incorrect DDR type value %d, use default %d\n", + __func__, cmd.ddr_type, DDR_TYPE_LPDDR5); + /*return -EINVAL;*/ + cmd.ddr_type = DDR_TYPE_LPDDR5; } dprintk(CVP_DSP, @@ -149,11 +150,20 @@ static int cvp_hyp_assign_from_dsp(void) static int cvp_dsp_rpmsg_probe(struct rpmsg_device *rpdev) { struct cvp_dsp_apps *me = &gfa_cv; + const char *edge_name = NULL; + int ret = 0; - if (strcmp(rpdev->dev.parent->of_node->name, "cdsp")) { + ret = of_property_read_string(rpdev->dev.parent->of_node, + "label", &edge_name); + if (ret) { + dprintk(CVP_ERR, "glink edge 'label' not found in node\n"); + return ret; + } + + if (strcmp(edge_name, "cdsp")) { dprintk(CVP_ERR, "%s: Failed to probe rpmsg device.Node name:%s\n", - __func__, rpdev->dev.parent->of_node->name); + __func__, edge_name); return -EINVAL; } @@ -163,7 +173,7 @@ static int cvp_dsp_rpmsg_probe(struct rpmsg_device *rpdev) complete(&me->completions[CPU2DSP_MAX_CMD]); mutex_unlock(&me->lock); - return 0; + return ret; } static void cvp_dsp_rpmsg_remove(struct rpmsg_device *rpdev) diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 4cc0a02404..2351c3d952 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -19,11 +19,6 @@ #include "msm_cvp_internal.h" #include "msm_cvp_debug.h" -#define DDR_TYPE_LPDDR4 0x6 -#define DDR_TYPE_LPDDR4X 0x7 -#define DDR_TYPE_LPDDR4Y 0x8 -#define DDR_TYPE_LPDDR5 0x9 - #define UBWC_CONFIG(mco, mlo, hbo, bslo, bso, rs, mc, ml, hbb, bsl, bsp) \ { \ .override_bit_info.max_channel_override = mco, \ From db00dd2137649d265f7cb6f10948b586305bf146 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Mon, 8 Feb 2021 17:41:05 -0800 Subject: [PATCH 029/317] msm: eva: enable DSP and fastRPC enable DSP and fastRPC driver Change-Id: I0f732dea09ab3e39dce617797e644f1592cbbf87 Signed-off-by: Yu SI --- msm/eva/msm_cvp_dsp.h | 2 +- msm/eva/msm_cvp_platform.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/eva/msm_cvp_dsp.h b/msm/eva/msm_cvp_dsp.h index fd58f9a267..10ffb4b04c 100644 --- a/msm/eva/msm_cvp_dsp.h +++ b/msm/eva/msm_cvp_dsp.h @@ -13,7 +13,7 @@ #include #include -/*#define FASTRPC_DRIVER_AVAILABLE*/ +#define FASTRPC_DRIVER_AVAILABLE #ifdef FASTRPC_DRIVER_AVAILABLE #include diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 2351c3d952..55287382d7 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -96,7 +96,7 @@ static struct msm_cvp_common_data sm8450_common_data[] = { }, { .key = "qcom,dsp-enabled", - .value = 0, + .value = 1, } }; From 6f2d4b9361f846bef8b6cca0152b678c2051b577 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 17 Feb 2021 23:42:14 -0800 Subject: [PATCH 030/317] msm: eva: enhance DSP session resource management Improve debugability and error handling in future. Change-Id: I4f116e106f243143f4f62eb28fbf338e219018c6 Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 46 ++++++--- msm/eva/msm_cvp_buf.h | 1 + msm/eva/msm_cvp_core.c | 3 + msm/eva/msm_cvp_core.h | 1 + msm/eva/msm_cvp_dsp.c | 192 ++++++++++++++++++++----------------- msm/eva/msm_cvp_dsp.h | 15 +-- msm/eva/msm_cvp_internal.h | 2 + 7 files changed, 148 insertions(+), 112 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index c61c5054df..4132f645d0 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1011,17 +1011,30 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) mutex_unlock(&inst->dma_cache.lock); mutex_lock(&inst->cvpdspbufs.lock); - list_for_each_entry_safe(cbuf, dummy, &inst->cvpdspbufs.list, - list) { + list_for_each_entry_safe(cbuf, dummy, &inst->cvpdspbufs.list, list) { print_internal_buffer(CVP_MEM, "remove dspbufs", inst, cbuf); - rc = cvp_dsp_deregister_buffer(hash32_ptr(session), - cbuf->fd, cbuf->smem->dma_buf->size, cbuf->size, - cbuf->offset, cbuf->index, - (uint32_t)cbuf->smem->device_addr); - if (rc) - dprintk(CVP_ERR, + if (cbuf->ownership == CLIENT) { + rc = cvp_dsp_deregister_buffer(hash32_ptr(session), + cbuf->fd, cbuf->smem->dma_buf->size, cbuf->size, + cbuf->offset, cbuf->index, + (uint32_t)cbuf->smem->device_addr); + if (rc) + dprintk(CVP_ERR, "%s: failed dsp deregistration fd=%d rc=%d", __func__, cbuf->fd, rc); + } else if (cbuf->ownership == DSP) { + rc = cvp_dsp_fastrpc_unmap(inst->process_id, cbuf); + if (rc) + dprintk(CVP_ERR, + "%s: failed to unmap buf from DSP\n", + __func__); + + rc = cvp_release_dsp_buffers(inst, cbuf); + if (rc) + dprintk(CVP_ERR, + "%s Fail to free buffer 0x%x\n", + __func__, rc); + } msm_cvp_unmap_smem(inst, cbuf->smem, "unmap dsp"); msm_cvp_smem_put_dma_buf(cbuf->smem->dma_buf); @@ -1232,7 +1245,7 @@ int cvp_allocate_dsp_bufs(struct msm_cvp_inst *inst, return -EINVAL; } - dprintk(CVP_ERR, "%s smem_flags 0x%x\n", __func__, smem_flags); + dprintk(CVP_MEM, "%s smem_flags 0x%x\n", __func__, smem_flags); buf->smem = kmem_cache_zalloc(cvp_driver->smem_cache, GFP_KERNEL); if (!buf->smem) { dprintk(CVP_ERR, "%s Out of memory\n", __func__); @@ -1246,11 +1259,11 @@ int cvp_allocate_dsp_bufs(struct msm_cvp_inst *inst, goto err_no_mem; } - dprintk(CVP_ERR, "%s dma_buf %pK\n", __func__, buf->smem->dma_buf); + dprintk(CVP_MEM, "%s dma_buf %pK\n", __func__, buf->smem->dma_buf); buf->size = buf->smem->size; buf->type = HFI_BUFFER_INTERNAL_PERSIST_1; - buf->ownership = CLIENT; + buf->ownership = DSP; return rc; @@ -1282,13 +1295,18 @@ int cvp_release_dsp_buffers(struct msm_cvp_inst *inst, return -EINVAL; } - if (buf->ownership == CLIENT) { + if (buf->ownership == DSP) { dprintk(CVP_MEM, - "%s: %x : fd %x %s size %d", - "free dsp buf", hash32_ptr(inst->session), buf->fd, + "%s: %x : fd %x %s size %d", + __func__, hash32_ptr(inst->session), buf->fd, smem->dma_buf->name, buf->size); msm_cvp_smem_free(smem); kmem_cache_free(cvp_driver->smem_cache, smem); + } else { + dprintk(CVP_ERR, + "%s: wrong owner %d %x : fd %x %s size %d", + __func__, buf->ownership, hash32_ptr(inst->session), + buf->fd, smem->dma_buf->name, buf->size); } return rc; diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index c46d4177af..036ebedca3 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -113,6 +113,7 @@ enum buffer_owner { DRIVER, FIRMWARE, CLIENT, + DSP, MAX_OWNER }; diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index a52327ff92..4e602ac245 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -382,6 +382,9 @@ int msm_cvp_close(void *instance) msm_cvp_comm_session_clean(inst); + if (inst->session_type == MSM_CVP_DSP) + cvp_dsp_del_sess(inst->process_id, inst); + kref_put(&inst->kref, close_helper); return 0; } diff --git a/msm/eva/msm_cvp_core.h b/msm/eva/msm_cvp_core.h index b94447c60e..91ecce975a 100644 --- a/msm/eva/msm_cvp_core.h +++ b/msm/eva/msm_cvp_core.h @@ -30,6 +30,7 @@ enum session_type { MSM_CVP_USER = 1, MSM_CVP_KERNEL, MSM_CVP_BOOT, + MSM_CVP_DSP, MSM_CVP_UNKNOWN, MSM_CVP_MAX_DEVICES = MSM_CVP_UNKNOWN, }; diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 7e2ad4b62f..bf70cd080a 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -644,7 +644,6 @@ static int cvp_reinit_dsp(void) return rc; } -#ifdef FASTRPC_DRIVER_AVAILABLE static struct cvp_dsp_fastrpc_driver_entry *cvp_find_fastrpc_node_with_handle( uint32_t handle) { @@ -667,9 +666,7 @@ static struct cvp_dsp_fastrpc_driver_entry *cvp_find_fastrpc_node_with_handle( return frpc_node; } -static void eva_fastrpc_driver_unregister(struct msm_cvp_inst *inst, - uint32_t handle, - bool force_exit); +static void eva_fastrpc_driver_unregister(uint32_t handle, bool force_exit); static int cvp_fastrpc_probe(struct fastrpc_device *rpc_dev) { @@ -769,11 +766,81 @@ static int eva_fastrpc_dev_unmap_dma(struct fastrpc_device *frpc_device, return rc; } +static void eva_fastrpc_driver_add_sess( + struct cvp_dsp_fastrpc_driver_entry *frpc, + struct msm_cvp_inst *inst) +{ + mutex_lock(&frpc->dsp_sessions.lock); + if (inst) + list_add_tail(&inst->dsp_list, &frpc->dsp_sessions.list); + else + dprintk(CVP_ERR, "%s incorrect input %pK\n", __func__, inst); + frpc->session_cnt++; + mutex_unlock(&frpc->dsp_sessions.lock); + dprintk(CVP_DSP, "add dsp sess %pK fastrpc_driver %pK\n", inst, frpc); +} + +int cvp_dsp_fastrpc_unmap(uint32_t process_id, struct cvp_internal_buf *buf) +{ + struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; + struct fastrpc_device *frpc_device = NULL; + int rc = 0; + + frpc_node = cvp_find_fastrpc_node_with_handle(process_id); + if (!frpc_node) { + dprintk(CVP_ERR, "%s no frpc node for process id %d\n", + __func__, process_id); + return -EINVAL; + } + frpc_device = frpc_node->cvp_fastrpc_device; + rc = eva_fastrpc_dev_unmap_dma(frpc_device, buf); + if (rc) { + dprintk(CVP_ERR, + "%s Fail to unmap buffer 0x%x\n", + __func__, rc); + return rc; + } + + return rc; +} + +int cvp_dsp_del_sess(uint32_t process_id, struct msm_cvp_inst *inst) +{ + struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; + struct list_head *ptr = NULL, *next = NULL; + struct msm_cvp_inst *sess; + bool found = false; + + frpc_node = cvp_find_fastrpc_node_with_handle(process_id); + if (!frpc_node) { + dprintk(CVP_ERR, "%s no frpc node for process id %d\n", + __func__, process_id); + return -EINVAL; + } + mutex_lock(&frpc_node->dsp_sessions.lock); + list_for_each_safe(ptr, next, &frpc_node->dsp_sessions.list) { + sess = list_entry(ptr, struct msm_cvp_inst, list); + if (sess == inst) { + dprintk(CVP_DSP, "%s Find sess %pK to be deleted\n", + __func__, inst); + found = true; + break; + } + } + if (found) { + list_del(&inst->dsp_list); + frpc_node->session_cnt--; + } + + mutex_unlock(&frpc_node->dsp_sessions.lock); + + return 0; +} + static int eva_fastrpc_driver_register(uint32_t handle) { struct cvp_dsp_apps *me = &gfa_cv; int rc = 0; - //struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; frpc_node = cvp_find_fastrpc_node_with_handle(handle); @@ -795,6 +862,7 @@ static int eva_fastrpc_driver_register(uint32_t handle) dprintk(CVP_DSP, "Add frpc node 0x%x to list\n", frpc_node); list_add_tail(&frpc_node->list, &me->fastrpc_driver_list.list); mutex_unlock(&me->fastrpc_driver_list.lock); + INIT_MSM_CVP_LIST(&frpc_node->dsp_sessions); /* register fastrpc device to this session */ frpc_node->handle = handle; @@ -815,13 +883,8 @@ static int eva_fastrpc_driver_register(uint32_t handle) __func__); goto fail_fastrpc_driver_timeout; } - - /* initialize dspbuf list */ - INIT_MSM_CVP_LIST(&frpc_node->dspbufs); } - frpc_node->session_cnt++; - return rc; fail_fastrpc_driver_timeout: @@ -835,18 +898,11 @@ fail_fastrpc_driver_register: return -EINVAL; } -static void eva_fastrpc_driver_unregister(struct msm_cvp_inst *inst, - uint32_t handle, - bool force_exit) +static void eva_fastrpc_driver_unregister(uint32_t handle, bool force_exit) { struct cvp_dsp_apps *me = &gfa_cv; - struct list_head *ptr = NULL, *next = NULL; struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; - struct msm_cvp_list *buf_list = NULL; - struct cvp_internal_buf *buf = NULL; - struct fastrpc_device *frpc_device = NULL; struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; - int rc = 0; dprintk(CVP_DSP, "%s Unregister fastrpc driver handle 0x%x, force %d\n", __func__, handle, (uint32_t)force_exit); @@ -857,48 +913,11 @@ static void eva_fastrpc_driver_unregister(struct msm_cvp_inst *inst, if (frpc_node == NULL) return; - frpc_node->session_cnt--; - if ((frpc_node->session_cnt == 0) || force_exit) { dprintk(CVP_DSP, "%s session cnt %d, force %d\n", __func__, frpc_node->session_cnt, (uint32_t)force_exit); - //Free any left over buffers - ptr = NULL; - next = NULL; - buf_list = &frpc_node->dspbufs; - mutex_lock(&buf_list->lock); - list_for_each_safe(ptr, next, &buf_list->list) { - buf = list_entry(ptr, struct cvp_internal_buf, list); - if (!buf->smem) { - dprintk(CVP_DSP, "%s Empyt smem\n", __func__); - list_del(&buf->list); - kfree(buf); - continue; - } - - rc = eva_fastrpc_dev_unmap_dma(frpc_device, buf); - if (rc) { - dprintk(CVP_ERR, - "%s Fail to unmap buffer 0x%x\n", - __func__, rc); - continue; - } - - rc = cvp_release_dsp_buffers(inst, buf); - if (rc) { - dprintk(CVP_ERR, - "%s Fail to free buffer 0x%x\n", - __func__, rc); - continue; - } - - list_del(&buf->list); - kfree(buf); - } - mutex_unlock(&buf_list->lock); - - DEINIT_MSM_CVP_LIST(&frpc_node->dspbufs); + DEINIT_MSM_CVP_LIST(&frpc_node->dsp_sessions); /* remove list if this is the last session */ mutex_lock(&me->fastrpc_driver_list.lock); @@ -910,8 +929,6 @@ static void eva_fastrpc_driver_unregister(struct msm_cvp_inst *inst, } } -#endif - void cvp_dsp_send_hfi_queue(void) { struct msm_cvp_core *core; @@ -1123,6 +1140,7 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) struct eva_kmd_session_control *sys_ctrl = NULL; int rc = 0; struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; + struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; cmd->ret = 0; @@ -1140,20 +1158,19 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) goto fail_frpc_driver_reg; } -#ifdef FASTRPC_DRIVER_AVAILABLE rc = eva_fastrpc_driver_register(dsp2cpu_cmd->pid); -#endif if (rc) { dprintk(CVP_ERR, "%s Register fastrpc driver fail\n", __func__); goto fail_frpc_driver_reg; } - inst = msm_cvp_open(MSM_CORE_CVP, MSM_CVP_USER); + inst = msm_cvp_open(MSM_CORE_CVP, MSM_CVP_DSP); if (!inst) { dprintk(CVP_ERR, "%s Failed create instance\n", __func__); goto fail_msm_cvp_open; } + inst->process_id = dsp2cpu_cmd->pid; kmd->type = EVA_KMD_SET_SYS_PROPERTY; sys_prop = (struct eva_kmd_sys_properties *)&kmd->data.sys_properties; sys_prop->prop_num = 5; @@ -1205,6 +1222,10 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) cmd->session_cpu_high = (uint32_t)((inst_handle & HIGH32) >> 32); cmd->session_cpu_low = (uint32_t)(inst_handle & LOW32); + frpc_node = cvp_find_fastrpc_node_with_handle(dsp2cpu_cmd->pid); + if (frpc_node) + eva_fastrpc_driver_add_sess(frpc_node, inst); + dprintk(CVP_DSP, "%s CREATE_SESS id 0x%x, cpu_low 0x%x, cpu_high 0x%x\n", __func__, cmd->session_id, cmd->session_cpu_low, @@ -1231,6 +1252,7 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) struct eva_kmd_session_control *sys_ctrl; int rc; struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; + struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; cmd->ret = 0; @@ -1241,6 +1263,14 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->pid); + frpc_node = cvp_find_fastrpc_node_with_handle(dsp2cpu_cmd->pid); + if (!frpc_node) { + dprintk(CVP_ERR, "%s pid 0x%x not registered with fastrpc\n", + __func__, dsp2cpu_cmd->pid); + cmd->ret = -1; + return; + } + kmd = kzalloc(sizeof(*kmd), GFP_KERNEL); if (!kmd) { dprintk(CVP_ERR, "%s kzalloc failure\n", __func__); @@ -1252,11 +1282,6 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->session_cpu_low); -#ifdef FASTRPC_DRIVER_AVAILABLE - /* unregister fastrpc driver */ - eva_fastrpc_driver_unregister(inst, dsp2cpu_cmd->pid, false); -#endif - kmd->type = EVA_KMD_SESSION_CONTROL; sys_ctrl = (struct eva_kmd_session_control *)&kmd->data.session_ctrl; @@ -1277,6 +1302,9 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) goto dsp_fail_delete; } + /* unregister fastrpc driver */ + eva_fastrpc_driver_unregister(dsp2cpu_cmd->pid, false); + dprintk(CVP_DSP, "%s DSP2CPU_DETELE_SESSION Done\n", __func__); dsp_fail_delete: kfree(kmd); @@ -1523,11 +1551,8 @@ static void __dsp_cvp_mem_alloc(struct cvp_dsp_cmd_msg *cmd) struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; uint64_t v_dsp_addr = 0; -#ifdef FASTRPC_DRIVER_AVAILABLE struct fastrpc_device *frpc_device = NULL; struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; - struct msm_cvp_list *buf_list = NULL; -#endif cmd->ret = 0; @@ -1538,7 +1563,6 @@ static void __dsp_cvp_mem_alloc(struct cvp_dsp_cmd_msg *cmd) dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->pid); -#ifdef FASTRPC_DRIVER_AVAILABLE frpc_node = cvp_find_fastrpc_node_with_handle(dsp2cpu_cmd->pid); if (!frpc_node) { dprintk(CVP_ERR, "%s Failed to find fastrpc node 0x%x\n", @@ -1546,38 +1570,34 @@ static void __dsp_cvp_mem_alloc(struct cvp_dsp_cmd_msg *cmd) goto fail_fastrpc_node; } frpc_device = frpc_node->cvp_fastrpc_device; -#endif inst = (struct msm_cvp_inst *)ptr_dsp2cpu( dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->session_cpu_low); - buf = kzalloc(sizeof(*buf), GFP_KERNEL); + buf = kmem_cache_zalloc(cvp_driver->buf_cache, GFP_KERNEL); if (!buf) goto fail_kzalloc_buf; rc = cvp_allocate_dsp_bufs(inst, buf, dsp2cpu_cmd->sbuf.size, dsp2cpu_cmd->sbuf.type); - if (rc != 0) + if (rc) goto fail_allocate_dsp_buf; -#ifdef FASTRPC_DRIVER_AVAILABLE rc = eva_fastrpc_dev_map_dma(frpc_device, buf, dsp2cpu_cmd->sbuf.dsp_remote_map, &v_dsp_addr); -#endif if (rc) { dprintk(CVP_ERR, "%s Failed to map buffer 0x%x\n", __func__, rc); goto fail_fastrpc_dev_map_dma; } -#ifdef FASTRPC_DRIVER_AVAILABLE - buf_list = &frpc_node->dspbufs; - mutex_lock(&buf_list->lock); - list_add_tail(&buf->list, &buf_list->list); - mutex_unlock(&buf_list->lock); -#endif + + mutex_lock(&inst->cvpdspbufs.lock); + list_add_tail(&buf->list, &inst->cvpdspbufs.list); + mutex_unlock(&inst->cvpdspbufs.lock); + dprintk(CVP_DSP, "%s allocate buffer done, addr 0x%llx\n", __func__, v_dsp_addr); @@ -1595,11 +1615,9 @@ static void __dsp_cvp_mem_alloc(struct cvp_dsp_cmd_msg *cmd) fail_fastrpc_dev_map_dma: cvp_release_dsp_buffers(inst, buf); fail_allocate_dsp_buf: - kfree(buf); + kmem_cache_free(cvp_driver->buf_cache, buf); fail_kzalloc_buf: -#ifdef FASTRPC_DRIVER_AVAILABLE fail_fastrpc_node: -#endif cmd->ret = -1; return; @@ -1607,7 +1625,6 @@ fail_fastrpc_node: static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) { -#ifdef FASTRPC_DRIVER_AVAILABLE struct cvp_dsp_apps *me = &gfa_cv; struct msm_cvp_inst *inst; int rc; @@ -1641,7 +1658,7 @@ static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) } frpc_device = frpc_node->cvp_fastrpc_device; - buf_list = &frpc_node->dspbufs; + buf_list = &inst->cvpdspbufs; mutex_lock(&buf_list->lock); list_for_each_safe(ptr, next, &buf_list->list) { buf = list_entry(ptr, struct cvp_internal_buf, list); @@ -1678,7 +1695,7 @@ static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) list_del(&buf->list); - kfree(buf); + kmem_cache_free(cvp_driver->buf_cache, buf); break; } } @@ -1686,7 +1703,6 @@ static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) fail_release_buf: fail_fastrpc_dev_unmap_dma: mutex_unlock(&buf_list->lock); -#endif } static int cvp_dsp_thread(void *data) diff --git a/msm/eva/msm_cvp_dsp.h b/msm/eva/msm_cvp_dsp.h index 10ffb4b04c..2fb7cd2cbb 100644 --- a/msm/eva/msm_cvp_dsp.h +++ b/msm/eva/msm_cvp_dsp.h @@ -12,13 +12,7 @@ #include #include - -#define FASTRPC_DRIVER_AVAILABLE - -#ifdef FASTRPC_DRIVER_AVAILABLE #include -#endif - #define CVP_APPS_DSP_GLINK_GUID "cvp-glink-apps-dsp" #define CVP_APPS_DSP_SMD_GUID "cvp-smd-apps-dsp" @@ -174,14 +168,11 @@ struct cvp_dsp_fastrpc_driver_entry { struct list_head list; uint32_t handle; uint32_t session_cnt; -#ifdef FASTRPC_DRIVER_AVAILABLE struct fastrpc_driver cvp_fastrpc_driver; struct fastrpc_device *cvp_fastrpc_device; -#endif struct completion fastrpc_probe_completion; - struct msm_cvp_list dspbufs; /* all dsp sessions list */ - struct msm_cvp_list dsp_session; + struct msm_cvp_list dsp_sessions; }; struct cvp_dsp_apps { @@ -261,5 +252,9 @@ int cvp_dsp_deregister_buffer(uint32_t session_id, uint32_t buff_fd, uint32_t buff_offset, uint32_t buff_index, uint32_t buff_fd_iova); +int cvp_dsp_fastrpc_unmap(uint32_t process_id, struct cvp_internal_buf *buf); + +int cvp_dsp_del_sess(uint32_t process_id, struct msm_cvp_inst *inst); + #endif // MSM_CVP_DSP_H diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index b5bbce357e..20288ecfea 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -290,9 +290,11 @@ struct msm_cvp_core { struct msm_cvp_inst { struct list_head list; + struct list_head dsp_list; struct mutex sync_lock, lock; struct msm_cvp_core *core; enum session_type session_type; + u32 process_id; struct cvp_session_queue session_queue; struct cvp_session_queue session_queue_fence; struct cvp_session_event event_handler; From 8f044d707ab369c691b5f36415c1d45eb8742238 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 18 Feb 2021 22:03:28 -0800 Subject: [PATCH 031/317] msm: eva: Deprecate dma_buf_get_flags() Migrate to new kernel API to retrieve buffer attributes. Change-Id: I1163c975b8e7f666694394be90f2999eabba1e23 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 10 ++-- msm/eva/msm_cvp_buf.c | 8 ++-- msm/eva/msm_cvp_buf.h | 10 ++-- msm/eva/msm_smem.c | 106 +++++++++++++++++++----------------------- 4 files changed, 63 insertions(+), 71 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index c6e69b9f0b..879ade4326 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -887,7 +887,8 @@ static int __smem_alloc(struct iris_hfi_device *dev, struct cvp_mem_addr *mem, } dprintk(CVP_INFO, "start to alloc size: %d, flags: %d\n", size, flags); - rc = msm_cvp_smem_alloc(size, align, flags, 1, (void *)dev->res, alloc); + alloc->flags = flags; + rc = msm_cvp_smem_alloc(size, align, 1, (void *)dev->res, alloc); if (rc) { dprintk(CVP_ERR, "Alloc failed\n"); rc = -ENOMEM; @@ -1615,7 +1616,7 @@ static int __interface_dsp_queues_init(struct iris_hfi_device *dev) dprintk(CVP_ERR, "%s: failed dma allocation\n", __func__); goto fail_dma_alloc; } - cb = msm_cvp_smem_get_context_bank(0, dev->res, 0); + cb = msm_cvp_smem_get_context_bank(dev->res, 0); if (!cb) { dprintk(CVP_ERR, "%s: failed to get context bank\n", __func__); @@ -1636,7 +1637,6 @@ static int __interface_dsp_queues_init(struct iris_hfi_device *dev) mem_data->device_addr = iova; mem_data->dma_handle = dma_handle; mem_data->size = q_size; - mem_data->ion_flags = 0; mem_data->mapping_info.cb_info = cb; if (!is_iommu_present(dev->res)) @@ -1692,7 +1692,7 @@ static void __interface_queues_release(struct iris_hfi_device *device) } mem_map = (struct cvp_hfi_mem_map *)(qdss + 1); - cb = msm_cvp_smem_get_context_bank(false, device->res, 0); + cb = msm_cvp_smem_get_context_bank(device->res, 0); for (i = 0; cb && i < num_entries; i++) { iommu_unmap(cb->domain, @@ -1916,7 +1916,7 @@ static int __interface_queues_init(struct iris_hfi_device *dev) qdss->mem_map_table_base_addr = mem_map_table_base_addr; mem_map = (struct cvp_hfi_mem_map *)(qdss + 1); - cb = msm_cvp_smem_get_context_bank(false, dev->res, 0); + cb = msm_cvp_smem_get_context_bank(dev->res, 0); if (!cb) { dprintk(CVP_ERR, "%s: failed to get context bank\n", __func__); diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 4132f645d0..e83463fdb7 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1117,8 +1117,9 @@ struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, goto fail_kzalloc; } - rc = msm_cvp_smem_alloc(buffer_size, 1, smem_flags, 0, - &(inst->core->resources), buf->smem); + buf->smem->flags = smem_flags; + rc = msm_cvp_smem_alloc(buffer_size, 1, 0, + &(inst->core->resources), buf->smem); if (rc) { dprintk(CVP_ERR, "Failed to allocate ARP memory\n"); goto err_no_mem; @@ -1252,7 +1253,8 @@ int cvp_allocate_dsp_bufs(struct msm_cvp_inst *inst, goto fail_kzalloc_smem_cache; } - rc = msm_cvp_smem_alloc(buffer_size, 1, smem_flags, 0, + buf->smem->flags = smem_flags; + rc = msm_cvp_smem_alloc(buffer_size, 1, 0, &(inst->core->resources), buf->smem); if (rc) { dprintk(CVP_ERR, "Failed to allocate ARP memory\n"); diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index 036ebedca3..59a2fd2143 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -34,7 +34,8 @@ enum smem_prop { SMEM_SECURE = 0x4, SMEM_ADSP = 0x8, SMEM_NON_PIXEL = 0x10, - SMEM_PIXEL = 0x20 + SMEM_PIXEL = 0x20, + SMEM_CAMERA = 0x40 }; struct msm_cvp_list { @@ -72,7 +73,6 @@ struct msm_cvp_smem { u32 size; u32 bitmap_index; u32 flags; - u32 ion_flags; struct cvp_dma_mapping_info mapping_info; }; @@ -151,12 +151,12 @@ void print_smem(u32 tag, const char *str, struct msm_cvp_smem *smem); /*Kernel DMA buffer and IOMMU mapping functions*/ -int msm_cvp_smem_alloc(size_t size, u32 align, u32 flags, int map_kernel, +int msm_cvp_smem_alloc(size_t size, u32 align, int map_kernel, void *res, struct msm_cvp_smem *smem); int msm_cvp_smem_free(struct msm_cvp_smem *smem); -struct context_bank_info *msm_cvp_smem_get_context_bank(bool is_secure, +struct context_bank_info *msm_cvp_smem_get_context_bank( struct msm_cvp_platform_resources *res, - unsigned long ion_flags); + unsigned int flags); int msm_cvp_map_smem(struct msm_cvp_inst *inst, struct msm_cvp_smem *smem, const char *str); diff --git a/msm/eva/msm_smem.c b/msm/eva/msm_smem.c index b401a45561..6002960e78 100644 --- a/msm/eva/msm_smem.c +++ b/msm/eva/msm_smem.c @@ -10,6 +10,8 @@ #include #include #include +#include +#include #include #include #include "msm_cvp_core.h" @@ -20,8 +22,7 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, u32 align, - dma_addr_t *iova, u32 flags, unsigned long ion_flags, - struct msm_cvp_platform_resources *res, + dma_addr_t *iova, u32 flags, struct msm_cvp_platform_resources *res, struct cvp_dma_mapping_info *mapping_info) { int rc = 0; @@ -36,8 +37,7 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, u32 align, } if (is_iommu_present(res)) { - cb = msm_cvp_smem_get_context_bank((flags & SMEM_SECURE), - res, ion_flags); + cb = msm_cvp_smem_get_context_bank(res, flags); if (!cb) { dprintk(CVP_ERR, "%s: Failed to get context bank device\n", @@ -165,13 +165,15 @@ int msm_cvp_map_smem(struct msm_cvp_inst *inst, struct msm_cvp_smem *smem, const char *str) { + int *vmid_list; + int *perms_list; + int nelems = 0; int rc = 0; dma_addr_t iova = 0; u32 temp = 0; u32 align = SZ_4K; struct dma_buf *dma_buf; - unsigned long ion_flags = 0; if (!inst || !smem) { dprintk(CVP_ERR, "%s: Invalid params: %pK %pK\n", @@ -180,20 +182,25 @@ int msm_cvp_map_smem(struct msm_cvp_inst *inst, } dma_buf = smem->dma_buf; - rc = dma_buf_get_flags(dma_buf, &ion_flags); + rc = mem_buf_dma_buf_copy_vmperm(dma_buf, + &vmid_list, &perms_list, &nelems); if (rc) { - dprintk(CVP_ERR, "Failed to get dma buf flags: %d\n", rc); - goto exit; + dprintk(CVP_ERR, "%s fail to get vmid and perms %d\n", + __func__, rc); + return rc; } - if (ion_flags & ION_FLAG_CACHED) - smem->flags |= SMEM_CACHED; - if (ion_flags & ION_FLAG_SECURE) - smem->flags |= SMEM_SECURE; + for (temp = 0; temp < nelems; temp++) { + if (vmid_list[temp] == VMID_CP_PIXEL) + smem->flags |= (SMEM_SECURE | SMEM_PIXEL); + else if (vmid_list[temp] == VMID_CP_NON_PIXEL) + smem->flags |= (SMEM_SECURE | SMEM_NON_PIXEL); + else if (vmid_list[temp] == VMID_CP_CAMERA) + smem->flags |= (SMEM_SECURE | SMEM_CAMERA); + } rc = msm_dma_get_device_address(dma_buf, align, &iova, smem->flags, - ion_flags, &(inst->core->resources), - &smem->mapping_info); + &(inst->core->resources), &smem->mapping_info); if (rc) { dprintk(CVP_ERR, "Failed to get device address: %d\n", rc); goto exit; @@ -209,9 +216,12 @@ int msm_cvp_map_smem(struct msm_cvp_inst *inst, smem->device_addr = (u32)iova; print_smem(CVP_MEM, str, inst, smem); - return rc; + goto success; exit: smem->device_addr = 0x0; +success: + kfree(vmid_list); + kfree(perms_list); return rc; } @@ -240,12 +250,11 @@ exit: return rc; } -static int alloc_dma_mem(size_t size, u32 align, u32 flags, int map_kernel, +static int alloc_dma_mem(size_t size, u32 align, int map_kernel, struct msm_cvp_platform_resources *res, struct msm_cvp_smem *mem) { dma_addr_t iova = 0; int rc = 0; - int ion_flags = 0; struct dma_buf *dbuf = NULL; struct dma_heap *heap; @@ -260,29 +269,23 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, int map_kernel, if (is_iommu_present(res)) { heap = dma_heap_find("qcom,system"); dprintk(CVP_MEM, "%s size %zx align %d flag %d\n", - __func__, size, align, flags); + __func__, size, align, mem->flags); } else { dprintk(CVP_ERR, "No IOMMU CB: allocate shared memory heap size %zx align %d\n", size, align); } - if (flags & SMEM_CACHED) - ion_flags |= ION_FLAG_CACHED; - - if (flags & SMEM_NON_PIXEL) { + if (mem->flags & SMEM_NON_PIXEL) heap = dma_heap_find("qcom,secure-non-pixel"); - ion_flags |= ION_FLAG_CP_NON_PIXEL; - } else if (flags & SMEM_PIXEL) { + else if (mem->flags & SMEM_PIXEL) heap = dma_heap_find("qcom,secure-pixel"); - ion_flags |= ION_FLAG_CP_PIXEL; - } dbuf = dma_heap_buffer_alloc(heap, size, 0, 0); if (IS_ERR_OR_NULL(dbuf)) { dprintk(CVP_ERR, "Failed to allocate shared memory = %x bytes, %x %x\n", - size, ion_flags, PTR_ERR(dbuf)); + size, mem->flags, PTR_ERR(dbuf)); rc = -ENOMEM; goto fail_shared_mem_alloc; } @@ -290,14 +293,12 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, int map_kernel, if (!gfa_cv.dmabuf_f_op) gfa_cv.dmabuf_f_op = (const struct file_operations *)dbuf->file->f_op; - mem->flags = flags; - mem->ion_flags = ion_flags; mem->size = size; mem->dma_buf = dbuf; mem->kvaddr = NULL; - rc = msm_dma_get_device_address(dbuf, align, &iova, flags, - ion_flags, res, &mem->mapping_info); + rc = msm_dma_get_device_address(dbuf, align, &iova, mem->flags, + res, &mem->mapping_info); if (rc) { dprintk(CVP_ERR, "Failed to get device address: %d\n", rc); @@ -322,9 +323,9 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, int map_kernel, } dprintk(CVP_MEM, - "%s: dma_buf = %pK, device_addr = %x, size = %d, kvaddr = %pK, ion_flags = %#x, flags = %#lx\n", + "%s: dma_buf=%pK,iova=%x,size=%d,kvaddr=%pK,flags=%#lx\n", __func__, mem->dma_buf, mem->device_addr, mem->size, - mem->kvaddr, mem->ion_flags, mem->flags); + mem->kvaddr, mem->flags); return rc; fail_map: @@ -339,9 +340,8 @@ fail_shared_mem_alloc: static int free_dma_mem(struct msm_cvp_smem *mem) { dprintk(CVP_MEM, - "%s: dma_buf = %pK, device_addr = %x, size = %d, kvaddr = %pK, ion_flags = %#x\n", - __func__, mem->dma_buf, mem->device_addr, mem->size, - mem->kvaddr, mem->ion_flags); + "%s: dma_buf = %pK, device_addr = %x, size = %d, kvaddr = %pK\n", + __func__, mem->dma_buf, mem->device_addr, mem->size, mem->kvaddr); if (mem->device_addr) { msm_dma_put_device_address(mem->flags, &mem->mapping_info); @@ -362,7 +362,7 @@ static int free_dma_mem(struct msm_cvp_smem *mem) return 0; } -int msm_cvp_smem_alloc(size_t size, u32 align, u32 flags, int map_kernel, +int msm_cvp_smem_alloc(size_t size, u32 align, int map_kernel, void *res, struct msm_cvp_smem *smem) { int rc = 0; @@ -373,9 +373,8 @@ int msm_cvp_smem_alloc(size_t size, u32 align, u32 flags, int map_kernel, return -EINVAL; } - rc = alloc_dma_mem(size, align, flags, map_kernel, - (struct msm_cvp_platform_resources *)res, - smem); + rc = alloc_dma_mem(size, align, map_kernel, + (struct msm_cvp_platform_resources *)res, smem); return rc; } @@ -397,23 +396,12 @@ int msm_cvp_smem_cache_operations(struct dma_buf *dbuf, enum smem_cache_ops cache_op, unsigned long offset, unsigned long size) { int rc = 0; - unsigned long flags = 0; if (!dbuf) { dprintk(CVP_ERR, "%s: Invalid params\n", __func__); return -EINVAL; } - /* Return if buffer doesn't support caching */ - rc = dma_buf_get_flags(dbuf, &flags); - if (rc) { - dprintk(CVP_ERR, "%s: dma_buf_get_flags failed, err %d\n", - __func__, rc); - return rc; - } else if (!(flags & ION_FLAG_CACHED)) { - return rc; - } - switch (cache_op) { case SMEM_CACHE_CLEAN: case SMEM_CACHE_CLEAN_INVALIDATE: @@ -442,18 +430,20 @@ int msm_cvp_smem_cache_operations(struct dma_buf *dbuf, return rc; } -struct context_bank_info *msm_cvp_smem_get_context_bank(bool is_secure, - struct msm_cvp_platform_resources *res, unsigned long ion_flags) +struct context_bank_info *msm_cvp_smem_get_context_bank( + struct msm_cvp_platform_resources *res, + unsigned int flags) { struct context_bank_info *cb = NULL, *match = NULL; char *search_str; char *non_secure_cb = "cvp_hlos"; char *secure_nonpixel_cb = "cvp_sec_nonpixel"; char *secure_pixel_cb = "cvp_sec_pixel"; + bool is_secure = (flags & SMEM_SECURE) ? true : false; - if (ion_flags & ION_FLAG_CP_PIXEL) + if (flags & SMEM_PIXEL) search_str = secure_pixel_cb; - else if (ion_flags & ION_FLAG_CP_NON_PIXEL) + else if (flags & SMEM_NON_PIXEL) search_str = secure_nonpixel_cb; else search_str = non_secure_cb; @@ -468,8 +458,8 @@ struct context_bank_info *msm_cvp_smem_get_context_bank(bool is_secure, if (!match) dprintk(CVP_ERR, - "%s: cb not found for ion_flags %x, is_secure %d\n", - __func__, ion_flags, is_secure); + "%s: cb not found for flags %x, is_secure %d\n", + __func__, flags, is_secure); return match; } @@ -499,7 +489,7 @@ int msm_cvp_map_ipcc_regs(u32 *iova) if (!paddr || !size) return -EINVAL; - cb = msm_cvp_smem_get_context_bank(false, dev->res, 0); + cb = msm_cvp_smem_get_context_bank(dev->res, 0); if (!cb) { dprintk(CVP_ERR, "%s: fail to get context bank\n", __func__); return -EINVAL; From 5487a06469d52aa6f25c070d3e34ea2316ed4656 Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 19 Feb 2021 16:48:05 -0800 Subject: [PATCH 032/317] msm: eva: enable EVA hw power collapse EVA control is allowed to power collapse EVA core during inter frame idle time. Change-Id: I4da4efe9a5d8f2c9a5f9dba6286cbd6c5a8ab903 Signed-off-by: George Shen --- msm/eva/msm_cvp_debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index ff7280d917..17924e7196 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -19,7 +19,7 @@ EXPORT_SYMBOL(msm_cvp_debug_out); int msm_cvp_fw_debug = 0x18; int msm_cvp_fw_debug_mode = 1; -int msm_cvp_fw_low_power_mode = !1; +int msm_cvp_fw_low_power_mode = 1; bool msm_cvp_fw_coverage = !true; bool msm_cvp_cacheop_enabled = true; bool msm_cvp_thermal_mitigation_disabled = !true; From e483c291f0f2f10437d73bda8c4fd507cec50ddb Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 22 Feb 2021 22:00:37 -0800 Subject: [PATCH 033/317] msm: eva: Enable EVA software power collapse Enable Suspend/Resume support. Change-Id: If88ce04998cdcc8166c34f4c28aee1530f2c7eb1 Signed-off-by: George Shen --- msm/eva/msm_cvp_platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 55287382d7..baec5d13c1 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -52,7 +52,7 @@ static struct msm_cvp_common_data sm8450_common_data[] = { }, { .key = "qcom,sw-power-collapse", - .value = 0, + .value = 1, }, { .key = "qcom,domain-attr-non-fatal-faults", From 521f3d374f8927c36dfb22e1bfbf3cdba3fd3089 Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 23 Feb 2021 13:23:17 -0800 Subject: [PATCH 034/317] msm: eva: Fixed static analysis error Fix static analysis tool detected errors. Change-Id: I882dd7aebe544b930abb49ba998c1482991a49c9 Signed-off-by: George Shen --- msm/eva/msm_cvp.c | 1 + msm/eva/msm_cvp_buf.c | 7 +++++-- msm/eva/msm_cvp_dsp.c | 1 + msm/eva/msm_smem.c | 2 +- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 85c1a2932b..c568654cac 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -607,6 +607,7 @@ exit: dprintk(CVP_SYNX, "%s exit\n", current->comm); cvp_put_inst(inst); do_exit(rc); + return rc; } static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst, diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index e83463fdb7..a839df97d0 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -352,12 +352,15 @@ int msm_cvp_map_buf_dsp_new(struct msm_cvp_inst *inst, dprintk(CVP_WARN, "%s incorrect pid\n", __func__); return -EINVAL; } - dprintk(CVP_WARN, "%s get pid_s 0x%x from pidA 0x%x\n", __func__, pid_s, pid); + dprintk(CVP_DSP, "%s get pid_s 0x%x from pidA 0x%x\n", __func__, pid_s, pid); /* task = get_pid_task(pid, PIDTYPE_PID); */ task = get_pid_task(pid_s, PIDTYPE_TGID); - if (!task) + if (!task) { dprintk(CVP_WARN, "%s task doesn't exist\n", __func__); + return -EINVAL; + } + file = msm_cvp_fget(buf->fd, task, FMODE_PATH, 1); if (file == NULL) { dprintk(CVP_WARN, "%s fail to get file from fd\n", __func__); diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index bf70cd080a..dc6268a571 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1838,6 +1838,7 @@ wait_dsp: exit: dprintk(CVP_DBG, "dsp thread exit\n"); do_exit(rc); + return rc; } int cvp_dsp_device_init(void) diff --git a/msm/eva/msm_smem.c b/msm/eva/msm_smem.c index 6002960e78..60227b43c2 100644 --- a/msm/eva/msm_smem.c +++ b/msm/eva/msm_smem.c @@ -256,7 +256,7 @@ static int alloc_dma_mem(size_t size, u32 align, int map_kernel, dma_addr_t iova = 0; int rc = 0; struct dma_buf *dbuf = NULL; - struct dma_heap *heap; + struct dma_heap *heap = NULL; if (!res) { dprintk(CVP_ERR, "%s: NULL res\n", __func__); From 26f93c062096949e9dbaf454e32f4fbae4fcf925 Mon Sep 17 00:00:00 2001 From: Ronald Karyodisa Date: Fri, 19 Feb 2021 11:47:01 -0800 Subject: [PATCH 035/317] msm: eva: Create qti_eva_kernel_headers Create qti_eva_kernel_headers for uapi access. Change-Id: Ibb00aadef499b82bf120bec21c776e2ae64c9c2d Signed-off-by: Ronald Karyodisa --- Android.bp | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 Android.bp diff --git a/Android.bp b/Android.bp new file mode 100644 index 0000000000..8037565099 --- /dev/null +++ b/Android.bp @@ -0,0 +1,5 @@ +cc_library_headers { + name: "qti_eva_kernel_headers", + export_include_dirs: ["include/uapi/eva/media"], + vendor_available: true +} From bf7faee9353378b75ff8ed1f2286d6ffddcb6813 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 1 Mar 2021 10:58:56 -0800 Subject: [PATCH 036/317] msm: eva: Add GCC reg mapping For better SMMU fault debugging in future. Change-Id: Iead03f9d701fc53690fb0b6864562e65f2cfc15f Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 34 ++++++++++++---------------------- msm/eva/msm_cvp_res_parse.c | 24 +++++++++++++++++++++++- msm/eva/msm_cvp_resources.h | 4 +++- 3 files changed, 38 insertions(+), 24 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 879ade4326..3328d9b56f 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1,6 +1,6 @@ // 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. */ #include @@ -3256,6 +3256,16 @@ static int __init_regs_and_interrupts(struct iris_hfi_device *device, goto error_irq_fail; } + if (res->gcc_reg_base) { + hal->gcc_reg_base = devm_ioremap(&res->pdev->dev, + res->gcc_reg_base, res->gcc_reg_size); + hal->gcc_reg_size = res->gcc_reg_size; + if (!hal->gcc_reg_base) + dprintk(CVP_ERR, + "could not map gcc reg addr %pa of size %d\n", + &res->gcc_reg_base, res->gcc_reg_size); + } + device->cvp_hal_data = hal; rc = request_irq(res->irq, iris_hfi_isr, IRQF_TRIGGER_HIGH, "msm_cvp", device); @@ -4199,27 +4209,7 @@ static void power_off_iris2(struct iris_hfi_device *device) sbm_ln0_low, main_sbm_ln0_low, main_sbm_ln1_high); } - /* HPG 6.1.2 Step 3, debug bridge to low power */ - __write_register(device, - CVP_WRAPPER_DEBUG_BRIDGE_LPI_CONTROL, 0x7); - - reg_status = 0; - count = 0; - while ((reg_status != 0x7) && count < max_count) { - lpi_status = __read_register(device, - CVP_WRAPPER_DEBUG_BRIDGE_LPI_STATUS); - reg_status = lpi_status & 0x7; - /* Wait for debug bridge lpi status to be set */ - usleep_range(50, 100); - count++; - } - dprintk(CVP_PWR, - "DBLP Set : lpi_status %d reg_status %d (count %d)\n", - lpi_status, reg_status, count); - if (count == max_count) { - dprintk(CVP_WARN, - "DBLP Set: status %x %x\n", reg_status, lpi_status); - } + /* HPG 6.1.2 Step 3, debug bridge to low power BYPASSED */ /* HPG 6.1.2 Step 4, debug bridge to lpi release */ __write_register(device, diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index 4a9d87e278..3d1b428499 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -1,6 +1,6 @@ // 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. */ #include @@ -134,6 +134,26 @@ static int msm_cvp_load_ipcc_regs(struct msm_cvp_platform_resources *res) return ret; } +static int msm_cvp_load_gcc_regs(struct msm_cvp_platform_resources *res) +{ + int ret = 0; + unsigned int reg_config[2]; + struct platform_device *pdev = res->pdev; + + ret = of_property_read_u32_array(pdev->dev.of_node, "qcom,gcc-reg", + reg_config, 2); + if (ret) { + dprintk(CVP_WARN, "No gcc reg configured: %d\n", ret); + return ret; + } + + res->gcc_reg_base = reg_config[0]; + res->gcc_reg_size = reg_config[1]; + + return ret; +} + + static int msm_cvp_load_reg_table(struct msm_cvp_platform_resources *res) { struct reg_set *reg_set; @@ -809,6 +829,8 @@ int cvp_read_platform_resources_from_dt( if (rc) dprintk(CVP_ERR, "Failed to load IPCC regs: %d\n", rc); + rc = msm_cvp_load_gcc_regs(res); + rc = msm_cvp_load_regulator_table(res); if (rc) { dprintk(CVP_ERR, "Failed to load list of regulators %d\n", rc); diff --git a/msm/eva/msm_cvp_resources.h b/msm/eva/msm_cvp_resources.h index 3686bf0d2e..f0e5fe6b27 100644 --- a/msm/eva/msm_cvp_resources.h +++ b/msm/eva/msm_cvp_resources.h @@ -1,6 +1,6 @@ /* 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. */ #ifndef __MSM_CVP_RESOURCES_H__ @@ -137,8 +137,10 @@ struct msm_cvp_platform_resources { phys_addr_t firmware_base; phys_addr_t register_base; phys_addr_t ipcc_reg_base; + phys_addr_t gcc_reg_base; uint32_t register_size; uint32_t ipcc_reg_size; + uint32_t gcc_reg_size; uint32_t irq; uint32_t sku_version; struct allowed_clock_rates_table *allowed_clks_tbl; From cc0d122772dadddd2bef51da99e73f0692aca063 Mon Sep 17 00:00:00 2001 From: Suman Voora Date: Wed, 24 Feb 2021 19:56:07 +0530 Subject: [PATCH 037/317] msm: eva: Update the max hfi packet size Need to update the Max HFI packet size to accomodate the Pyramid HFI packet Change-Id: Ie8bb3aeebc0c503a528a8a2c8c1ebc8dd4e2a085 Signed-off-by: Suman Voora --- include/uapi/eva/media/msm_eva_private.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/uapi/eva/media/msm_eva_private.h b/include/uapi/eva/media/msm_eva_private.h index 6876e0bb1b..082dae2275 100644 --- a/include/uapi/eva/media/msm_eva_private.h +++ b/include/uapi/eva/media/msm_eva_private.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ /* - * Copyright (c) 2018-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. */ #ifndef __MSM_EVA_PRIVATE_H__ #define __MSM_EVA_PRIVATE_H__ @@ -121,7 +121,7 @@ struct eva_kmd_client_data { }; -#define MAX_HFI_PKT_SIZE 470 +#define MAX_HFI_PKT_SIZE 490 struct eva_kmd_hfi_packet { __u32 pkt_data[MAX_HFI_PKT_SIZE]; From 600394cf35849ea35baf48a9b44840c5b651c197 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 15 Mar 2021 14:53:26 -0700 Subject: [PATCH 038/317] msm: eva: Update date of source To comply with open source scan requirements. Change-Id: Idd9a4dec7dbe7ee7d4dd7294083d9b045438f67d Signed-off-by: George Shen --- msm/eva/cvp.c | 2 +- msm/eva/cvp_comm_def.h | 2 +- msm/eva/cvp_core_hfi.c | 2 +- msm/eva/cvp_core_hfi.h | 2 +- msm/eva/cvp_fw_load.c | 2 +- msm/eva/cvp_hfi.h | 2 +- msm/eva/cvp_hfi_api.h | 2 +- msm/eva/cvp_hfi_helper.h | 2 +- msm/eva/cvp_hfi_io.h | 2 +- msm/eva/cvp_private.h | 2 +- msm/eva/hfi_packetization.c | 2 +- msm/eva/hfi_packetization.h | 2 +- msm/eva/hfi_response_handler.c | 2 +- msm/eva/msm_cvp.c | 2 +- msm/eva/msm_cvp.h | 2 +- msm/eva/msm_cvp_buf.c | 2 +- msm/eva/msm_cvp_buf.h | 2 +- msm/eva/msm_cvp_clocks.c | 2 +- msm/eva/msm_cvp_clocks.h | 2 +- msm/eva/msm_cvp_common.c | 2 +- msm/eva/msm_cvp_common.h | 2 +- msm/eva/msm_cvp_core.c | 2 +- msm/eva/msm_cvp_core.h | 2 +- msm/eva/msm_cvp_debug.c | 2 +- msm/eva/msm_cvp_debug.h | 2 +- msm/eva/msm_cvp_dsp.c | 2 +- msm/eva/msm_cvp_dsp.h | 2 +- msm/eva/msm_cvp_internal.h | 2 +- msm/eva/msm_cvp_ioctl.c | 2 +- msm/eva/msm_cvp_platform.c | 2 +- msm/eva/msm_cvp_res_parse.h | 2 +- msm/eva/msm_cvp_synx.c | 2 +- msm/eva/msm_cvp_synx.h | 2 +- msm/eva/msm_smem.c | 2 +- 34 files changed, 34 insertions(+), 34 deletions(-) diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index e3303f070b..f84c55892f 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -1,6 +1,6 @@ // 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. */ #include diff --git a/msm/eva/cvp_comm_def.h b/msm/eva/cvp_comm_def.h index 1e590fdc6e..a5de1d90d0 100644 --- a/msm/eva/cvp_comm_def.h +++ b/msm/eva/cvp_comm_def.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */ #ifndef _MSM_COMM_DEF_H_ diff --git a/msm/eva/cvp_core_hfi.c b/msm/eva/cvp_core_hfi.c index d6fae2f105..832fe0117b 100644 --- a/msm/eva/cvp_core_hfi.c +++ b/msm/eva/cvp_core_hfi.c @@ -1,6 +1,6 @@ // 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. */ #include diff --git a/msm/eva/cvp_core_hfi.h b/msm/eva/cvp_core_hfi.h index 7e8174a873..ae8b20470b 100644 --- a/msm/eva/cvp_core_hfi.h +++ b/msm/eva/cvp_core_hfi.h @@ -1,6 +1,6 @@ /* 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. */ #ifndef __H_CVP_CORE_HFI_H__ diff --git a/msm/eva/cvp_fw_load.c b/msm/eva/cvp_fw_load.c index a97c592d58..85c825684f 100644 --- a/msm/eva/cvp_fw_load.c +++ b/msm/eva/cvp_fw_load.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */ #include diff --git a/msm/eva/cvp_hfi.h b/msm/eva/cvp_hfi.h index ee43ff41e8..4e7c112871 100644 --- a/msm/eva/cvp_hfi.h +++ b/msm/eva/cvp_hfi.h @@ -1,6 +1,6 @@ /* 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. */ #ifndef __H_CVP_HFI_H__ diff --git a/msm/eva/cvp_hfi_api.h b/msm/eva/cvp_hfi_api.h index 983326f459..fe1227d00b 100644 --- a/msm/eva/cvp_hfi_api.h +++ b/msm/eva/cvp_hfi_api.h @@ -1,6 +1,6 @@ /* 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. */ #ifndef __CVP_HFI_API_H__ diff --git a/msm/eva/cvp_hfi_helper.h b/msm/eva/cvp_hfi_helper.h index 6f48b2f2d0..a5bf274b27 100644 --- a/msm/eva/cvp_hfi_helper.h +++ b/msm/eva/cvp_hfi_helper.h @@ -1,6 +1,6 @@ /* 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. */ #ifndef __H_CVP_HFI_HELPER_H__ diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index d4d55fb38a..c83f6793e3 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -1,6 +1,6 @@ /* 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. */ #ifndef __CVP_HFI_IO_H__ diff --git a/msm/eva/cvp_private.h b/msm/eva/cvp_private.h index a6d63271c9..6e7e3bec8c 100644 --- a/msm/eva/cvp_private.h +++ b/msm/eva/cvp_private.h @@ -1,6 +1,6 @@ /* 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. */ #ifndef _MSM_V4L2_PRIVATE_H_ diff --git a/msm/eva/hfi_packetization.c b/msm/eva/hfi_packetization.c index 2d1149131b..bebacc315f 100644 --- a/msm/eva/hfi_packetization.c +++ b/msm/eva/hfi_packetization.c @@ -1,6 +1,6 @@ // 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. */ #include "hfi_packetization.h" diff --git a/msm/eva/hfi_packetization.h b/msm/eva/hfi_packetization.h index 05c7be1305..094dc5899e 100644 --- a/msm/eva/hfi_packetization.h +++ b/msm/eva/hfi_packetization.h @@ -1,6 +1,6 @@ /* 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. */ #ifndef __HFI_PACKETIZATION__ #define __HFI_PACKETIZATION__ diff --git a/msm/eva/hfi_response_handler.c b/msm/eva/hfi_response_handler.c index 74a8f6093b..e72d74bdf0 100644 --- a/msm/eva/hfi_response_handler.c +++ b/msm/eva/hfi_response_handler.c @@ -1,6 +1,6 @@ // 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. */ #include diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index c568654cac..a406ba9dc9 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -1,6 +1,6 @@ // 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. */ #include "msm_cvp.h" diff --git a/msm/eva/msm_cvp.h b/msm/eva/msm_cvp.h index 494c6eccda..92ad2715ca 100644 --- a/msm/eva/msm_cvp.h +++ b/msm/eva/msm_cvp.h @@ -1,6 +1,6 @@ /* 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. */ #ifndef _MSM_CVP_H_ diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index a839df97d0..a6bbee5a63 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */ #include diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index 59a2fd2143..fc5b048c99 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */ #ifndef _MSM_CVP_BUF_H_ diff --git a/msm/eva/msm_cvp_clocks.c b/msm/eva/msm_cvp_clocks.c index 43300c82df..5e2324e423 100644 --- a/msm/eva/msm_cvp_clocks.c +++ b/msm/eva/msm_cvp_clocks.c @@ -1,6 +1,6 @@ // 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. */ #include "msm_cvp_common.h" diff --git a/msm/eva/msm_cvp_clocks.h b/msm/eva/msm_cvp_clocks.h index 401f89d472..5a1b77331f 100644 --- a/msm/eva/msm_cvp_clocks.h +++ b/msm/eva/msm_cvp_clocks.h @@ -1,6 +1,6 @@ /* 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. */ diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 1579adad39..860899bb9e 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -1,6 +1,6 @@ // 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. */ #include diff --git a/msm/eva/msm_cvp_common.h b/msm/eva/msm_cvp_common.h index bfef327fc9..3b9209490e 100644 --- a/msm/eva/msm_cvp_common.h +++ b/msm/eva/msm_cvp_common.h @@ -1,6 +1,6 @@ /* 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. */ diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 4e602ac245..93994ba7a2 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -1,6 +1,6 @@ // 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. */ #include diff --git a/msm/eva/msm_cvp_core.h b/msm/eva/msm_cvp_core.h index 91ecce975a..1b89622dd3 100644 --- a/msm/eva/msm_cvp_core.h +++ b/msm/eva/msm_cvp_core.h @@ -1,6 +1,6 @@ /* 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. */ #ifndef _MSM_CVP_CORE_H_ diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 17924e7196..ae35c70c58 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -1,6 +1,6 @@ // 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. */ #include diff --git a/msm/eva/msm_cvp_debug.h b/msm/eva/msm_cvp_debug.h index d3e804a3d0..1d57d6c770 100644 --- a/msm/eva/msm_cvp_debug.h +++ b/msm/eva/msm_cvp_debug.h @@ -1,6 +1,6 @@ /* 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. */ #ifndef __MSM_CVP_DEBUG__ diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index dc6268a571..620ff69751 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1,6 +1,6 @@ // 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. */ #include #include diff --git a/msm/eva/msm_cvp_dsp.h b/msm/eva/msm_cvp_dsp.h index 2fb7cd2cbb..72beb46029 100644 --- a/msm/eva/msm_cvp_dsp.h +++ b/msm/eva/msm_cvp_dsp.h @@ -1,6 +1,6 @@ /* 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. */ #ifndef MSM_CVP_DSP_H diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index 20288ecfea..39f5a79ad8 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -1,6 +1,6 @@ /* 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. */ #ifndef _MSM_CVP_INTERNAL_H_ diff --git a/msm/eva/msm_cvp_ioctl.c b/msm/eva/msm_cvp_ioctl.c index f01c4eb4ce..9197cd6e6f 100644 --- a/msm/eva/msm_cvp_ioctl.c +++ b/msm/eva/msm_cvp_ioctl.c @@ -1,6 +1,6 @@ // 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. */ #include diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index baec5d13c1..438099772d 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -1,6 +1,6 @@ // 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. */ #include diff --git a/msm/eva/msm_cvp_res_parse.h b/msm/eva/msm_cvp_res_parse.h index 814ee94e81..fce5f5eb6c 100644 --- a/msm/eva/msm_cvp_res_parse.h +++ b/msm/eva/msm_cvp_res_parse.h @@ -1,6 +1,6 @@ /* 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. */ #ifndef __MSM_CVP_RES_PARSE_H__ diff --git a/msm/eva/msm_cvp_synx.c b/msm/eva/msm_cvp_synx.c index 07f294f8c2..fb75f550d0 100644 --- a/msm/eva/msm_cvp_synx.c +++ b/msm/eva/msm_cvp_synx.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */ #include "msm_cvp_common.h" diff --git a/msm/eva/msm_cvp_synx.h b/msm/eva/msm_cvp_synx.h index 3e2fcce514..3f8c7d7b18 100644 --- a/msm/eva/msm_cvp_synx.h +++ b/msm/eva/msm_cvp_synx.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */ #ifndef _MSM_CVP_SYNX_H_ diff --git a/msm/eva/msm_smem.c b/msm/eva/msm_smem.c index 60227b43c2..380e2afa74 100644 --- a/msm/eva/msm_smem.c +++ b/msm/eva/msm_smem.c @@ -1,6 +1,6 @@ // 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. */ #include From 136da84f7812e9a6fe40028525fa5f377fa267f0 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 10 Mar 2021 13:28:30 -0800 Subject: [PATCH 039/317] msm: eva: DMA attribute inclusion change Include recommended downstream dma mapping header. Change-Id: I6d5ef47a8c86a010f17672256fbb7c49815eddb2 Signed-off-by: George Shen --- msm/eva/msm_smem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/msm/eva/msm_smem.c b/msm/eva/msm_smem.c index 380e2afa74..e4bc437663 100644 --- a/msm/eva/msm_smem.c +++ b/msm/eva/msm_smem.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "msm_cvp_core.h" #include "msm_cvp_debug.h" #include "msm_cvp_resources.h" From 9871416e79977a4002db29e3a6ea4978b247785d Mon Sep 17 00:00:00 2001 From: Yu SI Date: Wed, 17 Feb 2021 13:21:12 -0800 Subject: [PATCH 040/317] msm: eva: mmrm integration integrated mmrm api added make file and kbuild support code ready, enable flow. Change-Id: Ic7da142bc68e60312ee9a12128847be8ed27a685 Signed-off-by: Yu SI --- Android.mk | 20 ++++++++-- msm/Kbuild | 8 +++- msm/eva/cvp.c | 1 + msm/eva/cvp_core_hfi.h | 3 ++ msm/eva/cvp_hfi.c | 74 +++++++++++++++++++++++++++++++------ msm/eva/msm_cvp_clocks.c | 79 ++++++++++++++++++++++++++++++++++++++++ msm/eva/msm_cvp_clocks.h | 4 ++ msm/eva/msm_cvp_debug.c | 1 + msm/eva/msm_cvp_debug.h | 1 + 9 files changed, 174 insertions(+), 17 deletions(-) diff --git a/Android.mk b/Android.mk index 46548065d4..c9c9f556e7 100644 --- a/Android.mk +++ b/Android.mk @@ -1,7 +1,6 @@ ifneq ($(TARGET_PRODUCT), qssi) ifeq ($(call is-board-platform-in-list, $(TARGET_BOARD_PLATFORM)),true) -# Test dlkm DLKM_DIR := device/qcom/common/dlkm LOCAL_PATH := $(call my-dir) @@ -9,13 +8,26 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) # For incremental compilation LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/**/*) $(wildcard $(LOCAL_PATH)/*) -# LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/msm/eva/*) LOCAL_MODULE := msm-eva.ko LOCAL_MODULE_KBUILD_NAME := msm/msm-eva.ko LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) -# Include msm-eva.ko in the /vendor/lib/modules -# BOARD_VENDOR_KERNEL_MODULES += $(LOCAL_MODULE_PATH)/$(LOCAL_MODULE) + LOCAL_ADDITIONAL_DEPENDENCY := synx-driver.ko + +# export to kbuild +KBUILD_OPTIONS += KBUILD_EXTRA_SYMBOLS=$(shell pwd)/$(call intermediates-dir-for,DLKM,mmrm-module-symvers)/Module.symvers + +LOCAL_REQUIRED_MODULES := mmrm-module-symvers +LOCAL_ADDITIONAL_DEPENDENCIES := $(call intermediates-dir-for,DLKM,mmrm-module-symvers)/Module.symvers + +# print out variables +$(info KBUILD_OPTIONS = $(KBUILD_OPTIONS)) +$(info intermediates mmrm symvers path = $(call intermediates-dir-for,DLKM,mmrm-module-symvers)) +$(info LOCAL_ADDITIONAL_DEPENDENCY = $(LOCAL_ADDITIONAL_DEPENDENCY)) +$(info LOCAL_ADDITIONAL_DEPENDENCIES = $(LOCAL_ADDITIONAL_DEPENDENCIES)) +$(info LOCAL_REQUIRED_MODULES = $(LOCAL_REQUIRED_MODULES)) +$(info DLKM_DIR = $(DLKM_DIR)) + include $(DLKM_DIR)/Build_external_kernelmodule.mk endif # End of check for board platform diff --git a/msm/Kbuild b/msm/Kbuild index a4754e1d87..f950634c31 100644 --- a/msm/Kbuild +++ b/msm/Kbuild @@ -4,10 +4,16 @@ LINUXINCLUDE += -I$(EVA_ROOT)/include \ #srctree is /kernel_platform/common/ -#ccflags-m not working, why? ccflags-y += -I$(srctree)/techpack/eva/msm/eva/ \ -I$(srctree)/drivers/media/platform/msm/synx/ +# add flag to compile mmrm actual implementatio instead of stub version. +# to follow up with mmrm team if techpack users need to define this for long term? +KBUILD_CPPFLAGS += -DCONFIG_MSM_MMRM + +# ported from Android.mk +$(info within KBUILD file KBUILD_EXTRA_SYMBOLS = $(KBUILD_EXTRA_SYMBOLS)) + msm-eva-objs := eva/cvp.o \ eva/msm_cvp_ioctl.o \ eva/msm_cvp_platform.o \ diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index f84c55892f..5366db5013 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -638,4 +638,5 @@ static void __exit msm_cvp_exit(void) module_init(msm_cvp_init); module_exit(msm_cvp_exit); +MODULE_SOFTDEP("pre: msm-mmrm"); MODULE_LICENSE("GPL v2"); diff --git a/msm/eva/cvp_core_hfi.h b/msm/eva/cvp_core_hfi.h index ae8b20470b..c7c8ca1d73 100644 --- a/msm/eva/cvp_core_hfi.h +++ b/msm/eva/cvp_core_hfi.h @@ -11,6 +11,7 @@ #include #include #include +#include #include "cvp_hfi_api.h" #include "cvp_hfi_helper.h" #include "cvp_hfi_api.h" @@ -251,6 +252,8 @@ struct iris_hfi_device { int reg_count; struct iris_resources resources; struct msm_cvp_platform_resources *res; + struct mmrm_client_desc mmrm_cvp_desc; + struct mmrm_client *mmrm_cvp; enum iris_hfi_state state; struct cvp_hfi_packetization_ops *pkt_ops; enum hfi_packetization_type packetization_type; diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 3328d9b56f..b37e39cb24 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -29,6 +29,7 @@ #include "cvp_hfi_helper.h" #include "cvp_hfi_io.h" #include "msm_cvp_dsp.h" +#include "msm_cvp_clocks.h" #define FIRMWARE_SIZE 0X00A00000 #define REG_ADDR_OFFSET_BITMASK 0x000FFFFF @@ -1250,7 +1251,6 @@ static int iris_hfi_resume(void *dev) return rc; } - static int iris_hfi_suspend(void *dev) { int rc = 0; @@ -1349,16 +1349,31 @@ static int __set_clocks(struct iris_hfi_device *device, u32 freq) freq = freq * factorsrc2clk; dprintk(CVP_PWR, "%s: clock source rate set to: %ld\n", __func__, freq); - rc = clk_set_rate(cl->clk, freq); - if (rc) { - dprintk(CVP_ERR, - "Failed to set clock rate %u %s: %d %s\n", - freq, cl->name, rc, __func__); - return rc; - } + if (device->mmrm_cvp != NULL) { + /* set min freq as the value stored as 1st element in the table */ + rc = msm_cvp_mmrm_set_value_in_range(device, + device->res->allowed_clks_tbl[0].clock_rate * factorsrc2clk, + freq); + if (rc) { + dprintk(CVP_ERR, + "%s: Failed to set clock rate for %s: %d\n", + __func__, cl->name, rc); + return rc; + } + } else { + dprintk(CVP_PWR, "%s: set clock rate with clk_set_rate\n", + __func__); + rc = clk_set_rate(cl->clk, freq); + if (rc) { + dprintk(CVP_ERR, + "Failed to set clock rate %u %s: %d %s\n", + freq, cl->name, rc, __func__); + return rc; + } - dprintk(CVP_PWR, "Scaling clock %s to %u\n", + dprintk(CVP_PWR, "Scaling clock %s to %u\n", cl->name, freq); + } } } @@ -2123,6 +2138,15 @@ static int iris_hfi_core_init(void *device) cpu_latency_qos_add_request(&dev->qos, dev->res->pm_qos_latency_us); + /* mmrm registration */ + if (msm_cvp_mmrm_enabled) { + rc = msm_cvp_mmrm_register(device); + if (rc) { + dprintk(CVP_ERR, "Failed to register mmrm client\n"); + goto err_core_init; + } + } + mutex_unlock(&dev->lock); cvp_dsp_send_hfi_queue(); @@ -2162,6 +2186,21 @@ static int iris_hfi_core_release(void *dev) __dsp_shutdown(device, 0); + if (msm_cvp_mmrm_enabled) { + rc = mmrm_client_deregister(device->mmrm_cvp); + if (rc) { + dprintk(CVP_ERR, + "%s: Failed mmrm_client_deregister with rc: %d\n", + __func__, rc); + } else { + dprintk(CVP_PWR, + "%s: Succeed mmrm_client_deregister for mmrm_cvp:%p, type:%d, uid:%ld\n", + __func__, device->mmrm_cvp, device->mmrm_cvp->client_type, + device->mmrm_cvp->client_uid); + device->mmrm_cvp = NULL; + } + } + __unload_fw(device); /* unlink all sessions from device */ @@ -3474,9 +3513,20 @@ static inline int __prepare_enable_clks(struct iris_hfi_device *device) * them. Since we don't really have a load at this point, scale * it to the lowest frequency possible */ - if (cl->has_scaling) - clk_set_rate(cl->clk, clk_round_rate(cl->clk, 0)); - + if (cl->has_scaling) { + if (device->mmrm_cvp != NULL) { + // set min freq and cur freq to 0; + rc = msm_cvp_mmrm_set_value_in_range(device, 0, 0); + if (rc) + dprintk(CVP_ERR, + "%s Failed to set clock rate for %s: %d\n", + __func__, cl->name, rc); + } else { + dprintk(CVP_PWR, "%s: set clock rate with clk_set_rate\n", + __func__); + clk_set_rate(cl->clk, clk_round_rate(cl->clk, 0)); + } + } rc = clk_prepare_enable(cl->clk); if (rc) { dprintk(CVP_ERR, "Failed to enable clocks\n"); diff --git a/msm/eva/msm_cvp_clocks.c b/msm/eva/msm_cvp_clocks.c index 5e2324e423..a545ac97e4 100644 --- a/msm/eva/msm_cvp_clocks.c +++ b/msm/eva/msm_cvp_clocks.c @@ -23,3 +23,82 @@ int msm_cvp_set_clocks(struct msm_cvp_core *core) hdev->hfi_device_data, core->curr_freq); return rc; } + +int msm_cvp_mmrm_register(struct iris_hfi_device *device) +{ + int rc = 0; + struct clock_info *cl = NULL; + char *name = (char *)device->mmrm_cvp_desc.client_info.desc.name; + + if (!device) { + dprintk(CVP_ERR, "%s invalid device\n", __func__); + return -EINVAL; + } + + device->mmrm_cvp = NULL; + device->mmrm_cvp_desc.client_type = MMRM_CLIENT_CLOCK; + device->mmrm_cvp_desc.client_info.desc.client_domain = MMRM_CLIENT_DOMAIN_CVP; + /* TODO: use proper way to retrieve client id via dtsi */ + device->mmrm_cvp_desc.client_info.desc.client_id = 8; + + iris_hfi_for_each_clock(device, cl) { + if (cl->has_scaling) { /* only clk source enabled in dtsi */ + device->mmrm_cvp_desc.client_info.desc.clk = cl->clk; + strlcpy(name, cl->name, + sizeof(device->mmrm_cvp_desc.client_info.desc.name)); + } + } + device->mmrm_cvp_desc.priority = MMRM_CLIENT_PRIOR_LOW; + + dprintk(CVP_PWR, + "%s: Register for %s\n", + __func__, device->mmrm_cvp_desc.client_info.desc.name); + + device->mmrm_cvp = mmrm_client_register(&(device->mmrm_cvp_desc)); + if (device->mmrm_cvp == NULL) { + dprintk(CVP_ERR, "%s: Failed mmrm_client_register with mmrm_cvp: %p\n", + __func__, device->mmrm_cvp); + rc = -ENOENT; + } else { + dprintk(CVP_PWR, + "%s: Succeed mmrm_client_register with mmrm_cvp: %p, type :%d, uid: %ld\n", + __func__, device->mmrm_cvp, + device->mmrm_cvp->client_type, device->mmrm_cvp->client_uid); + } + + return rc; +} + +int msm_cvp_mmrm_set_value_in_range(struct iris_hfi_device *device, u32 freq_min, u32 freq_cur) +{ + int rc = 0; + struct mmrm_client_res_value val; + struct mmrm_client_data data; + + if (!device) { + dprintk(CVP_ERR, "%s invalid device\n", __func__); + return -EINVAL; + } + + dprintk(CVP_PWR, + "%s: set clock rate for mmrm_cvp: %p, type :%d, uid: %ld\n", + __func__, device->mmrm_cvp, + device->mmrm_cvp->client_type, device->mmrm_cvp->client_uid); + + val.min = freq_min; + val.cur = freq_cur; + data.num_hw_blocks = 1; + data.flags = 0; /* Not MMRM_CLIENT_DATA_FLAG_RESERVE_ONLY */ + + dprintk(CVP_PWR, + "%s: set clock rate to min %u cur %u: %d\n", + __func__, val.min, val.cur, rc); + + rc = mmrm_client_set_value_in_range(device->mmrm_cvp, &data, &val); + if (rc) { + dprintk(CVP_ERR, + "%s: Failed to set clock rate to min %u cur %u: %d\n", + __func__, val.min, val.cur, rc); + } + return rc; +} diff --git a/msm/eva/msm_cvp_clocks.h b/msm/eva/msm_cvp_clocks.h index 5a1b77331f..df6e28a25c 100644 --- a/msm/eva/msm_cvp_clocks.h +++ b/msm/eva/msm_cvp_clocks.h @@ -7,6 +7,10 @@ #ifndef _MSM_CVP_CLOCKS_H_ #define _MSM_CVP_CLOCKS_H_ #include "msm_cvp_internal.h" +#include "cvp_core_hfi.h" int msm_cvp_set_clocks(struct msm_cvp_core *core); +int msm_cvp_mmrm_register(struct iris_hfi_device *device); +int msm_cvp_mmrm_set_value_in_range(struct iris_hfi_device *device, u32 freq_min, u32 freq_cur); + #endif diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index ae35c70c58..0c0c7ab273 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -27,6 +27,7 @@ bool msm_cvp_cacheop_disabled = !true; int msm_cvp_clock_voting = !1; bool msm_cvp_syscache_disable = !true; bool msm_cvp_dsp_disable = !true; +bool msm_cvp_mmrm_enabled = true; #define MAX_DBG_BUF_SIZE 4096 diff --git a/msm/eva/msm_cvp_debug.h b/msm/eva/msm_cvp_debug.h index 1d57d6c770..c1fb775663 100644 --- a/msm/eva/msm_cvp_debug.h +++ b/msm/eva/msm_cvp_debug.h @@ -63,6 +63,7 @@ extern bool msm_cvp_cacheop_disabled; extern int msm_cvp_clock_voting; extern bool msm_cvp_syscache_disable; extern bool msm_cvp_dsp_disable; +extern bool msm_cvp_mmrm_enabled; #define dprintk(__level, __fmt, arg...) \ do { \ From d091c137582033fc745e7f299b1ce31ab91a115b Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 22 Mar 2021 16:03:22 -0700 Subject: [PATCH 041/317] msm: eva: Fix a dsp session list iterating issue Use dsp_list instead of generic list member of EVA session object when iterating session list tracked by CPU, DSP interface driver. Change-Id: I29b76f7e8adfac807830b0719456d92bb98da63d Signed-off-by: George Shen --- msm/eva/msm_cvp_dsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 620ff69751..1a8ca35151 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -819,7 +819,7 @@ int cvp_dsp_del_sess(uint32_t process_id, struct msm_cvp_inst *inst) } mutex_lock(&frpc_node->dsp_sessions.lock); list_for_each_safe(ptr, next, &frpc_node->dsp_sessions.list) { - sess = list_entry(ptr, struct msm_cvp_inst, list); + sess = list_entry(ptr, struct msm_cvp_inst, dsp_list); if (sess == inst) { dprintk(CVP_DSP, "%s Find sess %pK to be deleted\n", __func__, inst); From 98253a203d7ba6a45e40a686e02f3651e80c6cb6 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 24 Mar 2021 13:03:59 -0700 Subject: [PATCH 042/317] msm: eva: Disable excessive debug traces Prepare for L0 release. Change-Id: I427f91b9b6e255fb05ab1f52a1684ea1542ee528 Signed-off-by: George Shen --- msm/eva/msm_cvp_debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 0c0c7ab273..51b3fa3ab0 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -11,7 +11,7 @@ #define CREATE_TRACE_POINTS #define MAX_SSR_STRING_LEN 10 -int msm_cvp_debug = CVP_ERR | CVP_WARN | CVP_FW | CVP_DBG; +int msm_cvp_debug = CVP_ERR | CVP_WARN | CVP_FW; EXPORT_SYMBOL(msm_cvp_debug); int msm_cvp_debug_out = CVP_OUT_PRINTK; From d7abfce6f0f21ed4b1ce46ed22047e80d0c1c271 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Thu, 25 Mar 2021 19:37:04 -0700 Subject: [PATCH 043/317] msm: eva: obtain clk id via dt and parse obtain clock id from deviceTree file then parse in clock_info structure. Change-Id: I2c15b1c1d20ac12c0334b82534b9ad5633569d11 Signed-off-by: Yu SI --- msm/eva/msm_cvp_clocks.c | 10 +++++----- msm/eva/msm_cvp_res_parse.c | 25 +++++++++++++++++++++++-- msm/eva/msm_cvp_resources.h | 1 + 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/msm/eva/msm_cvp_clocks.c b/msm/eva/msm_cvp_clocks.c index a545ac97e4..39ce63b8a5 100644 --- a/msm/eva/msm_cvp_clocks.c +++ b/msm/eva/msm_cvp_clocks.c @@ -37,22 +37,22 @@ int msm_cvp_mmrm_register(struct iris_hfi_device *device) device->mmrm_cvp = NULL; device->mmrm_cvp_desc.client_type = MMRM_CLIENT_CLOCK; + device->mmrm_cvp_desc.priority = MMRM_CLIENT_PRIOR_LOW; device->mmrm_cvp_desc.client_info.desc.client_domain = MMRM_CLIENT_DOMAIN_CVP; - /* TODO: use proper way to retrieve client id via dtsi */ - device->mmrm_cvp_desc.client_info.desc.client_id = 8; iris_hfi_for_each_clock(device, cl) { if (cl->has_scaling) { /* only clk source enabled in dtsi */ device->mmrm_cvp_desc.client_info.desc.clk = cl->clk; + device->mmrm_cvp_desc.client_info.desc.client_id = cl->clk_id; strlcpy(name, cl->name, sizeof(device->mmrm_cvp_desc.client_info.desc.name)); } } - device->mmrm_cvp_desc.priority = MMRM_CLIENT_PRIOR_LOW; dprintk(CVP_PWR, - "%s: Register for %s\n", - __func__, device->mmrm_cvp_desc.client_info.desc.name); + "%s: Register for %s, clk_id %d\n", + __func__, device->mmrm_cvp_desc.client_info.desc.name, + device->mmrm_cvp_desc.client_info.desc.client_id); device->mmrm_cvp = mmrm_client_register(&(device->mmrm_cvp_desc)); if (device->mmrm_cvp == NULL) { diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index 3d1b428499..7e25a30bd7 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -597,6 +597,7 @@ static int msm_cvp_load_clock_table( { int rc = 0, num_clocks = 0, c = 0; struct platform_device *pdev = res->pdev; + int *clock_ids = NULL; int *clock_props = NULL; struct clock_set *clocks = &res->clock_set; @@ -609,6 +610,23 @@ static int msm_cvp_load_clock_table( goto err_load_clk_table_fail; } + clock_ids = devm_kzalloc(&pdev->dev, num_clocks * + sizeof(*clock_ids), GFP_KERNEL); + if (!clock_ids) { + dprintk(CVP_ERR, "No memory to read clock ids\n"); + rc = -ENOMEM; + goto err_load_clk_table_fail; + } + + rc = of_property_read_u32_array(pdev->dev.of_node, + "clock-ids", clock_ids, + num_clocks); + if (rc) { + dprintk(CVP_CORE, "Failed to read clock ids: %d\n", rc); + msm_cvp_mmrm_enabled = false; + dprintk(CVP_CORE, "flag msm_cvp_mmrm_enabled disabled\n"); + } + clock_props = devm_kzalloc(&pdev->dev, num_clocks * sizeof(*clock_props), GFP_KERNEL); if (!clock_props) { @@ -642,6 +660,9 @@ static int msm_cvp_load_clock_table( of_property_read_string_index(pdev->dev.of_node, "clock-names", c, &vc->name); + if (msm_cvp_mmrm_enabled == true) + vc->clk_id = clock_ids[c]; + if (clock_props[c] & CLOCK_PROP_HAS_SCALING) { vc->has_scaling = true; } else { @@ -654,8 +675,8 @@ static int msm_cvp_load_clock_table( else vc->has_mem_retention = false; - dprintk(CVP_CORE, "Found clock %s: scale-able = %s\n", vc->name, - vc->count ? "yes" : "no"); + dprintk(CVP_CORE, "Found clock %s id %d: scale-able = %s\n", + vc->name, vc->clk_id, vc->count ? "yes" : "no"); } return 0; diff --git a/msm/eva/msm_cvp_resources.h b/msm/eva/msm_cvp_resources.h index f0e5fe6b27..c39f15706f 100644 --- a/msm/eva/msm_cvp_resources.h +++ b/msm/eva/msm_cvp_resources.h @@ -54,6 +54,7 @@ struct regulator_set { struct clock_info { const char *name; + u32 clk_id; struct clk *clk; u32 count; bool has_scaling; From 98e9135563088d4290e1606050354afbc7147cbf Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 1 Apr 2021 13:13:18 -0700 Subject: [PATCH 044/317] msm: eva: Simplify EVA DSP interface Control EVA directly through kernel driver low-level functions. Add error handling in session creation. Unwind task and file reference count during buffer un-mapping. Change-Id: I1ae5ae4afd3fea8e90faee1d8fe2c1ff92eeb9c2 Signed-off-by: George Shen --- msm/eva/msm_cvp.c | 76 +-------- msm/eva/msm_cvp.h | 3 + msm/eva/msm_cvp_buf.c | 337 ++++++++++++------------------------- msm/eva/msm_cvp_buf.h | 5 + msm/eva/msm_cvp_dsp.c | 288 +++++++------------------------ msm/eva/msm_cvp_internal.h | 1 + 6 files changed, 190 insertions(+), 520 deletions(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index a406ba9dc9..9511111a12 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -14,8 +14,7 @@ struct cvp_power_level { unsigned long bw_sum; }; -static int msm_cvp_get_session_info(struct msm_cvp_inst *inst, - struct eva_kmd_session_info *session) +int msm_cvp_get_session_info(struct msm_cvp_inst *inst, u32 *session) { int rc = 0; struct msm_cvp_inst *s; @@ -30,8 +29,8 @@ static int msm_cvp_get_session_info(struct msm_cvp_inst *inst, return -ECONNRESET; s->cur_cmd_type = EVA_KMD_GET_SESSION_INFO; - session->session_id = hash32_ptr(inst->session); - dprintk(CVP_SESS, "%s: id 0x%x\n", __func__, session->session_id); + *session = hash32_ptr(inst->session); + dprintk(CVP_SESS, "%s: id 0x%x\n", __func__, *session); s->cur_cmd_type = 0; cvp_put_inst(s); @@ -963,7 +962,7 @@ static int adjust_bw_freqs(void) return rc; } -static int msm_cvp_update_power(struct msm_cvp_inst *inst) +int msm_cvp_update_power(struct msm_cvp_inst *inst) { int rc = 0; struct msm_cvp_core *core; @@ -990,68 +989,9 @@ static int msm_cvp_update_power(struct msm_cvp_inst *inst) return rc; } -static int msm_cvp_register_buffer(struct msm_cvp_inst *inst, - struct eva_kmd_buffer *buf) +int msm_cvp_session_delete(struct msm_cvp_inst *inst) { - struct cvp_hfi_device *hdev; - struct cvp_hal_session *session; - struct msm_cvp_inst *s; - int rc = 0; - - if (!inst || !inst->core || !buf) { - dprintk(CVP_ERR, "%s: invalid params\n", __func__); - return -EINVAL; - } - - if (!buf->index) - return 0; - - s = cvp_get_inst_validate(inst->core, inst); - if (!s) - return -ECONNRESET; - - inst->cur_cmd_type = EVA_KMD_REGISTER_BUFFER; - session = (struct cvp_hal_session *)inst->session; - if (!session) { - dprintk(CVP_ERR, "%s: invalid session\n", __func__); - rc = -EINVAL; - goto exit; - } - hdev = inst->core->device; - print_client_buffer(CVP_HFI, "register", inst, buf); - - rc = msm_cvp_map_buf_dsp(inst, buf); -exit: - inst->cur_cmd_type = 0; - cvp_put_inst(s); - return rc; -} - -static int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst, - struct eva_kmd_buffer *buf) -{ - struct msm_cvp_inst *s; - int rc = 0; - - if (!inst || !inst->core || !buf) { - dprintk(CVP_ERR, "%s: invalid params\n", __func__); - return -EINVAL; - } - - if (!buf->index) - return 0; - - s = cvp_get_inst_validate(inst->core, inst); - if (!s) - return -ECONNRESET; - - inst->cur_cmd_type = EVA_KMD_UNREGISTER_BUFFER; - print_client_buffer(CVP_HFI, "unregister", inst, buf); - - rc = msm_cvp_unmap_buf_dsp(inst, buf); - inst->cur_cmd_type = 0; - cvp_put_inst(s); - return rc; + return 0; } int msm_cvp_session_create(struct msm_cvp_inst *inst) @@ -1275,7 +1215,9 @@ static int msm_cvp_session_ctrl(struct msm_cvp_inst *inst, break; case SESSION_CREATE: rc = msm_cvp_session_create(inst); + break; case SESSION_DELETE: + rc = msm_cvp_session_delete(inst); break; case SESSION_INFO: default: @@ -1772,7 +1714,7 @@ int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct eva_kmd_arg *arg) struct eva_kmd_session_info *session = (struct eva_kmd_session_info *)&arg->data.session; - rc = msm_cvp_get_session_info(inst, session); + rc = msm_cvp_get_session_info(inst, &session->session_id); break; } case EVA_KMD_UPDATE_POWER: diff --git a/msm/eva/msm_cvp.h b/msm/eva/msm_cvp.h index 92ad2715ca..ff832a9a09 100644 --- a/msm/eva/msm_cvp.h +++ b/msm/eva/msm_cvp.h @@ -34,5 +34,8 @@ int msm_cvp_session_init(struct msm_cvp_inst *inst); int msm_cvp_session_deinit(struct msm_cvp_inst *inst); int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst); int msm_cvp_session_create(struct msm_cvp_inst *inst); +int msm_cvp_session_delete(struct msm_cvp_inst *inst); +int msm_cvp_get_session_info(struct msm_cvp_inst *inst, u32 *session); +int msm_cvp_update_power(struct msm_cvp_inst *inst); int cvp_stop_clean_fence_queue(struct msm_cvp_inst *inst); #endif diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index a6bbee5a63..6fb3c8ce56 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -86,30 +86,28 @@ void print_client_buffer(u32 tag, const char *str, cbuf->offset, cbuf->size, cbuf->type, cbuf->flags); } -int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) +static bool __is_buf_valid(struct msm_cvp_inst *inst, + struct eva_kmd_buffer *buf) { - int rc = 0; - bool found = false; - struct cvp_internal_buf *cbuf; - struct msm_cvp_smem *smem = NULL; struct cvp_hal_session *session; - struct dma_buf *dma_buf = NULL; + struct cvp_internal_buf *cbuf = NULL; + bool found = false; if (!inst || !inst->core || !buf) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); - return -EINVAL; + return false; } if (buf->fd < 0) { dprintk(CVP_ERR, "%s: Invalid fd = %d", __func__, buf->fd); - return 0; + return false; } if (buf->offset) { dprintk(CVP_ERR, "%s: offset is deprecated, set to 0.\n", __func__); - return -EINVAL; + return false; } session = (struct cvp_hal_session *)inst->session; @@ -121,7 +119,7 @@ int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) dprintk(CVP_ERR, "%s: buf size mismatch\n", __func__); mutex_unlock(&inst->cvpdspbufs.lock); - return -EINVAL; + return false; } found = true; break; @@ -130,131 +128,10 @@ int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) mutex_unlock(&inst->cvpdspbufs.lock); if (found) { print_internal_buffer(CVP_ERR, "duplicate", inst, cbuf); - return -EINVAL; + return false; } - dma_buf = msm_cvp_smem_get_dma_buf(buf->fd); - if (!dma_buf) { - dprintk(CVP_ERR, "%s: Invalid fd = %d", __func__, buf->fd); - return 0; - } - - cbuf = kmem_cache_zalloc(cvp_driver->buf_cache, GFP_KERNEL); - if (!cbuf) - return -ENOMEM; - - smem = kmem_cache_zalloc(cvp_driver->smem_cache, GFP_KERNEL); - if (!smem) { - kmem_cache_free(cvp_driver->buf_cache, cbuf); - return -ENOMEM; - } - - smem->dma_buf = dma_buf; - smem->bitmap_index = MAX_DMABUF_NUMS; - dprintk(CVP_MEM, "%s: dma_buf = %llx\n", __func__, dma_buf); - rc = msm_cvp_map_smem(inst, smem, "map dsp"); - if (rc) { - print_client_buffer(CVP_ERR, "map failed", inst, buf); - goto exit; - } - - if (buf->index) { - rc = cvp_dsp_register_buffer(hash32_ptr(session), buf->fd, - smem->dma_buf->size, buf->size, buf->offset, - buf->index, (uint32_t)smem->device_addr); - if (rc) { - dprintk(CVP_ERR, - "%s: failed dsp registration for fd=%d rc=%d", - __func__, buf->fd, rc); - goto exit; - } - } else { - dprintk(CVP_ERR, "%s: buf index is 0 fd=%d", __func__, buf->fd); - rc = -EINVAL; - goto exit; - } - - cbuf->smem = smem; - cbuf->fd = buf->fd; - cbuf->size = buf->size; - cbuf->offset = buf->offset; - cbuf->ownership = CLIENT; - cbuf->index = buf->index; - - mutex_lock(&inst->cvpdspbufs.lock); - list_add_tail(&cbuf->list, &inst->cvpdspbufs.list); - mutex_unlock(&inst->cvpdspbufs.lock); - - return rc; - -exit: - if (smem->device_addr) { - msm_cvp_unmap_smem(inst, smem, "unmap dsp"); - msm_cvp_smem_put_dma_buf(smem->dma_buf); - } - kmem_cache_free(cvp_driver->buf_cache, cbuf); - cbuf = NULL; - kmem_cache_free(cvp_driver->smem_cache, smem); - smem = NULL; - return rc; -} - -int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) -{ - int rc = 0; - bool found; - struct cvp_internal_buf *cbuf; - struct cvp_hal_session *session; - - if (!inst || !inst->core || !buf) { - dprintk(CVP_ERR, "%s: invalid params\n", __func__); - return -EINVAL; - } - - session = (struct cvp_hal_session *)inst->session; - if (!session) { - dprintk(CVP_ERR, "%s: invalid session\n", __func__); - return -EINVAL; - } - - mutex_lock(&inst->cvpdspbufs.lock); - found = false; - list_for_each_entry(cbuf, &inst->cvpdspbufs.list, list) { - if (cbuf->fd == buf->fd) { - found = true; - break; - } - } - mutex_unlock(&inst->cvpdspbufs.lock); - if (!found) { - print_client_buffer(CVP_ERR, "invalid", inst, buf); - return -EINVAL; - } - - if (buf->index) { - rc = cvp_dsp_deregister_buffer(hash32_ptr(session), buf->fd, - cbuf->smem->dma_buf->size, buf->size, buf->offset, - buf->index, (uint32_t)cbuf->smem->device_addr); - if (rc) { - dprintk(CVP_ERR, - "%s: failed dsp deregistration fd=%d rc=%d", - __func__, buf->fd, rc); - return rc; - } - } - - if (cbuf->smem->device_addr) { - msm_cvp_unmap_smem(inst, cbuf->smem, "unmap dsp"); - msm_cvp_smem_put_dma_buf(cbuf->smem->dma_buf); - } - - mutex_lock(&inst->cvpdspbufs.lock); - list_del(&cbuf->list); - mutex_unlock(&inst->cvpdspbufs.lock); - - kmem_cache_free(cvp_driver->smem_cache, cbuf->smem); - kmem_cache_free(cvp_driver->buf_cache, cbuf); - return rc; + return true; } static struct file *msm_cvp_fget(unsigned int fd, struct task_struct *task, @@ -292,119 +169,54 @@ static struct dma_buf *cvp_dma_buf_get(struct file *file, int fd, return file->private_data; } -int msm_cvp_map_buf_dsp_new(struct msm_cvp_inst *inst, - struct eva_kmd_buffer *buf, - int32_t pid, uint32_t *iova) +int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) { int rc = 0; - bool found = false; - struct cvp_internal_buf *cbuf; + struct cvp_internal_buf *cbuf = NULL; struct msm_cvp_smem *smem = NULL; - struct cvp_hal_session *session; struct dma_buf *dma_buf = NULL; - - struct pid *pid_s = NULL; - struct task_struct *task = NULL; struct file *file; - if (!inst || !inst->core || !buf) { - dprintk(CVP_ERR, "%s: invalid params\n", __func__); + if (!__is_buf_valid(inst, buf)) return -EINVAL; - } - if (buf->fd < 0) { - dprintk(CVP_ERR, "%s: Invalid fd = %d", __func__, buf->fd); - return 0; - } - - if (buf->offset) { - dprintk(CVP_ERR, - "%s: offset is deprecated, set to 0.\n", - __func__); + if (!inst->task) return -EINVAL; - } - session = (struct cvp_hal_session *)inst->session; - - mutex_lock(&inst->cvpdspbufs.lock); - list_for_each_entry(cbuf, &inst->cvpdspbufs.list, list) { - if (cbuf->fd == buf->fd) { - if (cbuf->size != buf->size) { - dprintk(CVP_ERR, "%s: buf size mismatch\n", - __func__); - mutex_unlock(&inst->cvpdspbufs.lock); - return -EINVAL; - } - found = true; - break; - } - } - mutex_unlock(&inst->cvpdspbufs.lock); - if (found) { - print_internal_buffer(CVP_ERR, "duplicate", inst, cbuf); - return -EINVAL; - } - - pid_s = find_get_pid(pid); - - - if (pid_s == NULL) { - dprintk(CVP_WARN, "%s incorrect pid\n", __func__); - return -EINVAL; - } - dprintk(CVP_DSP, "%s get pid_s 0x%x from pidA 0x%x\n", __func__, pid_s, pid); - /* task = get_pid_task(pid, PIDTYPE_PID); */ - task = get_pid_task(pid_s, PIDTYPE_TGID); - - if (!task) { - dprintk(CVP_WARN, "%s task doesn't exist\n", __func__); - return -EINVAL; - } - - file = msm_cvp_fget(buf->fd, task, FMODE_PATH, 1); + file = msm_cvp_fget(buf->fd, inst->task, FMODE_PATH, 1); if (file == NULL) { dprintk(CVP_WARN, "%s fail to get file from fd\n", __func__); - put_task_struct(task); return -EINVAL; } - //entry->file = file; dma_buf = cvp_dma_buf_get( file, buf->fd, - task); + inst->task); if (dma_buf == ERR_PTR(-EINVAL)) { dprintk(CVP_ERR, "%s: Invalid fd = %d", __func__, buf->fd); - fput(file); - put_task_struct(task); - return -EINVAL; + rc = -EINVAL; + goto exit; } - dprintk(CVP_WARN, "dma_buf from internal %llu\n", dma_buf); - /* to unmap dsp buf, below sequence is required - * fput(file); - * dma_buf_put(dma_buf); - * put_task_struct(task); - */ - - if (!dma_buf) { - dprintk(CVP_ERR, "%s: Invalid fd = %d", __func__, buf->fd); - return 0; - } + dprintk(CVP_MEM, "dma_buf from internal %llu\n", dma_buf); cbuf = kmem_cache_zalloc(cvp_driver->buf_cache, GFP_KERNEL); - if (!cbuf) - return -ENOMEM; + if (!cbuf) { + rc = -ENOMEM; + goto exit; + } smem = kmem_cache_zalloc(cvp_driver->smem_cache, GFP_KERNEL); if (!smem) { - kmem_cache_free(cvp_driver->buf_cache, cbuf); - return -ENOMEM; + rc = -ENOMEM; + goto exit; } smem->dma_buf = dma_buf; + smem->file = file; smem->bitmap_index = MAX_DMABUF_NUMS; - dprintk(CVP_DSP, "%s: dma_buf = %llx\n", __func__, dma_buf); + dprintk(CVP_MEM, "%s: dma_buf = %llx\n", __func__, dma_buf); rc = msm_cvp_map_smem(inst, smem, "map dsp"); if (rc) { print_client_buffer(CVP_ERR, "map failed", inst, buf); @@ -418,10 +230,7 @@ int msm_cvp_map_buf_dsp_new(struct msm_cvp_inst *inst, cbuf->ownership = CLIENT; cbuf->index = buf->index; - *iova = (uint32_t)smem->device_addr; - - dprintk(CVP_DSP, "%s: buf->fd %d, device_addr = %llx\n", - __func__, buf->fd, (uint32_t)smem->device_addr); + buf->reserved[0] = (uint32_t)smem->device_addr; mutex_lock(&inst->cvpdspbufs.lock); list_add_tail(&cbuf->list, &inst->cvpdspbufs.list); @@ -430,19 +239,20 @@ int msm_cvp_map_buf_dsp_new(struct msm_cvp_inst *inst, return rc; exit: - if (smem->device_addr) { - msm_cvp_unmap_smem(inst, smem, "unmap dsp"); - msm_cvp_smem_put_dma_buf(smem->dma_buf); + fput(file); + if (smem) { + if (smem->device_addr) { + msm_cvp_unmap_smem(inst, smem, "unmap dsp"); + msm_cvp_smem_put_dma_buf(smem->dma_buf); + } + kmem_cache_free(cvp_driver->smem_cache, smem); } - kmem_cache_free(cvp_driver->buf_cache, cbuf); - cbuf = NULL; - kmem_cache_free(cvp_driver->smem_cache, smem); - smem = NULL; + if (cbuf) + kmem_cache_free(cvp_driver->buf_cache, cbuf); return rc; } -int msm_cvp_unmap_buf_dsp_new(struct msm_cvp_inst *inst, - struct eva_kmd_buffer *buf) +int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) { int rc = 0; bool found; @@ -477,6 +287,7 @@ int msm_cvp_unmap_buf_dsp_new(struct msm_cvp_inst *inst, if (cbuf->smem->device_addr) { msm_cvp_unmap_smem(inst, cbuf->smem, "unmap dsp"); msm_cvp_smem_put_dma_buf(cbuf->smem->dma_buf); + fput(cbuf->smem->file); } mutex_lock(&inst->cvpdspbufs.lock); @@ -488,6 +299,7 @@ int msm_cvp_unmap_buf_dsp_new(struct msm_cvp_inst *inst, return rc; } + void msm_cvp_cache_operations(struct msm_cvp_smem *smem, u32 type, u32 offset, u32 size) { @@ -1316,3 +1128,72 @@ int cvp_release_dsp_buffers(struct msm_cvp_inst *inst, return rc; } + +int msm_cvp_register_buffer(struct msm_cvp_inst *inst, + struct eva_kmd_buffer *buf) +{ + struct cvp_hfi_device *hdev; + struct cvp_hal_session *session; + struct msm_cvp_inst *s; + int rc = 0; + + if (!inst || !inst->core || !buf) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + if (!buf->index) + return 0; + + s = cvp_get_inst_validate(inst->core, inst); + if (!s) + return -ECONNRESET; + + inst->cur_cmd_type = EVA_KMD_REGISTER_BUFFER; + session = (struct cvp_hal_session *)inst->session; + if (!session) { + dprintk(CVP_ERR, "%s: invalid session\n", __func__); + rc = -EINVAL; + goto exit; + } + hdev = inst->core->device; + print_client_buffer(CVP_HFI, "register", inst, buf); + + rc = msm_cvp_map_buf_dsp(inst, buf); + dprintk(CVP_DSP, "%s: fd %d, iova 0x%x\n", __func__, + buf->fd, buf->reserved[0]); +exit: + inst->cur_cmd_type = 0; + cvp_put_inst(s); + return rc; +} + +int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst, + struct eva_kmd_buffer *buf) +{ + struct msm_cvp_inst *s; + int rc = 0; + + if (!inst || !inst->core || !buf) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + if (!buf->index) + return 0; + + s = cvp_get_inst_validate(inst->core, inst); + if (!s) + return -ECONNRESET; + + inst->cur_cmd_type = EVA_KMD_UNREGISTER_BUFFER; + print_client_buffer(CVP_HFI, "unregister", inst, buf); + + rc = msm_cvp_unmap_buf_dsp(inst, buf); + inst->cur_cmd_type = 0; + cvp_put_inst(s); + return rc; +} + + + diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index fc5b048c99..b6d6f15732 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -67,6 +67,7 @@ struct msm_cvp_smem { struct list_head list; atomic_t refcount; struct dma_buf *dma_buf; + struct file *file; void *kvaddr; u32 device_addr; dma_addr_t dma_handle; @@ -203,6 +204,10 @@ int msm_cvp_map_frame(struct msm_cvp_inst *inst, struct eva_kmd_hfi_packet *in_pkt, unsigned int offset, unsigned int buf_num); void msm_cvp_unmap_frame(struct msm_cvp_inst *inst, u64 ktid); +int msm_cvp_register_buffer(struct msm_cvp_inst *inst, + struct eva_kmd_buffer *buf); +int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst, + struct eva_kmd_buffer *buf); int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst); void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst); int cvp_allocate_dsp_bufs(struct msm_cvp_inst *inst, diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 1a8ca35151..0e62c4df1a 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1062,85 +1062,16 @@ static void print_power(const struct eva_power_req *pwr_req) } } -static int msm_cvp_register_buffer_dsp(struct msm_cvp_inst *inst, - struct eva_kmd_buffer *buf, - int32_t pid, - uint32_t *iova) -{ - struct cvp_hfi_device *hdev; - struct cvp_hal_session *session; - struct msm_cvp_inst *s; - int rc = 0; - - if (!inst || !inst->core || !buf) { - dprintk(CVP_ERR, "%s: invalid params\n", __func__); - return -EINVAL; - } - - if (!buf->index) - return 0; - - s = cvp_get_inst_validate(inst->core, inst); - if (!s) - return -ECONNRESET; - - inst->cur_cmd_type = EVA_KMD_REGISTER_BUFFER; - session = (struct cvp_hal_session *)inst->session; - if (!session) { - dprintk(CVP_ERR, "%s: invalid session\n", __func__); - rc = -EINVAL; - goto exit; - } - hdev = inst->core->device; - print_client_buffer(CVP_HFI, "register", inst, buf); - - rc = msm_cvp_map_buf_dsp_new(inst, buf, pid, iova); - dprintk(CVP_DSP, "%s: fd %d, iova 0x%x\n", __func__, buf->fd, *iova); - -exit: - inst->cur_cmd_type = 0; - cvp_put_inst(s); - return rc; -} - -static int msm_cvp_unregister_buffer_dsp(struct msm_cvp_inst *inst, - struct eva_kmd_buffer *buf) -{ - struct msm_cvp_inst *s; - int rc = 0; - - if (!inst || !inst->core || !buf) { - dprintk(CVP_ERR, "%s: invalid params\n", __func__); - return -EINVAL; - } - - if (!buf->index) - return 0; - - s = cvp_get_inst_validate(inst->core, inst); - if (!s) - return -ECONNRESET; - - inst->cur_cmd_type = EVA_KMD_UNREGISTER_BUFFER; - print_client_buffer(CVP_HFI, "unregister", inst, buf); - - rc = msm_cvp_unmap_buf_dsp_new(inst, buf); - inst->cur_cmd_type = 0; - cvp_put_inst(s); - return rc; -} - static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) { struct cvp_dsp_apps *me = &gfa_cv; struct msm_cvp_inst *inst = NULL; uint64_t inst_handle = 0; - struct eva_kmd_arg *kmd; - struct eva_kmd_sys_properties *sys_prop = NULL; - struct eva_kmd_session_control *sys_ctrl = NULL; int rc = 0; struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; + struct pid *pid_s = NULL; + struct task_struct *task = NULL; cmd->ret = 0; @@ -1152,16 +1083,11 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) dsp2cpu_cmd->is_secure, dsp2cpu_cmd->pid); - kmd = kzalloc(sizeof(*kmd), GFP_KERNEL); - if (!kmd) { - dprintk(CVP_ERR, "%s kzalloc failure\n", __func__); - goto fail_frpc_driver_reg; - } - rc = eva_fastrpc_driver_register(dsp2cpu_cmd->pid); if (rc) { dprintk(CVP_ERR, "%s Register fastrpc driver fail\n", __func__); - goto fail_frpc_driver_reg; + cmd->ret = -1; + return; } inst = msm_cvp_open(MSM_CORE_CVP, MSM_CVP_DSP); @@ -1171,52 +1097,26 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) } inst->process_id = dsp2cpu_cmd->pid; - kmd->type = EVA_KMD_SET_SYS_PROPERTY; - sys_prop = (struct eva_kmd_sys_properties *)&kmd->data.sys_properties; - sys_prop->prop_num = 5; + inst->prop.kernel_mask = dsp2cpu_cmd->kernel_mask; + inst->prop.type = dsp2cpu_cmd->session_type; + inst->prop.priority = dsp2cpu_cmd->session_prio; + inst->prop.is_secure = dsp2cpu_cmd->is_secure; + inst->prop.dsp_mask = dsp2cpu_cmd->dsp_access_mask; - sys_prop->prop_data[0].prop_type = EVA_KMD_PROP_SESSION_KERNELMASK; - sys_prop->prop_data[0].data = dsp2cpu_cmd->kernel_mask; - sys_prop->prop_data[1].prop_type = EVA_KMD_PROP_SESSION_TYPE; - sys_prop->prop_data[1].data = dsp2cpu_cmd->session_type; - sys_prop->prop_data[2].prop_type = EVA_KMD_PROP_SESSION_PRIORITY; - sys_prop->prop_data[2].data = dsp2cpu_cmd->session_prio; - sys_prop->prop_data[3].prop_type = EVA_KMD_PROP_SESSION_SECURITY; - sys_prop->prop_data[3].data = dsp2cpu_cmd->is_secure; - sys_prop->prop_data[4].prop_type = EVA_KMD_PROP_SESSION_DSPMASK; - sys_prop->prop_data[4].data = dsp2cpu_cmd->dsp_access_mask; - - rc = msm_cvp_handle_syscall(inst, kmd); - if (rc) { - dprintk(CVP_ERR, "%s Failed to set sys property\n", __func__); - goto fail_set_sys_property; - } - dprintk(CVP_DSP, "%s set sys property done\n", __func__); - - - /* EVA_KMD_SESSION_CONTROL from DSP */ - memset(kmd, 0, sizeof(struct eva_kmd_arg)); - kmd->type = EVA_KMD_SESSION_CONTROL; - sys_ctrl = (struct eva_kmd_session_control *)&kmd->data.session_ctrl; - sys_ctrl->ctrl_type = SESSION_CREATE; - - rc = msm_cvp_handle_syscall(inst, kmd); + rc = msm_cvp_session_create(inst); if (rc) { dprintk(CVP_ERR, "Warning: send Session Create failed\n"); goto fail_session_create; + } else { + dprintk(CVP_DSP, "%s DSP Session Create done\n", __func__); } - dprintk(CVP_DSP, "%s send Session Create done\n", __func__); - /* Get session id */ - memset(kmd, 0, sizeof(struct eva_kmd_arg)); - kmd->type = EVA_KMD_GET_SESSION_INFO; - rc = msm_cvp_handle_syscall(inst, kmd); + rc = msm_cvp_get_session_info(inst, &cmd->session_id); if (rc) { - dprintk(CVP_ERR, "Warning: get session index failed\n"); + dprintk(CVP_ERR, "Warning: get session index failed %d\n", rc); goto fail_get_session_info; } - cmd->session_id = kmd->data.session.session_id; inst_handle = (uint64_t)inst; cmd->session_cpu_high = (uint32_t)((inst_handle & HIGH32) >> 32); @@ -1226,30 +1126,43 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) if (frpc_node) eva_fastrpc_driver_add_sess(frpc_node, inst); + pid_s = find_get_pid(inst->process_id); + if (pid_s == NULL) { + dprintk(CVP_WARN, "%s incorrect pid\n", __func__); + goto fail_get_pid; + } + dprintk(CVP_DSP, "%s get pid_s 0x%x from pidA 0x%x\n", __func__, + pid_s, inst->process_id); + + task = get_pid_task(pid_s, PIDTYPE_TGID); + if (!task) { + dprintk(CVP_WARN, "%s task doesn't exist\n", __func__); + goto fail_get_task; + } + + inst->task = task; dprintk(CVP_DSP, "%s CREATE_SESS id 0x%x, cpu_low 0x%x, cpu_high 0x%x\n", __func__, cmd->session_id, cmd->session_cpu_low, cmd->session_cpu_high); - kfree(kmd); return; +fail_get_pid: +fail_get_task: fail_get_session_info: fail_session_create: -fail_set_sys_property: + msm_cvp_close(inst); fail_msm_cvp_open: /* unregister fastrpc driver */ -fail_frpc_driver_reg: + eva_fastrpc_driver_unregister(dsp2cpu_cmd->pid, false); cmd->ret = -1; - kfree(kmd); } static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) { struct cvp_dsp_apps *me = &gfa_cv; struct msm_cvp_inst *inst; - struct eva_kmd_arg *kmd; - struct eva_kmd_session_control *sys_ctrl; int rc; struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; @@ -1271,24 +1184,11 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) return; } - kmd = kzalloc(sizeof(*kmd), GFP_KERNEL); - if (!kmd) { - dprintk(CVP_ERR, "%s kzalloc failure\n", __func__); - cmd->ret = -1; - return; - } - inst = (struct msm_cvp_inst *)ptr_dsp2cpu( dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->session_cpu_low); - kmd->type = EVA_KMD_SESSION_CONTROL; - sys_ctrl = (struct eva_kmd_session_control *)&kmd->data.session_ctrl; - - /* Session delete does nothing here */ - sys_ctrl->ctrl_type = SESSION_DELETE; - - rc = msm_cvp_handle_syscall(inst, kmd); + rc = msm_cvp_session_delete(inst); if (rc) { dprintk(CVP_ERR, "Warning: send Delete Session failed\n"); cmd->ret = -1; @@ -1305,17 +1205,18 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) /* unregister fastrpc driver */ eva_fastrpc_driver_unregister(dsp2cpu_cmd->pid, false); + if (inst->task) + put_task_struct(inst->task); + dprintk(CVP_DSP, "%s DSP2CPU_DETELE_SESSION Done\n", __func__); dsp_fail_delete: - kfree(kmd); + return; } static void __dsp_cvp_power_req(struct cvp_dsp_cmd_msg *cmd) { struct cvp_dsp_apps *me = &gfa_cv; struct msm_cvp_inst *inst; - struct eva_kmd_arg *kmd; - struct eva_kmd_sys_properties *sys_prop; int rc; struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; @@ -1326,109 +1227,46 @@ static void __dsp_cvp_power_req(struct cvp_dsp_cmd_msg *cmd) dsp2cpu_cmd->session_cpu_low, dsp2cpu_cmd->session_cpu_high); - kmd = kzalloc(sizeof(*kmd), GFP_KERNEL); - if (!kmd) { - dprintk(CVP_ERR, "%s kzalloc failure\n", __func__); - cmd->ret = -1; - return; - } - inst = (struct msm_cvp_inst *)ptr_dsp2cpu( dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->session_cpu_low); + if (!inst) { + cmd->ret = -1; + goto dsp_fail_power_req; + } + print_power(&dsp2cpu_cmd->power_req); - /* EVA_KMD_SET_SYS_PROPERTY - * Total 14 properties, 8 max once - * Need to do 2 rounds - */ - kmd->type = EVA_KMD_SET_SYS_PROPERTY; - sys_prop = (struct eva_kmd_sys_properties *)&kmd->data.sys_properties; - sys_prop->prop_num = 7; + inst->prop.fdu_cycles = dsp2cpu_cmd->power_req.clock_fdu; + inst->prop.ica_cycles = dsp2cpu_cmd->power_req.clock_ica; + inst->prop.od_cycles = dsp2cpu_cmd->power_req.clock_od; + inst->prop.mpu_cycles = dsp2cpu_cmd->power_req.clock_mpu; + inst->prop.fw_cycles = dsp2cpu_cmd->power_req.clock_fw; + inst->prop.ddr_bw = dsp2cpu_cmd->power_req.bw_ddr; + inst->prop.ddr_cache = dsp2cpu_cmd->power_req.bw_sys_cache; + inst->prop.fdu_op_cycles = dsp2cpu_cmd->power_req.op_clock_fdu; + inst->prop.ica_op_cycles = dsp2cpu_cmd->power_req.op_clock_ica; + inst->prop.od_op_cycles = dsp2cpu_cmd->power_req.op_clock_od; + inst->prop.mpu_op_cycles = dsp2cpu_cmd->power_req.op_clock_mpu; + inst->prop.fw_op_cycles = dsp2cpu_cmd->power_req.op_clock_fw; + inst->prop.ddr_op_bw = dsp2cpu_cmd->power_req.op_bw_ddr; + inst->prop.ddr_op_cache = dsp2cpu_cmd->power_req.op_bw_sys_cache; - sys_prop->prop_data[0].prop_type = EVA_KMD_PROP_PWR_FDU; - sys_prop->prop_data[0].data = - dsp2cpu_cmd->power_req.clock_fdu; - sys_prop->prop_data[1].prop_type = EVA_KMD_PROP_PWR_ICA; - sys_prop->prop_data[1].data = - dsp2cpu_cmd->power_req.clock_ica; - sys_prop->prop_data[2].prop_type = EVA_KMD_PROP_PWR_OD; - sys_prop->prop_data[2].data = - dsp2cpu_cmd->power_req.clock_od; - sys_prop->prop_data[3].prop_type = EVA_KMD_PROP_PWR_MPU; - sys_prop->prop_data[3].data = - dsp2cpu_cmd->power_req.clock_mpu; - sys_prop->prop_data[4].prop_type = EVA_KMD_PROP_PWR_FW; - sys_prop->prop_data[4].data = - dsp2cpu_cmd->power_req.clock_fw; - sys_prop->prop_data[5].prop_type = EVA_KMD_PROP_PWR_DDR; - sys_prop->prop_data[5].data = - dsp2cpu_cmd->power_req.bw_ddr; - sys_prop->prop_data[6].prop_type = EVA_KMD_PROP_PWR_SYSCACHE; - sys_prop->prop_data[6].data = - dsp2cpu_cmd->power_req.bw_sys_cache; - - rc = msm_cvp_handle_syscall(inst, kmd); - if (rc) { - dprintk(CVP_ERR, "%s Failed to set sys property\n", __func__); - cmd->ret = -1; - goto dsp_fail_power_req; - } - dprintk(CVP_DSP, "%s set sys property done part 1\n", __func__); - - /* EVA_KMD_SET_SYS_PROPERTY Round 2 */ - memset(kmd, 0, sizeof(struct eva_kmd_arg)); - kmd->type = EVA_KMD_SET_SYS_PROPERTY; - sys_prop = (struct eva_kmd_sys_properties *)&kmd->data.sys_properties; - sys_prop->prop_num = 7; - - sys_prop->prop_data[0].prop_type = EVA_KMD_PROP_PWR_FDU_OP; - sys_prop->prop_data[0].data = - dsp2cpu_cmd->power_req.op_clock_fdu; - sys_prop->prop_data[1].prop_type = EVA_KMD_PROP_PWR_ICA_OP; - sys_prop->prop_data[1].data = - dsp2cpu_cmd->power_req.op_clock_ica; - sys_prop->prop_data[2].prop_type = EVA_KMD_PROP_PWR_OD_OP; - sys_prop->prop_data[2].data = - dsp2cpu_cmd->power_req.op_clock_od; - sys_prop->prop_data[3].prop_type = EVA_KMD_PROP_PWR_MPU_OP; - sys_prop->prop_data[3].data = - dsp2cpu_cmd->power_req.op_clock_mpu; - sys_prop->prop_data[4].prop_type = EVA_KMD_PROP_PWR_FW_OP; - sys_prop->prop_data[4].data = - dsp2cpu_cmd->power_req.op_clock_fw; - sys_prop->prop_data[5].prop_type = EVA_KMD_PROP_PWR_DDR_OP; - sys_prop->prop_data[5].data = - dsp2cpu_cmd->power_req.op_bw_ddr; - sys_prop->prop_data[6].prop_type = EVA_KMD_PROP_PWR_SYSCACHE_OP; - sys_prop->prop_data[6].data = - dsp2cpu_cmd->power_req.op_bw_sys_cache; - - rc = msm_cvp_handle_syscall(inst, kmd); - if (rc) { - dprintk(CVP_ERR, "%s Failed to set sys property\n", __func__); - cmd->ret = -1; - goto dsp_fail_power_req; - } - dprintk(CVP_DSP, "%s set sys property done part 2\n", __func__); - - memset(kmd, 0, sizeof(struct eva_kmd_arg)); - kmd->type = EVA_KMD_UPDATE_POWER; - rc = msm_cvp_handle_syscall(inst, kmd); + rc = msm_cvp_update_power(inst); if (rc) { /* May need to define more error types * Check UMD implementation here: * https://opengrok.qualcomm.com/source/xref/LA.UM.9.14/vendor/qcom/proprietary/cv-noship/cvp/cpurev/src/cvpcpuRev_skel_imp_cvp2.cpp#380 */ - dprintk(CVP_ERR, "%s Failed to send update power numbers\n", __func__); + dprintk(CVP_ERR, "%s Failed update power\n", __func__); cmd->ret = -1; goto dsp_fail_power_req; } dprintk(CVP_DSP, "%s DSP2CPU_POWER_REQUEST Done\n", __func__); dsp_fail_power_req: - kfree(kmd); + return; } static void __dsp_cvp_buf_register(struct cvp_dsp_cmd_msg *cmd) @@ -1470,8 +1308,7 @@ static void __dsp_cvp_buf_register(struct cvp_dsp_cmd_msg *cmd) kmd_buf->pixelformat = 0; kmd_buf->flags = EVA_KMD_FLAG_UNSECURE; - rc = msm_cvp_register_buffer_dsp(inst, kmd_buf, - dsp2cpu_cmd->pid, &cmd->sbuf.iova); + rc = msm_cvp_register_buffer(inst, kmd_buf); if (rc) { dprintk(CVP_ERR, "%s Failed to register buffer\n", __func__); cmd->ret = -1; @@ -1479,6 +1316,7 @@ static void __dsp_cvp_buf_register(struct cvp_dsp_cmd_msg *cmd) } dprintk(CVP_DSP, "%s register buffer done\n", __func__); + cmd->sbuf.iova = kmd_buf->reserved[0]; cmd->sbuf.size = kmd_buf->size; cmd->sbuf.fd = kmd_buf->fd; cmd->sbuf.index = kmd_buf->index; @@ -1530,7 +1368,7 @@ static void __dsp_cvp_buf_deregister(struct cvp_dsp_cmd_msg *cmd) kmd_buf->pixelformat = 0; kmd_buf->flags = EVA_KMD_FLAG_UNSECURE; - rc = msm_cvp_unregister_buffer_dsp(inst, kmd_buf); + rc = msm_cvp_unregister_buffer(inst, kmd_buf); if (rc) { dprintk(CVP_ERR, "%s Failed to deregister buffer\n", __func__); cmd->ret = -1; diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index 39f5a79ad8..3c6e42d73e 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -295,6 +295,7 @@ struct msm_cvp_inst { struct msm_cvp_core *core; enum session_type session_type; u32 process_id; + struct task_struct *task; struct cvp_session_queue session_queue; struct cvp_session_queue session_queue_fence; struct cvp_session_event event_handler; From 64eb1ea98d53df21eb1af87e6977f5c973344683 Mon Sep 17 00:00:00 2001 From: Karthik Nagarajan Date: Mon, 12 Apr 2021 08:46:56 -0700 Subject: [PATCH 045/317] msm: eva: Enable query of eva workload Enable logic to provide current eva workload. Workload estimated across sessions at hardware block level. Change-Id: If8729f4ecd31b05a9b232475de9c7722845b37db Signed-off-by: Karthik Nagarajan --- msm/eva/msm_cvp.c | 75 ++++++++++++++++++++++++++++++++++++++ msm/eva/msm_cvp_internal.h | 8 ++++ 2 files changed, 83 insertions(+) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 9511111a12..7dc170be3f 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -1228,6 +1228,57 @@ static int msm_cvp_session_ctrl(struct msm_cvp_inst *inst, return rc; } +static unsigned int msm_cvp_get_hw_aggregate_cycles(enum hw_block hwblk) +{ + struct msm_cvp_core *core; + struct msm_cvp_inst *inst; + unsigned long cycles_sum = 0; + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + + if (!core) { + dprintk(CVP_ERR, "%s: invalid core\n", __func__); + return -EINVAL; + } + + mutex_lock(&core->clk_lock); + list_for_each_entry(inst, &core->instances, list) { + if (inst->state == MSM_CVP_CORE_INVALID || + inst->state == MSM_CVP_CORE_UNINIT || + !is_subblock_profile_existed(inst)) + continue; + switch (hwblk) { + case CVP_FDU: + { + cycles_sum += inst->prop.fdu_cycles; + break; + } + case CVP_ICA: + { + cycles_sum += inst->prop.ica_cycles; + break; + } + case CVP_MPU: + { + cycles_sum += inst->prop.mpu_cycles; + break; + } + case CVP_OD: + { + cycles_sum += inst->prop.od_cycles; + break; + } + default: + dprintk(CVP_ERR, "unrecognized hw block %d\n", + hwblk); + break; + } + } + mutex_unlock(&core->clk_lock); + cycles_sum = cycles_sum&0xFFFFFFFF; + return (unsigned int)cycles_sum; +} + static int msm_cvp_get_sysprop(struct msm_cvp_inst *inst, struct eva_kmd_arg *arg) { @@ -1251,6 +1302,30 @@ static int msm_cvp_get_sysprop(struct msm_cvp_inst *inst, props->prop_data[i].data = hfi->version; break; } + case EVA_KMD_PROP_PWR_FDU: + { + props->prop_data[i].data = + msm_cvp_get_hw_aggregate_cycles(CVP_FDU); + break; + } + case EVA_KMD_PROP_PWR_ICA: + { + props->prop_data[i].data = + msm_cvp_get_hw_aggregate_cycles(CVP_ICA); + break; + } + case EVA_KMD_PROP_PWR_OD: + { + props->prop_data[i].data = + msm_cvp_get_hw_aggregate_cycles(CVP_OD); + break; + } + case EVA_KMD_PROP_PWR_MPU: + { + props->prop_data[i].data = + msm_cvp_get_hw_aggregate_cycles(CVP_MPU); + break; + } default: dprintk(CVP_ERR, "unrecognized sys property %d\n", props->prop_data[i].prop_type); diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index 3c6e42d73e..6d20fe6451 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -61,6 +61,14 @@ enum cvp_core_state { * Do not change the enum values unless * you know what you are doing */ + +enum hw_block { + CVP_FDU = 0x0001, + CVP_ICA, + CVP_MPU, + CVP_OD +}; + enum instance_state { MSM_CVP_CORE_UNINIT_DONE = 0x0001, MSM_CVP_CORE_INIT, From faca8f4a0fed73b7ed5a46723a3117fa2f15acc3 Mon Sep 17 00:00:00 2001 From: palabhat Date: Mon, 19 Apr 2021 21:14:16 +0530 Subject: [PATCH 046/317] msm-eva : Changes to support cp_camera buffer mapping Change-Id: I93fb5b06f43f4099ebf7d62267ce2c9614b6d7ff --- msm/eva/msm_smem.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/msm/eva/msm_smem.c b/msm/eva/msm_smem.c index e4bc437663..f2dcd623b7 100644 --- a/msm/eva/msm_smem.c +++ b/msm/eva/msm_smem.c @@ -79,7 +79,11 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, u32 align, } if (table->sgl) { - *iova = table->sgl->dma_address; + if (flags & SMEM_CAMERA) { + *iova = sg_phys(table->sgl); + } else { + *iova = table->sgl->dma_address; + } } else { dprintk(CVP_ERR, "sgl is NULL\n"); rc = -ENOMEM; @@ -446,6 +450,8 @@ struct context_bank_info *msm_cvp_smem_get_context_bank( search_str = secure_pixel_cb; else if (flags & SMEM_NON_PIXEL) search_str = secure_nonpixel_cb; + else if (flags & SMEM_CAMERA) + search_str = secure_pixel_cb; else search_str = non_secure_cb; From ef51f2160692b359e4b0234c96a9475dd1c842a8 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Thu, 22 Apr 2021 10:46:35 -0700 Subject: [PATCH 047/317] msm: eva: avoid cache entry for unwanted buffer Error handle to avoid dereferencing of unwanted buffer during deinit Change-Id: I4d051f81f86582a16c639e33429d9c1ed893f5e5 Signed-off-by: Yu SI --- msm/eva/msm_cvp_buf.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 6fb3c8ce56..4e71290c9d 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -431,7 +431,11 @@ static struct msm_cvp_smem *msm_cvp_session_get_smem(struct msm_cvp_inst *inst, rc = msm_cvp_map_smem(inst, smem, "map cpu"); if (rc) goto exit; - + if (buf->size > smem->size || buf->size > smem->size - buf->offset) { + dprintk(CVP_ERR, "%s: invalid offset %d or size %d for a new entry\n", + __func__, buf->offset, buf->size); + goto exit2; + } rc = msm_cvp_session_add_smem(inst, smem); if (rc && rc != -ENOMEM) goto exit2; From b566b0b0913d412d50267dca81de74fe1671e41f Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 23 Apr 2021 11:42:17 -0700 Subject: [PATCH 048/317] msm: eva: Remove inappropriate comment To ensure compliance with kernel module coding convention. Change-Id: Ib511ea3df44d83078456d1de5e4651e31e0ff1dc Signed-off-by: George Shen --- msm/eva/msm_cvp_dsp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 0e62c4df1a..5c5264b437 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1255,9 +1255,9 @@ static void __dsp_cvp_power_req(struct cvp_dsp_cmd_msg *cmd) rc = msm_cvp_update_power(inst); if (rc) { - /* May need to define more error types - * Check UMD implementation here: - * https://opengrok.qualcomm.com/source/xref/LA.UM.9.14/vendor/qcom/proprietary/cv-noship/cvp/cpurev/src/cvpcpuRev_skel_imp_cvp2.cpp#380 + /* + *May need to define more error types + * Check UMD implementation */ dprintk(CVP_ERR, "%s Failed update power\n", __func__); cmd->ret = -1; From 68b7c2cfa3a9f6043424843a808f313187f61381 Mon Sep 17 00:00:00 2001 From: Ronald Karyodisa Date: Fri, 30 Apr 2021 12:41:43 -0700 Subject: [PATCH 049/317] msm: eva: Fix sum fps aggregation setting Initialize the sum fps calculation to avoid the value keep increasing. Add addional option (fps=0) to disable FD dcvs. Fix HFI header size checking. Change-Id: Ieb44b626a112205091327c7785a8c92c8c77c0b0 Signed-off-by: Ronald Karyodisa --- msm/eva/msm_cvp.c | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 7dc170be3f..df5ada125d 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -427,7 +427,7 @@ static int cvp_check_clock(struct msm_cvp_inst *inst, u32 avg_cycles = core->dyn_clk.cycle[i].total>>3; if ((avg_cycles > core->dyn_clk.hi_ctrl_lim[i]) - || (avg_cycles <= + || (avg_cycles <= core->dyn_clk.lo_ctrl_lim[i])) { rc = cvp_readjust_clock(core, avg_cycles, @@ -479,13 +479,24 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, timeout = msecs_to_jiffies(CVP_MAX_WAIT_TIME); rc = cvp_wait_process_message(inst, sq, &ktid, timeout, (struct eva_kmd_hfi_packet *)&hdr); - if (get_msg_size((struct cvp_hfi_msg_session_hdr *) &hdr) - == sizeof(struct cvp_hfi_msg_session_hdr_ext)) { + + /* Only FD support dcvs at certain FW */ + if (hdr.size == sizeof(struct cvp_hfi_msg_session_hdr_ext) + + sizeof(struct cvp_hfi_buf_type) ) { struct cvp_hfi_msg_session_hdr_ext *fhdr = (struct cvp_hfi_msg_session_hdr_ext *)&hdr; - dprintk(CVP_HFI, "busy cycle 0x%x, total 0x%x\n", + struct msm_cvp_core *core = inst->core; + dprintk(CVP_PWR, "busy cycle %d, total %d\n", fhdr->busy_cycles, fhdr->total_cycles); - clock_check = true; + + if (core && + (core->dyn_clk.sum_fps[HFI_HW_FDU] || + core->dyn_clk.sum_fps[HFI_HW_MPU] || + core->dyn_clk.sum_fps[HFI_HW_OD] || + core->dyn_clk.sum_fps[HFI_HW_ICA])) + { + clock_check = true; + } } hfi_err = hdr.error_type; if (rc) { @@ -755,6 +766,10 @@ static void aggregate_power_update(struct msm_cvp_core *core, unsigned long op_fdu_max[2] = {0}, op_od_max[2] = {0}; unsigned long op_mpu_max[2] = {0}, op_ica_max[2] = {0}; unsigned long op_fw_max[2] = {0}, bw_sum[2] = {0}, op_bw_max[2] = {0}; + core->dyn_clk.sum_fps[HFI_HW_FDU] = 0; + core->dyn_clk.sum_fps[HFI_HW_MPU] = 0; + core->dyn_clk.sum_fps[HFI_HW_OD] = 0; + core->dyn_clk.sum_fps[HFI_HW_ICA] = 0; list_for_each_entry(inst, &core->instances, list) { if (inst->state == MSM_CVP_CORE_INVALID || From e3e3be25570e8bca1c81df00b74c562b1413b408 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Mon, 3 May 2021 14:39:40 -0700 Subject: [PATCH 050/317] msm: eva: check on inst value from ptr_dsp2cpu check the validity of returned inst from ptr_dsp2cpu in func __dsp_cvp_mem_free. Change-Id: Icb2e5721aa5f8381b76e0cc4f991c48a1d74c45e Signed-off-by: Yu SI --- msm/eva/msm_cvp_dsp.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 5c5264b437..9d8a226fcc 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1486,6 +1486,12 @@ static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) inst = (struct msm_cvp_inst *)ptr_dsp2cpu( dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->session_cpu_low); + if (!inst) { + dprintk(CVP_ERR, "%s Failed to get inst\n", + __func__); + cmd->ret = -1; + return; + } frpc_node = cvp_find_fastrpc_node_with_handle(dsp2cpu_cmd->pid); if (!frpc_node) { From b78beff7acdd58cccabd31d72dd9b3a5105ea58b Mon Sep 17 00:00:00 2001 From: Yu SI Date: Tue, 13 Apr 2021 14:06:37 -0700 Subject: [PATCH 051/317] msm: eva: re-org clock related functions modularize clock related functions to clock source file Change-Id: Ifcfdcd266e0bffcfff2fe74823743be3363c7494 Signed-off-by: Yu SI --- msm/eva/cvp_core_hfi.h | 2 +- msm/eva/cvp_hfi.c | 201 ++-------------------------------- msm/eva/msm_cvp_clocks.c | 225 ++++++++++++++++++++++++++++++++++++--- msm/eva/msm_cvp_clocks.h | 10 +- 4 files changed, 228 insertions(+), 210 deletions(-) diff --git a/msm/eva/cvp_core_hfi.h b/msm/eva/cvp_core_hfi.h index c7c8ca1d73..5a9c2cec4d 100644 --- a/msm/eva/cvp_core_hfi.h +++ b/msm/eva/cvp_core_hfi.h @@ -252,7 +252,7 @@ struct iris_hfi_device { int reg_count; struct iris_resources resources; struct msm_cvp_platform_resources *res; - struct mmrm_client_desc mmrm_cvp_desc; + struct mmrm_client_desc mmrm_desc; struct mmrm_client *mmrm_cvp; enum iris_hfi_state state; struct cvp_hfi_packetization_ops *pkt_ops; diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index b37e39cb24..50773274cf 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -324,15 +324,12 @@ static inline int __resume(struct iris_hfi_device *device); static inline int __suspend(struct iris_hfi_device *device); static int __disable_regulators(struct iris_hfi_device *device); static int __enable_regulators(struct iris_hfi_device *device); -static inline int __prepare_enable_clks(struct iris_hfi_device *device); -static inline void __disable_unprepare_clks(struct iris_hfi_device *device); static void __flush_debug_queue(struct iris_hfi_device *device, u8 *packet); static int __initialize_packetization(struct iris_hfi_device *device); static struct cvp_hal_session *__get_session(struct iris_hfi_device *device, u32 session_id); static bool __is_session_valid(struct iris_hfi_device *device, struct cvp_hal_session *session, const char *func); -static int __set_clocks(struct iris_hfi_device *device, u32 freq); static int __iface_cmdq_write(struct iris_hfi_device *device, void *pkt); static int __load_fw(struct iris_hfi_device *device); @@ -1332,54 +1329,6 @@ exit: return rc; } -static int __set_clocks(struct iris_hfi_device *device, u32 freq) -{ - struct clock_info *cl; - int rc = 0; - int factorsrc2clk = 3; // ratio factor for clock source : clk - - dprintk(CVP_PWR, "%s: entering with freq : %ld\n", __func__, freq); - - iris_hfi_for_each_clock(device, cl) { - if (cl->has_scaling) {/* has_scaling */ - device->clk_freq = freq; - if (msm_cvp_clock_voting) - freq = msm_cvp_clock_voting; - - freq = freq * factorsrc2clk; - dprintk(CVP_PWR, "%s: clock source rate set to: %ld\n", __func__, freq); - - if (device->mmrm_cvp != NULL) { - /* set min freq as the value stored as 1st element in the table */ - rc = msm_cvp_mmrm_set_value_in_range(device, - device->res->allowed_clks_tbl[0].clock_rate * factorsrc2clk, - freq); - if (rc) { - dprintk(CVP_ERR, - "%s: Failed to set clock rate for %s: %d\n", - __func__, cl->name, rc); - return rc; - } - } else { - dprintk(CVP_PWR, "%s: set clock rate with clk_set_rate\n", - __func__); - rc = clk_set_rate(cl->clk, freq); - if (rc) { - dprintk(CVP_ERR, - "Failed to set clock rate %u %s: %d %s\n", - freq, cl->name, rc, __func__); - return rc; - } - - dprintk(CVP_PWR, "Scaling clock %s to %u\n", - cl->name, freq); - } - } - } - - return 0; -} - static int iris_hfi_scale_clocks(void *dev, u32 freq) { int rc = 0; @@ -1398,29 +1347,13 @@ static int iris_hfi_scale_clocks(void *dev, u32 freq) goto exit; } - rc = __set_clocks(device, freq); + rc = msm_cvp_set_clocks_impl(device, freq); exit: mutex_unlock(&device->lock); return rc; } -static int __scale_clocks(struct iris_hfi_device *device) -{ - int rc = 0; - struct allowed_clock_rates_table *allowed_clks_tbl = NULL; - u32 rate = 0; - - allowed_clks_tbl = device->res->allowed_clks_tbl; - - rate = device->clk_freq ? device->clk_freq : - allowed_clks_tbl[0].clock_rate; - - dprintk(CVP_PWR, "%s: scale clock rate %d\n", __func__, rate); - rc = __set_clocks(device, rate); - return rc; -} - /* Writes into cmdq without raising an interrupt */ static int __iface_cmdq_write_relaxed(struct iris_hfi_device *device, void *pkt, bool *requires_interrupt) @@ -3327,55 +3260,6 @@ err_core_init: } -static inline void __deinit_clocks(struct iris_hfi_device *device) -{ - struct clock_info *cl; - - device->clk_freq = 0; - iris_hfi_for_each_clock_reverse(device, cl) { - if (cl->clk) { - clk_put(cl->clk); - cl->clk = NULL; - } - } -} - -static inline int __init_clocks(struct iris_hfi_device *device) -{ - int rc = 0; - struct clock_info *cl = NULL; - - if (!device) { - dprintk(CVP_ERR, "Invalid params: %pK\n", device); - return -EINVAL; - } - - iris_hfi_for_each_clock(device, cl) { - - dprintk(CVP_PWR, "%s: scalable? %d, count %d\n", - cl->name, cl->has_scaling, cl->count); - } - - iris_hfi_for_each_clock(device, cl) { - if (!cl->clk) { - cl->clk = clk_get(&device->res->pdev->dev, cl->name); - if (IS_ERR_OR_NULL(cl->clk)) { - dprintk(CVP_ERR, - "Failed to get clock: %s\n", cl->name); - rc = PTR_ERR(cl->clk) ?: -EINVAL; - cl->clk = NULL; - goto err_clk_get; - } - } - } - device->clk_freq = 0; - return 0; - -err_clk_get: - __deinit_clocks(device); - return rc; -} - static int __handle_reset_clk(struct msm_cvp_platform_resources *res, int reset_index, enum reset_state state, enum power_state pwr_state) @@ -3440,22 +3324,6 @@ failed_to_reset: return rc; } -static inline void __disable_unprepare_clks(struct iris_hfi_device *device) -{ - struct clock_info *cl; - - if (!device) { - dprintk(CVP_ERR, "Invalid params: %pK\n", device); - return; - } - - iris_hfi_for_each_clock_reverse(device, cl) { - dprintk(CVP_PWR, "Clock: %s disable and unprepare\n", - cl->name); - clk_disable_unprepare(cl->clk); - } -} - static int reset_ahb2axi_bridge(struct iris_hfi_device *device) { int rc, i; @@ -3497,59 +3365,6 @@ failed_to_reset: return rc; } -static inline int __prepare_enable_clks(struct iris_hfi_device *device) -{ - struct clock_info *cl = NULL, *cl_fail = NULL; - int rc = 0, c = 0; - - if (!device) { - dprintk(CVP_ERR, "Invalid params: %pK\n", device); - return -EINVAL; - } - - iris_hfi_for_each_clock(device, cl) { - /* - * For the clocks we control, set the rate prior to preparing - * them. Since we don't really have a load at this point, scale - * it to the lowest frequency possible - */ - if (cl->has_scaling) { - if (device->mmrm_cvp != NULL) { - // set min freq and cur freq to 0; - rc = msm_cvp_mmrm_set_value_in_range(device, 0, 0); - if (rc) - dprintk(CVP_ERR, - "%s Failed to set clock rate for %s: %d\n", - __func__, cl->name, rc); - } else { - dprintk(CVP_PWR, "%s: set clock rate with clk_set_rate\n", - __func__); - clk_set_rate(cl->clk, clk_round_rate(cl->clk, 0)); - } - } - rc = clk_prepare_enable(cl->clk); - if (rc) { - dprintk(CVP_ERR, "Failed to enable clocks\n"); - cl_fail = cl; - goto fail_clk_enable; - } - - c++; - dprintk(CVP_PWR, "Clock: %s prepared and enabled\n", cl->name); - } - - return rc; - -fail_clk_enable: - iris_hfi_for_each_clock_reverse_continue(device, cl, c) { - dprintk(CVP_ERR, "Clock: %s disable and unprepare\n", - cl->name); - clk_disable_unprepare(cl->clk); - } - - return rc; -} - static void __deinit_bus(struct iris_hfi_device *device) { struct bus_info *bus = NULL; @@ -3717,7 +3532,7 @@ static int __init_resources(struct iris_hfi_device *device, return -ENODEV; } - rc = __init_clocks(device); + rc = msm_cvp_init_clocks(device); if (rc) { dprintk(CVP_ERR, "Failed to init clocks\n"); rc = -ENODEV; @@ -3751,7 +3566,7 @@ static int __init_resources(struct iris_hfi_device *device, err_init_reset_clk: err_init_bus: - __deinit_clocks(device); + msm_cvp_deinit_clocks(device); err_init_clocks: __deinit_regulators(device); return rc; @@ -3761,7 +3576,7 @@ static void __deinit_resources(struct iris_hfi_device *device) { __deinit_subcaches(device); __deinit_bus(device); - __deinit_clocks(device); + msm_cvp_deinit_clocks(device); __deinit_regulators(device); kfree(device->sys_init_capabilities); device->sys_init_capabilities = NULL; @@ -4122,13 +3937,13 @@ static int __iris_power_on(struct iris_hfi_device *device) goto fail_enable_clks; } - rc = __prepare_enable_clks(device); + rc = msm_cvp_prepare_enable_clks(device); if (rc) { dprintk(CVP_ERR, "Failed to enable clocks: %d\n", rc); goto fail_enable_clks; } - rc = __scale_clocks(device); + rc = msm_cvp_scale_clocks(device); if (rc) { dprintk(CVP_WARN, "Failed to scale clocks, perf may regress\n"); @@ -4171,7 +3986,7 @@ void power_off_common(struct iris_hfi_device *device) disable_irq_nosync(device->cvp_hal_data->irq); device->intr_status = 0; - __disable_unprepare_clks(device); + msm_cvp_disable_unprepare_clks(device); if (__disable_regulators(device)) dprintk(CVP_WARN, "Failed to disable regulators\n"); @@ -4281,7 +4096,7 @@ static void power_off_iris2(struct iris_hfi_device *device) } /* HPG 6.1.2 Step 6 */ - __disable_unprepare_clks(device); + msm_cvp_disable_unprepare_clks(device); /* * HPG 6.1.2 Step 7 & 8 diff --git a/msm/eva/msm_cvp_clocks.c b/msm/eva/msm_cvp_clocks.c index 39ce63b8a5..728a3c6b76 100644 --- a/msm/eva/msm_cvp_clocks.c +++ b/msm/eva/msm_cvp_clocks.c @@ -28,48 +28,51 @@ int msm_cvp_mmrm_register(struct iris_hfi_device *device) { int rc = 0; struct clock_info *cl = NULL; - char *name = (char *)device->mmrm_cvp_desc.client_info.desc.name; + char *name = (char *)device->mmrm_desc.client_info.desc.name; if (!device) { dprintk(CVP_ERR, "%s invalid device\n", __func__); return -EINVAL; } - device->mmrm_cvp = NULL; - device->mmrm_cvp_desc.client_type = MMRM_CLIENT_CLOCK; - device->mmrm_cvp_desc.priority = MMRM_CLIENT_PRIOR_LOW; - device->mmrm_cvp_desc.client_info.desc.client_domain = MMRM_CLIENT_DOMAIN_CVP; + device->mmrm_cvp=NULL; + device->mmrm_desc.client_type=MMRM_CLIENT_CLOCK; + device->mmrm_desc.priority=MMRM_CLIENT_PRIOR_LOW; + device->mmrm_desc.client_info.desc.client_domain=MMRM_CLIENT_DOMAIN_CVP; iris_hfi_for_each_clock(device, cl) { if (cl->has_scaling) { /* only clk source enabled in dtsi */ - device->mmrm_cvp_desc.client_info.desc.clk = cl->clk; - device->mmrm_cvp_desc.client_info.desc.client_id = cl->clk_id; + device->mmrm_desc.client_info.desc.clk=cl->clk; + device->mmrm_desc.client_info.desc.client_id=cl->clk_id; strlcpy(name, cl->name, - sizeof(device->mmrm_cvp_desc.client_info.desc.name)); + sizeof(device->mmrm_desc.client_info.desc.name)); } } dprintk(CVP_PWR, "%s: Register for %s, clk_id %d\n", - __func__, device->mmrm_cvp_desc.client_info.desc.name, - device->mmrm_cvp_desc.client_info.desc.client_id); + __func__, device->mmrm_desc.client_info.desc.name, + device->mmrm_desc.client_info.desc.client_id); - device->mmrm_cvp = mmrm_client_register(&(device->mmrm_cvp_desc)); + device->mmrm_cvp = mmrm_client_register(&(device->mmrm_desc)); if (device->mmrm_cvp == NULL) { - dprintk(CVP_ERR, "%s: Failed mmrm_client_register with mmrm_cvp: %p\n", + dprintk(CVP_ERR, + "%s: Failed mmrm_client_register with mmrm_cvp: %p\n", __func__, device->mmrm_cvp); rc = -ENOENT; } else { dprintk(CVP_PWR, - "%s: Succeed mmrm_client_register with mmrm_cvp: %p, type :%d, uid: %ld\n", + "%s: mmrm_client_register done: %p, type:%d, uid:%ld\n", __func__, device->mmrm_cvp, - device->mmrm_cvp->client_type, device->mmrm_cvp->client_uid); + device->mmrm_cvp->client_type, + device->mmrm_cvp->client_uid); } return rc; } -int msm_cvp_mmrm_set_value_in_range(struct iris_hfi_device *device, u32 freq_min, u32 freq_cur) +int msm_cvp_mmrm_set_value_in_range(struct iris_hfi_device *device, + u32 freq_min, u32 freq_cur) { int rc = 0; struct mmrm_client_res_value val; @@ -102,3 +105,195 @@ int msm_cvp_mmrm_set_value_in_range(struct iris_hfi_device *device, u32 freq_min } return rc; } + +int msm_cvp_set_clocks_impl(struct iris_hfi_device *device, u32 freq) +{ + struct clock_info *cl; + int rc = 0; + int fsrc2clk = 3; + // ratio factor for clock source : clk + u32 freq_min = device->res->allowed_clks_tbl[0].clock_rate * fsrc2clk; + + dprintk(CVP_PWR, "%s: entering with freq : %ld\n", __func__, freq); + + iris_hfi_for_each_clock(device, cl) { + if (cl->has_scaling) {/* has_scaling */ + device->clk_freq = freq; + if (msm_cvp_clock_voting) + freq = msm_cvp_clock_voting; + + freq = freq * fsrc2clk; + dprintk(CVP_PWR, + "%s: clock source rate set to: %ld\n", + __func__, freq); + + if (device->mmrm_cvp != NULL) { + /* min freq : 1st element value in the table */ + rc = msm_cvp_mmrm_set_value_in_range(device, + freq_min, freq); + if (rc) { + dprintk(CVP_ERR, + "Failed set clock %s: %d\n", + cl->name, rc); + return rc; + } + } + else { + dprintk(CVP_PWR, + "%s: set clock with clk_set_rate\n", + __func__); + rc = clk_set_rate(cl->clk, freq); + if (rc) { + dprintk(CVP_ERR, + "Failed set clock %u %s: %d\n", + freq, cl->name, rc); + return rc; + } + + dprintk(CVP_PWR, "Scaling clock %s to %u\n", + cl->name, freq); + } + } + } + + return 0; +} + +int msm_cvp_scale_clocks(struct iris_hfi_device *device) +{ + int rc = 0; + struct allowed_clock_rates_table *allowed_clks_tbl = NULL; + u32 rate = 0; + + allowed_clks_tbl = device->res->allowed_clks_tbl; + + rate = device->clk_freq ? device->clk_freq : + allowed_clks_tbl[0].clock_rate; + + dprintk(CVP_PWR, "%s: scale clock rate %d\n", __func__, rate); + rc = msm_cvp_set_clocks_impl(device, rate); + return rc; +} + +int msm_cvp_prepare_enable_clks(struct iris_hfi_device *device) +{ + struct clock_info *cl = NULL, *cl_fail = NULL; + int rc = 0, c = 0; + + if (!device) { + dprintk(CVP_ERR, "Invalid params: %pK\n", device); + return -EINVAL; + } + + iris_hfi_for_each_clock(device, cl) { + /* + * For the clocks we control, set the rate prior to preparing + * them. Since we don't really have a load at this point, + * scale it to the lowest frequency possible + */ + if (cl->has_scaling) { + if (device->mmrm_cvp != NULL) { + // set min freq and cur freq to 0; + rc = msm_cvp_mmrm_set_value_in_range(device, + 0, 0); + if (rc) + dprintk(CVP_ERR, + "%s Failed set clock %s: %d\n", + __func__, cl->name, rc); + } + else { + dprintk(CVP_PWR, + "%s: set clock with clk_set_rate\n", + __func__); + clk_set_rate(cl->clk, + clk_round_rate(cl->clk, 0)); + } + } + rc = clk_prepare_enable(cl->clk); + if (rc) { + dprintk(CVP_ERR, "Failed to enable clocks\n"); + cl_fail = cl; + goto fail_clk_enable; + } + + c++; + dprintk(CVP_PWR, "Clock: %s prepared and enabled\n", + cl->name); + } + + return rc; + +fail_clk_enable: + iris_hfi_for_each_clock_reverse_continue(device, cl, c) { + dprintk(CVP_ERR, "Clock: %s disable and unprepare\n", + cl->name); + clk_disable_unprepare(cl->clk); + } + + return rc; +} + +void msm_cvp_disable_unprepare_clks(struct iris_hfi_device *device) +{ + struct clock_info *cl; + + if (!device) { + dprintk(CVP_ERR, "Invalid params: %pK\n", device); + return; + } + + iris_hfi_for_each_clock_reverse(device, cl) { + dprintk(CVP_PWR, "Clock: %s disable and unprepare\n", + cl->name); + clk_disable_unprepare(cl->clk); + } +} + +int msm_cvp_init_clocks(struct iris_hfi_device *device) +{ + int rc = 0; + struct clock_info *cl = NULL; + + if (!device) { + dprintk(CVP_ERR, "Invalid params: %pK\n", device); + return -EINVAL; + } + + iris_hfi_for_each_clock(device, cl) { + + dprintk(CVP_PWR, "%s: scalable? %d, count %d\n", + cl->name, cl->has_scaling, cl->count); + } + + iris_hfi_for_each_clock(device, cl) { + if (!cl->clk) { + cl->clk = clk_get(&device->res->pdev->dev, cl->name); + if (IS_ERR_OR_NULL(cl->clk)) { + dprintk(CVP_ERR, + "Failed to get clock: %s\n", cl->name); + rc = PTR_ERR(cl->clk) ? : -EINVAL; + cl->clk = NULL; + goto err_clk_get; + } + } + } + device->clk_freq = 0; + return 0; + +err_clk_get: + msm_cvp_deinit_clocks(device); + return rc; +} + +void msm_cvp_deinit_clocks(struct iris_hfi_device *device) +{ + struct clock_info *cl; + + device->clk_freq = 0; + iris_hfi_for_each_clock_reverse(device, cl) { + if (cl->clk) { + clk_put(cl->clk); + cl->clk = NULL; + } + } +} diff --git a/msm/eva/msm_cvp_clocks.h b/msm/eva/msm_cvp_clocks.h index df6e28a25c..0660da328b 100644 --- a/msm/eva/msm_cvp_clocks.h +++ b/msm/eva/msm_cvp_clocks.h @@ -12,5 +12,13 @@ int msm_cvp_set_clocks(struct msm_cvp_core *core); int msm_cvp_mmrm_register(struct iris_hfi_device *device); int msm_cvp_mmrm_set_value_in_range(struct iris_hfi_device *device, u32 freq_min, u32 freq_cur); - +int msm_cvp_set_clocks_impl(struct iris_hfi_device *device, u32 freq); +int msm_cvp_scale_clocks(struct iris_hfi_device *device); +//below APIs previously declared as inline +//static inline int __prepare_enable_clks(struct iris_hfi_device *device); +int msm_cvp_prepare_enable_clks(struct iris_hfi_device *device); +//static inline void __disable_unprepare_clks(struct iris_hfi_device *device); +void msm_cvp_disable_unprepare_clks(struct iris_hfi_device *device); +int msm_cvp_init_clocks(struct iris_hfi_device *device); +void msm_cvp_deinit_clocks(struct iris_hfi_device *device); #endif From fe9fae2af4aae4153a976ce697330dcb99f0d7e5 Mon Sep 17 00:00:00 2001 From: Ronald Karyodisa Date: Tue, 4 May 2021 15:07:38 -0700 Subject: [PATCH 052/317] msm: eva: Add debug option to disable DCVS Add debug option using debugfs to disable DCVS. Add extra check for DCVS. Change-Id: I989ef72857dde306fa0ca9466843ebc1d2b30f85 Signed-off-by: Ronald Karyodisa --- msm/eva/msm_cvp.c | 39 ++++++++++++++++++++------------------- msm/eva/msm_cvp_debug.c | 5 +++++ msm/eva/msm_cvp_debug.h | 1 + 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index df5ada125d..17cf7c153b 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -292,10 +292,17 @@ static int cvp_readjust_clock(struct msm_cvp_core *core, unsigned long lo_freq = 0; u32 j; - dprintk(CVP_PWR, - "%s:%d - %d - avg_cycles %u > hi_tresh %u\n", - __func__, __LINE__, i, avg_cycles, - core->dyn_clk.hi_ctrl_lim[i]); + tbl = core->resources.allowed_clks_tbl; + tbl_size = core->resources.allowed_clks_tbl_size; + cvp_min_rate = tbl[0].clock_rate; + cvp_max_rate = tbl[tbl_size - 1].clock_rate; + + if (!((avg_cycles > core->dyn_clk.hi_ctrl_lim[i] && + core->curr_freq != cvp_max_rate) || + (avg_cycles <= core->dyn_clk.lo_ctrl_lim[i] && + core->curr_freq != cvp_min_rate))) { + return rc; + } core->curr_freq = ((avg_cycles * core->dyn_clk.sum_fps[i]) << 1)/3; dprintk(CVP_PWR, @@ -306,11 +313,6 @@ static int cvp_readjust_clock(struct msm_cvp_core *core, core->dyn_clk.sum_fps[i], core->curr_freq); - tbl = core->resources.allowed_clks_tbl; - tbl_size = core->resources.allowed_clks_tbl_size; - cvp_min_rate = tbl[0].clock_rate; - cvp_max_rate = tbl[tbl_size - 1].clock_rate; - if (core->curr_freq > cvp_max_rate) { core->curr_freq = cvp_max_rate; lo_freq = (tbl_size > 1) ? @@ -426,13 +428,10 @@ static int cvp_check_clock(struct msm_cvp_inst *inst, && core->dyn_clk.hi_ctrl_lim[i] != 0) { u32 avg_cycles = core->dyn_clk.cycle[i].total>>3; - if ((avg_cycles > core->dyn_clk.hi_ctrl_lim[i]) - || (avg_cycles <= - core->dyn_clk.lo_ctrl_lim[i])) { - rc = cvp_readjust_clock(core, - avg_cycles, - i); - } + + rc = cvp_readjust_clock(core, + avg_cycles, + i); } } } @@ -481,8 +480,9 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, (struct eva_kmd_hfi_packet *)&hdr); /* Only FD support dcvs at certain FW */ - if (hdr.size == sizeof(struct cvp_hfi_msg_session_hdr_ext) - + sizeof(struct cvp_hfi_buf_type) ) { + if (!msm_cvp_dcvs_disable && + (hdr.size == sizeof(struct cvp_hfi_msg_session_hdr_ext) + + sizeof(struct cvp_hfi_buf_type))) { struct cvp_hfi_msg_session_hdr_ext *fhdr = (struct cvp_hfi_msg_session_hdr_ext *)&hdr; struct msm_cvp_core *core = inst->core; @@ -664,7 +664,8 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst, pkt = (struct cvp_hfi_cmd_session_hdr *)&fence_pkt->pkt_data; idx = get_pkt_index((struct cvp_hal_session_cmd_pkt *)pkt); - if (idx < 0 || (pkt->size > MAX_HFI_FENCE_OFFSET * sizeof(unsigned int))) { + if (idx < 0 || + (pkt->size > MAX_HFI_FENCE_OFFSET * sizeof(unsigned int))) { dprintk(CVP_ERR, "%s incorrect packet %d %#x\n", __func__, pkt->size, pkt->packet_type); goto exit; diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 51b3fa3ab0..68487ab5e8 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -28,6 +28,7 @@ int msm_cvp_clock_voting = !1; bool msm_cvp_syscache_disable = !true; bool msm_cvp_dsp_disable = !true; bool msm_cvp_mmrm_enabled = true; +bool msm_cvp_dcvs_disable = !true; #define MAX_DBG_BUF_SIZE 4096 @@ -260,6 +261,10 @@ struct dentry *msm_cvp_debugfs_init_drv(void) &msm_cvp_syscache_disable); if (IS_ERR_OR_NULL(f)) goto failed_create_dir; + f = debugfs_create_bool("disable_dcvs", 0644, dir, + &msm_cvp_dcvs_disable); + if (IS_ERR_OR_NULL(f)) + goto failed_create_dir; debugfs_create_file("cvp_power", 0644, dir, NULL, &cvp_pwr_fops); diff --git a/msm/eva/msm_cvp_debug.h b/msm/eva/msm_cvp_debug.h index c1fb775663..23912b9023 100644 --- a/msm/eva/msm_cvp_debug.h +++ b/msm/eva/msm_cvp_debug.h @@ -64,6 +64,7 @@ extern int msm_cvp_clock_voting; extern bool msm_cvp_syscache_disable; extern bool msm_cvp_dsp_disable; extern bool msm_cvp_mmrm_enabled; +extern bool msm_cvp_dcvs_disable; #define dprintk(__level, __fmt, arg...) \ do { \ From 1a6c0d1a39b758dac5b0475471950c37fc1bc700 Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 7 May 2021 13:12:05 -0700 Subject: [PATCH 053/317] msm: eva: Avoid NoC access during SMMU fault Noc logger doesn't work when handling SMMU fault in driver. Change-Id: I4ac6bca6e015b7f5424be4cb9e6d535877baa410 Signed-off-by: George Shen --- msm/eva/msm_cvp_common.c | 4 +--- msm/eva/msm_cvp_platform.c | 2 +- msm/eva/msm_cvp_res_parse.c | 1 - 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 860899bb9e..0a2674c262 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -1338,15 +1338,13 @@ int msm_cvp_noc_error_info(struct msm_cvp_core *core) return -EINVAL; } - if (!core->resources.non_fatal_pagefaults) - return 0; - if (!core->smmu_fault_handled) return 0; hdev = core->device; call_hfi_op(hdev, noc_error_info, hdev->hfi_device_data); + BUG_ON(!core->resources.non_fatal_pagefaults); return 0; } diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 438099772d..4de7f29e9f 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -56,7 +56,7 @@ static struct msm_cvp_common_data sm8450_common_data[] = { }, { .key = "qcom,domain-attr-non-fatal-faults", - .value = 1, + .value = 0, }, { .key = "qcom,max-secure-instances", diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index 7e25a30bd7..013088f988 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -976,7 +976,6 @@ int msm_cvp_smmu_fault_handler(struct iommu_domain *domain, msm_cvp_print_inst_bufs(inst); } core->smmu_fault_handled = true; - msm_cvp_noc_error_info(core); mutex_unlock(&core->lock); /* * Return -EINVAL to elicit the default behaviour of smmu driver. From 79fd263380ffcf44fa0a922d51e10d03e97acec1 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 10 May 2021 23:03:33 -0700 Subject: [PATCH 054/317] msm: eva: Avoid double free of DSP dma buffer In DSP use case, if application failed to free dma buffer before session end. Kernel driver will free all dma buffers belong to the dsp session. During this process, same dma buffer was freed twice. This change is to fix the problem. Change-Id: I641f9fc0eafbd6fe5c04276085ccd3946e439b41 Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 5 ++--- msm/eva/msm_cvp_dsp.c | 12 ++++++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 4e71290c9d..2efc6c4d33 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -841,6 +841,8 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) dprintk(CVP_ERR, "%s: failed dsp deregistration fd=%d rc=%d", __func__, cbuf->fd, rc); + msm_cvp_unmap_smem(inst, cbuf->smem, "unmap dsp"); + msm_cvp_smem_put_dma_buf(cbuf->smem->dma_buf); } else if (cbuf->ownership == DSP) { rc = cvp_dsp_fastrpc_unmap(inst->process_id, cbuf); if (rc) @@ -854,9 +856,6 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) "%s Fail to free buffer 0x%x\n", __func__, rc); } - - msm_cvp_unmap_smem(inst, cbuf->smem, "unmap dsp"); - msm_cvp_smem_put_dma_buf(cbuf->smem->dma_buf); list_del(&cbuf->list); kmem_cache_free(cvp_driver->buf_cache, cbuf); } diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 9d8a226fcc..3f444b922e 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1166,6 +1166,7 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) int rc; struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; + struct task_struct *task = NULL; cmd->ret = 0; @@ -1187,6 +1188,11 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) inst = (struct msm_cvp_inst *)ptr_dsp2cpu( dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->session_cpu_low); + if (!inst) { + dprintk(CVP_ERR, "%s incorrect session ID\n", __func__); + cmd->ret = -1; + goto dsp_fail_delete; + } rc = msm_cvp_session_delete(inst); if (rc) { @@ -1195,6 +1201,8 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) goto dsp_fail_delete; } + task = inst->task; + rc = msm_cvp_close(inst); if (rc) { dprintk(CVP_ERR, "Warning: Failed to close cvp instance\n"); @@ -1205,8 +1213,8 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) /* unregister fastrpc driver */ eva_fastrpc_driver_unregister(dsp2cpu_cmd->pid, false); - if (inst->task) - put_task_struct(inst->task); + if (task) + put_task_struct(task); dprintk(CVP_DSP, "%s DSP2CPU_DETELE_SESSION Done\n", __func__); dsp_fail_delete: From 077b0f11d388eaa1e0f0f06695be1b65e0659590 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Mon, 24 May 2021 16:56:19 -0700 Subject: [PATCH 055/317] msm: eva: update NOC reg offset update offset for SIDEBANDMANAGER related reg for Waipio temp commented code to read reg since dependency not ready. Change-Id: If87ab1ed4b80bad9835417d6972983825f065881 Signed-off-by: Yu SI --- msm/eva/cvp_hfi.c | 12 ++++++++---- msm/eva/cvp_hfi_io.h | 4 ++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 50773274cf..29fd81a99b 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -4032,8 +4032,6 @@ err_tzbsp_suspend: static void power_off_iris2(struct iris_hfi_device *device) { u32 lpi_status, reg_status = 0, count = 0, max_count = 1000; - u32 pc_ready, wfi_status, sbm_ln0_low; - u32 main_sbm_ln0_low, main_sbm_ln1_high; if (!device->power_enabled || !device->res->sw_power_collapsible) return; @@ -4060,18 +4058,24 @@ static void power_off_iris2(struct iris_hfi_device *device) "Noc: lpi_status %x noc_status %x (count %d)\n", lpi_status, reg_status, count); if (count == max_count) { + u32 pc_ready, wfi_status, sbm_ln0_low; + /*u32 main_sbm_ln0_low, main_sbm_ln1_high; */ + wfi_status = __read_register(device, CVP_WRAPPER_CPU_STATUS); pc_ready = __read_register(device, CVP_CTRL_STATUS); sbm_ln0_low = __read_register(device, CVP_NOC_SBM_SENSELN0_LOW); + /*temp commented till dependency ready*/ + /* main_sbm_ln0_low = __read_register(device, CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_LOW); main_sbm_ln1_high = __read_register(device, CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN1_HIGH); + */ dprintk(CVP_WARN, - "NOC not in qaccept status %x %x %x %x %x %x %x\n", + "NOC not in qaccept status %x %x %x %x %x\n", reg_status, lpi_status, wfi_status, pc_ready, - sbm_ln0_low, main_sbm_ln0_low, main_sbm_ln1_high); + sbm_ln0_low); } /* HPG 6.1.2 Step 3, debug bridge to low power BYPASSED */ diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index c83f6793e3..fb9c66d7e3 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -182,9 +182,9 @@ #define CVP_NOC_CORE_BASE_OFFS 0x00010000 #define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_LOW \ - (CVP_NOC_CORE_BASE_OFFS + 0x1100) + (CVP_NOC_CORE_BASE_OFFS + 0x7100) #define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN1_HIGH \ - (CVP_NOC_CORE_BASE_OFFS + 0x110C) + (CVP_NOC_CORE_BASE_OFFS + 0x710C) #define CVP_NOC_CORE_ERR_SWID_LOW_OFFS \ (CVP_NOC_CORE_BASE_OFFS + 0x1200) #define CVP_NOC_CORE_ERR_SWID_HIGH_OFFS \ From 349e2309124a0dbbfcac5492859f8b668be3966e Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 27 May 2021 14:22:03 -0700 Subject: [PATCH 056/317] msm: eva: Fix EVA SSR recovery in DSP Avoid deadlock in DSP EVA session creation after EVA SSR. Change-Id: I22b363883db5d3bf8e8554a3708cb549437899ba Signed-off-by: George Shen --- msm/eva/msm_cvp_debug.c | 30 +++++++++++++ msm/eva/msm_cvp_dsp.c | 97 +++++++++++++++++++++++++---------------- msm/eva/msm_cvp_dsp.h | 15 +++++-- 3 files changed, 101 insertions(+), 41 deletions(-) diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 68487ab5e8..fb0f23d4af 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -8,6 +8,7 @@ #include "msm_cvp_common.h" #include "cvp_core_hfi.h" #include "cvp_hfi_api.h" +#include "msm_cvp_dsp.h" #define CREATE_TRACE_POINTS #define MAX_SSR_STRING_LEN 10 @@ -333,6 +334,30 @@ static int _clk_rate_get(void *data, u64 *val) DEFINE_DEBUGFS_ATTRIBUTE(clk_rate_fops, _clk_rate_get, _clk_rate_set, "%llu\n"); +static int _dsp_dbg_set(void *data, u64 val) +{ + + if (val == 0 || val > (1 << EVA_MEM_DEBUG_ON)) { + dprintk(CVP_WARN, "DSP debug mask cannot be %llx\n", val); + return 0; + } + + gfa_cv.debug_mask = (uint32_t)val; + + cvp_dsp_send_debug_mask(); + + return 0; +} + +static int _dsp_dbg_get(void *data, u64 *val) +{ + *val = gfa_cv.debug_mask; + + return 0; +} + +DEFINE_DEBUGFS_ATTRIBUTE(dsp_debug_fops, _dsp_dbg_get, _dsp_dbg_set, "%llu\n"); + struct dentry *msm_cvp_debugfs_init_core(struct msm_cvp_core *core, struct dentry *parent) @@ -366,6 +391,11 @@ struct dentry *msm_cvp_debugfs_init_core(struct msm_cvp_core *core, dprintk(CVP_ERR, "debugfs_create_file: clock_rate fail\n"); goto failed_create_dir; } + if (!debugfs_create_file("dsp_debug_level", 0644, dir, + NULL, &dsp_debug_fops)) { + dprintk(CVP_ERR, "debugfs_create: dsp_debug_level fail\n"); + goto failed_create_dir; + } failed_create_dir: return dir; diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 3f444b922e..00f6853b69 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -167,11 +167,11 @@ static int cvp_dsp_rpmsg_probe(struct rpmsg_device *rpdev) return -EINVAL; } - mutex_lock(&me->lock); + mutex_lock(&me->tx_lock); me->chan = rpdev; me->state = DSP_PROBED; complete(&me->completions[CPU2DSP_MAX_CMD]); - mutex_unlock(&me->lock); + mutex_unlock(&me->tx_lock); return ret; } @@ -182,12 +182,12 @@ static void cvp_dsp_rpmsg_remove(struct rpmsg_device *rpdev) dprintk(CVP_WARN, "%s: CDSP SSR triggered\n", __func__); - mutex_lock(&me->lock); + mutex_lock(&me->tx_lock); cvp_hyp_assign_from_dsp(); me->chan = NULL; me->state = DSP_UNINIT; - mutex_unlock(&me->lock); + mutex_unlock(&me->tx_lock); /* kernel driver needs clean all dsp sessions */ } @@ -248,7 +248,7 @@ int cvp_dsp_suspend(uint32_t session_flag) cmd.type = CPU2DSP_SUSPEND; - mutex_lock(&me->lock); + mutex_lock(&me->tx_lock); if (me->state != DSP_READY) goto exit; @@ -269,10 +269,10 @@ retry: if (rsp.ret == CPU2DSP_EFATAL) { if (!retried) { - mutex_unlock(&me->lock); + mutex_unlock(&me->tx_lock); retried = true; rc = cvp_reinit_dsp(); - mutex_lock(&me->lock); + mutex_lock(&me->tx_lock); if (rc) goto fatal_exit; else @@ -290,7 +290,7 @@ fatal_exit: cvp_hyp_assign_from_dsp(); rc = -ENOTSUPP; exit: - mutex_unlock(&me->lock); + mutex_unlock(&me->tx_lock); return rc; } @@ -324,7 +324,7 @@ int cvp_dsp_shutdown(uint32_t session_flag) cmd.type = CPU2DSP_SHUTDOWN; - mutex_lock(&me->lock); + mutex_lock(&me->tx_lock); if (me->state == DSP_INVALID) goto exit; @@ -341,7 +341,7 @@ int cvp_dsp_shutdown(uint32_t session_flag) rc = cvp_hyp_assign_from_dsp(); exit: - mutex_unlock(&me->lock); + mutex_unlock(&me->tx_lock); return rc; } @@ -372,7 +372,7 @@ int cvp_dsp_register_buffer(uint32_t session_id, uint32_t buff_fd, dprintk(CVP_DSP, "%s: buff_size=0x%x session_id=0x%x\n", __func__, cmd.buff_size, cmd.session_id); - mutex_lock(&me->lock); + mutex_lock(&me->tx_lock); retry: rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg), &rsp); if (rc) { @@ -391,10 +391,10 @@ retry: if (rsp.ret == CPU2DSP_EFATAL) { if (!retried) { - mutex_unlock(&me->lock); + mutex_unlock(&me->tx_lock); retried = true; rc = cvp_reinit_dsp(); - mutex_lock(&me->lock); + mutex_lock(&me->tx_lock); if (rc) goto fatal_exit; else @@ -411,7 +411,7 @@ fatal_exit: cvp_hyp_assign_from_dsp(); rc = -ENOTSUPP; exit: - mutex_unlock(&me->lock); + mutex_unlock(&me->tx_lock); return rc; } @@ -442,7 +442,7 @@ int cvp_dsp_deregister_buffer(uint32_t session_id, uint32_t buff_fd, dprintk(CVP_DSP, "%s: buff_size=0x%x session_id=0x%x\n", __func__, cmd.buff_size, cmd.session_id); - mutex_lock(&me->lock); + mutex_lock(&me->tx_lock); retry: rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg), &rsp); if (rc) { @@ -461,10 +461,10 @@ retry: if (rsp.ret == CPU2DSP_EFATAL) { if (!retried) { - mutex_unlock(&me->lock); + mutex_unlock(&me->tx_lock); retried = true; rc = cvp_reinit_dsp(); - mutex_lock(&me->lock); + mutex_lock(&me->tx_lock); if (rc) goto fatal_exit; else @@ -481,7 +481,7 @@ fatal_exit: cvp_hyp_assign_from_dsp(); rc = -ENOTSUPP; exit: - mutex_unlock(&me->lock); + mutex_unlock(&me->tx_lock); return rc; } @@ -590,7 +590,7 @@ static int __reinit_dsp(void) return rc; /* Resend HFI queue */ - mutex_lock(&me->lock); + mutex_lock(&me->tx_lock); if (!device->dsp_iface_q_table.align_virtual_addr) { dprintk(CVP_ERR, "%s: DSP HFI queue released\n", __func__); rc = -EINVAL; @@ -625,7 +625,7 @@ static int __reinit_dsp(void) rc = -ENODEV; } exit: - mutex_unlock(&me->lock); + mutex_unlock(&me->tx_lock); return rc; } @@ -636,10 +636,10 @@ static int cvp_reinit_dsp(void) rc = __reinit_dsp(); if (rc) { - mutex_lock(&me->lock); + mutex_lock(&me->tx_lock); me->state = DSP_INVALID; cvp_hyp_assign_from_dsp(); - mutex_unlock(&me->lock); + mutex_unlock(&me->tx_lock); } return rc; } @@ -929,6 +929,27 @@ static void eva_fastrpc_driver_unregister(uint32_t handle, bool force_exit) } } +void cvp_dsp_send_debug_mask(void) +{ + struct cvp_dsp_cmd_msg cmd; + struct cvp_dsp_apps *me = &gfa_cv; + struct cvp_dsp_rsp_msg rsp; + int rc; + + cmd.type = CPU2DSP_SET_DEBUG_LEVEL; + cmd.eva_dsp_debug_mask = me->debug_mask; + + dprintk(CVP_DSP, + "%s: debug mask 0x%x\n", + __func__, cmd.eva_dsp_debug_mask); + + rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg), &rsp); + if (rc) + dprintk(CVP_ERR, + "%s: cvp_dsp_send_cmd failed rc = %d\n", + __func__, rc); +} + void cvp_dsp_send_hfi_queue(void) { struct msm_cvp_core *core; @@ -953,13 +974,11 @@ void cvp_dsp_send_hfi_queue(void) dprintk(CVP_DSP, "Entering %s\n", __func__); mutex_lock(&device->lock); - mutex_lock(&me->lock); + mutex_lock(&me->tx_lock); if (!device->dsp_iface_q_table.align_virtual_addr) { dprintk(CVP_ERR, "%s: DSP HFI queue released\n", __func__); - mutex_unlock(&me->lock); - mutex_unlock(&device->lock); - return; + goto exit; } addr = (uint64_t)device->dsp_iface_q_table.mem_data.dma_handle; @@ -1009,20 +1028,20 @@ void cvp_dsp_send_hfi_queue(void) } else if (rsp.ret == CPU2DSP_EINVALSTATE) { dprintk(CVP_ERR, "%s dsp invalid state %d\n", __func__, rsp.dsp_state); - mutex_unlock(&me->lock); + mutex_unlock(&me->tx_lock); if (cvp_reinit_dsp()) { dprintk(CVP_ERR, "%s reinit dsp fail\n", __func__); mutex_unlock(&device->lock); return; } - mutex_lock(&me->lock); + mutex_lock(&me->tx_lock); } dprintk(CVP_DSP, "%s: dsp initialized\n", __func__); me->state = DSP_READY; exit: - mutex_unlock(&me->lock); + mutex_unlock(&me->tx_lock); mutex_unlock(&device->lock); } /* 32 or 64 bit CPU Side Ptr <-> 2 32 bit DSP Pointers. Dirty Fix. */ @@ -1599,7 +1618,7 @@ wait_dsp: if (rc == -ERESTARTSYS) { dprintk(CVP_WARN, "%s received interrupt signal\n", __func__); } else { - mutex_lock(&me->lock); + mutex_lock(&me->rx_lock); switch (me->pending_dsp2cpu_cmd.type) { case DSP2CPU_POWERON: { @@ -1608,19 +1627,19 @@ wait_dsp: break; } - mutex_unlock(&me->lock); + mutex_lock(&me->tx_lock); old_state = me->state; me->state = DSP_READY; rc = call_hfi_op(hdev, resume, hdev->hfi_device_data); if (rc) { dprintk(CVP_WARN, "%s Failed to resume cvp\n", __func__); - mutex_lock(&me->lock); me->state = old_state; + mutex_unlock(&me->tx_lock); cmd.ret = 1; break; } - mutex_lock(&me->lock); + mutex_unlock(&me->tx_lock); cmd.ret = 0; break; } @@ -1678,7 +1697,7 @@ wait_dsp: break; } me->pending_dsp2cpu_cmd.type = CVP_INVALID_RPMSG_TYPE; - mutex_unlock(&me->lock); + mutex_unlock(&me->rx_lock); } /* Responds to DSP */ rc = cvp_dsp_send_cmd(&cmd, sizeof(struct cvp_dsp_cmd_msg)); @@ -1700,7 +1719,8 @@ int cvp_dsp_device_init(void) int rc; int i; - mutex_init(&me->lock); + mutex_init(&me->tx_lock); + mutex_init(&me->rx_lock); me->state = DSP_INVALID; me->hyp_assigned = false; @@ -1739,15 +1759,16 @@ void cvp_dsp_device_exit(void) struct cvp_dsp_apps *me = &gfa_cv; int i; - mutex_lock(&me->lock); + mutex_lock(&me->tx_lock); me->state = DSP_INVALID; - mutex_unlock(&me->lock); + mutex_unlock(&me->tx_lock); DEINIT_MSM_CVP_LIST(&me->fastrpc_driver_list); for (i = 0; i <= CPU2DSP_MAX_CMD; i++) complete_all(&me->completions[i]); - mutex_destroy(&me->lock); + mutex_destroy(&me->tx_lock); + mutex_destroy(&me->rx_lock); unregister_rpmsg_driver(&cvp_dsp_rpmsg_client); } diff --git a/msm/eva/msm_cvp_dsp.h b/msm/eva/msm_cvp_dsp.h index 72beb46029..32f354b8e6 100644 --- a/msm/eva/msm_cvp_dsp.h +++ b/msm/eva/msm_cvp_dsp.h @@ -73,7 +73,7 @@ enum CVP_DSP_COMMAND { CVP_DSP_MAX_CMD = 21, }; -enum eva_dsp_debug_level { +enum eva_dsp_debug_bits { EVA_PORT_INFO_ON = 0, EVA_PORT_DEBUG_ON = 1, EVA_QDI_INFO_ON = 2, @@ -123,7 +123,7 @@ struct cvp_dsp_cmd_msg { uint32_t buff_offset; uint32_t buff_fd_size; - uint32_t eva_dsp_debug_level; + uint32_t eva_dsp_debug_mask; /* Create Session */ uint32_t session_cpu_low; @@ -176,9 +176,16 @@ struct cvp_dsp_fastrpc_driver_entry { }; struct cvp_dsp_apps { - struct mutex lock; + /* + * tx_lock for sending CPU2DSP cmds or msgs + * and dsp state change + */ + struct mutex tx_lock; + /* rx_lock for receiving DSP2CPU cmds or msgs */ + struct mutex rx_lock; struct rpmsg_device *chan; uint32_t state; + uint32_t debug_mask; bool hyp_assigned; uint64_t addr; uint32_t size; @@ -256,5 +263,7 @@ int cvp_dsp_fastrpc_unmap(uint32_t process_id, struct cvp_internal_buf *buf); int cvp_dsp_del_sess(uint32_t process_id, struct msm_cvp_inst *inst); +void cvp_dsp_send_debug_mask(void); + #endif // MSM_CVP_DSP_H From 11a18d4d23c2f944eba53fc8a8204635734354a1 Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 7 May 2021 19:44:04 -0700 Subject: [PATCH 057/317] msm: cvp: Reduce kmd's feature dependency Move feature configuration processing out of kmd. Relocate feature specific code to msm_cvp_platform.c and cvp_hfi.h. Change-Id: I425ee8b8638bd7b81c653c860f1ed1f5d95abac8 Signed-off-by: George Shen --- msm/eva/cvp_comm_def.h | 3 +- msm/eva/cvp_hfi.c | 298 --------------------------------- msm/eva/cvp_hfi.h | 70 ++++++-- msm/eva/cvp_hfi_api.h | 106 ++---------- msm/eva/cvp_hfi_helper.h | 7 - msm/eva/hfi_response_handler.c | 78 --------- msm/eva/msm_cvp.c | 90 +++++----- msm/eva/msm_cvp.h | 2 +- msm/eva/msm_cvp_common.c | 60 +------ msm/eva/msm_cvp_core.c | 2 +- msm/eva/msm_cvp_platform.c | 233 ++++++++++++++++++++++++++ 11 files changed, 361 insertions(+), 588 deletions(-) diff --git a/msm/eva/cvp_comm_def.h b/msm/eva/cvp_comm_def.h index a5de1d90d0..bb660e4f3b 100644 --- a/msm/eva/cvp_comm_def.h +++ b/msm/eva/cvp_comm_def.h @@ -18,7 +18,8 @@ enum op_mode { enum queue_state { QUEUE_INIT, QUEUE_ACTIVE = 1, - QUEUE_STOP = 2, + QUEUE_START, + QUEUE_STOP, QUEUE_INVALID, }; #endif diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 29fd81a99b..00d9e5e3a2 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -36,262 +36,6 @@ #define QDSS_IOVA_START 0x80001000 #define MIN_PAYLOAD_SIZE 3 -const struct msm_cvp_hfi_defs cvp_hfi_defs[] = { - { - .size = HFI_DFS_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_DFS_CONFIG, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_SESSION_DFS_CONFIG_CMD_DONE, - }, - { - .size = HFI_DFS_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_DFS_FRAME, - .buf_offset = HFI_DFS_FRAME_BUFFERS_OFFSET, - .buf_num = HFI_DFS_BUF_NUM, - .resp = HAL_NO_RESP, - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_SGM_OF_CONFIG, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_SESSION_SGM_OF_CONFIG_CMD_DONE, - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_SGM_OF_FRAME, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_NO_RESP, - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_WARP_NCC_CONFIG, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_SESSION_WARP_NCC_CONFIG_CMD_DONE, - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_WARP_NCC_FRAME, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_NO_RESP, - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_WARP_CONFIG, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_SESSION_WARP_CONFIG_CMD_DONE, - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_WARP_DS_PARAMS, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_SESSION_WARP_DS_PARAMS_CMD_DONE, - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_WARP_FRAME, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_NO_RESP, - }, - { - .size = HFI_DMM_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_DMM_CONFIG, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_SESSION_DMM_CONFIG_CMD_DONE, - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_DMM_PARAMS, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_SESSION_DMM_PARAMS_CMD_DONE, - }, - { - .size = HFI_DMM_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_DMM_FRAME, - .buf_offset = HFI_DMM_FRAME_BUFFERS_OFFSET, - .buf_num = HFI_DMM_BUF_NUM, - .resp = HAL_NO_RESP, - }, - { - .size = HFI_PERSIST_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS, - .buf_offset = HFI_PERSIST_BUFFERS_OFFSET, - .buf_num = HFI_PERSIST_BUF_NUM, - .resp = HAL_SESSION_PERSIST_SET_DONE, - }, - { - .size = 0xffffffff, - .type = HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_SESSION_PERSIST_REL_DONE, - }, - { - .size = HFI_DS_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_DS, - .buf_offset = HFI_DS_BUFFERS_OFFSET, - .buf_num = HFI_DS_BUF_NUM, - .resp = HAL_NO_RESP, - }, - { - .size = HFI_OF_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_CV_TME_CONFIG, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_SESSION_TME_CONFIG_CMD_DONE, - }, - { - .size = HFI_OF_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_CV_TME_FRAME, - .buf_offset = HFI_OF_BUFFERS_OFFSET, - .buf_num = HFI_OF_BUF_NUM, - .resp = HAL_NO_RESP, - }, - { - .size = HFI_ODT_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_CV_ODT_CONFIG, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_SESSION_ODT_CONFIG_CMD_DONE, - }, - { - .size = HFI_ODT_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_CV_ODT_FRAME, - .buf_offset = HFI_ODT_BUFFERS_OFFSET, - .buf_num = HFI_ODT_BUF_NUM, - .resp = HAL_NO_RESP, - }, - { - .size = HFI_OD_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_CV_OD_CONFIG, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_SESSION_OD_CONFIG_CMD_DONE, - }, - { - .size = HFI_OD_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_CV_OD_FRAME, - .buf_offset = HFI_OD_BUFFERS_OFFSET, - .buf_num = HFI_OD_BUF_NUM, - .resp = HAL_NO_RESP, - }, - { - .size = HFI_NCC_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_NCC_CONFIG, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_SESSION_NCC_CONFIG_CMD_DONE, - }, - { - .size = HFI_NCC_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_NCC_FRAME, - .buf_offset = HFI_NCC_BUFFERS_OFFSET, - .buf_num = HFI_NCC_BUF_NUM, - .resp = HAL_NO_RESP, - }, - { - .size = HFI_ICA_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_ICA_CONFIG, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_SESSION_ICA_CONFIG_CMD_DONE, - }, - { - .size = HFI_ICA_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_ICA_FRAME, - .buf_offset = HFI_ICA_BUFFERS_OFFSET, - .buf_num = HFI_ICA_BUF_NUM, - .resp = HAL_NO_RESP, - }, - { - .size = HFI_HCD_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_HCD_CONFIG, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_SESSION_HCD_CONFIG_CMD_DONE, - }, - { - .size = HFI_HCD_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_HCD_FRAME, - .buf_offset = HFI_HCD_BUFFERS_OFFSET, - .buf_num = HFI_HCD_BUF_NUM, - .resp = HAL_NO_RESP, - }, - { - .size = HFI_DCM_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_DC_CONFIG, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_SESSION_DC_CONFIG_CMD_DONE, - }, - { - .size = HFI_DCM_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_DC_FRAME, - .buf_offset = HFI_DCM_BUFFERS_OFFSET, - .buf_num = HFI_DCM_BUF_NUM, - .resp = HAL_NO_RESP, - }, - { - .size = HFI_DCM_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_DCM_CONFIG, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_SESSION_DCM_CONFIG_CMD_DONE, - }, - { - .size = HFI_DCM_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_DCM_FRAME, - .buf_offset = HFI_DCM_BUFFERS_OFFSET, - .buf_num = HFI_DCM_BUF_NUM, - .resp = HAL_NO_RESP, - }, - { - .size = HFI_PYS_HCD_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_PYS_HCD_CONFIG, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_SESSION_PYS_HCD_CONFIG_CMD_DONE, - }, - { - .size = HFI_PYS_HCD_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_PYS_HCD_FRAME, - .buf_offset = HFI_PYS_HCD_BUFFERS_OFFSET, - .buf_num = HFI_PYS_HCD_BUF_NUM, - .resp = HAL_NO_RESP, - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_SESSION_MODEL_BUF_CMD_DONE, - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_FD_CONFIG, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_SESSION_FD_CONFIG_CMD_DONE, - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_FD_FRAME, - .buf_offset = 0, - .buf_num = 0, - .resp = HAL_NO_RESP, - }, - -}; - struct cvp_tzbsp_memprot { u32 cp_start; u32 cp_size; @@ -389,17 +133,6 @@ static inline bool is_sys_cache_present(struct iris_hfi_device *device) #define ROW_SIZE 32 -int get_pkt_index(struct cvp_hal_session_cmd_pkt *hdr) -{ - int i, pkt_num = ARRAY_SIZE(cvp_hfi_defs); - - for (i = 0; i < pkt_num; i++) - if (cvp_hfi_defs[i].type == hdr->packet_type) - return i; - - return -EINVAL; -} - int get_hfi_version(void) { struct msm_cvp_core *core; @@ -469,17 +202,6 @@ int get_msg_opconfigs(void *msg, unsigned int *session_id, return 0; } -int get_signal_from_pkt_type(unsigned int type) -{ - int i, pkt_num = ARRAY_SIZE(cvp_hfi_defs); - - for (i = 0; i < pkt_num; i++) - if (cvp_hfi_defs[i].type == type) - return cvp_hfi_defs[i].resp; - - return -EINVAL; -} - static void __dump_packet(u8 *packet, enum cvp_msg_prio log_level) { u32 c = 0, packet_size = *(u32 *)packet; @@ -2929,26 +2651,6 @@ static void **get_session_id(struct msm_cvp_cb_info *info) case HAL_SESSION_RELEASE_BUFFER_DONE: case HAL_SESSION_REGISTER_BUFFER_DONE: case HAL_SESSION_UNREGISTER_BUFFER_DONE: - case HAL_SESSION_DFS_CONFIG_CMD_DONE: - case HAL_SESSION_DMM_CONFIG_CMD_DONE: - case HAL_SESSION_WARP_CONFIG_CMD_DONE: - case HAL_SESSION_WARP_NCC_CONFIG_CMD_DONE: - case HAL_SESSION_SGM_OF_CONFIG_CMD_DONE: - case HAL_SESSION_TME_CONFIG_CMD_DONE: - case HAL_SESSION_ODT_CONFIG_CMD_DONE: - case HAL_SESSION_OD_CONFIG_CMD_DONE: - case HAL_SESSION_NCC_CONFIG_CMD_DONE: - case HAL_SESSION_ICA_CONFIG_CMD_DONE: - case HAL_SESSION_HCD_CONFIG_CMD_DONE: - case HAL_SESSION_DCM_CONFIG_CMD_DONE: - case HAL_SESSION_DC_CONFIG_CMD_DONE: - case HAL_SESSION_PYS_HCD_CONFIG_CMD_DONE: - case HAL_SESSION_DMM_PARAMS_CMD_DONE: - case HAL_SESSION_WARP_DS_PARAMS_CMD_DONE: - case HAL_SESSION_PERSIST_SET_DONE: - case HAL_SESSION_PERSIST_REL_DONE: - case HAL_SESSION_FD_CONFIG_CMD_DONE: - case HAL_SESSION_MODEL_BUF_CMD_DONE: case HAL_SESSION_PROPERTY_INFO: case HAL_SESSION_EVENT_CHANGE: session_id = &info->response.cmd.session_id; diff --git a/msm/eva/cvp_hfi.h b/msm/eva/cvp_hfi.h index 4e7c112871..17ca9f2a30 100644 --- a/msm/eva/cvp_hfi.h +++ b/msm/eva/cvp_hfi.h @@ -207,6 +207,46 @@ #define CVP_IFACEQ_VAR_LARGE_PKT_SIZE 512 #define CVP_IFACEQ_VAR_HUGE_PKT_SIZE (1024*12) +/* HFI packet info needed for sanity check */ +#define HFI_DFS_CONFIG_CMD_SIZE 38 +#define HFI_DFS_FRAME_CMD_SIZE 16 + +#define HFI_DMM_CONFIG_CMD_SIZE 194 +#define HFI_DMM_BASIC_CONFIG_CMD_SIZE 51 +#define HFI_DMM_FRAME_CMD_SIZE 28 + +#define HFI_PERSIST_CMD_SIZE 11 + +#define HFI_DS_CMD_SIZE 50 + +#define HFI_OF_CONFIG_CMD_SIZE 34 +#define HFI_OF_FRAME_CMD_SIZE 24 + +#define HFI_ODT_CONFIG_CMD_SIZE 23 +#define HFI_ODT_FRAME_CMD_SIZE 33 + +#define HFI_OD_CONFIG_CMD_SIZE 24 +#define HFI_OD_FRAME_CMD_SIZE 12 + +#define HFI_NCC_CONFIG_CMD_SIZE 47 +#define HFI_NCC_FRAME_CMD_SIZE 22 + +#define HFI_ICA_CONFIG_CMD_SIZE 127 +#define HFI_ICA_FRAME_CMD_SIZE 14 + +#define HFI_HCD_CONFIG_CMD_SIZE 46 +#define HFI_HCD_FRAME_CMD_SIZE 18 + +#define HFI_DCM_CONFIG_CMD_SIZE 20 +#define HFI_DCM_FRAME_CMD_SIZE 19 + +#define HFI_PYS_HCD_CONFIG_CMD_SIZE 461 +#define HFI_PYS_HCD_FRAME_CMD_SIZE 66 + +#define HFI_FD_CONFIG_CMD_SIZE 28 +#define HFI_FD_FRAME_CMD_SIZE 10 + + struct cvp_hfi_cmd_session_flush_packet { u32 size; u32 packet_type; @@ -247,19 +287,23 @@ struct cvp_hal_session { void *device; }; -struct msm_cvp_fw { - int cookie; +enum buf_map_type { + MAP_PERSIST = 1, + UNMAP_PERSIST = 2, + MAP_FRAME = 3, + MAP_INVALID, }; -int cvp_hfi_process_msg_packet(u32 device_id, - void *msg_hdr, struct msm_cvp_cb_info *info); - -enum cvp_status cvp_hfi_process_sys_init_done_prop_read( - struct cvp_hfi_msg_sys_init_done_packet *pkt, - struct cvp_hal_sys_init_done *sys_init_done); - -enum cvp_status hfi_process_session_init_done_prop_read( - struct cvp_hfi_msg_sys_session_init_done_packet *pkt, - struct cvp_hal_session_init_done *session_init_done); - +static inline enum buf_map_type cvp_find_map_type(int pkt_type) +{ + if (pkt_type == HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS || + pkt_type == HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS || + pkt_type == HFI_CMD_SESSION_CVP_DMM_PARAMS || + pkt_type == HFI_CMD_SESSION_CVP_WARP_DS_PARAMS) + return MAP_PERSIST; + else if (pkt_type == HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS) + return UNMAP_PERSIST; + else + return MAP_FRAME; +} #endif diff --git a/msm/eva/cvp_hfi_api.h b/msm/eva/cvp_hfi_api.h index fe1227d00b..53d419b13a 100644 --- a/msm/eva/cvp_hfi_api.h +++ b/msm/eva/cvp_hfi_api.h @@ -30,74 +30,6 @@ /* 16 encoder and 16 decoder sessions */ #define CVP_MAX_SESSIONS 32 -#define HFI_DFS_CONFIG_CMD_SIZE 38 -#define HFI_DFS_FRAME_CMD_SIZE 16 -#define HFI_DFS_FRAME_BUFFERS_OFFSET 8 -#define HFI_DFS_BUF_NUM 4 - -#define HFI_DMM_CONFIG_CMD_SIZE 194 -#define HFI_DMM_BASIC_CONFIG_CMD_SIZE 51 -#define HFI_DMM_FRAME_CMD_SIZE 28 -#define HFI_DMM_FRAME_BUFFERS_OFFSET 12 -#define HFI_DMM_BUF_NUM 8 - -#define HFI_PERSIST_CMD_SIZE 11 -#define HFI_PERSIST_BUFFERS_OFFSET 7 -#define HFI_PERSIST_BUF_NUM 2 - -#define HFI_DS_CMD_SIZE 50 -#define HFI_DS_BUFFERS_OFFSET 44 -#define HFI_DS_BUF_NUM 3 - -#define HFI_OF_CONFIG_CMD_SIZE 34 -#define HFI_OF_FRAME_CMD_SIZE 24 -#define HFI_OF_BUFFERS_OFFSET 8 -#define HFI_OF_BUF_NUM 8 - -#define HFI_ODT_CONFIG_CMD_SIZE 23 -#define HFI_ODT_FRAME_CMD_SIZE 33 -#define HFI_ODT_BUFFERS_OFFSET 11 -#define HFI_ODT_BUF_NUM 11 - -#define HFI_OD_CONFIG_CMD_SIZE 24 -#define HFI_OD_FRAME_CMD_SIZE 12 -#define HFI_OD_BUFFERS_OFFSET 6 -#define HFI_OD_BUF_NUM 3 - -#define HFI_NCC_CONFIG_CMD_SIZE 47 -#define HFI_NCC_FRAME_CMD_SIZE 22 -#define HFI_NCC_BUFFERS_OFFSET 8 -#define HFI_NCC_BUF_NUM 7 - -#define HFI_ICA_CONFIG_CMD_SIZE 127 -#define HFI_ICA_FRAME_CMD_SIZE 14 -#define HFI_ICA_BUFFERS_OFFSET 6 -#define HFI_ICA_BUF_NUM 4 - -#define HFI_HCD_CONFIG_CMD_SIZE 46 -#define HFI_HCD_FRAME_CMD_SIZE 18 -#define HFI_HCD_BUFFERS_OFFSET 12 -#define HFI_HCD_BUF_NUM 3 - -#define HFI_DCM_CONFIG_CMD_SIZE 20 -#define HFI_DCM_FRAME_CMD_SIZE 19 -#define HFI_DCM_BUFFERS_OFFSET 9 -#define HFI_DCM_BUF_NUM 5 - -#define HFI_PYS_HCD_CONFIG_CMD_SIZE 461 -#define HFI_PYS_HCD_FRAME_CMD_SIZE 66 -#define HFI_PYS_HCD_BUFFERS_OFFSET 14 -#define HFI_PYS_HCD_BUF_NUM 26 - -#define HFI_FD_CONFIG_CMD_SIZE 28 -#define HFI_FD_FRAME_CMD_SIZE 10 -#define HFI_FD_BUFFERS_OFFSET 6 -#define HFI_FD_BUF_NUM 2 - -#define HFI_MODEL_CMD_SIZE 9 -#define HFI_MODEL_BUFFERS_OFFSET 7 -#define HFI_MODEL_BUF_NUM 1 - #define HFI_VERSION_MAJOR_MASK 0xFF000000 #define HFI_VERSION_MAJOR_SHFIT 24 #define HFI_VERSION_MINOR_MASK 0x00FFFFE0 @@ -210,26 +142,6 @@ enum hal_command_response { HAL_SESSION_REGISTER_BUFFER_DONE, HAL_SESSION_UNREGISTER_BUFFER_DONE, HAL_SESSION_RELEASE_RESOURCE_DONE, - HAL_SESSION_SGM_OF_CONFIG_CMD_DONE, - HAL_SESSION_DFS_CONFIG_CMD_DONE, - HAL_SESSION_DMM_CONFIG_CMD_DONE, - HAL_SESSION_DMM_PARAMS_CMD_DONE, - HAL_SESSION_WARP_CONFIG_CMD_DONE, - HAL_SESSION_WARP_DS_PARAMS_CMD_DONE, - HAL_SESSION_WARP_NCC_CONFIG_CMD_DONE, - HAL_SESSION_TME_CONFIG_CMD_DONE, - HAL_SESSION_ODT_CONFIG_CMD_DONE, - HAL_SESSION_OD_CONFIG_CMD_DONE, - HAL_SESSION_NCC_CONFIG_CMD_DONE, - HAL_SESSION_ICA_CONFIG_CMD_DONE, - HAL_SESSION_HCD_CONFIG_CMD_DONE, - HAL_SESSION_DC_CONFIG_CMD_DONE, - HAL_SESSION_DCM_CONFIG_CMD_DONE, - HAL_SESSION_PYS_HCD_CONFIG_CMD_DONE, - HAL_SESSION_FD_CONFIG_CMD_DONE, - HAL_SESSION_PERSIST_SET_DONE, - HAL_SESSION_PERSIST_REL_DONE, - HAL_SESSION_MODEL_BUF_CMD_DONE, HAL_SESSION_PROPERTY_INFO, HAL_SESSION_ERROR, HAL_RESPONSE_UNUSED = 0x10000000, @@ -324,8 +236,7 @@ struct cvp_hal_cmd_sys_get_property_packet { struct msm_cvp_hfi_defs { unsigned int size; unsigned int type; - unsigned int buf_offset; - unsigned int buf_num; + bool is_config_pkt; enum hal_command_response resp; }; @@ -359,6 +270,20 @@ typedef void (*hfi_cmd_response_callback) (enum hal_command_response cmd, void *data); typedef void (*msm_cvp_callback) (enum hal_command_response response, void *callback); +struct msm_cvp_fw { + int cookie; +}; + +int cvp_hfi_process_msg_packet(u32 device_id, + void *msg_hdr, struct msm_cvp_cb_info *info); + +enum cvp_status cvp_hfi_process_sys_init_done_prop_read( + struct cvp_hfi_msg_sys_init_done_packet *pkt, + struct cvp_hal_sys_init_done *sys_init_done); + +enum cvp_status hfi_process_session_init_done_prop_read( + struct cvp_hfi_msg_sys_session_init_done_packet *pkt, + struct cvp_hal_session_init_done *session_init_done); struct cvp_hfi_device *cvp_hfi_initialize(enum msm_cvp_hfi_type hfi_type, u32 device_id, struct msm_cvp_platform_resources *res, @@ -367,7 +292,6 @@ void cvp_hfi_deinitialize(enum msm_cvp_hfi_type hfi_type, struct cvp_hfi_device *hdev); int get_pkt_index(struct cvp_hal_session_cmd_pkt *hdr); -int get_signal_from_pkt_type(unsigned int type); int get_hfi_version(void); unsigned int get_msg_size(struct cvp_hfi_msg_session_hdr *hdr); unsigned int get_msg_session_id(void *msg); diff --git a/msm/eva/cvp_hfi_helper.h b/msm/eva/cvp_hfi_helper.h index a5bf274b27..c4126450dc 100644 --- a/msm/eva/cvp_hfi_helper.h +++ b/msm/eva/cvp_hfi_helper.h @@ -222,13 +222,6 @@ struct cvp_hfi_cmd_sys_get_property_packet { u32 rg_property_data[1]; }; -enum HFI_SESSION_TYPE { - HFI_SESSION_CV = 1, - HFI_SESSION_DMM, - HFI_SESSION_ODT, - HFI_SESSION_FD -}; - struct cvp_hfi_cmd_sys_session_init_packet { u32 size; u32 packet_type; diff --git a/msm/eva/hfi_response_handler.c b/msm/eva/hfi_response_handler.c index e72d74bdf0..742cf1149e 100644 --- a/msm/eva/hfi_response_handler.c +++ b/msm/eva/hfi_response_handler.c @@ -388,66 +388,6 @@ static int hfi_process_session_rel_buf_done(u32 device_id, return 0; } -static int hfi_process_session_cvp_operation_config(u32 device_id, - void *hdr, struct msm_cvp_cb_info *info) -{ - struct cvp_hfi_msg_session_op_cfg_packet *pkt = - (struct cvp_hfi_msg_session_op_cfg_packet *)hdr; - struct cvp_hfi_msg_session_hdr *lhdr = - (struct cvp_hfi_msg_session_hdr *)hdr; - struct msm_cvp_cb_cmd_done cmd_done = {0}; - int signal; - unsigned int conf_id, session_id, error_type; - - if (!pkt) { - dprintk(CVP_ERR, "%s: invalid param\n", __func__); - return -EINVAL; - } else if (pkt->size < get_msg_size(lhdr)) { - dprintk(CVP_ERR, - "%s: bad_pkt_size\n", __func__); - return -E2BIG; - } - - get_msg_opconfigs(pkt, &session_id, &error_type, &conf_id); - cmd_done.device_id = device_id; - cmd_done.session_id = (void *)(uintptr_t)session_id; - cmd_done.status = hfi_map_err_status(error_type); - cmd_done.size = 0; - - dprintk(CVP_HFI, - "%s: device_id=%d status=%d, sessionid=%pK config=%x\n", - __func__, device_id, cmd_done.status, - cmd_done.session_id, pkt->op_conf_id); - - if (pkt->packet_type == HFI_MSG_SESSION_CVP_SET_PERSIST_BUFFERS) - signal = get_signal_from_pkt_type( - HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS); - else if (pkt->packet_type == - HFI_MSG_SESSION_CVP_RELEASE_PERSIST_BUFFERS) - signal = get_signal_from_pkt_type( - HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS); - else if (pkt->packet_type == HFI_MSG_SESSION_CVP_SET_MODEL_BUFFERS) - signal = get_signal_from_pkt_type( - HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS); - else if (pkt->packet_type == HFI_MSG_SESSION_CVP_DMM_PARAMS) - signal = get_signal_from_pkt_type( - HFI_CMD_SESSION_CVP_DMM_PARAMS); - else if (pkt->packet_type == HFI_MSG_SESSION_CVP_WARP_DS_PARAMS) - signal = get_signal_from_pkt_type( - HFI_CMD_SESSION_CVP_WARP_DS_PARAMS); - else - signal = get_signal_from_pkt_type(conf_id); - - if (signal < 0) { - dprintk(CVP_ERR, "%s Invalid op config id\n", __func__); - return -EINVAL; - } - - info->response_type = signal; - info->response.cmd = cmd_done; - return 0; -} - static struct msm_cvp_inst *cvp_get_inst_from_id(struct msm_cvp_core *core, unsigned int session_id) { @@ -658,24 +598,6 @@ int cvp_hfi_process_msg_packet(u32 device_id, void *hdr, case HFI_MSG_SESSION_CVP_FLUSH: pkt_func = (pkt_func_def)hfi_process_session_flush_done; break; - case HFI_MSG_SESSION_CVP_OPERATION_CONFIG: - case HFI_MSG_SESSION_CVP_SET_PERSIST_BUFFERS: - case HFI_MSG_SESSION_CVP_RELEASE_PERSIST_BUFFERS: - case HFI_MSG_SESSION_CVP_SET_MODEL_BUFFERS: - case HFI_MSG_SESSION_CVP_DMM_PARAMS: - case HFI_MSG_SESSION_CVP_WARP_DS_PARAMS: - pkt_func = - (pkt_func_def)hfi_process_session_cvp_operation_config; - break; - case HFI_MSG_SESSION_CVP_DS: - case HFI_MSG_SESSION_CVP_DFS: - case HFI_MSG_SESSION_CVP_DMM: - case HFI_MSG_SESSION_CVP_WARP: - case HFI_MSG_SESSION_CVP_WARP_NCC: - case HFI_MSG_SESSION_CVP_FD: - case HFI_MSG_SESSION_CVP_SGM_OF: - pkt_func = (pkt_func_def)hfi_process_session_cvp_msg; - break; default: dprintk(CVP_HFI, "Use default msg handler: %#x\n", msg_hdr->packet); diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 17cf7c153b..f8ecb51670 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -47,7 +47,7 @@ static bool cvp_msg_pending(struct cvp_session_queue *sq, mptr = NULL; spin_lock(&sq->lock); - if (sq->state != QUEUE_ACTIVE) { + if (sq->state == QUEUE_INIT || sq->state == QUEUE_INVALID) { /* The session is being deleted */ spin_unlock(&sq->lock); *msg = NULL; @@ -101,7 +101,8 @@ static int cvp_wait_process_message(struct msm_cvp_inst *inst, sq->state, sq->msg_count); if (inst->state >= MSM_CVP_CLOSE_DONE || - sq->state != QUEUE_ACTIVE) { + (sq->state != QUEUE_ACTIVE && + sq->state != QUEUE_START)) { rc = -ECONNRESET; goto exit; } @@ -160,9 +161,11 @@ static int msm_cvp_session_process_hfi( { int pkt_idx, pkt_type, rc = 0; struct cvp_hfi_device *hdev; - unsigned int offset, buf_num, signal; + unsigned int offset = 0, buf_num = 0, signal; struct cvp_session_queue *sq; struct msm_cvp_inst *s; + bool is_config_pkt; + enum buf_map_type map_type; if (!inst || !inst->core || !in_pkt) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); @@ -183,17 +186,25 @@ static int msm_cvp_session_process_hfi( in_pkt->pkt_data[1]); goto exit; } else { - offset = cvp_hfi_defs[pkt_idx].buf_offset; - buf_num = cvp_hfi_defs[pkt_idx].buf_num; signal = cvp_hfi_defs[pkt_idx].resp; + is_config_pkt = cvp_hfi_defs[pkt_idx].is_config_pkt; } + if (signal == HAL_NO_RESP) { /* Frame packets are not allowed before session starts*/ sq = &inst->session_queue; spin_lock(&sq->lock); - if (sq->state != QUEUE_ACTIVE) { + if ((sq->state != QUEUE_START && !is_config_pkt) || + (sq->state >= QUEUE_INVALID)) { + /* + * A init packet is allowed in case of + * QUEUE_ACTIVE, QUEUE_START, QUEUE_STOP + * A frame packet is only allowed in case of + * QUEUE_START + */ spin_unlock(&sq->lock); - dprintk(CVP_ERR, "%s: invalid queue state\n", __func__); + dprintk(CVP_ERR, "%s: invalid queue state %d\n", + __func__, sq->state); rc = -EINVAL; goto exit; } @@ -209,12 +220,11 @@ static int msm_cvp_session_process_hfi( return -EINVAL; } pkt_type = in_pkt->pkt_data[1]; - if (pkt_type == HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS || - pkt_type == HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS || - pkt_type == HFI_CMD_SESSION_CVP_DMM_PARAMS || - pkt_type == HFI_CMD_SESSION_CVP_WARP_DS_PARAMS) + map_type = cvp_find_map_type(pkt_type); + + if (map_type == MAP_PERSIST) rc = msm_cvp_map_user_persist(inst, in_pkt, offset, buf_num); - else if (pkt_type == HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS) + else if (map_type == UNMAP_PERSIST) rc = msm_cvp_mark_user_persist(inst, in_pkt, offset, buf_num); else rc = msm_cvp_map_frame(inst, in_pkt, offset, buf_num); @@ -230,22 +240,10 @@ static int msm_cvp_session_process_hfi( goto exit; } - if (signal != HAL_NO_RESP) { - rc = wait_for_sess_signal_receipt(inst, signal); - if (rc) { - dprintk(CVP_ERR, - "%s: wait for signal failed, rc %d %d, %x %d\n", - __func__, rc, - in_pkt->pkt_data[0], - in_pkt->pkt_data[1], - signal); - goto exit; - } - if (pkt_type == HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS) - rc = msm_cvp_unmap_user_persist(inst, in_pkt, - offset, buf_num); + if (signal != HAL_NO_RESP) + dprintk(CVP_ERR, "%s signal %d from UMD is not HAL_NO_RESP\n", + __func__, signal); - } exit: inst->cur_cmd_type = 0; cvp_put_inst(inst); @@ -261,7 +259,7 @@ static bool cvp_fence_wait(struct cvp_fence_queue *q, *fence = NULL; mutex_lock(&q->lock); *state = q->state; - if (*state != QUEUE_ACTIVE) { + if (*state != QUEUE_START) { mutex_unlock(&q->lock); return true; } @@ -582,7 +580,7 @@ wait: f = NULL; wait_event_interruptible(q->wq, cvp_fence_wait(q, &f, &state)); - if (state != QUEUE_ACTIVE) + if (state != QUEUE_START) goto exit; if (!f) @@ -608,7 +606,7 @@ wait: cvp_free_fence_data(f); - if (rc && state != QUEUE_ACTIVE) + if (rc && state != QUEUE_START) goto exit; goto wait; @@ -629,7 +627,7 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst, struct eva_kmd_hfi_synx_packet *synx_pkt; struct eva_kmd_fence_ctrl *kfc; struct cvp_hfi_cmd_session_hdr *pkt; - unsigned int offset, buf_num, in_offset, in_buf_num; + unsigned int offset = 0, buf_num = 0, in_offset, in_buf_num; struct msm_cvp_inst *s; struct cvp_fence_command *f; struct cvp_fence_queue *q; @@ -674,9 +672,6 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst, if (in_offset && in_buf_num) { offset = in_offset; buf_num = in_buf_num; - } else { - offset = cvp_hfi_defs[idx].buf_offset; - buf_num = cvp_hfi_defs[idx].buf_num; } if (!is_buf_param_valid(buf_num, offset)) { @@ -1014,6 +1009,7 @@ int msm_cvp_session_create(struct msm_cvp_inst *inst) { int rc = 0; struct synx_initialization_params params; + struct cvp_session_queue *sq; if (!inst || !inst->core) return -EINVAL; @@ -1049,6 +1045,11 @@ int msm_cvp_session_create(struct msm_cvp_inst *inst) rc = -EFAULT; } + sq = &inst->session_queue; + spin_lock(&sq->lock); + sq->state = QUEUE_ACTIVE; + spin_unlock(&sq->lock); + fail_init: return rc; } @@ -1080,7 +1081,7 @@ static int cvp_fence_thread_start(struct msm_cvp_inst *inst) q = &inst->fence_cmd_queue; mutex_lock(&q->lock); - q->state = QUEUE_ACTIVE; + q->state = QUEUE_START; mutex_unlock(&q->lock); for (i = 0; i < inst->prop.fthread_nr; ++i) { @@ -1100,7 +1101,7 @@ static int cvp_fence_thread_start(struct msm_cvp_inst *inst) sq = &inst->session_queue_fence; spin_lock(&sq->lock); - sq->state = QUEUE_ACTIVE; + sq->state = QUEUE_START; spin_unlock(&sq->lock); exit: @@ -1151,7 +1152,7 @@ static int msm_cvp_session_start(struct msm_cvp_inst *inst, spin_unlock(&sq->lock); return -EINVAL; } - sq->state = QUEUE_ACTIVE; + sq->state = QUEUE_START; spin_unlock(&sq->lock); return cvp_fence_thread_start(inst); @@ -1597,9 +1598,10 @@ static void cvp_clean_fence_queue(struct msm_cvp_inst *inst, int synx_state) mutex_unlock(&q->lock); } -int cvp_stop_clean_fence_queue(struct msm_cvp_inst *inst) +int cvp_clean_session_queues(struct msm_cvp_inst *inst) { struct cvp_fence_queue *q; + struct cvp_session_queue *sq; u32 count = 0, max_retries = 100; cvp_clean_fence_queue(inst, SYNX_STATE_SIGNALED_ERROR); @@ -1619,6 +1621,16 @@ retry: return -EBUSY; goto retry; + + sq = &inst->session_queue_fence; + spin_lock(&sq->lock); + sq->state = QUEUE_INVALID; + spin_unlock(&sq->lock); + + sq = &inst->session_queue_fence; + spin_lock(&sq->lock); + sq->state = QUEUE_INVALID; + spin_unlock(&sq->lock); } static int cvp_flush_all(struct msm_cvp_inst *inst) @@ -1917,7 +1929,7 @@ int msm_cvp_session_init(struct msm_cvp_inst *inst) inst->clk_data.ddr_bw = 1000; inst->clk_data.sys_cache_bw = 1000; - inst->prop.type = HFI_SESSION_CV; + inst->prop.type = 1; inst->prop.kernel_mask = 0xFFFFFFFF; inst->prop.priority = 0; inst->prop.is_secure = 0; diff --git a/msm/eva/msm_cvp.h b/msm/eva/msm_cvp.h index ff832a9a09..79ecf7434e 100644 --- a/msm/eva/msm_cvp.h +++ b/msm/eva/msm_cvp.h @@ -37,5 +37,5 @@ int msm_cvp_session_create(struct msm_cvp_inst *inst); int msm_cvp_session_delete(struct msm_cvp_inst *inst); int msm_cvp_get_session_info(struct msm_cvp_inst *inst, u32 *session); int msm_cvp_update_power(struct msm_cvp_inst *inst); -int cvp_stop_clean_fence_queue(struct msm_cvp_inst *inst); +int cvp_clean_session_queues(struct msm_cvp_inst *inst); #endif diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 0a2674c262..42a0e5a600 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -214,42 +214,6 @@ struct msm_cvp_inst *cvp_get_inst_validate(struct msm_cvp_core *core, return s; } -static void cvp_handle_session_cmd_done(enum hal_command_response cmd, - void *data) -{ - struct msm_cvp_cb_cmd_done *response = data; - struct msm_cvp_inst *inst; - - if (!response) { - dprintk(CVP_ERR, "%s: Invalid release_buf_done response\n", - __func__); - return; - } - - inst = cvp_get_inst(get_cvp_core(response->device_id), - response->session_id); - if (!inst) { - dprintk(CVP_ERR, "%s: Got response for an inactive session\n", - __func__); - return; - } - - if (response->status) - dprintk(CVP_ERR, "HFI MSG error %d cmd response %d\n", - response->status, cmd); - - dprintk(CVP_SESS, "%s: inst=%pK\n", __func__, inst); - - if (IS_HAL_SESSION_CMD(cmd)) { - dprintk(CVP_INFO, "%s: calling completion for index = %d", - __func__, SESSION_MSG_INDEX(cmd)); - complete(&inst->completions[SESSION_MSG_INDEX(cmd)]); - } else - dprintk(CVP_ERR, - "%s: Invalid inst cmd response: %d\n", __func__, cmd); - cvp_put_inst(inst); -} - static void handle_session_set_buf_done(enum hal_command_response cmd, void *data) { @@ -666,7 +630,7 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) inst->cur_cmd_type, inst->state); if (inst->state != MSM_CVP_CORE_INVALID) { change_cvp_inst_state(inst, MSM_CVP_CORE_INVALID); - if (cvp_stop_clean_fence_queue(inst)) + if (cvp_clean_session_queues(inst)) dprintk(CVP_ERR, "Failed to clean fences\n"); for (i = 0; i < ARRAY_SIZE(inst->completions); i++) complete(&inst->completions[i]); @@ -792,28 +756,6 @@ void cvp_handle_cmd_response(enum hal_command_response cmd, void *data) case HAL_SESSION_RELEASE_BUFFER_DONE: handle_session_release_buf_done(cmd, data); break; - case HAL_SESSION_SGM_OF_CONFIG_CMD_DONE: - case HAL_SESSION_DFS_CONFIG_CMD_DONE: - case HAL_SESSION_DMM_CONFIG_CMD_DONE: - case HAL_SESSION_DMM_PARAMS_CMD_DONE: - case HAL_SESSION_WARP_CONFIG_CMD_DONE: - case HAL_SESSION_WARP_DS_PARAMS_CMD_DONE: - case HAL_SESSION_WARP_NCC_CONFIG_CMD_DONE: - case HAL_SESSION_PERSIST_SET_DONE: - case HAL_SESSION_PERSIST_REL_DONE: - case HAL_SESSION_TME_CONFIG_CMD_DONE: - case HAL_SESSION_ODT_CONFIG_CMD_DONE: - case HAL_SESSION_OD_CONFIG_CMD_DONE: - case HAL_SESSION_NCC_CONFIG_CMD_DONE: - case HAL_SESSION_ICA_CONFIG_CMD_DONE: - case HAL_SESSION_HCD_CONFIG_CMD_DONE: - case HAL_SESSION_DCM_CONFIG_CMD_DONE: - case HAL_SESSION_DC_CONFIG_CMD_DONE: - case HAL_SESSION_PYS_HCD_CONFIG_CMD_DONE: - case HAL_SESSION_FD_CONFIG_CMD_DONE: - case HAL_SESSION_MODEL_BUF_CMD_DONE: - cvp_handle_session_cmd_done(cmd, data); - break; default: dprintk(CVP_HFI, "response unhandled: %d\n", cmd); break; diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 93994ba7a2..63cb89922f 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -119,7 +119,7 @@ static void __deinit_session_queue(struct msm_cvp_inst *inst) kmem_cache_free(cvp_driver->msg_cache, msg); } inst->session_queue.msg_count = 0; - inst->session_queue.state = QUEUE_STOP; + inst->session_queue.state = QUEUE_INVALID; spin_unlock(&inst->session_queue.lock); wake_up_all(&inst->session_queue.wq); diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 4de7f29e9f..9d93d34fa9 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -18,6 +18,8 @@ #include #include "msm_cvp_internal.h" #include "msm_cvp_debug.h" +#include "cvp_hfi_api.h" +#include "cvp_hfi.h" #define UBWC_CONFIG(mco, mlo, hbo, bslo, bso, rs, mc, ml, hbb, bsl, bsp) \ { \ @@ -133,6 +135,237 @@ static const struct of_device_id msm_cvp_dt_match[] = { {}, }; +const struct msm_cvp_hfi_defs cvp_hfi_defs[] = { + { + .size = HFI_DFS_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DFS_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_DFS_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DFS_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_SGM_OF_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_SGM_OF_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_WARP_NCC_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_WARP_NCC_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_WARP_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_WARP_DS_PARAMS, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_WARP_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_DMM_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DMM_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_DMM_PARAMS, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_DMM_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DMM_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_PERSIST_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = 0xffffffff, + .type = HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_DS_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DS, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_OF_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_CV_TME_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_OF_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_CV_TME_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_ODT_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_CV_ODT_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_ODT_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_CV_ODT_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_OD_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_CV_OD_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_OD_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_CV_OD_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_NCC_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_NCC_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_NCC_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_NCC_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_ICA_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_ICA_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_ICA_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_ICA_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_HCD_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_HCD_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_HCD_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_HCD_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_DCM_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DC_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_DCM_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DC_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_DCM_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DCM_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_DCM_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DCM_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_PYS_HCD_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_PYS_HCD_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = HFI_PYS_HCD_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_PYS_HCD_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_FD_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_FD_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + }, + +}; + +int get_pkt_index(struct cvp_hal_session_cmd_pkt *hdr) +{ + int i, pkt_num = ARRAY_SIZE(cvp_hfi_defs); + + for (i = 0; i < pkt_num; i++) + if (cvp_hfi_defs[i].type == hdr->packet_type) + return i; + + return -EINVAL; +} + MODULE_DEVICE_TABLE(of, msm_cvp_dt_match); void *cvp_get_drv_data(struct device *dev) From 322bbdeaa331e7a181d53d099213ea157f1db897 Mon Sep 17 00:00:00 2001 From: Karthik Nagarajan Date: Fri, 4 Jun 2021 12:15:07 -0700 Subject: [PATCH 058/317] msm: eva: Enable hangdump mode in EVA Include new hfi packets and enable the pipeline to dump hangdump buffers in UMD. Change-Id: Id66538c69d3080c09c5a140dadcb0dfe87d9efc7 Signed-off-by: Karthik Nagarajan --- include/uapi/eva/media/msm_eva_private.h | 2 ++ msm/eva/cvp.c | 3 ++ msm/eva/cvp_hfi.c | 1 + msm/eva/cvp_hfi.h | 20 +++++++++-- msm/eva/cvp_hfi_api.h | 1 + msm/eva/cvp_hfi_helper.h | 10 ++++++ msm/eva/hfi_response_handler.c | 45 ++++++++++++++++++++++++ msm/eva/msm_cvp.c | 27 ++++++++++++++ msm/eva/msm_cvp_common.c | 31 ++++++++++++++++ msm/eva/msm_cvp_internal.h | 3 ++ msm/eva/msm_cvp_platform.c | 24 +++++++++++++ 11 files changed, 165 insertions(+), 2 deletions(-) diff --git a/include/uapi/eva/media/msm_eva_private.h b/include/uapi/eva/media/msm_eva_private.h index 082dae2275..4ab350dde5 100644 --- a/include/uapi/eva/media/msm_eva_private.h +++ b/include/uapi/eva/media/msm_eva_private.h @@ -133,6 +133,8 @@ struct eva_kmd_hfi_packet { #define EVA_KMD_PROP_SESSION_PRIORITY 4 #define EVA_KMD_PROP_SESSION_SECURITY 5 #define EVA_KMD_PROP_SESSION_DSPMASK 6 +#define EVA_KMD_PROP_SESSION_DUMPOFFSET 7 +#define EVA_KMD_PROP_SESSION_DUMPSIZE 8 #define EVA_KMD_PROP_PWR_FDU 0x10 #define EVA_KMD_PROP_PWR_ICA 0x11 diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index 5366db5013..89b83a1613 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -70,6 +70,9 @@ static unsigned int cvp_poll(struct file *filp, struct poll_table_struct *p) spin_lock_irqsave(&inst->event_handler.lock, flags); if (inst->event_handler.event == CVP_SSR_EVENT) rc |= POLLPRI; + if (inst->event_handler.event == CVP_DUMP_EVENT) + rc |= POLLIN; + inst->event_handler.event = CVP_NO_EVENT; spin_unlock_irqrestore(&inst->event_handler.lock, flags); return rc; diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 00d9e5e3a2..3cd7376068 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -2653,6 +2653,7 @@ static void **get_session_id(struct msm_cvp_cb_info *info) case HAL_SESSION_UNREGISTER_BUFFER_DONE: case HAL_SESSION_PROPERTY_INFO: case HAL_SESSION_EVENT_CHANGE: + case HAL_SESSION_DUMP_NOTIFY: session_id = &info->response.cmd.session_id; break; case HAL_SESSION_ERROR: diff --git a/msm/eva/cvp_hfi.h b/msm/eva/cvp_hfi.h index 17ca9f2a30..713c9e6209 100644 --- a/msm/eva/cvp_hfi.h +++ b/msm/eva/cvp_hfi.h @@ -131,7 +131,14 @@ (HFI_CMD_SESSION_CVP_START + 0x064) #define HFI_CMD_SESSION_CVP_WARP_DS_PARAMS\ (HFI_CMD_SESSION_CVP_START + 0x065) - +#define HFI_CMD_SESSION_CVP_SET_SNAPSHOT_BUFFERS\ + (HFI_CMD_SESSION_CVP_START + 0x070) +#define HFI_CMD_SESSION_CVP_RELEASE_SNAPSHOT_BUFFERS\ + (HFI_CMD_SESSION_CVP_START + 0x071) +#define HFI_CMD_SESSION_CVP_SNAPSHOT_WRITE_DONE\ + (HFI_CMD_SESSION_CVP_START + 0x072) +#define HFI_CMD_SESSION_CVP_SET_SNAPSHOT_MODE\ + (HFI_CMD_SESSION_CVP_START + 0x073) #define HFI_CMD_SESSION_CVP_ICA_FRAME\ (HFI_CMD_SESSION_CVP_START + 0x100) #define HFI_CMD_SESSION_CVP_ICA_CONFIG\ @@ -196,6 +203,12 @@ (HFI_MSG_SESSION_CVP_START + 0x040) #define HFI_MSG_SESSION_CVP_WARP_DS_PARAMS\ (HFI_MSG_SESSION_CVP_START + 0x041) +#define HFI_MSG_SESSION_CVP_SET_SNAPSHOT_BUFFERS\ + (HFI_MSG_SESSION_CVP_START + 0x042) +#define HFI_MSG_SESSION_CVP_RELEASE_SNAPSHOT_BUFFERS\ + (HFI_MSG_SESSION_CVP_START + 0x043) +#define HFI_MSG_EVENT_NOTIFY_SNAPSHOT_READY\ + (HFI_MSG_SESSION_CVP_START + 0x044) #define HFI_MSG_SESSION_CVP_FLUSH\ (HFI_MSG_SESSION_CVP_START + 0x004A) @@ -299,9 +312,12 @@ static inline enum buf_map_type cvp_find_map_type(int pkt_type) if (pkt_type == HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS || pkt_type == HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS || pkt_type == HFI_CMD_SESSION_CVP_DMM_PARAMS || + pkt_type == HFI_CMD_SESSION_CVP_SET_SNAPSHOT_BUFFERS || pkt_type == HFI_CMD_SESSION_CVP_WARP_DS_PARAMS) return MAP_PERSIST; - else if (pkt_type == HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS) + else if (pkt_type == HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS || + pkt_type == + HFI_CMD_SESSION_CVP_RELEASE_SNAPSHOT_BUFFERS) return UNMAP_PERSIST; else return MAP_FRAME; diff --git a/msm/eva/cvp_hfi_api.h b/msm/eva/cvp_hfi_api.h index 53d419b13a..39f45061df 100644 --- a/msm/eva/cvp_hfi_api.h +++ b/msm/eva/cvp_hfi_api.h @@ -143,6 +143,7 @@ enum hal_command_response { HAL_SESSION_UNREGISTER_BUFFER_DONE, HAL_SESSION_RELEASE_RESOURCE_DONE, HAL_SESSION_PROPERTY_INFO, + HAL_SESSION_DUMP_NOTIFY, HAL_SESSION_ERROR, HAL_RESPONSE_UNUSED = 0x10000000, }; diff --git a/msm/eva/cvp_hfi_helper.h b/msm/eva/cvp_hfi_helper.h index c4126450dc..4b2ad11cfc 100644 --- a/msm/eva/cvp_hfi_helper.h +++ b/msm/eva/cvp_hfi_helper.h @@ -329,6 +329,16 @@ struct cvp_hfi_msg_session_hdr { u32 stream_idx; } __packed; +struct cvp_hfi_dumpmsg_session_hdr { + u32 size; + u32 packet_type; + u32 session_id; + u32 error_type; + struct cvp_hfi_client client_data; + u32 dump_offset; + u32 dump_size; +} __packed; + #define HFI_MAX_HW_ACTIVATIONS_PER_FRAME (6) #define HFI_MAX_HW_THREADS (4) diff --git a/msm/eva/hfi_response_handler.c b/msm/eva/hfi_response_handler.c index 742cf1149e..e8d35b8f5f 100644 --- a/msm/eva/hfi_response_handler.c +++ b/msm/eva/hfi_response_handler.c @@ -424,6 +424,48 @@ retry: } +static int hfi_process_session_dump_notify(u32 device_id, + void *hdr, struct msm_cvp_cb_info *info) +{ + struct msm_cvp_inst *inst = NULL; + struct msm_cvp_core *core; + struct cvp_session_prop *session_prop; + unsigned int session_id; + struct msm_cvp_cb_cmd_done cmd_done = {0}; + struct cvp_hfi_dumpmsg_session_hdr *pkt = + (struct cvp_hfi_dumpmsg_session_hdr *)hdr; + + if (!pkt) { + dprintk(CVP_ERR, "%s: invalid param\n", __func__); + return -EINVAL; + } else if (pkt->size > sizeof(struct cvp_hfi_dumpmsg_session_hdr)) { + dprintk(CVP_ERR, "%s: bad_pkt_size %d\n", __func__, pkt->size); + return -E2BIG; + } + session_id = get_msg_session_id(pkt); + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + inst = cvp_get_inst_from_id(core, session_id); + if (!inst) { + dprintk(CVP_ERR, "%s: invalid session\n", __func__); + return -EINVAL; + } + session_prop = &inst->prop; + session_prop->dump_offset = pkt->dump_offset; + session_prop->dump_size = pkt->dump_size; + + dprintk(CVP_SESS, "RECEIVED: SESSION_DUMP[%x]\n", session_id); + + cmd_done.device_id = device_id; + cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.status = hfi_map_err_status(pkt->error_type); + cmd_done.size = 0; + + info->response_type = HAL_SESSION_DUMP_NOTIFY; + info->response.cmd = cmd_done; + + return 0; +} + static int hfi_process_session_cvp_msg(u32 device_id, void *hdr, struct msm_cvp_cb_info *info) { @@ -598,6 +640,9 @@ int cvp_hfi_process_msg_packet(u32 device_id, void *hdr, case HFI_MSG_SESSION_CVP_FLUSH: pkt_func = (pkt_func_def)hfi_process_session_flush_done; break; + case HFI_MSG_EVENT_NOTIFY_SNAPSHOT_READY: + pkt_func = (pkt_func_def)hfi_process_session_dump_notify; + break; default: dprintk(CVP_HFI, "Use default msg handler: %#x\n", msg_hdr->packet); diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index f8ecb51670..753ac50838 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -1302,6 +1302,7 @@ static int msm_cvp_get_sysprop(struct msm_cvp_inst *inst, struct eva_kmd_sys_properties *props = &arg->data.sys_properties; struct cvp_hfi_device *hdev; struct iris_hfi_device *hfi; + struct cvp_session_prop *session_prop; int i, rc = 0; if (!inst || !inst->core || !inst->core->device) { @@ -1312,6 +1313,14 @@ static int msm_cvp_get_sysprop(struct msm_cvp_inst *inst, hdev = inst->core->device; hfi = hdev->hfi_device_data; + if (props->prop_num > MAX_KMD_PROP_NUM_PER_PACKET) { + dprintk(CVP_ERR, "Too many properties %d to get\n", + props->prop_num); + return -E2BIG; + } + + session_prop = &inst->prop; + for (i = 0; i < props->prop_num; i++) { switch (props->prop_data[i].prop_type) { case EVA_KMD_PROP_HFI_VERSION: @@ -1319,6 +1328,18 @@ static int msm_cvp_get_sysprop(struct msm_cvp_inst *inst, props->prop_data[i].data = hfi->version; break; } + case EVA_KMD_PROP_SESSION_DUMPOFFSET: + { + props->prop_data[i].data = + session_prop->dump_offset; + break; + } + case EVA_KMD_PROP_SESSION_DUMPSIZE: + { + props->prop_data[i].data = + session_prop->dump_size; + break; + } case EVA_KMD_PROP_PWR_FDU: { props->prop_data[i].data = @@ -1449,6 +1470,12 @@ static int msm_cvp_set_sysprop(struct msm_cvp_inst *inst, case EVA_KMD_PROP_PWR_FPS_ICA: session_prop->fps[HFI_HW_ICA] = prop_array[i].data; break; + case EVA_KMD_PROP_SESSION_DUMPOFFSET: + session_prop->dump_offset = prop_array[i].data; + break; + case EVA_KMD_PROP_SESSION_DUMPSIZE: + session_prop->dump_size = prop_array[i].data; + break; default: dprintk(CVP_ERR, "unrecognized sys property to set %d\n", diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 42a0e5a600..f5537b1124 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -463,6 +463,34 @@ static void handle_event_change(enum hal_command_response cmd, void *data) dprintk(CVP_WARN, "%s is not supported on CVP!\n", __func__); } +static void handle_session_dump_notify(enum hal_command_response cmd, + void *data) +{ + struct msm_cvp_cb_cmd_done *response = data; + struct msm_cvp_inst *inst; + unsigned long flags = 0; + + if (!response) { + dprintk(CVP_ERR, + "Failed to get valid response during dump notify\n"); + return; + } + + inst = cvp_get_inst(get_cvp_core(response->device_id), + response->session_id); + if (!inst) { + dprintk(CVP_WARN, "%s:Got a response for an inactive session\n", + __func__); + return; + } + spin_lock_irqsave(&inst->event_handler.lock, flags); + inst->event_handler.event = CVP_DUMP_EVENT; + spin_unlock_irqrestore(&inst->event_handler.lock, flags); + wake_up_all(&inst->event_handler.wq); + dprintk(CVP_ERR,"Event_handler woken up\n"); + cvp_put_inst(inst); +} + static void handle_release_res_done(enum hal_command_response cmd, void *data) { struct msm_cvp_cb_cmd_done *response = data; @@ -756,6 +784,9 @@ void cvp_handle_cmd_response(enum hal_command_response cmd, void *data) case HAL_SESSION_RELEASE_BUFFER_DONE: handle_session_release_buf_done(cmd, data); break; + case HAL_SESSION_DUMP_NOTIFY: + handle_session_dump_notify(cmd, data); + break; default: dprintk(CVP_HFI, "response unhandled: %d\n", cmd); break; diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index 6d20fe6451..e79a0d7965 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -250,6 +250,8 @@ struct cvp_session_prop { u32 ddr_cache; u32 ddr_op_cache; u32 fps[HFI_MAX_HW_THREADS]; + u32 dump_offset; + u32 dump_size; }; enum cvp_event_t { @@ -259,6 +261,7 @@ enum cvp_event_t { CVP_MAX_CLIENTS_EVENT, CVP_HW_UNSUPPORTED_EVENT, CVP_INVALID_EVENT, + CVP_DUMP_EVENT, }; struct cvp_session_event { diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 9d93d34fa9..c6fcd96dcb 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -340,6 +340,30 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[] = { .is_config_pkt = true, .resp = HAL_NO_RESP, }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_SET_SNAPSHOT_BUFFERS, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_RELEASE_SNAPSHOT_BUFFERS, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_SET_SNAPSHOT_MODE, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_SNAPSHOT_WRITE_DONE, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + }, { .size = 0xFFFFFFFF, .type = HFI_CMD_SESSION_CVP_FD_CONFIG, From dd913bddc05c9787baf8cc1526fb67912a3dafaf Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 8 Jun 2021 06:09:22 -0700 Subject: [PATCH 059/317] msm: eva: Deprecate secure heap reference Use mem_buf_lend to assign system memory to secure VM. Change-Id: I6a09e65ddb72dbd6eadd6a88ae56df5430825c9e Signed-off-by: George Shen --- msm/eva/msm_smem.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) diff --git a/msm/eva/msm_smem.c b/msm/eva/msm_smem.c index f2dcd623b7..d436603ff9 100644 --- a/msm/eva/msm_smem.c +++ b/msm/eva/msm_smem.c @@ -262,6 +262,9 @@ static int alloc_dma_mem(size_t size, u32 align, int map_kernel, int rc = 0; struct dma_buf *dbuf = NULL; struct dma_heap *heap = NULL; + struct mem_buf_lend_kernel_arg arg; + int vmids[1]; + int perms[1]; if (!res) { dprintk(CVP_ERR, "%s: NULL res\n", __func__); @@ -281,20 +284,34 @@ static int alloc_dma_mem(size_t size, u32 align, int map_kernel, size, align); } - if (mem->flags & SMEM_NON_PIXEL) - heap = dma_heap_find("qcom,secure-non-pixel"); - else if (mem->flags & SMEM_PIXEL) - heap = dma_heap_find("qcom,secure-pixel"); - dbuf = dma_heap_buffer_alloc(heap, size, 0, 0); if (IS_ERR_OR_NULL(dbuf)) { dprintk(CVP_ERR, - "Failed to allocate shared memory = %x bytes, %x %x\n", - size, mem->flags, PTR_ERR(dbuf)); + "Failed to allocate shared memory = %x bytes, %x %x\n", + size, mem->flags, PTR_ERR(dbuf)); rc = -ENOMEM; goto fail_shared_mem_alloc; } + perms[0] = PERM_READ | PERM_WRITE; + arg.nr_acl_entries = 1; + arg.vmids = vmids; + arg.perms = perms; + + if (mem->flags & SMEM_NON_PIXEL) { + vmids[0] = VMID_CP_NON_PIXEL; + rc = mem_buf_lend(dbuf, &arg); + } else if (mem->flags & SMEM_PIXEL) { + vmids[0] = VMID_CP_PIXEL; + rc = mem_buf_lend(dbuf, &arg); + } + + if (rc) { + dprintk(CVP_ERR, "Failed to lend dmabuf %d, vmid %d\n", + rc, vmids[0]); + goto fail_device_address; + } + if (!gfa_cv.dmabuf_f_op) gfa_cv.dmabuf_f_op = (const struct file_operations *)dbuf->file->f_op; From ce3bd728317c476150dade9bcfa239887bc52a92 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Thu, 10 Jun 2021 18:59:46 -0700 Subject: [PATCH 060/317] msm: eva: access sideband manager regs in PC added code to access sideband manager regs in __power_collapse, set bit field in CVP_CPU_CS_X2RPMh before access, and reset after. Change-Id: I73f3528b1d49060b0b2de8c2b54515461f8d3e65 Signed-off-by: Yu SI --- msm/eva/cvp_hfi.c | 21 +++++++++++++++++---- msm/eva/cvp_hfi_io.h | 3 +++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 3cd7376068..156dcc6611 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -3762,19 +3762,32 @@ static void power_off_iris2(struct iris_hfi_device *device) lpi_status, reg_status, count); if (count == max_count) { u32 pc_ready, wfi_status, sbm_ln0_low; - /*u32 main_sbm_ln0_low, main_sbm_ln1_high; */ + u32 main_sbm_ln0_low, main_sbm_ln1_high; + u32 cpu_cs_x2rpmh; wfi_status = __read_register(device, CVP_WRAPPER_CPU_STATUS); pc_ready = __read_register(device, CVP_CTRL_STATUS); sbm_ln0_low = __read_register(device, CVP_NOC_SBM_SENSELN0_LOW); - /*temp commented till dependency ready*/ - /* + + cpu_cs_x2rpmh = __read_register(device, + CVP_CPU_CS_X2RPMh); + + __write_register(device, CVP_CPU_CS_X2RPMh, + (cpu_cs_x2rpmh | CVP_CPU_CS_X2RPMh_SWOVERRIDE_BMSK)); + cpu_cs_x2rpmh = __read_register(device, + CVP_CPU_CS_X2RPMh); + dprintk(CVP_PWR, "cpu_cs_x2rpmh (%#x)\n", + cpu_cs_x2rpmh); + main_sbm_ln0_low = __read_register(device, CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_LOW); main_sbm_ln1_high = __read_register(device, CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN1_HIGH); - */ + + __write_register(device, CVP_CPU_CS_X2RPMh, + (cpu_cs_x2rpmh & (~CVP_CPU_CS_X2RPMh_SWOVERRIDE_BMSK))); + dprintk(CVP_WARN, "NOC not in qaccept status %x %x %x %x %x\n", reg_status, lpi_status, wfi_status, pc_ready, diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index fb9c66d7e3..4d17a72a48 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -220,4 +220,7 @@ #define CVP_CC_MVS1C_GDSCR (CVP_CC_BASE_OFFS + 0x74) #define CVP_CC_MVS1C_CBCR (CVP_CC_BASE_OFFS + 0x8C) #define CVP_CC_MVS1_GDSCR (CVP_CC_BASE_OFFS + 0xC0) +#define CVP_CC_MVS1_CBCR (CVP_CC_BASE_OFFS + 0xD4) + +#define CVP_GCC_VIDEO_AXI1_CBCR (0x32020) #endif From a8eef953d6c1c20b6b95eda84a0d13f251f133b4 Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 22 Jun 2021 12:03:17 -0700 Subject: [PATCH 061/317] msm: eva: Replace TARGET_PRODUCT with TARGET_BOARD_PLATFORM. Change-Id: I91c7396512be295a6a4ea3302547fd6a0572bcd8 Signed-off-by: George Shen --- Android.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Android.mk b/Android.mk index c9c9f556e7..58cd734031 100644 --- a/Android.mk +++ b/Android.mk @@ -1,4 +1,4 @@ -ifneq ($(TARGET_PRODUCT), qssi) +ifneq ($(TARGET_BOARD_PLATFORM), qssi) ifeq ($(call is-board-platform-in-list, $(TARGET_BOARD_PLATFORM)),true) DLKM_DIR := device/qcom/common/dlkm @@ -31,4 +31,4 @@ $(info DLKM_DIR = $(DLKM_DIR)) include $(DLKM_DIR)/Build_external_kernelmodule.mk endif # End of check for board platform -endif # End of check for target product \ No newline at end of file +endif # End of check for target product From 99ad8575b2bf05f370ba3bfa3fe8346bb19d4a00 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Wed, 23 Jun 2021 13:17:26 -0700 Subject: [PATCH 062/317] msm: eva: adjust log level for non-fatal msg change msg trace level to CVP_INFO for cvp_wait_process_msg non-fatal. Change-Id: If2e245f894d3076ed129f322e477ad5b1beead32 Signed-off-by: Yu SI --- msm/eva/msm_cvp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 753ac50838..ba56d4c589 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -508,7 +508,7 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, current->comm, __func__); synx_state = SYNX_STATE_SIGNALED_CANCEL; } else if (hfi_err == HFI_ERR_SESSION_STREAM_CORRUPT) { - dprintk(CVP_WARN, "%s %s: cvp_wait_process_msg non-fatal %d\n", + dprintk(CVP_INFO, "%s %s: cvp_wait_process_msg non-fatal %d\n", current->comm, __func__, hfi_err); synx_state = SYNX_STATE_SIGNALED_SUCCESS; } else if (hfi_err != HFI_ERR_NONE) { From 022b7d2d1b740c5159954bf020adc70144466b33 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 24 Jun 2021 15:50:06 -0700 Subject: [PATCH 063/317] msm: eva: Avoid printing unnecessary warnings When handling HFI response of config packets. Change-Id: I16e373d07c1cc7617624160921bcca972381277b Signed-off-by: George Shen --- msm/eva/cvp.c | 2 +- msm/eva/cvp_hfi_api.h | 1 + msm/eva/msm_cvp.c | 8 +++++++- msm/eva/msm_cvp_platform.c | 9 +++++++-- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index 89b83a1613..6f3c69215f 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -437,7 +437,7 @@ static int msm_probe_cvp_device(struct platform_device *pdev) goto err_fail_sub_device_probe; } - atomic64_set(&core->kernel_trans_id, 0); + atomic64_set(&core->kernel_trans_id, get_pkt_array_size()); if (core->resources.dsp_enabled) { rc = cvp_dsp_device_init(); diff --git a/msm/eva/cvp_hfi_api.h b/msm/eva/cvp_hfi_api.h index 39f45061df..09abd55fa0 100644 --- a/msm/eva/cvp_hfi_api.h +++ b/msm/eva/cvp_hfi_api.h @@ -293,6 +293,7 @@ void cvp_hfi_deinitialize(enum msm_cvp_hfi_type hfi_type, struct cvp_hfi_device *hdev); int get_pkt_index(struct cvp_hal_session_cmd_pkt *hdr); +int get_pkt_array_size(void); int get_hfi_version(void); unsigned int get_msg_size(struct cvp_hfi_msg_session_hdr *hdr); unsigned int get_msg_session_id(void *msg); diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index ba56d4c589..fd5a6ce76a 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -118,7 +118,8 @@ static int cvp_wait_process_message(struct msm_cvp_inst *inst, hdr = (struct cvp_hfi_msg_session_hdr *)&msg->pkt; memcpy(out, &msg->pkt, get_msg_size(hdr)); - msm_cvp_unmap_frame(inst, hdr->client_data.kdata); + if (hdr->client_data.kdata >= get_pkt_array_size()) + msm_cvp_unmap_frame(inst, hdr->client_data.kdata); kmem_cache_free(cvp_driver->msg_cache, msg); exit: @@ -166,6 +167,7 @@ static int msm_cvp_session_process_hfi( struct msm_cvp_inst *s; bool is_config_pkt; enum buf_map_type map_type; + struct cvp_hfi_cmd_session_hdr *cmd_hdr; if (!inst || !inst->core || !in_pkt) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); @@ -222,6 +224,10 @@ static int msm_cvp_session_process_hfi( pkt_type = in_pkt->pkt_data[1]; map_type = cvp_find_map_type(pkt_type); + cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; + /* The kdata will be overriden by transaction ID if the cmd has buf */ + cmd_hdr->client_data.kdata = pkt_idx; + if (map_type == MAP_PERSIST) rc = msm_cvp_map_user_persist(inst, in_pkt, offset, buf_num); else if (map_type == UNMAP_PERSIST) diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index c6fcd96dcb..6670203fda 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -379,11 +379,16 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[] = { }; +int get_pkt_array_size(void) +{ + return ARRAY_SIZE(cvp_hfi_defs); +} + int get_pkt_index(struct cvp_hal_session_cmd_pkt *hdr) { - int i, pkt_num = ARRAY_SIZE(cvp_hfi_defs); + int i; - for (i = 0; i < pkt_num; i++) + for (i = 0; i < get_pkt_array_size(); i++) if (cvp_hfi_defs[i].type == hdr->packet_type) return i; From 27b6f5dacdc8ee65cefbfcda2050e0da30dc6269 Mon Sep 17 00:00:00 2001 From: George Shen Date: Sat, 3 Jul 2021 20:30:12 -0700 Subject: [PATCH 064/317] msm: cvp: Update EVA power sequence To be more compliant with programming guide. Change-Id: I7908ed0a4a4c2baebaef0ec7dbf95ebb149683e8 Signed-off-by: George Shen --- msm/eva/cvp_core_hfi.h | 1 + msm/eva/cvp_hfi.c | 434 +++++++++++++++++++++++++++++---------- msm/eva/cvp_hfi_io.h | 11 + msm/eva/msm_cvp_clocks.c | 48 +++-- msm/eva/msm_cvp_clocks.h | 12 +- 5 files changed, 370 insertions(+), 136 deletions(-) diff --git a/msm/eva/cvp_core_hfi.h b/msm/eva/cvp_core_hfi.h index 5a9c2cec4d..e56e4a8eea 100644 --- a/msm/eva/cvp_core_hfi.h +++ b/msm/eva/cvp_core_hfi.h @@ -7,6 +7,7 @@ #define __H_CVP_CORE_HFI_H__ #include +#include #include #include #include diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 156dcc6611..4f71bfbf66 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -66,8 +66,10 @@ static void iris_hfi_pm_handler(struct work_struct *work); static DECLARE_DELAYED_WORK(iris_hfi_pm_work, iris_hfi_pm_handler); static inline int __resume(struct iris_hfi_device *device); static inline int __suspend(struct iris_hfi_device *device); -static int __disable_regulators(struct iris_hfi_device *device); -static int __enable_regulators(struct iris_hfi_device *device); +static int __disable_regulator(struct iris_hfi_device *device, + const char *name); +static int __enable_regulator(struct iris_hfi_device *device, + const char *name); static void __flush_debug_queue(struct iris_hfi_device *device, u8 *packet); static int __initialize_packetization(struct iris_hfi_device *device); static struct cvp_hal_session *__get_session(struct iris_hfi_device *device, @@ -96,6 +98,8 @@ static int __set_ubwc_config(struct iris_hfi_device *device); static void __noc_error_info_iris2(struct iris_hfi_device *device); static int __enable_hw_power_collapse(struct iris_hfi_device *device); +static int __power_off_controller(struct iris_hfi_device *device); + static struct iris_hfi_vpu_ops iris2_ops = { .interrupt_init = interrupt_init_iris2, .setup_dsp_uc_memmap = setup_dsp_uc_memmap_vpu5, @@ -669,6 +673,42 @@ static void __write_register(struct iris_hfi_device *device, wmb(); } +static int __read_gcc_register(struct iris_hfi_device *device, u32 reg) +{ + int rc = 0; + u8 *base_addr; + + if (!device) { + dprintk(CVP_ERR, "Invalid params: %pK\n", device); + return -EINVAL; + } + + __strict_check(device); + + if (!device->power_enabled) { + dprintk(CVP_WARN, + "%s HFI Read register failed : Power is OFF\n", + __func__); + msm_cvp_res_handle_fatal_hw_error(device->res, true); + return -EINVAL; + } + + base_addr = device->cvp_hal_data->gcc_reg_base; + + rc = readl_relaxed(base_addr + reg); + /* + * Memory barrier to make sure value is read correctly from the + * register. + */ + rmb(); + dprintk(CVP_REG, + "GCC Base addr: %pK, read from: %#x, value: %#x...\n", + base_addr, reg, rc); + + return rc; +} + + static int __read_register(struct iris_hfi_device *device, u32 reg) { int rc = 0; @@ -3285,7 +3325,7 @@ static void __deinit_resources(struct iris_hfi_device *device) device->sys_init_capabilities = NULL; } -static int __disable_regulator(struct regulator_info *rinfo, +static int __disable_regulator_impl(struct regulator_info *rinfo, struct iris_hfi_device *device) { int rc = 0; @@ -3345,48 +3385,54 @@ static int __enable_hw_power_collapse(struct iris_hfi_device *device) return rc; } -static int __enable_regulators(struct iris_hfi_device *device) +static int __enable_regulator(struct iris_hfi_device *device, + const char *name) { - int rc = 0, c = 0; + int rc = 0; struct regulator_info *rinfo; - dprintk(CVP_PWR, "Enabling regulators\n"); - iris_hfi_for_each_regulator(device, rinfo) { + if (strcmp(rinfo->name, name)) + continue; rc = regulator_enable(rinfo->regulator); if (rc) { dprintk(CVP_ERR, "Failed to enable %s: %d\n", rinfo->name, rc); - goto err_reg_enable_failed; + return rc; + } + + if (!regulator_is_enabled(rinfo->regulator)) { + dprintk(CVP_ERR,"%s: regulator %s not enabled\n", + __func__, rinfo->name); + regulator_disable(rinfo->regulator); + return -EINVAL; } dprintk(CVP_PWR, "Enabled regulator %s\n", rinfo->name); - c++; + return 0; } - return 0; - -err_reg_enable_failed: - iris_hfi_for_each_regulator_reverse_continue(device, rinfo, c) - __disable_regulator(rinfo, device); - - return rc; + dprintk(CVP_ERR, "regulator %s not found\n"); + return -EINVAL; } -static int __disable_regulators(struct iris_hfi_device *device) +static int __disable_regulator(struct iris_hfi_device *device, + const char *name) { struct regulator_info *rinfo; - dprintk(CVP_PWR, "Disabling regulators\n"); - iris_hfi_for_each_regulator_reverse(device, rinfo) { - __disable_regulator(rinfo, device); - if (rinfo->has_hw_power_collapse) - regulator_set_mode(rinfo->regulator, - REGULATOR_MODE_NORMAL); + + if (strcmp(rinfo->name, name)) + continue; + + __disable_regulator_impl(rinfo, device); + dprintk(CVP_PWR, "%s Disabled regulator %s\n", __func__, name); + return 0; } - return 0; + dprintk(CVP_ERR, "%s regulator %s not found\n", __func__, name); + return -EINVAL; } static int __enable_subcaches(struct iris_hfi_device *device) @@ -3612,6 +3658,65 @@ fail_to_set_ubwc_config: return rc; } +static int __power_on_controller(struct iris_hfi_device *device) +{ + int rc = 0; + + rc = __enable_regulator(device, "cvp"); + if (rc) { + dprintk(CVP_ERR, "Failed to enable ctrler: %d\n", rc); + return rc; + } + + rc = call_iris_op(device, reset_ahb2axi_bridge, device); + if (rc) { + dprintk(CVP_ERR, "Failed to reset ahb2axi: %d\n", rc); + goto fail_reset_clks; + } + + rc = msm_cvp_prepare_enable_clk(device, "gcc_video_axi1"); + if (rc) { + dprintk(CVP_ERR, "Failed to enable axi1 clk: %d\n", rc); + goto fail_reset_clks; + } + + rc = msm_cvp_prepare_enable_clk(device, "cvp_clk"); + if (rc) { + dprintk(CVP_ERR, "Failed to enable cvp_clk: %d\n", rc); + goto fail_enable_clk; + } + + dprintk(CVP_PWR, "EVA controller powered on\n"); + return 0; + +fail_enable_clk: + msm_cvp_disable_unprepare_clk(device, "gcc_video_axi1"); +fail_reset_clks: + __disable_regulator(device, "cvp"); + return rc; +} + +static int __power_on_core(struct iris_hfi_device *device) +{ + int rc = 0; + + rc = __enable_regulator(device, "cvp-core"); + if (rc) { + dprintk(CVP_ERR, "Failed to enable core: %d\n", rc); + return rc; + } + + rc = msm_cvp_prepare_enable_clk(device, "core_clk"); + if (rc) { + dprintk(CVP_ERR, "Failed to enable core_clk: %d\n", rc); + __disable_regulator(device, "cvp-core"); + return rc; + } + + dprintk(CVP_PWR, "EVA core powered on\n"); + return 0; +} + static int __iris_power_on(struct iris_hfi_device *device) { int rc = 0; @@ -3628,35 +3733,26 @@ static int __iris_power_on(struct iris_hfi_device *device) goto fail_vote_buses; } - rc = __enable_regulators(device); - if (rc) { - dprintk(CVP_ERR, "Failed to enable GDSC, err = %d\n", rc); - goto fail_enable_gdsc; - } + rc = __power_on_controller(device); + if (rc) + goto fail_enable_controller; - rc = call_iris_op(device, reset_ahb2axi_bridge, device); - if (rc) { - dprintk(CVP_ERR, "Failed to reset ahb2axi: %d\n", rc); - goto fail_enable_clks; - } - - rc = msm_cvp_prepare_enable_clks(device); - if (rc) { - dprintk(CVP_ERR, "Failed to enable clocks: %d\n", rc); - goto fail_enable_clks; - } + rc = __power_on_core(device); + if (rc) + goto fail_enable_core; rc = msm_cvp_scale_clocks(device); if (rc) { dprintk(CVP_WARN, "Failed to scale clocks, perf may regress\n"); rc = 0; + } else { + dprintk(CVP_PWR, "Done with scaling\n"); } /*Do not access registers before this point!*/ device->power_enabled = true; - dprintk(CVP_PWR, "Done with scaling\n"); /* * Re-program all of the registers that get reset as a result of * regulator_disable() and _enable() @@ -3669,35 +3765,18 @@ static int __iris_power_on(struct iris_hfi_device *device) device->intr_status = 0; enable_irq(device->cvp_hal_data->irq); - return rc; + pr_info(CVP_DBG_TAG "cvp (eva) powered on\n", "pwr"); + return 0; -fail_enable_clks: - __disable_regulators(device); -fail_enable_gdsc: +fail_enable_core: + __power_off_controller(device); +fail_enable_controller: __unvote_buses(device); fail_vote_buses: device->power_enabled = false; return rc; } -void power_off_common(struct iris_hfi_device *device) -{ - if (!device->power_enabled) - return; - - if (!(device->intr_status & CVP_WRAPPER_INTR_STATUS_A2HWD_BMSK)) - disable_irq_nosync(device->cvp_hal_data->irq); - device->intr_status = 0; - - msm_cvp_disable_unprepare_clks(device); - if (__disable_regulators(device)) - dprintk(CVP_WARN, "Failed to disable regulators\n"); - - if (__unvote_buses(device)) - dprintk(CVP_WARN, "Failed to unvote for buses\n"); - device->power_enabled = false; -} - static inline int __suspend(struct iris_hfi_device *device) { int rc = 0; @@ -3725,28 +3804,65 @@ static inline int __suspend(struct iris_hfi_device *device) __disable_subcaches(device); call_iris_op(device, power_off, device); - dprintk(CVP_PWR, "Iris power off\n"); return rc; err_tzbsp_suspend: return rc; } -static void power_off_iris2(struct iris_hfi_device *device) +static void __print_sidebandmanager_regs(struct iris_hfi_device *device) +{ + u32 sbm_ln0_low, axi_cbcr; + u32 main_sbm_ln0_low = 0xdeadbeef, main_sbm_ln0_high = 0xdeadbeef; + u32 main_sbm_ln1_high = 0xdeadbeef, cpu_cs_x2rpmh; + + sbm_ln0_low = + __read_register(device, CVP_NOC_SBM_SENSELN0_LOW); + + cpu_cs_x2rpmh = __read_register(device, CVP_CPU_CS_X2RPMh); + + __write_register(device, CVP_CPU_CS_X2RPMh, + (cpu_cs_x2rpmh | CVP_CPU_CS_X2RPMh_SWOVERRIDE_BMSK)); + usleep_range(500, 1000); + cpu_cs_x2rpmh = __read_register(device, CVP_CPU_CS_X2RPMh); + if (!(cpu_cs_x2rpmh & CVP_CPU_CS_X2RPMh_SWOVERRIDE_BMSK)) { + dprintk(CVP_WARN, + "failed set CVP_CPU_CS_X2RPMH mask %x\n", + cpu_cs_x2rpmh); + goto exit; + } + + axi_cbcr = __read_gcc_register(device, CVP_GCC_VIDEO_AXI1_CBCR); + if (axi_cbcr & 0x80000000) { + dprintk(CVP_WARN, "failed to turn on AXI clock %x\n", + axi_cbcr); + goto exit; + } + + main_sbm_ln0_low = __read_register(device, + CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_LOW); + main_sbm_ln0_high = __read_register(device, + CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_HIGH); + main_sbm_ln1_high = __read_register(device, + CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN1_HIGH); + +exit: + cpu_cs_x2rpmh = cpu_cs_x2rpmh & (~CVP_CPU_CS_X2RPMh_SWOVERRIDE_BMSK); + __write_register(device, CVP_CPU_CS_X2RPMh, cpu_cs_x2rpmh); + dprintk(CVP_WARN, "Sidebandmanager regs %x %x %x %x %x\n", + sbm_ln0_low, main_sbm_ln0_low, + main_sbm_ln0_high, main_sbm_ln1_high, + cpu_cs_x2rpmh); +} + +static int __power_off_controller(struct iris_hfi_device *device) { u32 lpi_status, reg_status = 0, count = 0, max_count = 1000; - if (!device->power_enabled || !device->res->sw_power_collapsible) - return; - - if (!(device->intr_status & CVP_WRAPPER_INTR_STATUS_A2HWD_BMSK)) - disable_irq_nosync(device->cvp_hal_data->irq); - device->intr_status = 0; - - /* HPG 6.1.2 Step 1 */ + /* HPG 6.2.2 Step 1 */ __write_register(device, CVP_CPU_CS_X2RPMh, 0x3); - /* HPG 6.1.2 Step 2, noc to low power */ + /* HPG 6.2.2 Step 2, noc to low power */ __write_register(device, CVP_AON_WRAPPER_MVP_NOC_LPI_CONTROL, 0x1); while (!reg_status && count < max_count) { lpi_status = @@ -3761,42 +3877,21 @@ static void power_off_iris2(struct iris_hfi_device *device) "Noc: lpi_status %x noc_status %x (count %d)\n", lpi_status, reg_status, count); if (count == max_count) { - u32 pc_ready, wfi_status, sbm_ln0_low; - u32 main_sbm_ln0_low, main_sbm_ln1_high; - u32 cpu_cs_x2rpmh; + u32 pc_ready, wfi_status; wfi_status = __read_register(device, CVP_WRAPPER_CPU_STATUS); pc_ready = __read_register(device, CVP_CTRL_STATUS); - sbm_ln0_low = - __read_register(device, CVP_NOC_SBM_SENSELN0_LOW); - - cpu_cs_x2rpmh = __read_register(device, - CVP_CPU_CS_X2RPMh); - - __write_register(device, CVP_CPU_CS_X2RPMh, - (cpu_cs_x2rpmh | CVP_CPU_CS_X2RPMh_SWOVERRIDE_BMSK)); - cpu_cs_x2rpmh = __read_register(device, - CVP_CPU_CS_X2RPMh); - dprintk(CVP_PWR, "cpu_cs_x2rpmh (%#x)\n", - cpu_cs_x2rpmh); - - main_sbm_ln0_low = __read_register(device, - CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_LOW); - main_sbm_ln1_high = __read_register(device, - CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN1_HIGH); - - __write_register(device, CVP_CPU_CS_X2RPMh, - (cpu_cs_x2rpmh & (~CVP_CPU_CS_X2RPMh_SWOVERRIDE_BMSK))); dprintk(CVP_WARN, - "NOC not in qaccept status %x %x %x %x %x\n", - reg_status, lpi_status, wfi_status, pc_ready, - sbm_ln0_low); + "NOC not in qaccept status %x %x %x %x\n", + reg_status, lpi_status, wfi_status, pc_ready); + + __print_sidebandmanager_regs(device); } - /* HPG 6.1.2 Step 3, debug bridge to low power BYPASSED */ + /* HPG 6.2.2 Step 3, debug bridge to low power BYPASSED */ - /* HPG 6.1.2 Step 4, debug bridge to lpi release */ + /* HPG 6.2.2 Step 4, debug bridge to lpi release */ __write_register(device, CVP_WRAPPER_DEBUG_BRIDGE_LPI_CONTROL, 0x0); lpi_status = 0x1; @@ -3815,22 +3910,141 @@ static void power_off_iris2(struct iris_hfi_device *device) "DBLP Release: lpi_status %x\n", lpi_status); } - /* HPG 6.1.2 Step 6 */ - msm_cvp_disable_unprepare_clks(device); + /* HPG 6.2.2 Step 5 */ + msm_cvp_disable_unprepare_clk(device, "cvp_clk"); + + /* HPG 6.2.2 Step 6 */ + __disable_regulator(device, "cvp"); + + /* HPG 6.2.2 Step 7 */ + msm_cvp_disable_unprepare_clk(device, "gcc_video_axi1"); + + return 0; +} + +static int __power_off_core(struct iris_hfi_device *device) +{ + u32 config, value = 0, count = 0, warn_flag = 0; + const u32 max_count = 10; + + value = __read_register(device, CVP_CC_MVS1_GDSCR); + if (!(value & 0x80000000)) { + /* + * Core has been powered off by f/w. + * Check NOC reset registers to ensure + * NO outstanding NoC transactions + */ + value = __read_register(device, CVP_NOC_RESET_ACK); + if (value) { + dprintk(CVP_WARN, + "Core off with NOC RESET ACK non-zero %x\n", + value); + __print_sidebandmanager_regs(device); + } + __disable_regulator(device, "cvp-core"); + msm_cvp_disable_unprepare_clk(device, "core_clk"); + return 0; + } + + dprintk(CVP_PWR, "Driver controls Core power off now\n"); + /* + * check to make sure core clock branch enabled else + * we cannot read core idle register + */ + config = __read_register(device, CVP_WRAPPER_CORE_CLOCK_CONFIG); + if (config) { + dprintk(CVP_PWR, + "core clock config not enabled, enable it to access core\n"); + __write_register(device, CVP_WRAPPER_CORE_CLOCK_CONFIG, 0); + } /* - * HPG 6.1.2 Step 7 & 8 - * per new HPG update, core clock reset will be unnecessary + * add MNoC idle check before collapsing MVS1 per HPG update + * poll for NoC DMA idle -> HPG 6.2.1 + * */ + do { + value = __read_register(device, CVP_SS_IDLE_STATUS); + if (value & 0x400000) + break; + else + usleep_range(1000, 2000); + count++; + } while (count < max_count); + + if (count == max_count) { + dprintk(CVP_WARN, "Core fail to go idle %x\n", value); + warn_flag = 1; + } + + /* Apply partial reset on MSF interface and wait for ACK */ + __write_register(device, CVP_NOC_RESET_REQ, 0x7); + count = 0; + do { + value = __read_register(device, CVP_NOC_RESET_ACK); + if ((value & 0x7) == 0x7) + break; + else + usleep_range(100, 200); + count++; + } while (count < max_count); + + if (count == max_count) { + dprintk(CVP_WARN, "Core NoC reset assert failed %x\n", value); + warn_flag = 1; + } + + /* De-assert partial reset on MSF interface and wait for ACK */ + __write_register(device, CVP_NOC_RESET_REQ, 0x0); + count = 0; + do { + value = __read_register(device, CVP_NOC_RESET_ACK); + if ((value & 0x1) == 0x0) + break; + else + usleep_range(100, 200); + count++; + } while (count < max_count); + + if (count == max_count) { + dprintk(CVP_WARN, "Core NoC reset de-assert failed\n"); + warn_flag = 1; + } + + if (warn_flag) + __print_sidebandmanager_regs(device); + + /* Reset both sides of 2 ahb2ahb_bridges (TZ and non-TZ) */ + __write_register(device, CVP_AHB_BRIDGE_SYNC_RESET, 0x3); + __write_register(device, CVP_AHB_BRIDGE_SYNC_RESET, 0x2); + __write_register(device, CVP_AHB_BRIDGE_SYNC_RESET, 0x0); + + __write_register(device, CVP_WRAPPER_CORE_CLOCK_CONFIG, config); + + __disable_regulator(device, "cvp-core"); + msm_cvp_disable_unprepare_clk(device, "core_clk"); + return 0; +} + +static void power_off_iris2(struct iris_hfi_device *device) +{ + if (!device->power_enabled || !device->res->sw_power_collapsible) + return; + + if (!(device->intr_status & CVP_WRAPPER_INTR_STATUS_A2HWD_BMSK)) + disable_irq_nosync(device->cvp_hal_data->irq); + device->intr_status = 0; + + __power_off_core(device); + + __power_off_controller(device); + if (__unvote_buses(device)) dprintk(CVP_WARN, "Failed to unvote for buses\n"); - /* HPG 6.1.2 Step 5 */ - if (__disable_regulators(device)) - dprintk(CVP_WARN, "Failed to disable regulators\n"); - /*Do not access registers after this point!*/ device->power_enabled = false; + pr_info(CVP_DBG_TAG "cvp (eva) power collapsed\n", "pwr"); } static inline int __resume(struct iris_hfi_device *device) diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index 4d17a72a48..602742d704 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -8,6 +8,9 @@ #include +#define CVP_TOP_BASE_OFFS 0x00000000 +#define CVP_SS_IDLE_STATUS (CVP_TOP_BASE_OFFS + 0x50) + #define CVP_CPU_BASE_OFFS 0x000A0000 #define CVP_AON_BASE_OFFS 0x000E0000 @@ -61,6 +64,8 @@ #define CVP_CPU_CS_H2ASOFTINT (CVP_CPU_BASE_OFFS + 0x150) #define CVP_CPU_CS_H2ASOFTINTCLR (CVP_CPU_BASE_OFFS + 0x154) +#define CVP_AHB_BRIDGE_SYNC_RESET (CVP_CPU_BASE_OFFS + 0x160) + /* FAL10 Feature Control */ #define CVP_CPU_CS_X2RPMh (CVP_CPU_BASE_OFFS + 0x168) #define CVP_CPU_CS_X2RPMh_MASK0_BMSK 0x1 @@ -183,6 +188,8 @@ #define CVP_NOC_CORE_BASE_OFFS 0x00010000 #define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_LOW \ (CVP_NOC_CORE_BASE_OFFS + 0x7100) +#define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_HIGH \ + (CVP_NOC_CORE_BASE_OFFS + 0x7104) #define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN1_HIGH \ (CVP_NOC_CORE_BASE_OFFS + 0x710C) #define CVP_NOC_CORE_ERR_SWID_LOW_OFFS \ @@ -211,6 +218,10 @@ (CVP_NOC_CORE_BASE_OFFS + 0x1238) #define CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS \ (CVP_NOC_CORE_BASE_OFFS + 0x123C) +#define CVP_NOC_RESET_REQ \ + (CVP_NOC_CORE_BASE_OFFS + 0xf000) +#define CVP_NOC_RESET_ACK \ + (CVP_NOC_CORE_BASE_OFFS + 0xf004) #define CVP_AON_WRAPPER_MVP_NOC_LPI_CONTROL (CVP_AON_BASE_OFFS) diff --git a/msm/eva/msm_cvp_clocks.c b/msm/eva/msm_cvp_clocks.c index 728a3c6b76..1b3c889e63 100644 --- a/msm/eva/msm_cvp_clocks.c +++ b/msm/eva/msm_cvp_clocks.c @@ -175,10 +175,11 @@ int msm_cvp_scale_clocks(struct iris_hfi_device *device) return rc; } -int msm_cvp_prepare_enable_clks(struct iris_hfi_device *device) +int msm_cvp_prepare_enable_clk(struct iris_hfi_device *device, + const char *name) { - struct clock_info *cl = NULL, *cl_fail = NULL; - int rc = 0, c = 0; + struct clock_info *cl = NULL; + int rc = 0; if (!device) { dprintk(CVP_ERR, "Invalid params: %pK\n", device); @@ -186,6 +187,8 @@ int msm_cvp_prepare_enable_clks(struct iris_hfi_device *device) } iris_hfi_for_each_clock(device, cl) { + if (strcmp(cl->name, name)) + continue; /* * For the clocks we control, set the rate prior to preparing * them. Since we don't really have a load at this point, @@ -211,42 +214,47 @@ int msm_cvp_prepare_enable_clks(struct iris_hfi_device *device) } rc = clk_prepare_enable(cl->clk); if (rc) { - dprintk(CVP_ERR, "Failed to enable clocks\n"); - cl_fail = cl; - goto fail_clk_enable; + dprintk(CVP_ERR, "Failed to enable clock %s\n", + cl->name); + return rc; + } + if (!__clk_is_enabled(cl->clk)) { + dprintk(CVP_ERR, "%s: clock %s not enabled\n", + __func__, cl->name); + clk_disable_unprepare(cl->clk); + return -EINVAL; } - c++; dprintk(CVP_PWR, "Clock: %s prepared and enabled\n", cl->name); + return 0; } - return rc; - -fail_clk_enable: - iris_hfi_for_each_clock_reverse_continue(device, cl, c) { - dprintk(CVP_ERR, "Clock: %s disable and unprepare\n", - cl->name); - clk_disable_unprepare(cl->clk); - } - - return rc; + dprintk(CVP_ERR, "%s clock %s not found\n", __func__, name); + return -EINVAL; } -void msm_cvp_disable_unprepare_clks(struct iris_hfi_device *device) +int msm_cvp_disable_unprepare_clk(struct iris_hfi_device *device, + const char *name) { struct clock_info *cl; if (!device) { dprintk(CVP_ERR, "Invalid params: %pK\n", device); - return; + return -EINVAL; } iris_hfi_for_each_clock_reverse(device, cl) { + if (strcmp(cl->name, name)) + continue; + clk_disable_unprepare(cl->clk); dprintk(CVP_PWR, "Clock: %s disable and unprepare\n", cl->name); - clk_disable_unprepare(cl->clk); + return 0; } + + dprintk(CVP_ERR, "%s clock %s not found\n", __func__, name); + return -EINVAL; } int msm_cvp_init_clocks(struct iris_hfi_device *device) diff --git a/msm/eva/msm_cvp_clocks.h b/msm/eva/msm_cvp_clocks.h index 0660da328b..8b402d11d7 100644 --- a/msm/eva/msm_cvp_clocks.h +++ b/msm/eva/msm_cvp_clocks.h @@ -11,14 +11,14 @@ int msm_cvp_set_clocks(struct msm_cvp_core *core); int msm_cvp_mmrm_register(struct iris_hfi_device *device); -int msm_cvp_mmrm_set_value_in_range(struct iris_hfi_device *device, u32 freq_min, u32 freq_cur); +int msm_cvp_mmrm_set_value_in_range(struct iris_hfi_device *device, + u32 freq_min, u32 freq_cur); int msm_cvp_set_clocks_impl(struct iris_hfi_device *device, u32 freq); int msm_cvp_scale_clocks(struct iris_hfi_device *device); -//below APIs previously declared as inline -//static inline int __prepare_enable_clks(struct iris_hfi_device *device); -int msm_cvp_prepare_enable_clks(struct iris_hfi_device *device); -//static inline void __disable_unprepare_clks(struct iris_hfi_device *device); -void msm_cvp_disable_unprepare_clks(struct iris_hfi_device *device); +int msm_cvp_prepare_enable_clk(struct iris_hfi_device *device, + const char *name); +int msm_cvp_disable_unprepare_clk(struct iris_hfi_device *device, + const char *name); int msm_cvp_init_clocks(struct iris_hfi_device *device); void msm_cvp_deinit_clocks(struct iris_hfi_device *device); #endif From 966d521450326313a5d464579fbe2724247eed74 Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 9 Jul 2021 14:26:17 -0700 Subject: [PATCH 065/317] msm: eva: Remove warning during buf unmapping Persistent buffer unmap is different than frame buffer. It's expected to be released at the end of session instead of at frame boundary. Remove the warning of "unexpected unmapping". Change-Id: I24bfae0b67b1a8989e6a710556d94c8bc4e90aff Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 3 ++- msm/eva/msm_cvp_buf.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 2efc6c4d33..62ebeb2a77 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -484,6 +484,7 @@ static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, if (!smem) goto exit; + smem->flags |= SMEM_PERSIST; pbuf->smem = smem; pbuf->fd = buf->fd; pbuf->size = buf->size; @@ -819,7 +820,7 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) smem = inst->dma_cache.entries[i]; if (atomic_read(&smem->refcount) == 0) { print_smem(CVP_MEM, "free", inst, smem); - } else { + } else if (!(smem->flags & SMEM_PERSIST)) { print_smem(CVP_WARN, "in use", inst, smem); } msm_cvp_unmap_smem(inst, smem, "unmap cpu"); diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index b6d6f15732..bb575c8588 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -35,7 +35,8 @@ enum smem_prop { SMEM_ADSP = 0x8, SMEM_NON_PIXEL = 0x10, SMEM_PIXEL = 0x20, - SMEM_CAMERA = 0x40 + SMEM_CAMERA = 0x40, + SMEM_PERSIST = 0x100, }; struct msm_cvp_list { From 01496a76354b710ede9a5558ee290101017e00d9 Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 13 Jul 2021 15:03:49 -0700 Subject: [PATCH 066/317] msm: eva: Avoid racing in power update Lock clk_lock mutex before changing CVP instance list. Change-Id: Ie2c88f2eaa082a3661ab776093f5ded0fa261985 Signed-off-by: George Shen --- msm/eva/msm_cvp_core.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 63cb89922f..04bfd92627 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -202,7 +202,9 @@ void *msm_cvp_open(int core_id, int session_type) msm_cvp_session_init(inst); mutex_lock(&core->lock); + mutex_lock(&core->clk_lock); list_add_tail(&inst->list, &core->instances); + mutex_unlock(&core->clk_lock); mutex_unlock(&core->lock); __init_fence_queue(inst); @@ -321,9 +323,12 @@ int msm_cvp_destroy(struct msm_cvp_inst *inst) core = inst->core; + /* Ensure no path has core->clk_lock and core->lock sequence */ mutex_lock(&core->lock); + mutex_lock(&core->clk_lock); /* inst->list lives in core->instances */ list_del(&inst->list); + mutex_unlock(&core->clk_lock); mutex_unlock(&core->lock); DEINIT_MSM_CVP_LIST(&inst->persistbufs); From b632dc32be5fac4a3199ceeb552c71157f133819 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Tue, 1 Jun 2021 18:19:18 -0700 Subject: [PATCH 067/317] msm: eva: mmrm adding notifier callback added call back function for notifier when throttling case happen. Change-Id: If8fc1c12ea087b7478e47f905184c0413764a0a7 Signed-off-by: Yu SI --- msm/eva/msm_cvp_clocks.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_clocks.c b/msm/eva/msm_cvp_clocks.c index 1b3c889e63..35b120d7ff 100644 --- a/msm/eva/msm_cvp_clocks.c +++ b/msm/eva/msm_cvp_clocks.c @@ -8,6 +8,34 @@ #include "msm_cvp_debug.h" #include "msm_cvp_clocks.h" +int msm_cvp_mmrm_notifier_cb( + struct mmrm_client_notifier_data *notifier_data) +{ + if (!notifier_data) { + dprintk(CVP_WARN, "%s Invalid notifier data: %pK\n", + __func__, notifier_data); + return -EINVAL; + } + + if (notifier_data->cb_type == MMRM_CLIENT_RESOURCE_VALUE_CHANGE) { + struct iris_hfi_device *dev = notifier_data->pvt_data; + + dprintk(CVP_PWR, + "%s: Clock %s throttled from %ld to %ld \n", + __func__, dev->mmrm_desc.client_info.desc.name, + notifier_data->cb_data.val_chng.old_val, + notifier_data->cb_data.val_chng.new_val); + + /*TODO: if need further handling to notify eva client */ + } else { + dprintk(CVP_WARN, "%s Invalid cb type: %d\n", + __func__, notifier_data->cb_type); + return -EINVAL; + } + + return 0; +} + int msm_cvp_set_clocks(struct msm_cvp_core *core) { struct cvp_hfi_device *hdev; @@ -28,16 +56,19 @@ int msm_cvp_mmrm_register(struct iris_hfi_device *device) { int rc = 0; struct clock_info *cl = NULL; - char *name = (char *)device->mmrm_desc.client_info.desc.name; + char *name; if (!device) { dprintk(CVP_ERR, "%s invalid device\n", __func__); return -EINVAL; } + name = (char *)device->mmrm_desc.client_info.desc.name; device->mmrm_cvp=NULL; device->mmrm_desc.client_type=MMRM_CLIENT_CLOCK; device->mmrm_desc.priority=MMRM_CLIENT_PRIOR_LOW; + device->mmrm_desc.pvt_data = device; + device->mmrm_desc.notifier_callback_fn = msm_cvp_mmrm_notifier_cb; device->mmrm_desc.client_info.desc.client_domain=MMRM_CLIENT_DOMAIN_CVP; iris_hfi_for_each_clock(device, cl) { From a031b0d054fb3f531bf5127d1444da0919b1f992 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Tue, 27 Jul 2021 16:07:01 -0700 Subject: [PATCH 068/317] msm: eva: add QMAA compliance to eva kernel dlkm added check on QMAA related flags to decide if compile eva kernel ko. Change-Id: Iae09c460d75be90afb82b4178555497ebae9e573 Signed-off-by: Yu SI --- eva_kernel_board.mk | 10 ++++++++++ eva_kernel_product.mk | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/eva_kernel_board.mk b/eva_kernel_board.mk index d23cf37402..86dcf02f47 100644 --- a/eva_kernel_board.mk +++ b/eva_kernel_board.mk @@ -1,6 +1,16 @@ # Build eva kernel driver + +ENABLE_EVA_KERNEL := true +ifeq ($(TARGET_USES_QMAA), true) +ifneq ($(TARGET_USES_QMAA_OVERRIDE_CVP), true) +ENABLE_EVA_KERNEL := false +endif +endif + +ifeq ($(ENABLE_EVA_KERNEL), true) ifneq ($(TARGET_BOARD_AUTO),true) ifeq ($(call is-board-platform-in-list,$(TARGET_BOARD_PLATFORM)),true) BOARD_VENDOR_KERNEL_MODULES += $(KERNEL_MODULES_OUT)/msm-eva.ko endif +endif endif \ No newline at end of file diff --git a/eva_kernel_product.mk b/eva_kernel_product.mk index da7ee60cb0..61b6e04681 100644 --- a/eva_kernel_product.mk +++ b/eva_kernel_product.mk @@ -1 +1,10 @@ +ENABLE_EVA_KERNEL := true +ifeq ($(TARGET_USES_QMAA), true) +ifneq ($(TARGET_USES_QMAA_OVERRIDE_CVP), true) +ENABLE_EVA_KERNEL := false +endif +endif + +ifeq ($(ENABLE_EVA_KERNEL), true) PRODUCT_PACKAGES += msm-eva.ko +endif From d6bee86fa3ce60abe7c65cb3a06537797e815b70 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 28 Jul 2021 14:42:16 -0700 Subject: [PATCH 069/317] msm: eva: Avoid nested mutext lock in dsp Unlock dsp mutex early, right after critical section ends. In this way, HFI queue send will lock mutex without nested locking concern. Change-Id: I1af64565440585e3fffe041d39d2e4a03f846c1a Signed-off-by: George Shen --- msm/eva/msm_cvp_dsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 00f6853b69..c9b6ff994c 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -170,8 +170,8 @@ static int cvp_dsp_rpmsg_probe(struct rpmsg_device *rpdev) mutex_lock(&me->tx_lock); me->chan = rpdev; me->state = DSP_PROBED; - complete(&me->completions[CPU2DSP_MAX_CMD]); mutex_unlock(&me->tx_lock); + complete(&me->completions[CPU2DSP_MAX_CMD]); return ret; } From 30223d90a7b6609a8f2e06304294f7b0ddf788e3 Mon Sep 17 00:00:00 2001 From: Chris Goldsworthy Date: Fri, 30 Jul 2021 10:13:52 -0700 Subject: [PATCH 070/317] msm: eva: Fix DMA-BUF double free msm_cvp_smem_put_dma_buf() releases the EVA driver's reference it uses for DMA mappings, by decrementing the refcount of the underlying struct file that all DMA-BUFs use for life cycle tracking. By accident, the EVA driver held a direct reference to the underlying file using the struct msm_cvp_smem->file variable. The EVA driver, after releasing it's reference to the DMA-BUF, inadvertently called fput() on the struct_cvp_smem->file variable, which leads to a double free. Resolve this by removing the struct msm_cvp_smmem->file variable, and by removing the corresponding fput(). Change-Id: I108cd87509673008ff55fc94fda76aa21f21bd5d Signed-off-by: Chris Goldsworthy --- msm/eva/msm_cvp_buf.c | 2 -- msm/eva/msm_cvp_buf.h | 1 - 2 files changed, 3 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 62ebeb2a77..ff522503e4 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -214,7 +214,6 @@ int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) } smem->dma_buf = dma_buf; - smem->file = file; smem->bitmap_index = MAX_DMABUF_NUMS; dprintk(CVP_MEM, "%s: dma_buf = %llx\n", __func__, dma_buf); rc = msm_cvp_map_smem(inst, smem, "map dsp"); @@ -287,7 +286,6 @@ int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) if (cbuf->smem->device_addr) { msm_cvp_unmap_smem(inst, cbuf->smem, "unmap dsp"); msm_cvp_smem_put_dma_buf(cbuf->smem->dma_buf); - fput(cbuf->smem->file); } mutex_lock(&inst->cvpdspbufs.lock); diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index bb575c8588..29c6963476 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -68,7 +68,6 @@ struct msm_cvp_smem { struct list_head list; atomic_t refcount; struct dma_buf *dma_buf; - struct file *file; void *kvaddr; u32 device_addr; dma_addr_t dma_handle; From 72eb20af3d92c89eaa7f23c0dc25b43ad5ef47a4 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 21 Jul 2021 17:30:08 -0700 Subject: [PATCH 071/317] msm: eva: Add SSR counter Support configurable number of SSR tolerance before calling BUG_ON in SMMU fault scenario. Change-Id: I19dabbeaa1cf5be86f42a6ace62ef5da12743e79 Signed-off-by: George Shen --- msm/eva/cvp.c | 1 + msm/eva/cvp_hfi.c | 106 +++++++++++++++++++++++++----------- msm/eva/msm_cvp_buf.c | 63 +++++++++++++++++++-- msm/eva/msm_cvp_buf.h | 2 +- msm/eva/msm_cvp_common.c | 15 +++-- msm/eva/msm_cvp_debug.c | 35 +++++++++++- msm/eva/msm_cvp_internal.h | 66 +++++++++++++++++++++- msm/eva/msm_cvp_platform.c | 9 +-- msm/eva/msm_cvp_res_parse.c | 23 +++----- msm/eva/msm_cvp_resources.h | 2 +- 10 files changed, 256 insertions(+), 66 deletions(-) diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index 6f3c69215f..ea1a965ada 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -148,6 +148,7 @@ static int msm_cvp_initialize_core(struct platform_device *pdev, INIT_DELAYED_WORK(&core->fw_unload_work, msm_cvp_fw_unload_handler); INIT_WORK(&core->ssr_work, msm_cvp_ssr_handler); init_cycle_info(&core->dyn_clk); + core->ssr_count = 0; return rc; } diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 4f71bfbf66..2272f47526 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1889,7 +1889,7 @@ static int iris_hfi_core_release(void *dev) __func__, rc); } else { dprintk(CVP_PWR, - "%s: Succeed mmrm_client_deregister for mmrm_cvp:%p, type:%d, uid:%ld\n", + "%s: Succeed mmrm_client_deregister for mmrm_cvp:%pK, type:%d, uid:%ld\n", __func__, device->mmrm_cvp, device->mmrm_cvp->client_type, device->mmrm_cvp->client_uid); device->mmrm_cvp = NULL; @@ -2736,7 +2736,7 @@ static int __response_handler(struct iris_hfi_device *device) if (!raw_packet || !packets) { dprintk(CVP_ERR, - "%s: Invalid args : Res packet = %p, Raw packet = %p\n", + "%s: Invalid args : Res pkt = %pK, Raw pkt = %pK\n", __func__, packets, raw_packet); return 0; } @@ -4226,9 +4226,6 @@ static int iris_hfi_get_core_capabilities(void *dev) return 0; } -static u32 cvp_arp_test_regs[16]; -static u32 cvp_dma_test_regs[512]; - static const char * const mid_names[16] = { "CVP_FW", "ARP_DATA", @@ -4258,63 +4255,108 @@ static void __print_reg_details(u32 val) dprintk(CVP_ERR, "Sub-client:%s, SID: %d\n", mid_names[mid], sid); } +static void __err_log(bool logging, u32 *data, const char *name, u32 val) +{ + if (logging) + *data = val; + + dprintk(CVP_ERR, "%s: %#x\n", name, val); +} + static void __noc_error_info_iris2(struct iris_hfi_device *device) { + struct msm_cvp_core *core; + struct cvp_noc_log *noc_log; u32 val = 0, regi, i; + bool log_required = false; + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + + if (!core->ssr_count && core->resources.max_ssr_allowed > 1) + log_required = true; + + noc_log = &core->log.noc_log; val = __read_register(device, CVP_NOC_ERR_SWID_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_SWID_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_swid_low, + "CVP_NOC_ERL_MAIN_SWID_LOW", val); val = __read_register(device, CVP_NOC_ERR_SWID_HIGH_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_SWID_HIGH: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_swid_high, + "CVP_NOC_ERL_MAIN_SWID_HIGH", val); val = __read_register(device, CVP_NOC_ERR_MAINCTL_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_MAINCTL_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_mainctl_low, + "CVP_NOC_ERL_MAIN_MAINCTL_LOW", val); val = __read_register(device, CVP_NOC_ERR_ERRVLD_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRVLD_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_errvld_low, + "CVP_NOC_ERL_MAIN_ERRVLD_LOW", val); val = __read_register(device, CVP_NOC_ERR_ERRCLR_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRCLR_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_errclr_low, + "CVP_NOC_ERL_MAIN_ERRCLR_LOW", val); val = __read_register(device, CVP_NOC_ERR_ERRLOG0_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG0_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_errlog0_low, + "CVP_NOC_ERL_MAIN_ERRLOG0_LOW", val); val = __read_register(device, CVP_NOC_ERR_ERRLOG0_HIGH_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG0_HIGH: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_errlog0_high, + "CVP_NOC_ERL_MAIN_ERRLOG0_HIGH", val); val = __read_register(device, CVP_NOC_ERR_ERRLOG1_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG1_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_errlog1_low, + "CVP_NOC_ERL_MAIN_ERRLOG1_LOW", val); val = __read_register(device, CVP_NOC_ERR_ERRLOG1_HIGH_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG1_HIGH: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_errlog1_high, + "CVP_NOC_ERL_MAIN_ERRLOG1_HIGH", val); val = __read_register(device, CVP_NOC_ERR_ERRLOG2_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG2_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_errlog2_low, + "CVP_NOC_ERL_MAIN_ERRLOG2_LOW", val); val = __read_register(device, CVP_NOC_ERR_ERRLOG2_HIGH_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG2_HIGH: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_errlog2_high, + "CVP_NOC_ERL_MAIN_ERRLOG2_HIGH", val); val = __read_register(device, CVP_NOC_ERR_ERRLOG3_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG3_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_errlog3_low, + "CVP_NOC_ERL_MAIN_ERRLOG3_LOW", val); val = __read_register(device, CVP_NOC_ERR_ERRLOG3_HIGH_OFFS); - dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG3_HIGH: %#x\n", val); + __err_log(log_required, &noc_log->err_ctrl_errlog3_high, + "CVP_NOC_ERL_MAIN_ERRLOG3_HIGH", val); val = __read_register(device, CVP_NOC_CORE_ERR_SWID_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC__CORE_ERL_MAIN_SWID_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_core_swid_low, + "CVP_NOC__CORE_ERL_MAIN_SWID_LOW", val); val = __read_register(device, CVP_NOC_CORE_ERR_SWID_HIGH_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_SWID_HIGH: %#x\n", val); + __err_log(log_required, &noc_log->err_core_swid_high, + "CVP_NOC_CORE_ERL_MAIN_SWID_HIGH", val); val = __read_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_MAINCTL_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_core_mainctl_low, + "CVP_NOC_CORE_ERL_MAIN_MAINCTL_LOW", val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRVLD_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_core_errvld_low, + "CVP_NOC_CORE_ERL_MAIN_ERRVLD_LOW", val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRCLR_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_core_errclr_low, + "CVP_NOC_CORE_ERL_MAIN_ERRCLR_LOW", val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_core_errlog0_low, + "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_LOW", val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_HIGH: %#x\n", val); + __err_log(log_required, &noc_log->err_core_errlog0_high, + "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_HIGH", val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_core_errlog1_low, + "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_LOW", val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_HIGH: %#x\n", val); + __err_log(log_required, &noc_log->err_core_errlog1_high, + "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_HIGH", val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_LOW: %#x\n", val); + __err_log(log_required, &noc_log->err_core_errlog2_low, + "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_LOW", val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_HIGH: %#x\n", val); + __err_log(log_required, &noc_log->err_core_errlog2_high, + "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_HIGH", val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS); + __err_log(log_required, &noc_log->err_core_errlog3_low, + "CORE ERRLOG3_LOW, below details", val); __print_reg_details(val); val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS); - dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG3_HIGH: %#x\n", val); + __err_log(log_required, &noc_log->err_core_errlog3_high, + "CVP_NOC_CORE_ERL_MAIN_ERRLOG3_HIGH", val); #define CVP_SS_CLK_HALT 0x8 #define CVP_SS_CLK_EN 0xC #define CVP_SS_ARP_TEST_BUS_CONTROL 0x700 @@ -4330,7 +4372,7 @@ static void __noc_error_info_iris2(struct iris_hfi_device *device) regi = 0xC0000000 + i; __write_register(device, CVP_SS_ARP_TEST_BUS_CONTROL, regi); val = __read_register(device, CVP_SS_ARP_TEST_BUS_REGISTER); - cvp_arp_test_regs[i] = val; + noc_log->arp_test_bus[i] = val; dprintk(CVP_ERR, "ARP_CTL:%x - %x\n", regi, val); } @@ -4338,7 +4380,7 @@ static void __noc_error_info_iris2(struct iris_hfi_device *device) regi = 0x40000000 + i; __write_register(device, CVP_DMA_TEST_BUS_CONTROL, regi); val = __read_register(device, CVP_DMA_TEST_BUS_REGISTER); - cvp_dma_test_regs[i] = val; + noc_log->dma_test_bus[i] = val; dprintk(CVP_ERR, "DMA_CTL:%x - %x\n", regi, val); } } diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index ff522503e4..eed7670272 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -74,6 +74,51 @@ void print_cvp_buffer(u32 tag, const char *str, struct msm_cvp_inst *inst, cbuf->smem->device_addr, cbuf->size); } +static void _log_smem(struct inst_snapshot *snapshot, struct msm_cvp_inst *inst, + struct msm_cvp_smem *smem, bool logging) +{ + print_smem(CVP_ERR, "bufdump", inst, smem); + if (!logging || !snapshot) + return; + if (snapshot && snapshot->smem_index < MAX_ENTRIES) { + struct smem_data *s; + s = &snapshot->smem_log[snapshot->smem_index]; + snapshot->smem_index++; + s->size = smem->size; + s->flags = smem->flags; + s->device_addr = smem->device_addr; + s->bitmap_index = smem->bitmap_index; + s->refcount = atomic_read(&smem->refcount); + } +} + +static void _log_buf(struct inst_snapshot *snapshot, enum smem_prop prop, + struct msm_cvp_inst *inst, struct cvp_internal_buf *cbuf, + bool logging) +{ + struct cvp_buf_data *buf = NULL; + u32 index; + print_cvp_buffer(CVP_ERR, "bufdump", inst, cbuf); + if (!logging) + return; + if (snapshot) { + if (prop == SMEM_ADSP && snapshot->dsp_index < MAX_ENTRIES) { + index = snapshot->dsp_index; + buf = &snapshot->dsp_buf_log[index]; + snapshot->dsp_index++; + } else if (prop == SMEM_PERSIST && + snapshot->persist_index < MAX_ENTRIES) { + index = snapshot->persist_index; + buf = &snapshot->persist_buf_log[index]; + snapshot->persist_index++; + } + if (buf) { + buf->device_addr = cbuf->smem->device_addr; + buf->size = cbuf->size; + } + } +} + void print_client_buffer(u32 tag, const char *str, struct msm_cvp_inst *inst, struct eva_kmd_buffer *cbuf) { @@ -863,11 +908,20 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) return rc; } -void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst) +void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) { struct cvp_internal_buf *buf; + struct msm_cvp_core *core; + struct inst_snapshot *snap = NULL; int i; + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (log && core->log.snapshot_index < 16) { + snap = &core->log.snapshot[core->log.snapshot_index]; + snap->session = inst->session; + core->log.snapshot_index++; + } + if (!inst) { dprintk(CVP_ERR, "%s - invalid param %pK\n", __func__, inst); @@ -882,20 +936,19 @@ void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst) dprintk(CVP_ERR, "dma cache:\n"); if (inst->dma_cache.nr <= MAX_DMABUF_NUMS) for (i = 0; i < inst->dma_cache.nr; i++) - print_smem(CVP_ERR, "bufdump", inst, - inst->dma_cache.entries[i]); + _log_smem(snap, inst, inst->dma_cache.entries[i], log); mutex_unlock(&inst->dma_cache.lock); mutex_lock(&inst->cvpdspbufs.lock); dprintk(CVP_ERR, "dsp buffer list:\n"); list_for_each_entry(buf, &inst->cvpdspbufs.list, list) - print_cvp_buffer(CVP_ERR, "bufdump", inst, buf); + _log_buf(snap, SMEM_ADSP, inst, buf, log); mutex_unlock(&inst->cvpdspbufs.lock); mutex_lock(&inst->persistbufs.lock); dprintk(CVP_ERR, "persist buffer list:\n"); list_for_each_entry(buf, &inst->persistbufs.list, list) - print_cvp_buffer(CVP_ERR, "bufdump", inst, buf); + _log_buf(snap, SMEM_PERSIST, inst, buf, log); mutex_unlock(&inst->persistbufs.lock); } diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index 29c6963476..1eaef46154 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -209,7 +209,7 @@ int msm_cvp_register_buffer(struct msm_cvp_inst *inst, int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf); int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst); -void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst); +void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log); int cvp_allocate_dsp_bufs(struct msm_cvp_inst *inst, struct cvp_internal_buf *buf, u32 buffer_size, diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index f5537b1124..e3f5abb854 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -670,7 +670,7 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) } if (!core->trigger_ssr) - msm_cvp_print_inst_bufs(inst); + msm_cvp_print_inst_bufs(inst, false); } /* handle the hw error before core released to get full debug info */ @@ -1036,7 +1036,6 @@ static int msm_comm_init_core(struct msm_cvp_inst *inst) goto fail_core_init; } core->state = CVP_CORE_INIT; - core->smmu_fault_handled = false; core->trigger_ssr = false; core_already_inited: @@ -1304,6 +1303,7 @@ int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state) int msm_cvp_noc_error_info(struct msm_cvp_core *core) { struct cvp_hfi_device *hdev; + static u32 last_fault_count = 0; if (!core || !core->device) { dprintk(CVP_WARN, "%s: Invalid parameters: %pK\n", @@ -1311,13 +1311,20 @@ int msm_cvp_noc_error_info(struct msm_cvp_core *core) return -EINVAL; } - if (!core->smmu_fault_handled) + if (!core->smmu_fault_count || + core->smmu_fault_count == last_fault_count) return 0; + last_fault_count = core->smmu_fault_count; + core->ssr_count++; + dprintk(CVP_ERR, "cvp ssr count %d %d\n", core->ssr_count, + core->resources.max_ssr_allowed); hdev = core->device; call_hfi_op(hdev, noc_error_info, hdev->hfi_device_data); - BUG_ON(!core->resources.non_fatal_pagefaults); + if (core->ssr_count >= core->resources.max_ssr_allowed) + BUG_ON(!core->resources.non_fatal_pagefaults); + return 0; } diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index fb0f23d4af..099f9b0f40 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -358,6 +358,33 @@ static int _dsp_dbg_get(void *data, u64 *val) DEFINE_DEBUGFS_ATTRIBUTE(dsp_debug_fops, _dsp_dbg_get, _dsp_dbg_set, "%llu\n"); +static int _max_ssr_set(void *data, u64 val) +{ + struct msm_cvp_core *core; + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (core) { + if (val < 1) { + dprintk(CVP_WARN, + "Invalid max_ssr_allowed value %llx\n", val); + return 0; + } + + core->resources.max_ssr_allowed = (unsigned int)val; + } + return 0; +} + +static int _max_ssr_get(void *data, u64 *val) +{ + struct msm_cvp_core *core; + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (core) + *val = core->resources.max_ssr_allowed; + + return 0; +} + +DEFINE_DEBUGFS_ATTRIBUTE(max_ssr_fops, _max_ssr_get, _max_ssr_set, "%llu\n"); struct dentry *msm_cvp_debugfs_init_core(struct msm_cvp_core *core, struct dentry *parent) @@ -397,6 +424,12 @@ struct dentry *msm_cvp_debugfs_init_core(struct msm_cvp_core *core, goto failed_create_dir; } + if (!debugfs_create_file("max_ssr_allowed", 0644, dir, + NULL, &max_ssr_fops)) { + dprintk(CVP_ERR, "debugfs_create: max_ssr_allowed fail\n"); + goto failed_create_dir; + } + failed_create_dir: return dir; } @@ -512,7 +545,7 @@ struct dentry *msm_cvp_debugfs_init_inst(struct msm_cvp_inst *inst, dprintk(CVP_ERR, "Invalid params, inst: %pK\n", inst); goto exit; } - snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%p", inst); + snprintf(debugfs_name, MAX_DEBUGFS_NAME, "inst_%pK", inst); idata = kzalloc(sizeof(*idata), GFP_KERNEL); if (!idata) { diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index e79a0d7965..a86c7e9cc6 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -270,6 +270,68 @@ struct cvp_session_event { wait_queue_head_t wq; }; +#define MAX_ENTRIES 64 + +struct smem_data { + u32 size; + u32 flags; + u32 device_addr; + u32 bitmap_index; + u32 refcount; +}; + +struct cvp_buf_data { + u32 device_addr; + u32 size; +}; + +struct inst_snapshot { + void *session; + u32 smem_index; + u32 dsp_index; + u32 persist_index; + struct smem_data smem_log[MAX_ENTRIES]; + struct cvp_buf_data dsp_buf_log[MAX_ENTRIES]; + struct cvp_buf_data persist_buf_log[MAX_ENTRIES]; +}; + +struct cvp_noc_log { + u32 err_ctrl_swid_low; + u32 err_ctrl_swid_high; + u32 err_ctrl_mainctl_low; + u32 err_ctrl_errvld_low; + u32 err_ctrl_errclr_low; + u32 err_ctrl_errlog0_low; + u32 err_ctrl_errlog0_high; + u32 err_ctrl_errlog1_low; + u32 err_ctrl_errlog1_high; + u32 err_ctrl_errlog2_low; + u32 err_ctrl_errlog2_high; + u32 err_ctrl_errlog3_low; + u32 err_ctrl_errlog3_high; + u32 err_core_swid_low; + u32 err_core_swid_high; + u32 err_core_mainctl_low; + u32 err_core_errvld_low; + u32 err_core_errclr_low; + u32 err_core_errlog0_low; + u32 err_core_errlog0_high; + u32 err_core_errlog1_low; + u32 err_core_errlog1_high; + u32 err_core_errlog2_low; + u32 err_core_errlog2_high; + u32 err_core_errlog3_low; + u32 err_core_errlog3_high; + u32 arp_test_bus[16]; + u32 dma_test_bus[512]; +}; + +struct cvp_debug_log { + struct cvp_noc_log noc_log; + u32 snapshot_index; + struct inst_snapshot snapshot[16]; +}; + struct msm_cvp_core { struct list_head list; struct mutex lock; @@ -291,12 +353,14 @@ struct msm_cvp_core { struct delayed_work fw_unload_work; struct work_struct ssr_work; enum hal_ssr_trigger_type ssr_type; - bool smmu_fault_handled; + u32 smmu_fault_count; u32 last_fault_addr; + u32 ssr_count; bool trigger_ssr; unsigned long curr_freq; struct cvp_cycle_info dyn_clk; atomic64_t kernel_trans_id; + struct cvp_debug_log log; }; struct msm_cvp_inst { diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 6670203fda..20c9702337 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -72,12 +72,9 @@ static struct msm_cvp_common_data sm8450_common_data[] = { */ }, { - .key = "qcom,max-hw-load", - .value = 3916800, /* - * 1920x1088/256 MBs@480fps. It is less - * any other usecases (ex: - * 3840x2160@120fps, 4096x2160@96ps, - * 7680x4320@30fps) + .key = "qcom,max-ssr-allowed", + .value = 1, /* + * Maxinum number of SSR before BUG_ON */ }, { diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index 013088f988..e3a521b3f8 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -771,8 +771,8 @@ int cvp_read_platform_resources_from_drv_data( res->dsp_enabled = find_key_value(platform_data, "qcom,dsp-enabled"); - res->max_load = find_key_value(platform_data, - "qcom,max-hw-load"); + res->max_ssr_allowed = find_key_value(platform_data, + "qcom,max-ssr-allowed"); res->sw_power_collapsible = find_key_value(platform_data, "qcom,sw-power-collapse"); @@ -952,7 +952,7 @@ int msm_cvp_smmu_fault_handler(struct iommu_domain *domain, { struct msm_cvp_core *core = token; struct msm_cvp_inst *inst; - u32 *pfaddr = &core->last_fault_addr; + bool log = false; if (!domain || !core) { dprintk(CVP_ERR, "%s - invalid param %pK %pK\n", @@ -960,22 +960,15 @@ int msm_cvp_smmu_fault_handler(struct iommu_domain *domain, return -EINVAL; } - if (core->smmu_fault_handled) { - if (core->resources.non_fatal_pagefaults) { - WARN_ONCE(1, "%s: non-fatal pagefault address: %lx\n", - __func__, iova); - *pfaddr = (*pfaddr == 0) ? iova : (*pfaddr); - return 0; - } - } - - dprintk(CVP_ERR, "%s - faulting address: %lx\n", __func__, iova); + core->smmu_fault_count++; + dprintk(CVP_ERR, "%s - faulting address: %lx, %d\n", + __func__, iova, core->smmu_fault_count); mutex_lock(&core->lock); + log = (core->log.snapshot_index > 0)? false : true; list_for_each_entry(inst, &core->instances, list) { - msm_cvp_print_inst_bufs(inst); + msm_cvp_print_inst_bufs(inst, log); } - core->smmu_fault_handled = true; mutex_unlock(&core->lock); /* * Return -EINVAL to elicit the default behaviour of smmu driver. diff --git a/msm/eva/msm_cvp_resources.h b/msm/eva/msm_cvp_resources.h index c39f15706f..268f5baccf 100644 --- a/msm/eva/msm_cvp_resources.h +++ b/msm/eva/msm_cvp_resources.h @@ -152,7 +152,7 @@ struct msm_cvp_platform_resources { struct subcache_set subcache_set; struct reg_set reg_set; struct addr_set qdss_addr_set; - uint32_t max_load; + uint32_t max_ssr_allowed; struct platform_device *pdev; struct regulator_set regulator_set; struct clock_set clock_set; From de1ef5829ca0939d51742a803ddf1d7f7c3b5c5a Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 30 Jul 2021 19:59:02 -0700 Subject: [PATCH 072/317] msm: eva: Add support of DSP SSR Clean up DSP sessions and their opened resources. Change-Id: Ibf1468e52c8da1ebf450c08ca2df2c57de191423 Signed-off-by: George Shen --- msm/eva/msm_cvp_dsp.c | 137 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 129 insertions(+), 8 deletions(-) diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index c9b6ff994c..581722cf99 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -176,10 +176,87 @@ static int cvp_dsp_rpmsg_probe(struct rpmsg_device *rpdev) return ret; } +static int eva_fastrpc_dev_unmap_dma( + struct fastrpc_device *frpc_device, + struct cvp_internal_buf *buf); + +static int delete_dsp_session(struct msm_cvp_inst *inst, + struct cvp_dsp_fastrpc_driver_entry *frpc_node) +{ + struct msm_cvp_list *buf_list = NULL; + struct list_head *ptr_dsp_buf = NULL, *next_dsp_buf = NULL; + struct cvp_internal_buf *buf = NULL; + struct task_struct *task = NULL; + int rc; + + if (!inst) + return -EINVAL; + + buf_list = &inst->cvpdspbufs; + + mutex_lock(&buf_list->lock); + ptr_dsp_buf = &buf_list->list; + list_for_each_safe(ptr_dsp_buf, next_dsp_buf, &buf_list->list) { + buf = list_entry(ptr_dsp_buf, struct cvp_internal_buf, list); + if (buf) { + dprintk(CVP_DSP, "fd in list 0x%x\n", buf->fd); + + if (!buf->smem) { + dprintk(CVP_DSP, "Empyt smem\n"); + continue; + } + + dprintk(CVP_DSP, "%s find device addr 0x%x\n", + __func__, buf->smem->device_addr); + + rc = eva_fastrpc_dev_unmap_dma( + frpc_node->cvp_fastrpc_device, + buf); + if (rc) + dprintk(CVP_WARN, + "%s Failed to unmap buffer 0x%x\n", + __func__, rc); + + rc = cvp_release_dsp_buffers(inst, buf); + if (rc) + dprintk(CVP_ERR, + "%s Failed to free buffer 0x%x\n", + __func__, rc); + + list_del(&buf->list); + + kmem_cache_free(cvp_driver->buf_cache, buf); + } + } + + mutex_unlock(&buf_list->lock); + + rc = msm_cvp_session_delete(inst); + if (rc) + dprintk(CVP_ERR, "Warning: send Delete Session failed\n"); + + task = inst->task; + + rc = msm_cvp_close(inst); + if (rc) + dprintk(CVP_ERR, "Warning: Failed to close cvp instance\n"); + + if (task) + put_task_struct(task); + + dprintk(CVP_DSP, "%s DSP2CPU_DETELE_SESSION Done\n", __func__); + return rc; +} + static void cvp_dsp_rpmsg_remove(struct rpmsg_device *rpdev) { struct cvp_dsp_apps *me = &gfa_cv; + struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; + struct list_head *ptr = NULL, *next = NULL; + struct list_head *s = NULL, *next_s = NULL; + struct msm_cvp_inst *inst = NULL; + dprintk(CVP_WARN, "%s: CDSP SSR triggered\n", __func__); mutex_lock(&me->tx_lock); @@ -188,8 +265,38 @@ static void cvp_dsp_rpmsg_remove(struct rpmsg_device *rpdev) me->chan = NULL; me->state = DSP_UNINIT; mutex_unlock(&me->tx_lock); - /* kernel driver needs clean all dsp sessions */ + ptr = &me->fastrpc_driver_list.list; + list_for_each_safe(ptr, next, &me->fastrpc_driver_list.list) { + frpc_node = list_entry(ptr, + struct cvp_dsp_fastrpc_driver_entry, list); + + if (frpc_node) { + s = &frpc_node->dsp_sessions.list; + list_for_each_safe(s, next_s, + &frpc_node->dsp_sessions.list) { + inst = list_entry(s, struct msm_cvp_inst, + dsp_list); + delete_dsp_session(inst, frpc_node); + } + + dprintk(CVP_DSP, "%s DEINIT_MSM_CVP_LIST 0x%x\n", + __func__, frpc_node->dsp_sessions); + DEINIT_MSM_CVP_LIST(&frpc_node->dsp_sessions); + dprintk(CVP_DSP, "%s list_del fastrpc node 0x%x\n", + __func__, frpc_node); + list_del(&frpc_node->list); + fastrpc_driver_unregister( + &frpc_node->cvp_fastrpc_driver); + dprintk(CVP_DSP, + "%s Unregistered fastrpc handle 0x%x\n", + __func__, frpc_node->handle); + kfree(frpc_node); + frpc_node = NULL; + } + } + + dprintk(CVP_WARN, "%s: CDSP SSR handled\n", __func__); } static int cvp_dsp_rpmsg_callback(struct rpmsg_device *rpdev, @@ -649,20 +756,23 @@ static struct cvp_dsp_fastrpc_driver_entry *cvp_find_fastrpc_node_with_handle( { struct cvp_dsp_apps *me = &gfa_cv; struct list_head *ptr = NULL, *next = NULL; - struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; + struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL, *tmp_node = NULL; mutex_lock(&me->fastrpc_driver_list.lock); list_for_each_safe(ptr, next, &me->fastrpc_driver_list.list) { - frpc_node = list_entry(ptr, + tmp_node = list_entry(ptr, struct cvp_dsp_fastrpc_driver_entry, list); - if (handle == frpc_node->handle) { - dprintk(CVP_DSP, "Find frpc_node with handle 0x%x\n", + if (handle == tmp_node->handle) { + frpc_node = tmp_node; + dprintk(CVP_DSP, "Find tmp_node with handle 0x%x\n", handle); break; } } mutex_unlock(&me->fastrpc_driver_list.lock); + dprintk(CVP_DSP, "%s found fastrpc probe handle %pK pid 0x%x\n", + __func__, frpc_node, handle); return frpc_node; } @@ -695,6 +805,7 @@ static int cvp_fastrpc_callback(struct fastrpc_device *rpc_dev, * any handling can happen here, such as * eva_fastrpc_driver_unregister(rpc_dev->handle, true); */ + eva_fastrpc_driver_unregister(rpc_dev->handle, true); return 0; } @@ -843,9 +954,13 @@ static int eva_fastrpc_driver_register(uint32_t handle) int rc = 0; struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; + dprintk(CVP_DSP, "%s -> cvp_find_fastrpc_node_with_handle pid 0x%x\n", + __func__, handle); frpc_node = cvp_find_fastrpc_node_with_handle(handle); if (frpc_node == NULL) { + dprintk(CVP_DSP, "%s new fastrpc node pid 0x%x\n", + __func__, handle); frpc_node = kzalloc(sizeof(*frpc_node), GFP_KERNEL); if (!frpc_node) { dprintk(CVP_DSP, "%s allocate frpc node fail\n", @@ -883,17 +998,20 @@ static int eva_fastrpc_driver_register(uint32_t handle) __func__); goto fail_fastrpc_driver_timeout; } + } else { + dprintk(CVP_DSP, "%s fastrpc probe hndl %pK pid 0x%x\n", + __func__, frpc_node, handle); } return rc; fail_fastrpc_driver_timeout: + fastrpc_driver_unregister(&frpc_node->cvp_fastrpc_driver); +fail_fastrpc_driver_register: /* remove list if this is the last session */ mutex_lock(&me->fastrpc_driver_list.lock); list_del(&frpc_node->list); mutex_unlock(&me->fastrpc_driver_list.lock); - fastrpc_driver_unregister(&frpc_node->cvp_fastrpc_driver); -fail_fastrpc_driver_register: kfree(frpc_node); return -EINVAL; } @@ -910,8 +1028,11 @@ static void eva_fastrpc_driver_unregister(uint32_t handle, bool force_exit) /* Foundd fastrpc node */ frpc_node = cvp_find_fastrpc_node_with_handle(dsp2cpu_cmd->pid); - if (frpc_node == NULL) + if (frpc_node == NULL) { + dprintk(CVP_DSP, "%s fastrpc handle 0x%x unregistered\n", + __func__, handle); return; + } if ((frpc_node->session_cnt == 0) || force_exit) { dprintk(CVP_DSP, "%s session cnt %d, force %d\n", From 55eeb27ba89f8028b5b2f94045c2eb232f1ba657 Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 17 Aug 2021 14:31:38 -0700 Subject: [PATCH 073/317] msm: eva: Support EVA DSP clients in mult-process Each process requires unique driver name. Change-Id: I72993470dcd60de20dfda8133b0b3f4dfbbf8f8d Signed-off-by: George Shen --- msm/eva/msm_cvp_dsp.c | 68 +++++++++++++++++++++++++++++++++++++++---- msm/eva/msm_cvp_dsp.h | 19 ++++++++++-- 2 files changed, 79 insertions(+), 8 deletions(-) diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 581722cf99..f12ba7bbf5 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -248,6 +248,35 @@ static int delete_dsp_session(struct msm_cvp_inst *inst, return rc; } +static int eva_fastrpc_driver_get_name( + struct cvp_dsp_fastrpc_driver_entry *frpc_node) +{ + int i = 0; + struct cvp_dsp_apps *me = &gfa_cv; + for (i = 0; i < MAX_FASTRPC_DRIVER_NUM; i++) { + if (me->cvp_fastrpc_name[i].status == DRIVER_NAME_AVAILABLE) { + frpc_node->driver_name_idx = i; + frpc_node->cvp_fastrpc_driver.driver.name = + me->cvp_fastrpc_name[i].name; + me->cvp_fastrpc_name[i].status = DRIVER_NAME_USED; + dprintk(CVP_DSP, "%s -> handle 0x%x get name %s\n", + __func__, frpc_node->cvp_fastrpc_driver.handle, + frpc_node->cvp_fastrpc_driver.driver.name); + return 0; + } + } + + return -1; +} + +static void eva_fastrpc_driver_release_name( + struct cvp_dsp_fastrpc_driver_entry *frpc_node) +{ + struct cvp_dsp_apps *me = &gfa_cv; + me->cvp_fastrpc_name[frpc_node->driver_name_idx].status = + DRIVER_NAME_AVAILABLE; +} + static void cvp_dsp_rpmsg_remove(struct rpmsg_device *rpdev) { struct cvp_dsp_apps *me = &gfa_cv; @@ -291,6 +320,9 @@ static void cvp_dsp_rpmsg_remove(struct rpmsg_device *rpdev) dprintk(CVP_DSP, "%s Unregistered fastrpc handle 0x%x\n", __func__, frpc_node->handle); + mutex_lock(&me->driver_name_lock); + eva_fastrpc_driver_release_name(frpc_node); + mutex_unlock(&me->driver_name_lock); kfree(frpc_node); frpc_node = NULL; } @@ -814,9 +846,6 @@ static int cvp_fastrpc_callback(struct fastrpc_device *rpc_dev, static struct fastrpc_driver cvp_fastrpc_client = { .probe = cvp_fastrpc_probe, .callback = cvp_fastrpc_callback, - .driver = { - .name = "qcom,fastcv", - }, }; @@ -970,6 +999,19 @@ static int eva_fastrpc_driver_register(uint32_t handle) memset(frpc_node, 0, sizeof(*frpc_node)); + /* Setup fastrpc_node */ + frpc_node->handle = handle; + frpc_node->cvp_fastrpc_driver = cvp_fastrpc_client; + frpc_node->cvp_fastrpc_driver.handle = handle; + mutex_lock(&me->driver_name_lock); + rc = eva_fastrpc_driver_get_name(frpc_node); + mutex_unlock(&me->driver_name_lock); + if (rc) { + dprintk(CVP_ERR, "%s fastrpc get name fail err %d\n", + __func__, rc); + goto fail_fastrpc_driver_get_name; + } + /* Init completion */ init_completion(&frpc_node->fastrpc_probe_completion); @@ -980,9 +1022,6 @@ static int eva_fastrpc_driver_register(uint32_t handle) INIT_MSM_CVP_LIST(&frpc_node->dsp_sessions); /* register fastrpc device to this session */ - frpc_node->handle = handle; - frpc_node->cvp_fastrpc_driver = cvp_fastrpc_client; - frpc_node->cvp_fastrpc_driver.handle = handle; rc = fastrpc_driver_register(&frpc_node->cvp_fastrpc_driver); if (rc) { dprintk(CVP_ERR, "%s fastrpc driver reg fail err %d\n", @@ -1012,6 +1051,11 @@ fail_fastrpc_driver_register: mutex_lock(&me->fastrpc_driver_list.lock); list_del(&frpc_node->list); mutex_unlock(&me->fastrpc_driver_list.lock); + + mutex_lock(&me->driver_name_lock); + eva_fastrpc_driver_release_name(frpc_node); + mutex_unlock(&me->driver_name_lock); +fail_fastrpc_driver_get_name: kfree(frpc_node); return -EINVAL; } @@ -1046,6 +1090,9 @@ static void eva_fastrpc_driver_unregister(uint32_t handle, bool force_exit) mutex_unlock(&me->fastrpc_driver_list.lock); fastrpc_driver_unregister(&frpc_node->cvp_fastrpc_driver); + mutex_lock(&me->driver_name_lock); + eva_fastrpc_driver_release_name(frpc_node); + mutex_unlock(&me->driver_name_lock); kfree(frpc_node); } } @@ -1839,6 +1886,7 @@ int cvp_dsp_device_init(void) char tname[16]; int rc; int i; + char name[CVP_FASTRPC_DRIVER_NAME_SIZE] = "qcom,fastcv0\0"; mutex_init(&me->tx_lock); mutex_init(&me->rx_lock); @@ -1853,6 +1901,13 @@ int cvp_dsp_device_init(void) INIT_MSM_CVP_LIST(&me->fastrpc_driver_list); + mutex_init(&me->driver_name_lock); + for (i = 0; i < MAX_FASTRPC_DRIVER_NUM; i++) { + me->cvp_fastrpc_name[i].status = DRIVER_NAME_AVAILABLE; + snprintf(me->cvp_fastrpc_name[i].name, sizeof(name), name); + name[11]++; + } + rc = register_rpmsg_driver(&cvp_dsp_rpmsg_client); if (rc) { dprintk(CVP_ERR, @@ -1891,5 +1946,6 @@ void cvp_dsp_device_exit(void) mutex_destroy(&me->tx_lock); mutex_destroy(&me->rx_lock); + mutex_destroy(&me->driver_name_lock); unregister_rpmsg_driver(&cvp_dsp_rpmsg_client); } diff --git a/msm/eva/msm_cvp_dsp.h b/msm/eva/msm_cvp_dsp.h index 32f354b8e6..f0cb9708cd 100644 --- a/msm/eva/msm_cvp_dsp.h +++ b/msm/eva/msm_cvp_dsp.h @@ -31,10 +31,11 @@ #define HIGH32 (0xFFFFFFFF00000000LL) #define LOW32 (0xFFFFFFFFLL) +#define CVP_FASTRPC_DRIVER_NAME_SIZE 16 -/* Supports up to 8 DSP sessions in 4 processes */ -#define MAX_FASTRPC_DRIVER_NUM (4) +/* Supports up to 8 DSP sessions in 8 processes */ #define MAX_DSP_SESSION_NUM (8) +#define MAX_FASTRPC_DRIVER_NUM (MAX_DSP_SESSION_NUM) int cvp_dsp_device_init(void); void cvp_dsp_device_exit(void); @@ -164,10 +165,22 @@ struct cvp_dsp2cpu_cmd_msg { uint32_t data[CVP_DSP2CPU_RESERVED]; }; +struct driver_name { + uint32_t status; + char name[CVP_FASTRPC_DRIVER_NAME_SIZE]; +}; + +enum DRIVER_NAME_STATUS { + DRIVER_NAME_INVALID = 0, + DRIVER_NAME_AVAILABLE = 1, + DRIVER_NAME_USED = 2, +}; + struct cvp_dsp_fastrpc_driver_entry { struct list_head list; uint32_t handle; uint32_t session_cnt; + uint32_t driver_name_idx; struct fastrpc_driver cvp_fastrpc_driver; struct fastrpc_device *cvp_fastrpc_device; struct completion fastrpc_probe_completion; @@ -183,6 +196,7 @@ struct cvp_dsp_apps { struct mutex tx_lock; /* rx_lock for receiving DSP2CPU cmds or msgs */ struct mutex rx_lock; + struct mutex driver_name_lock; struct rpmsg_device *chan; uint32_t state; uint32_t debug_mask; @@ -197,6 +211,7 @@ struct cvp_dsp_apps { const struct file_operations *dmabuf_f_op; uint32_t buf_num; struct msm_cvp_list fastrpc_driver_list; + struct driver_name cvp_fastrpc_name[MAX_FASTRPC_DRIVER_NUM]; }; extern struct cvp_dsp_apps gfa_cv; From c2d59a4698f20417498f2845699e8319ee7b6217 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Tue, 10 Aug 2021 18:54:34 -0700 Subject: [PATCH 074/317] msm: eva: set clk to 0 before mmrm deregistration set clock value to 0 before call mmrm_client_deregister, fixed an issue that peak cur value overshoot between SSRs. Change-Id: I2b884614f0c9e1b19d63102277cad7b951fdd908 Signed-off-by: Yu SI --- msm/eva/cvp_hfi.c | 10 ++------ msm/eva/msm_cvp_clocks.c | 50 +++++++++++++++++++++++++++++++++++++--- msm/eva/msm_cvp_clocks.h | 1 + 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 2272f47526..f3be16ace6 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1882,17 +1882,11 @@ static int iris_hfi_core_release(void *dev) __dsp_shutdown(device, 0); if (msm_cvp_mmrm_enabled) { - rc = mmrm_client_deregister(device->mmrm_cvp); + rc = msm_cvp_mmrm_deregister(device); if (rc) { dprintk(CVP_ERR, - "%s: Failed mmrm_client_deregister with rc: %d\n", + "%s: Failed msm_cvp_mmrm_deregister:%d\n", __func__, rc); - } else { - dprintk(CVP_PWR, - "%s: Succeed mmrm_client_deregister for mmrm_cvp:%pK, type:%d, uid:%ld\n", - __func__, device->mmrm_cvp, device->mmrm_cvp->client_type, - device->mmrm_cvp->client_uid); - device->mmrm_cvp = NULL; } } diff --git a/msm/eva/msm_cvp_clocks.c b/msm/eva/msm_cvp_clocks.c index 35b120d7ff..d1d1df4d6f 100644 --- a/msm/eva/msm_cvp_clocks.c +++ b/msm/eva/msm_cvp_clocks.c @@ -88,12 +88,12 @@ int msm_cvp_mmrm_register(struct iris_hfi_device *device) device->mmrm_cvp = mmrm_client_register(&(device->mmrm_desc)); if (device->mmrm_cvp == NULL) { dprintk(CVP_ERR, - "%s: Failed mmrm_client_register with mmrm_cvp: %p\n", + "%s: Failed mmrm_client_register with mmrm_cvp: %pK\n", __func__, device->mmrm_cvp); rc = -ENOENT; } else { dprintk(CVP_PWR, - "%s: mmrm_client_register done: %p, type:%d, uid:%ld\n", + "%s: mmrm_client_register done: %pK, type:%d, uid:%ld\n", __func__, device->mmrm_cvp, device->mmrm_cvp->client_type, device->mmrm_cvp->client_uid); @@ -102,6 +102,50 @@ int msm_cvp_mmrm_register(struct iris_hfi_device *device) return rc; } +int msm_cvp_mmrm_deregister(struct iris_hfi_device *device) +{ + int rc = 0; + struct clock_info *cl = NULL; + + if (!device || !device->mmrm_cvp) { + dprintk(CVP_ERR, + "%s invalid args: device %pK, or device->mmrm_cvp \n", + __func__, device); + return -EINVAL; + } + + /* set clk value to 0 before deregister */ + iris_hfi_for_each_clock(device, cl) { + if (cl->has_scaling) { + // set min freq and cur freq to 0; + rc = msm_cvp_mmrm_set_value_in_range(device, + 0, 0); + if (rc) { + dprintk(CVP_ERR, + "%s Failed set clock %s: %d\n", + __func__, cl->name, rc); + } + } + } + + rc = mmrm_client_deregister(device->mmrm_cvp); + if (rc) { + dprintk(CVP_ERR, + "%s: Failed mmrm_client_deregister with rc: %d\n", + __func__, rc); + } + else { + dprintk(CVP_PWR, + "%s: mmrm_client_deregister done:%pK,type:%d,uid:%ld\n", + __func__, device->mmrm_cvp, + device->mmrm_cvp->client_type, + device->mmrm_cvp->client_uid); + device->mmrm_cvp = NULL; + } + + return rc; +} + int msm_cvp_mmrm_set_value_in_range(struct iris_hfi_device *device, u32 freq_min, u32 freq_cur) { @@ -115,7 +159,7 @@ int msm_cvp_mmrm_set_value_in_range(struct iris_hfi_device *device, } dprintk(CVP_PWR, - "%s: set clock rate for mmrm_cvp: %p, type :%d, uid: %ld\n", + "%s: set clock rate for mmrm_cvp: %pK, type :%d, uid: %ld\n", __func__, device->mmrm_cvp, device->mmrm_cvp->client_type, device->mmrm_cvp->client_uid); diff --git a/msm/eva/msm_cvp_clocks.h b/msm/eva/msm_cvp_clocks.h index 8b402d11d7..0cd95546dd 100644 --- a/msm/eva/msm_cvp_clocks.h +++ b/msm/eva/msm_cvp_clocks.h @@ -11,6 +11,7 @@ int msm_cvp_set_clocks(struct msm_cvp_core *core); int msm_cvp_mmrm_register(struct iris_hfi_device *device); +int msm_cvp_mmrm_deregister(struct iris_hfi_device *device); int msm_cvp_mmrm_set_value_in_range(struct iris_hfi_device *device, u32 freq_min, u32 freq_cur); int msm_cvp_set_clocks_impl(struct iris_hfi_device *device, u32 freq); From 27a7be786903ac3a71c802e3010bf58e0dc7689f Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 17 Aug 2021 11:49:50 -0700 Subject: [PATCH 075/317] msm: eva: Disable LLCC during SSR Avoid pending transactions after EVA powered off. Change-Id: Ic18d9184b4a8dcb158671e9a151a9cd8ec9e4ef6 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index f3be16ace6..bfd3529a65 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1776,6 +1776,14 @@ static int iris_hfi_core_init(void *device) goto err_load_fw; } + /* mmrm registration */ + if (msm_cvp_mmrm_enabled) { + rc = msm_cvp_mmrm_register(device); + if (rc) { + dprintk(CVP_ERR, "Failed to register mmrm client\n"); + goto err_core_init; + } + } __set_state(dev, IRIS_STATE_INIT); dev->reg_dumped = false; @@ -1788,7 +1796,7 @@ static int iris_hfi_core_init(void *device) if (rc) { dprintk(CVP_ERR, "failed to init queues\n"); rc = -ENOMEM; - goto err_core_init; + goto err_mmrm_dereg; } rc = msm_cvp_map_ipcc_regs(&ipcc_iova); @@ -1801,7 +1809,7 @@ static int iris_hfi_core_init(void *device) if (rc) { dprintk(CVP_ERR, "Failed to start core\n"); rc = -ENODEV; - goto err_core_init; + goto err_mmrm_dereg; } dev->version = __read_register(dev, CVP_VERSION_INFO); @@ -1809,12 +1817,12 @@ static int iris_hfi_core_init(void *device) rc = call_hfi_pkt_op(dev, sys_init, &pkt, 0); if (rc) { dprintk(CVP_ERR, "Failed to create sys init pkt\n"); - goto err_core_init; + goto err_mmrm_dereg; } if (__iface_cmdq_write(dev, &pkt)) { rc = -ENOTEMPTY; - goto err_core_init; + goto err_mmrm_dereg; } rc = call_hfi_pkt_op(dev, sys_image_version, &version_pkt); @@ -1833,15 +1841,6 @@ static int iris_hfi_core_init(void *device) cpu_latency_qos_add_request(&dev->qos, dev->res->pm_qos_latency_us); - /* mmrm registration */ - if (msm_cvp_mmrm_enabled) { - rc = msm_cvp_mmrm_register(device); - if (rc) { - dprintk(CVP_ERR, "Failed to register mmrm client\n"); - goto err_core_init; - } - } - mutex_unlock(&dev->lock); cvp_dsp_send_hfi_queue(); @@ -1849,6 +1848,8 @@ static int iris_hfi_core_init(void *device) dprintk(CVP_CORE, "Core inited successfully\n"); return 0; +err_mmrm_dereg: + msm_cvp_mmrm_deregister(dev); err_core_init: __set_state(dev, IRIS_STATE_DEINIT); __unload_fw(dev); @@ -1890,6 +1891,7 @@ static int iris_hfi_core_release(void *dev) } } + __disable_subcaches(device); __unload_fw(device); /* unlink all sessions from device */ From d49b4e5574088e64e2d904d54d81b1e8a791f8f7 Mon Sep 17 00:00:00 2001 From: Ronald Karyodisa Date: Wed, 18 Aug 2021 09:55:37 -0700 Subject: [PATCH 076/317] msm: eva: Add FD type check for DCVS Add FD packet check and add log to catch the unexpected FD packet size. Change-Id: I794d659a2e33e5efc521d31476c6923ca5462554 Signed-off-by: Ronald Karyodisa --- msm/eva/msm_cvp.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index fd5a6ce76a..0602c68baf 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -485,21 +485,26 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, /* Only FD support dcvs at certain FW */ if (!msm_cvp_dcvs_disable && - (hdr.size == sizeof(struct cvp_hfi_msg_session_hdr_ext) - + sizeof(struct cvp_hfi_buf_type))) { - struct cvp_hfi_msg_session_hdr_ext *fhdr = - (struct cvp_hfi_msg_session_hdr_ext *)&hdr; - struct msm_cvp_core *core = inst->core; - dprintk(CVP_PWR, "busy cycle %d, total %d\n", - fhdr->busy_cycles, fhdr->total_cycles); + hdr.packet_type == HFI_MSG_SESSION_CVP_FD) { + if (hdr.size == sizeof(struct cvp_hfi_msg_session_hdr_ext) + + sizeof(struct cvp_hfi_buf_type)) { + struct cvp_hfi_msg_session_hdr_ext *fhdr = + (struct cvp_hfi_msg_session_hdr_ext *)&hdr; + struct msm_cvp_core *core = inst->core; - if (core && - (core->dyn_clk.sum_fps[HFI_HW_FDU] || - core->dyn_clk.sum_fps[HFI_HW_MPU] || - core->dyn_clk.sum_fps[HFI_HW_OD] || - core->dyn_clk.sum_fps[HFI_HW_ICA])) - { - clock_check = true; + dprintk(CVP_PWR, "busy cycle %d, total %d\n", + fhdr->busy_cycles, fhdr->total_cycles); + + if (core && (core->dyn_clk.sum_fps[HFI_HW_FDU] || + core->dyn_clk.sum_fps[HFI_HW_MPU] || + core->dyn_clk.sum_fps[HFI_HW_OD] || + core->dyn_clk.sum_fps[HFI_HW_ICA])) { + clock_check = true; + } + } else { + dprintk(CVP_WARN, "dcvs is disabled, %d != %d + %d\n", + hdr.size, sizeof(struct cvp_hfi_msg_session_hdr_ext), + sizeof(struct cvp_hfi_buf_type)); } } hfi_err = hdr.error_type; From 4b4bb300cfb1c9824c663a7e7dcef617357c9490 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Tue, 17 Aug 2021 18:34:02 -0700 Subject: [PATCH 077/317] msm: eva: prepare enable video_cc_mvs1_clk_src prepare and enable video_cc_mvs1_clk_src in power on core sequence; and disable and unprepare in power off core sequence. Change-Id: I5558516bb54a7886e9faf9739a0743d8ad59d81b Signed-off-by: Yu SI --- msm/eva/cvp_hfi.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index bfd3529a65..5ffa847eeb 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -3702,6 +3702,14 @@ static int __power_on_core(struct iris_hfi_device *device) return rc; } + rc = msm_cvp_prepare_enable_clk(device, "video_cc_mvs1_clk_src"); + if (rc) { + dprintk(CVP_ERR, "Failed to enable video_cc_mvs1_clk_src:%d\n", + rc); + __disable_regulator(device, "cvp-core"); + return rc; + } + rc = msm_cvp_prepare_enable_clk(device, "core_clk"); if (rc) { dprintk(CVP_ERR, "Failed to enable core_clk: %d\n", rc); @@ -3939,6 +3947,7 @@ static int __power_off_core(struct iris_hfi_device *device) } __disable_regulator(device, "cvp-core"); msm_cvp_disable_unprepare_clk(device, "core_clk"); + msm_cvp_disable_unprepare_clk(device, "video_cc_mvs1_clk_src"); return 0; } @@ -4019,6 +4028,7 @@ static int __power_off_core(struct iris_hfi_device *device) __disable_regulator(device, "cvp-core"); msm_cvp_disable_unprepare_clk(device, "core_clk"); + msm_cvp_disable_unprepare_clk(device, "video_cc_mvs1_clk_src"); return 0; } From a610c57ca1951f0ad95502f719f1cf0992665d98 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 18 Aug 2021 17:22:06 -0700 Subject: [PATCH 078/317] msm: eva: Add control of EVA SSR behavior For better debugging, it's conveninet to stall device when EVA SSR happens. Change-Id: I1bfd97d99ad3b6c0276282be9de4e7bb2456227d Signed-off-by: George Shen --- msm/eva/msm_cvp_common.c | 1 + msm/eva/msm_cvp_debug.c | 28 ++++++++++++++++++++++++++++ msm/eva/msm_cvp_res_parse.c | 1 + msm/eva/msm_cvp_resources.h | 1 + 4 files changed, 31 insertions(+) diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index e3f5abb854..b63c6c20e5 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -691,6 +691,7 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) mutex_unlock(&core->lock); dprintk(CVP_WARN, "SYS_ERROR handled.\n"); + BUG_ON(core->resources.fatal_ssr); } void msm_cvp_comm_session_clean(struct msm_cvp_inst *inst) diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 099f9b0f40..51f6a4b752 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -386,6 +386,29 @@ static int _max_ssr_get(void *data, u64 *val) DEFINE_DEBUGFS_ATTRIBUTE(max_ssr_fops, _max_ssr_get, _max_ssr_set, "%llu\n"); +static int _ssr_stall_set(void *data, u64 val) +{ + struct msm_cvp_core *core; + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (core) + core->resources.fatal_ssr = (val >= 1) ? true : false; + + return 0; +} + +static int _ssr_stall_get(void *data, u64 *val) +{ + struct msm_cvp_core *core; + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (core) + *val = core->resources.fatal_ssr ? 1 : 0; + + return 0; +} + +DEFINE_DEBUGFS_ATTRIBUTE(ssr_stall_fops, _ssr_stall_get, _ssr_stall_set, "%llu\n"); + + struct dentry *msm_cvp_debugfs_init_core(struct msm_cvp_core *core, struct dentry *parent) { @@ -430,6 +453,11 @@ struct dentry *msm_cvp_debugfs_init_core(struct msm_cvp_core *core, goto failed_create_dir; } + if (!debugfs_create_file("ssr_stall", 0644, dir, + NULL, &ssr_stall_fops)) { + dprintk(CVP_ERR, "debugfs_create: ssr_stall fail\n"); + goto failed_create_dir; + } failed_create_dir: return dir; } diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index e3a521b3f8..5999ce941c 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -804,6 +804,7 @@ int cvp_read_platform_resources_from_drv_data( res->vpu_ver = platform_data->vpu_ver; res->ubwc_config = platform_data->ubwc_config; + res->fatal_ssr = false; return rc; } diff --git a/msm/eva/msm_cvp_resources.h b/msm/eva/msm_cvp_resources.h index 268f5baccf..f5349b50dd 100644 --- a/msm/eva/msm_cvp_resources.h +++ b/msm/eva/msm_cvp_resources.h @@ -176,6 +176,7 @@ struct msm_cvp_platform_resources { int msm_cvp_firmware_unload_delay; uint32_t msm_cvp_pwr_collapse_delay; bool non_fatal_pagefaults; + bool fatal_ssr; struct msm_cvp_mem_cdsp mem_cdsp; uint32_t vpu_ver; uint32_t fw_cycles; From 73df69a866f739076653497c7829a10a8fd93cf9 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Thu, 19 Aug 2021 18:49:58 -0700 Subject: [PATCH 079/317] msm: eva: mmrm set clk to 0 when disable unprepare set clk value to 0 with mmrm api when disable and unprepare clk Change-Id: Ia14042abf5dc0b6798869ad95e22b4c12a973881 Signed-off-by: Yu SI --- msm/eva/msm_cvp_clocks.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/msm/eva/msm_cvp_clocks.c b/msm/eva/msm_cvp_clocks.c index d1d1df4d6f..2533ed3863 100644 --- a/msm/eva/msm_cvp_clocks.c +++ b/msm/eva/msm_cvp_clocks.c @@ -313,6 +313,7 @@ int msm_cvp_disable_unprepare_clk(struct iris_hfi_device *device, const char *name) { struct clock_info *cl; + int rc = 0; if (!device) { dprintk(CVP_ERR, "Invalid params: %pK\n", device); @@ -325,6 +326,18 @@ int msm_cvp_disable_unprepare_clk(struct iris_hfi_device *device, clk_disable_unprepare(cl->clk); dprintk(CVP_PWR, "Clock: %s disable and unprepare\n", cl->name); + + if (cl->has_scaling) { + if (device->mmrm_cvp != NULL) { + // set min freq and cur freq to 0; + rc = msm_cvp_mmrm_set_value_in_range(device, + 0, 0); + if (rc) + dprintk(CVP_ERR, + "%s Failed set clock %s: %d\n", + __func__, cl->name, rc); + } + } return 0; } From 27132cb6263e5aeb29544f565adcb5221d32ef65 Mon Sep 17 00:00:00 2001 From: Ronald Karyodisa Date: Thu, 19 Aug 2021 14:13:08 -0700 Subject: [PATCH 080/317] msm: cvp: Fix dynamic clock voting Prevent dcvs voting below the current aggregated clock. Change-Id: Ie3ea259521a7b241cdef40a049563f054b089687 Signed-off-by: Ronald Karyodisa --- msm/eva/msm_cvp.c | 9 +++++++++ msm/eva/msm_cvp_internal.h | 1 + 2 files changed, 10 insertions(+) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 0602c68baf..a2285c9110 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -333,6 +333,14 @@ static int cvp_readjust_clock(struct msm_cvp_core *core, lo_freq = tbl[j-1].clock_rate; } + if (core->orig_core_sum > core->curr_freq) { + dprintk(CVP_PWR, + "%s - %d - Cancel readjust, core %u, freq %u\n", + __func__, i, core->orig_core_sum, core->curr_freq); + core->curr_freq = tmp; + return rc; + } + dprintk(CVP_PWR, "%s:%d - %d - Readjust to %u\n", __func__, __LINE__, i, core->curr_freq); @@ -957,6 +965,7 @@ static int adjust_bw_freqs(void) tmp = core->curr_freq; core->curr_freq = core_sum; + core->orig_core_sum = core_sum; rc = msm_cvp_set_clocks(core); if (rc) { dprintk(CVP_ERR, diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index a86c7e9cc6..d95a76b0c5 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -358,6 +358,7 @@ struct msm_cvp_core { u32 ssr_count; bool trigger_ssr; unsigned long curr_freq; + unsigned long orig_core_sum; struct cvp_cycle_info dyn_clk; atomic64_t kernel_trans_id; struct cvp_debug_log log; From 07806574914c1405dcf9b3532411db4e5e04e20a Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 20 Aug 2021 14:06:32 -0700 Subject: [PATCH 081/317] msm: eva: Fix typo in DSP debug mask check Don't ingore memory debugging level. Change-Id: I2d1df82c2c7ba1741e373ab6cd69635b5f54215e Signed-off-by: George Shen --- msm/eva/msm_cvp_debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 51f6a4b752..4bf257418a 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -337,7 +337,7 @@ DEFINE_DEBUGFS_ATTRIBUTE(clk_rate_fops, _clk_rate_get, _clk_rate_set, "%llu\n"); static int _dsp_dbg_set(void *data, u64 val) { - if (val == 0 || val > (1 << EVA_MEM_DEBUG_ON)) { + if (val == 0 || val >= (1 << (EVA_MEM_DEBUG_ON + 1))) { dprintk(CVP_WARN, "DSP debug mask cannot be %llx\n", val); return 0; } From 7634c56a2a0a1b07b56f51e9065c2c3fa6b23cb8 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Mon, 23 Aug 2021 18:36:32 -0700 Subject: [PATCH 082/317] msm: eva: rm log access mmrm clientStr after dereg Removed the logging which access mmrm eva client structure after calling mmrm deregister. Change-Id: I467c147bd76b980971b0ca512212292e572b1b18 Signed-off-by: Yu SI --- msm/eva/msm_cvp_clocks.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/msm/eva/msm_cvp_clocks.c b/msm/eva/msm_cvp_clocks.c index 2533ed3863..73d0c6f0f9 100644 --- a/msm/eva/msm_cvp_clocks.c +++ b/msm/eva/msm_cvp_clocks.c @@ -134,14 +134,6 @@ int msm_cvp_mmrm_deregister(struct iris_hfi_device *device) "%s: Failed mmrm_client_deregister with rc: %d\n", __func__, rc); } - else { - dprintk(CVP_PWR, - "%s: mmrm_client_deregister done:%pK,type:%d,uid:%ld\n", - __func__, device->mmrm_cvp, - device->mmrm_cvp->client_type, - device->mmrm_cvp->client_uid); - device->mmrm_cvp = NULL; - } return rc; } From 3eaf705b300557c697d203cd6c1614e643ce8838 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 23 Aug 2021 19:32:52 -0700 Subject: [PATCH 083/317] msm: eva: Flush EVA CPU DDR transactions Before power collapsing EVA subsystem. Change-Id: I84ea3278a3229346677cc28d2aec1e62bbe5868c Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 38 +++++++++++++++++++++++++++++++++++--- msm/eva/cvp_hfi_io.h | 3 +++ 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 5ffa847eeb..09670ae281 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -3862,6 +3862,7 @@ exit: static int __power_off_controller(struct iris_hfi_device *device) { u32 lpi_status, reg_status = 0, count = 0, max_count = 1000; + u32 sbm_ln0_low; /* HPG 6.2.2 Step 1 */ __write_register(device, CVP_CPU_CS_X2RPMh, 0x3); @@ -3873,12 +3874,12 @@ static int __power_off_controller(struct iris_hfi_device *device) __read_register(device, CVP_AON_WRAPPER_MVP_NOC_LPI_STATUS); reg_status = lpi_status & BIT(0); - /* Wait for noc lpi status to be set */ + /* Wait for Core noc lpi status to be set */ usleep_range(50, 100); count++; } dprintk(CVP_PWR, - "Noc: lpi_status %x noc_status %x (count %d)\n", + "Core Noc: lpi_status %x noc_status %x (count %d)\n", lpi_status, reg_status, count); if (count == max_count) { u32 pc_ready, wfi_status; @@ -3887,12 +3888,43 @@ static int __power_off_controller(struct iris_hfi_device *device) pc_ready = __read_register(device, CVP_CTRL_STATUS); dprintk(CVP_WARN, - "NOC not in qaccept status %x %x %x %x\n", + "Core NOC not in qaccept status %x %x %x %x\n", reg_status, lpi_status, wfi_status, pc_ready); __print_sidebandmanager_regs(device); } + /* New addition to put CPU/Tensilica to low power */ + reg_status = 0; + count = 0; + __write_register(device, CVP_WRAPPER_CPU_NOC_LPI_CONTROL, 0x1); + while (!reg_status && count < max_count) { + lpi_status = + __read_register(device, + CVP_WRAPPER_CPU_NOC_LPI_STATUS); + reg_status = lpi_status & BIT(0); + /* Wait for CPU noc lpi status to be set */ + usleep_range(50, 100); + count++; + } + sbm_ln0_low = __read_register(device, CVP_NOC_SBM_SENSELN0_LOW); + dprintk(CVP_PWR, + "CPU Noc: lpi_status %x noc_status %x (count %d) 0x%x\n", + lpi_status, reg_status, count, sbm_ln0_low); + if (count == max_count) { + u32 pc_ready, wfi_status; + + wfi_status = __read_register(device, CVP_WRAPPER_CPU_STATUS); + pc_ready = __read_register(device, CVP_CTRL_STATUS); + + dprintk(CVP_WARN, + "CPU NOC not in qaccept status %x %x %x %x\n", + reg_status, lpi_status, wfi_status, pc_ready); + + __print_sidebandmanager_regs(device); + } + + /* HPG 6.2.2 Step 3, debug bridge to low power BYPASSED */ /* HPG 6.2.2 Step 4, debug bridge to lpi release */ diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index 602742d704..67bcc5cf34 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -115,6 +115,8 @@ #define CVP_WRAPPER_CPU_CLOCK_CONFIG (CVP_WRAPPER_BASE_OFFS + 0x50) #define CVP_WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (CVP_WRAPPER_BASE_OFFS + 0x54) #define CVP_WRAPPER_DEBUG_BRIDGE_LPI_STATUS (CVP_WRAPPER_BASE_OFFS + 0x58) +#define CVP_WRAPPER_CPU_NOC_LPI_CONTROL (CVP_WRAPPER_BASE_OFFS + 0x5C) +#define CVP_WRAPPER_CPU_NOC_LPI_STATUS (CVP_WRAPPER_BASE_OFFS + 0x60) #define CVP_WRAPPER_CORE_CLOCK_CONFIG (CVP_WRAPPER_BASE_OFFS + 0x88) #define CVP_CTRL_INIT CVP_CPU_CS_SCIACMD @@ -184,6 +186,7 @@ #define CVP_NOC_ERR_ERRLOG3_LOW_OFFS (CVP_NOC_BASE_OFFS + 0xB8) #define CVP_NOC_ERR_ERRLOG3_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0xBC) #define CVP_NOC_SBM_SENSELN0_LOW (CVP_NOC_BASE_OFFS + 0x300) +#define CVP_NOC_CPU_PENDING_MASK 0x3F80000 #define CVP_NOC_CORE_BASE_OFFS 0x00010000 #define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_LOW \ From 16375cefa47bb2097d0642acd5f87ac3c69de2e2 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Fri, 27 Aug 2021 19:32:56 -0700 Subject: [PATCH 084/317] msm: eva: reorder MMRM Dereg in release seq &cleanup re-order the mmrm deregister call in core release sequence; set eva mmrm client structure ptr to NULL after deregister; re-arrange the error handling code; in mmrm dereg check if clk enabled before call set value to 0, since already set value to 0 once when unprepare & disable clk. Change-Id: Ia89919e219ffda94a19b5214e91f1b3adc575086 Signed-off-by: Yu SI --- msm/eva/cvp_hfi.c | 21 ++++++++++++--------- msm/eva/msm_cvp_clocks.c | 4 +++- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 09670ae281..a0594f7395 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1796,7 +1796,7 @@ static int iris_hfi_core_init(void *device) if (rc) { dprintk(CVP_ERR, "failed to init queues\n"); rc = -ENOMEM; - goto err_mmrm_dereg; + goto err_core_init; } rc = msm_cvp_map_ipcc_regs(&ipcc_iova); @@ -1809,7 +1809,7 @@ static int iris_hfi_core_init(void *device) if (rc) { dprintk(CVP_ERR, "Failed to start core\n"); rc = -ENODEV; - goto err_mmrm_dereg; + goto err_core_init; } dev->version = __read_register(dev, CVP_VERSION_INFO); @@ -1817,12 +1817,12 @@ static int iris_hfi_core_init(void *device) rc = call_hfi_pkt_op(dev, sys_init, &pkt, 0); if (rc) { dprintk(CVP_ERR, "Failed to create sys init pkt\n"); - goto err_mmrm_dereg; + goto err_core_init; } if (__iface_cmdq_write(dev, &pkt)) { rc = -ENOTEMPTY; - goto err_mmrm_dereg; + goto err_core_init; } rc = call_hfi_pkt_op(dev, sys_image_version, &version_pkt); @@ -1848,11 +1848,14 @@ static int iris_hfi_core_init(void *device) dprintk(CVP_CORE, "Core inited successfully\n"); return 0; -err_mmrm_dereg: - msm_cvp_mmrm_deregister(dev); + err_core_init: __set_state(dev, IRIS_STATE_DEINIT); __unload_fw(dev); + if (dev->mmrm_cvp) + { + msm_cvp_mmrm_deregister(dev); + } err_load_fw: err_no_mem: dprintk(CVP_ERR, "Core init failed\n"); @@ -1882,6 +1885,9 @@ static int iris_hfi_core_release(void *dev) __dsp_shutdown(device, 0); + __disable_subcaches(device); + __unload_fw(device); + if (msm_cvp_mmrm_enabled) { rc = msm_cvp_mmrm_deregister(device); if (rc) { @@ -1891,9 +1897,6 @@ static int iris_hfi_core_release(void *dev) } } - __disable_subcaches(device); - __unload_fw(device); - /* unlink all sessions from device */ list_for_each_entry_safe(session, next, &device->sess_head, list) { list_del(&session->list); diff --git a/msm/eva/msm_cvp_clocks.c b/msm/eva/msm_cvp_clocks.c index 73d0c6f0f9..2ab9880412 100644 --- a/msm/eva/msm_cvp_clocks.c +++ b/msm/eva/msm_cvp_clocks.c @@ -116,7 +116,7 @@ int msm_cvp_mmrm_deregister(struct iris_hfi_device *device) /* set clk value to 0 before deregister */ iris_hfi_for_each_clock(device, cl) { - if (cl->has_scaling) { + if ((cl->has_scaling) && (__clk_is_enabled(cl->clk))){ // set min freq and cur freq to 0; rc = msm_cvp_mmrm_set_value_in_range(device, 0, 0); @@ -135,6 +135,8 @@ int msm_cvp_mmrm_deregister(struct iris_hfi_device *device) __func__, rc); } + device->mmrm_cvp = NULL; + return rc; } From e230150be8cfa6941258930b47c22f095c0c0d01 Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 7 Sep 2021 11:35:31 -0700 Subject: [PATCH 085/317] msm: eva: Check files pointer before accessing it There is a chance user process crashed when EVA is being used. In that case, files pointer is set to NULL by kernel. Add support of global timestamp support. Check wfi after pc ready. Change-Id: Id01d07a79beec03e48885dd051549b5c39bc4846 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 15 ++++++++++++--- msm/eva/msm_cvp_buf.c | 3 +++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index a0594f7395..4649e43a49 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -2492,8 +2492,16 @@ static int __power_collapse(struct iris_hfi_device *device, bool force) if (count == max_tries) { dprintk(CVP_ERR, - "Skip PC. Core is not in right state (%#x, %#x)\n", - wfi_status, pc_ready); + "Skip PC. Core is not ready (%#x, %#x)\n", + wfi_status, pc_ready); + goto skip_power_off; + } + } else { + wfi_status = __read_register(device, CVP_WRAPPER_CPU_STATUS); + if (!(wfi_status & BIT(0))) { + dprintk(CVP_WARN, + "Skip PC as wfi_status (%#x) bit not set\n", + wfi_status); goto skip_power_off; } } @@ -3771,7 +3779,8 @@ static int __iris_power_on(struct iris_hfi_device *device) dprintk(CVP_CORE, "Done with interrupt enabling\n"); device->intr_status = 0; enable_irq(device->cvp_hal_data->irq); - + __write_register(device, + CVP_WRAPPER_DEBUG_BRIDGE_LPI_CONTROL, 0x7); pr_info(CVP_DBG_TAG "cvp (eva) powered on\n", "pwr"); return 0; diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index eed7670272..04be53a6ea 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -185,6 +185,9 @@ static struct file *msm_cvp_fget(unsigned int fd, struct task_struct *task, struct files_struct *files = task->files; struct file *file; + if (!files) + return NULL; + rcu_read_lock(); loop: file = fcheck_files(files, fd); From f8342d4cf9bca7fdb8360c160fce59007de7d2a4 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 26 Aug 2021 11:19:56 -0700 Subject: [PATCH 086/317] msm: eva: Remove deprecated header Allows compiling independent of synx, fastrpc and mmrm readiness. Avoid including KP 2.0 deprecated headers. Change-Id: Ibf026f409b7f6284705c95b01a5251ac6a498b32 Signed-off-by: George Shen --- msm/eva/cvp_comm_def.h | 4 ++ msm/eva/cvp_hfi.h | 1 - msm/eva/msm_cvp.c | 8 +--- msm/eva/msm_cvp_buf.c | 5 +++ msm/eva/msm_cvp_buf.h | 1 - msm/eva/msm_cvp_clocks.c | 36 +++++++++++++++-- msm/eva/msm_cvp_common.c | 3 -- msm/eva/msm_cvp_core.c | 3 +- msm/eva/msm_cvp_core.h | 1 - msm/eva/msm_cvp_dsp.c | 41 +++++++++++++++---- msm/eva/msm_cvp_internal.h | 1 - msm/eva/msm_cvp_platform.c | 80 ++++++++++++++++++++++++++++++++++++- msm/eva/msm_cvp_resources.h | 1 + msm/eva/msm_cvp_synx.c | 26 +++++++++++- msm/eva/msm_cvp_synx.h | 48 ++++++++++++++++++++++ msm/eva/msm_smem.c | 38 ++++++++++++++++-- 16 files changed, 266 insertions(+), 31 deletions(-) diff --git a/msm/eva/cvp_comm_def.h b/msm/eva/cvp_comm_def.h index bb660e4f3b..7f86433adf 100644 --- a/msm/eva/cvp_comm_def.h +++ b/msm/eva/cvp_comm_def.h @@ -22,4 +22,8 @@ enum queue_state { QUEUE_STOP, QUEUE_INVALID, }; + +#define CVP_SYNX_ENABLED 1 +#define CVP_MMRM_ENABLED 1 +#define CVP_FASTRPC_ENABLED 1 #endif diff --git a/msm/eva/cvp_hfi.h b/msm/eva/cvp_hfi.h index 713c9e6209..0f1e943dfc 100644 --- a/msm/eva/cvp_hfi.h +++ b/msm/eva/cvp_hfi.h @@ -6,7 +6,6 @@ #ifndef __H_CVP_HFI_H__ #define __H_CVP_HFI_H__ -#include #include "cvp_hfi_helper.h" #include "cvp_hfi_api.h" #include "cvp_comm_def.h" diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index a2285c9110..94861b9707 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -1028,7 +1028,6 @@ int msm_cvp_session_delete(struct msm_cvp_inst *inst) int msm_cvp_session_create(struct msm_cvp_inst *inst) { int rc = 0; - struct synx_initialization_params params; struct cvp_session_queue *sq; if (!inst || !inst->core) @@ -1059,12 +1058,7 @@ int msm_cvp_session_create(struct msm_cvp_inst *inst) goto fail_init; } - params.name = "cvp-kernel-client"; - if (synx_initialize(&inst->synx_session_id, ¶ms)) { - dprintk(CVP_ERR, "%s synx_initialize failed\n", __func__); - rc = -EFAULT; - } - + cvp_sess_init_synx(inst); sq = &inst->session_queue; spin_lock(&sq->lock); sq->state = QUEUE_ACTIVE; diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 04be53a6ea..e18ac92ad4 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "msm_cvp_common.h" #include "cvp_hfi_api.h" #include "msm_cvp_debug.h" @@ -190,7 +191,11 @@ static struct file *msm_cvp_fget(unsigned int fd, struct task_struct *task, rcu_read_lock(); loop: +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 13, 0)) file = fcheck_files(files, fd); +#else + file = files_lookup_fd_rcu(files, fd); +#endif if (file) { /* File object ref couldn't be taken. * dup2() atomicity guarantee is the reason diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index 1eaef46154..3897816d01 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -10,7 +10,6 @@ #include #include #include -#include #include #include #include diff --git a/msm/eva/msm_cvp_clocks.c b/msm/eva/msm_cvp_clocks.c index 2ab9880412..ceb678522e 100644 --- a/msm/eva/msm_cvp_clocks.c +++ b/msm/eva/msm_cvp_clocks.c @@ -8,6 +8,36 @@ #include "msm_cvp_debug.h" #include "msm_cvp_clocks.h" +static struct mmrm_client *__mmrm_client_register( + struct mmrm_client_desc *client) +{ +#ifdef CVP_MMRM_ENABLED + return mmrm_client_register(client); +#else + return NULL; +#endif +} + +static int __mmrm_client_deregister(struct mmrm_client *client) +{ +#ifdef CVP_MMRM_ENABLED + return mmrm_client_deregister(client); +#else + return -ENODEV; +#endif +} + +static int __mmrm_client_set_value_in_range(struct mmrm_client *client, + struct mmrm_client_data *data, + struct mmrm_client_res_value *val) +{ +#ifdef CVP_MMRM_ENABLED + return mmrm_client_set_value_in_range(client, data, val); +#else + return -ENODEV; +#endif +} + int msm_cvp_mmrm_notifier_cb( struct mmrm_client_notifier_data *notifier_data) { @@ -85,7 +115,7 @@ int msm_cvp_mmrm_register(struct iris_hfi_device *device) __func__, device->mmrm_desc.client_info.desc.name, device->mmrm_desc.client_info.desc.client_id); - device->mmrm_cvp = mmrm_client_register(&(device->mmrm_desc)); + device->mmrm_cvp = __mmrm_client_register(&(device->mmrm_desc)); if (device->mmrm_cvp == NULL) { dprintk(CVP_ERR, "%s: Failed mmrm_client_register with mmrm_cvp: %pK\n", @@ -128,7 +158,7 @@ int msm_cvp_mmrm_deregister(struct iris_hfi_device *device) } } - rc = mmrm_client_deregister(device->mmrm_cvp); + rc = __mmrm_client_deregister(device->mmrm_cvp); if (rc) { dprintk(CVP_ERR, "%s: Failed mmrm_client_deregister with rc: %d\n", @@ -166,7 +196,7 @@ int msm_cvp_mmrm_set_value_in_range(struct iris_hfi_device *device, "%s: set clock rate to min %u cur %u: %d\n", __func__, val.min, val.cur, rc); - rc = mmrm_client_set_value_in_range(device->mmrm_cvp, &data, &val); + rc = __mmrm_client_set_value_in_range(device->mmrm_cvp, &data, &val); if (rc) { dprintk(CVP_ERR, "%s: Failed to set clock rate to min %u cur %u: %d\n", diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index b63c6c20e5..facb59d2e6 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -8,9 +8,6 @@ #include #include #include -#ifndef CVP_MDT_ENABLED -#include -#endif #include #include "msm_cvp_common.h" #include "cvp_hfi_api.h" diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 04bfd92627..5800cae815 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -15,7 +15,6 @@ #include "cvp_hfi_api.h" #include "msm_cvp_clocks.h" #include -#include #define MAX_EVENTS 30 #define NUM_CYCLES16X16_HCD_FRAME 95 @@ -343,7 +342,7 @@ int msm_cvp_destroy(struct msm_cvp_inst *inst) __deinit_session_queue(inst); __deinit_fence_queue(inst); - synx_uninitialize(inst->synx_session_id); + cvp_sess_deinit_synx(inst); pr_info(CVP_DBG_TAG "Closed cvp instance: %pK session_id = %d\n", "sess", inst, hash32_ptr(inst->session)); diff --git a/msm/eva/msm_cvp_core.h b/msm/eva/msm_cvp_core.h index 1b89622dd3..c00fd102f6 100644 --- a/msm/eva/msm_cvp_core.h +++ b/msm/eva/msm_cvp_core.h @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index f12ba7bbf5..b14b90b331 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -20,6 +20,33 @@ static int hlosVMperm[HLOS_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC }; static int cvp_reinit_dsp(void); +static int __fastrpc_driver_register(struct fastrpc_driver *driver) +{ +#ifdef CVP_FASTRPC_ENABLED + return fastrpc_driver_register(driver); +#else + return -ENODEV; +#endif +} + +static void __fastrpc_driver_unregister(struct fastrpc_driver *driver) +{ +#ifdef CVP_FASTRPC_ENABLED + return fastrpc_driver_unregister(driver); +#endif +} + +static int __fastrpc_driver_invoke(struct fastrpc_device *dev, + enum fastrpc_driver_invoke_nums invoke_num, + unsigned long invoke_param) +{ +#ifdef CVP_FASTRPC_ENABLED + return fastrpc_driver_invoke(dev, invoke_num, invoke_param); +#else + return -ENODEV; +#endif +} + static int cvp_dsp_send_cmd(struct cvp_dsp_cmd_msg *cmd, uint32_t len) { int rc = 0; @@ -83,7 +110,7 @@ static int cvp_dsp_send_cmd_hfi_queue(phys_addr_t *phys_addr, cmd.type = CPU2DSP_SEND_HFI_QUEUE; cmd.msg_ptr = (uint64_t)phys_addr; cmd.msg_ptr_len = size_in_bytes; - cmd.ddr_type = of_fdt_get_ddrtype(); + cmd.ddr_type = cvp_of_fdt_get_ddrtype(); if (cmd.ddr_type < 0) { dprintk(CVP_WARN, "%s: Incorrect DDR type value %d, use default %d\n", @@ -315,7 +342,7 @@ static void cvp_dsp_rpmsg_remove(struct rpmsg_device *rpdev) dprintk(CVP_DSP, "%s list_del fastrpc node 0x%x\n", __func__, frpc_node); list_del(&frpc_node->list); - fastrpc_driver_unregister( + __fastrpc_driver_unregister( &frpc_node->cvp_fastrpc_driver); dprintk(CVP_DSP, "%s Unregistered fastrpc handle 0x%x\n", @@ -866,7 +893,7 @@ static int eva_fastrpc_dev_map_dma(struct fastrpc_device *frpc_device, "%s frpc_map_buf size %d, dma_buf %pK, map %pK, 0x%x\n", __func__, frpc_map_buf.size, frpc_map_buf.buf, &frpc_map_buf, (unsigned long)&frpc_map_buf); - rc = fastrpc_driver_invoke(frpc_device, FASTRPC_DEV_MAP_DMA, + rc = __fastrpc_driver_invoke(frpc_device, FASTRPC_DEV_MAP_DMA, (unsigned long)(&frpc_map_buf)); if (rc) { dprintk(CVP_ERR, @@ -892,7 +919,7 @@ static int eva_fastrpc_dev_unmap_dma(struct fastrpc_device *frpc_device, /* Only if buffer is mapped to dsp */ if (buf->fd != 0) { frpc_unmap_buf.buf = buf->smem->dma_buf; - rc = fastrpc_driver_invoke(frpc_device, FASTRPC_DEV_UNMAP_DMA, + rc = __fastrpc_driver_invoke(frpc_device, FASTRPC_DEV_UNMAP_DMA, (unsigned long)(&frpc_unmap_buf)); if (rc) { dprintk(CVP_ERR, "%s Failed to unmap buffer 0x%x\n", @@ -1022,7 +1049,7 @@ static int eva_fastrpc_driver_register(uint32_t handle) INIT_MSM_CVP_LIST(&frpc_node->dsp_sessions); /* register fastrpc device to this session */ - rc = fastrpc_driver_register(&frpc_node->cvp_fastrpc_driver); + rc = __fastrpc_driver_register(&frpc_node->cvp_fastrpc_driver); if (rc) { dprintk(CVP_ERR, "%s fastrpc driver reg fail err %d\n", __func__, rc); @@ -1045,7 +1072,7 @@ static int eva_fastrpc_driver_register(uint32_t handle) return rc; fail_fastrpc_driver_timeout: - fastrpc_driver_unregister(&frpc_node->cvp_fastrpc_driver); + __fastrpc_driver_unregister(&frpc_node->cvp_fastrpc_driver); fail_fastrpc_driver_register: /* remove list if this is the last session */ mutex_lock(&me->fastrpc_driver_list.lock); @@ -1089,7 +1116,7 @@ static void eva_fastrpc_driver_unregister(uint32_t handle, bool force_exit) list_del(&frpc_node->list); mutex_unlock(&me->fastrpc_driver_list.lock); - fastrpc_driver_unregister(&frpc_node->cvp_fastrpc_driver); + __fastrpc_driver_unregister(&frpc_node->cvp_fastrpc_driver); mutex_lock(&me->driver_name_lock); eva_fastrpc_driver_release_name(frpc_node); mutex_unlock(&me->driver_name_lock); diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index d95a76b0c5..53da1544bc 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -20,7 +20,6 @@ #include #include #include "msm_cvp_core.h" -#include #include #include "cvp_hfi_api.h" #include "cvp_hfi_helper.h" diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 20c9702337..302f563951 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -99,6 +99,62 @@ static struct msm_cvp_common_data sm8450_common_data[] = { } }; +static struct msm_cvp_common_data sm8550_common_data[] = { + { + .key = "qcom,auto-pil", + .value = 0, + }, + { + .key = "qcom,never-unload-fw", + .value = 1, + }, + { + .key = "qcom,sw-power-collapse", + .value = 0, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 0, + }, + { + .key = "qcom,max-secure-instances", + .value = 2, /* + * As per design driver allows 3rd + * instance as well since the secure + * flags were updated later for the + * current instance. Hence total + * secure sessions would be + * max-secure-instances + 1. + */ + }, + { + .key = "qcom,max-ssr-allowed", + .value = 1, /* + * Maxinum number of SSR before BUG_ON + */ + }, + { + .key = "qcom,power-collapse-delay", + .value = 3000, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 2000, + }, + { + .key = "qcom,dsp-resp-timeout", + .value = 1000, + }, + { + .key = "qcom,debug-timeout", + .value = 0, + }, + { + .key = "qcom,dsp-enabled", + .value = 0, + } +}; + /* Default UBWC config for LPDDR5 */ @@ -123,12 +179,24 @@ static struct msm_cvp_platform_data sm8450_data = { .ubwc_config = kona_ubwc_data, }; +static struct msm_cvp_platform_data sm8550_data = { + .common_data = sm8550_common_data, + .common_data_length = ARRAY_SIZE(sm8550_common_data), + .sku_version = 0, + .vpu_ver = VPU_VERSION_5, + .ubwc_config = kona_ubwc_data, +}; static const struct of_device_id msm_cvp_dt_match[] = { { .compatible = "qcom,waipio-cvp", .data = &sm8450_data, }, + { + .compatible = "qcom,kailua-cvp", + .data = &sm8550_data, + }, + {}, }; @@ -394,6 +462,16 @@ int get_pkt_index(struct cvp_hal_session_cmd_pkt *hdr) MODULE_DEVICE_TABLE(of, msm_cvp_dt_match); +int cvp_of_fdt_get_ddrtype(void) +{ +#ifdef FIXED_DDR_TYPE + /* of_fdt_get_ddrtype() is usually unavailable during pre-sil */ + return DDR_TYPE_LPDDR5; +#else + return of_fdt_get_ddrtype(); +#endif +} + void *cvp_get_drv_data(struct device *dev) { struct msm_cvp_platform_data *driver_data; @@ -413,7 +491,7 @@ void *cvp_get_drv_data(struct device *dev) driver_data = (struct msm_cvp_platform_data *)match->data; if (!strcmp(match->compatible, "qcom,waipio-cvp")) { - ddr_type = of_fdt_get_ddrtype(); + ddr_type = cvp_of_fdt_get_ddrtype(); if (ddr_type == -ENOENT) { dprintk(CVP_ERR, "Failed to get ddr type, use LPDDR5\n"); diff --git a/msm/eva/msm_cvp_resources.h b/msm/eva/msm_cvp_resources.h index f5349b50dd..03940d3813 100644 --- a/msm/eva/msm_cvp_resources.h +++ b/msm/eva/msm_cvp_resources.h @@ -188,5 +188,6 @@ static inline bool is_iommu_present(struct msm_cvp_platform_resources *res) return !list_empty(&res->context_banks); } +int cvp_of_fdt_get_ddrtype(void); #endif diff --git a/msm/eva/msm_cvp_synx.c b/msm/eva/msm_cvp_synx.c index fb75f550d0..084e7300a4 100644 --- a/msm/eva/msm_cvp_synx.c +++ b/msm/eva/msm_cvp_synx.c @@ -9,6 +9,30 @@ #include "msm_cvp_core.h" #include "msm_cvp_dsp.h" +#ifdef CVP_SYNX_ENABLED +int cvp_sess_init_synx(struct msm_cvp_inst *inst) +{ + struct synx_initialization_params params; + + params.name = "cvp-kernel-client"; + if (synx_initialize(&inst->synx_session_id, ¶ms)) { + dprintk(CVP_ERR, "%s synx_initialize failed\n", __func__); + return -EFAULT; + } + + return 0; +} + +int cvp_sess_deinit_synx(struct msm_cvp_inst *inst) +{ + if (!inst) { + dprintk(CVP_ERR, "Used invalid sess in deinit_synx\n"); + return -EINVAL; + } + synx_uninitialize(inst->synx_session_id); + return 0; +} + void cvp_dump_fence_queue(struct msm_cvp_inst *inst) { struct cvp_fence_queue *q; @@ -242,4 +266,4 @@ int cvp_synx_ops(struct msm_cvp_inst *inst, enum cvp_synx_type type, return -EINVAL; } } - +#endif diff --git a/msm/eva/msm_cvp_synx.h b/msm/eva/msm_cvp_synx.h index 3f8c7d7b18..59c5c5ac65 100644 --- a/msm/eva/msm_cvp_synx.h +++ b/msm/eva/msm_cvp_synx.h @@ -44,6 +44,9 @@ enum cvp_synx_type { CVP_INVALID_SYNX, }; +#ifdef CVP_SYNX_ENABLED +int cvp_sess_init_synx(struct msm_cvp_inst *inst); +int cvp_sess_deinit_synx(struct msm_cvp_inst *inst); int cvp_import_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, u32 *fence); int cvp_release_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc); @@ -52,4 +55,49 @@ int cvp_cancel_synx(struct msm_cvp_inst *inst, enum cvp_synx_type type, int cvp_synx_ops(struct msm_cvp_inst *inst, enum cvp_synx_type type, struct cvp_fence_command *fc, u32 *synx_state); void cvp_dump_fence_queue(struct msm_cvp_inst *inst); +#else +static inline int cvp_sess_init_synx(struct msm_cvp_inst *inst) +{ + return -ENODEV; +} + +static inline int cvp_sess_deinit_synx(struct msm_cvp_inst *inst) +{ + return -ENODEV; +} + +static inline int cvp_import_synx(struct msm_cvp_inst *inst, + struct cvp_fence_command *fc, + u32 *fence) +{ + return -ENODEV; +} + +static inline int cvp_release_synx(struct msm_cvp_inst *inst, + struct cvp_fence_command *fc) +{ + return -ENODEV; +} + +static inline int cvp_cancel_synx(struct msm_cvp_inst *inst, + enum cvp_synx_type type, + struct cvp_fence_command *fc, + int synx_state) +{ + return -ENODEV; +} + +static inline int cvp_synx_ops(struct msm_cvp_inst *inst, + enum cvp_synx_type type, + struct cvp_fence_command *fc, + u32 *synx_state) +{ + return -ENODEV; +} + +static inline void cvp_dump_fence_queue(struct msm_cvp_inst *inst) +{ + return; +} +#endif #endif diff --git a/msm/eva/msm_smem.c b/msm/eva/msm_smem.c index d436603ff9..66a4dc8a67 100644 --- a/msm/eva/msm_smem.c +++ b/msm/eva/msm_smem.c @@ -8,19 +8,51 @@ #include #include #include -#include #include #include #include #include #include #include +#include #include "msm_cvp_core.h" #include "msm_cvp_debug.h" #include "msm_cvp_resources.h" #include "cvp_core_hfi.h" #include "msm_cvp_dsp.h" +static void * __cvp_dma_buf_vmap(struct dma_buf *dbuf) +{ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 13, 0)) + return dma_buf_vmap(dbuf); +#else + struct dma_buf_map map; + void *dma_map; + int err; + + err = dma_buf_vmap(dbuf, &map); + dma_map = err ? NULL : map.vaddr; + if (!dma_map) + dprintk(CVP_ERR, "map to kvaddr failed\n"); + + return dma_map; +#endif +} + +static void __cvp_dma_buf_vunmap(void *vaddr, struct dma_buf *dbuf) +{ +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 13, 0)) + dma_buf_vunmap(dbuf, vaddr); +#else + struct dma_buf_map map = { \ + .vaddr = vaddr, \ + .is_iomem = false, \ + }; + + if (vaddr) + dma_buf_vunmap(dbuf, &map); +#endif +} static int msm_dma_get_device_address(struct dma_buf *dbuf, u32 align, dma_addr_t *iova, u32 flags, struct msm_cvp_platform_resources *res, @@ -335,7 +367,7 @@ static int alloc_dma_mem(size_t size, u32 align, int map_kernel, if (map_kernel) { dma_buf_begin_cpu_access(dbuf, DMA_BIDIRECTIONAL); - mem->kvaddr = dma_buf_vmap(dbuf); + mem->kvaddr = __cvp_dma_buf_vmap(dbuf); if (!mem->kvaddr) { dprintk(CVP_ERR, "Failed to map shared mem in kernel\n"); @@ -371,7 +403,7 @@ static int free_dma_mem(struct msm_cvp_smem *mem) } if (mem->kvaddr) { - dma_buf_vunmap(mem->dma_buf, mem->kvaddr); + __cvp_dma_buf_vunmap(mem->dma_buf, mem->kvaddr); mem->kvaddr = NULL; dma_buf_end_cpu_access(mem->dma_buf, DMA_BIDIRECTIONAL); } From ac94467aa29c7e13b681c51a9cd9d77bf0b7bdea Mon Sep 17 00:00:00 2001 From: Sabharsh Sidhu Date: Fri, 10 Sep 2021 12:00:52 -0700 Subject: [PATCH 087/317] msm: eva: Increase MAX_HFI_FENCE_SIZE to 64 in uapi Increases max synx objects supported by eva_kmd_arg from 16/2=8 to 64/2=32. Change-Id: I8d893b829a6af5f1929298cc8562095f22b0c633 Signed-off-by: Sabharsh Sidhu --- include/uapi/eva/media/msm_eva_private.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/uapi/eva/media/msm_eva_private.h b/include/uapi/eva/media/msm_eva_private.h index 4ab350dde5..3950279133 100644 --- a/include/uapi/eva/media/msm_eva_private.h +++ b/include/uapi/eva/media/msm_eva_private.h @@ -179,8 +179,8 @@ struct eva_kmd_session_control { __u32 ctrl_data[8]; }; -#define MAX_HFI_FENCE_SIZE 16 -#define MAX_HFI_FENCE_OFFSET (MAX_HFI_PKT_SIZE-MAX_HFI_FENCE_SIZE) +#define MAX_HFI_FENCE_SIZE 64 +#define MAX_HFI_FENCE_OFFSET MAX_HFI_PKT_SIZE struct eva_kmd_hfi_fence_packet { __u32 pkt_data[MAX_HFI_FENCE_OFFSET]; __u32 fence_data[MAX_HFI_FENCE_SIZE]; From bc49527660af79eed1f57150d43557b3ce2eeda6 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 13 Sep 2021 10:27:58 -0700 Subject: [PATCH 088/317] msm: cvp: Avoid interrupting FW after WFI Flushing debug queue may trigger interrupt to FW. So flushing it before Tensilica going to WFI. Change-Id: I3b93183612439d5f499a30aadea18f0c2348ee13 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 4 ++-- msm/eva/msm_cvp_common.c | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 4649e43a49..c982d7efd6 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -2452,6 +2452,8 @@ static int __power_collapse(struct iris_hfi_device *device, bool force) else if (rc) goto skip_power_off; + __flush_debug_queue(device, device->raw_packet); + pc_ready = __read_register(device, CVP_CTRL_STATUS) & CVP_CTRL_STATUS_PC_READY; if (!pc_ready) { @@ -2506,8 +2508,6 @@ static int __power_collapse(struct iris_hfi_device *device, bool force) } } - __flush_debug_queue(device, device->raw_packet); - rc = __suspend(device); if (rc) dprintk(CVP_ERR, "Failed __suspend\n"); diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index facb59d2e6..73f7ec56ba 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -1315,8 +1315,9 @@ int msm_cvp_noc_error_info(struct msm_cvp_core *core) last_fault_count = core->smmu_fault_count; core->ssr_count++; - dprintk(CVP_ERR, "cvp ssr count %d %d\n", core->ssr_count, - core->resources.max_ssr_allowed); + dprintk(CVP_ERR, "cvp ssr count %d %d %d\n", core->ssr_count, + core->resources.max_ssr_allowed, + core->smmu_fault_count); hdev = core->device; call_hfi_op(hdev, noc_error_info, hdev->hfi_device_data); From b30be7e544f81bdc4e756bb07c8b1d24ac48dd32 Mon Sep 17 00:00:00 2001 From: Aniruddh Sharma Date: Wed, 28 Jul 2021 12:18:38 +0530 Subject: [PATCH 089/317] msm: eva: Minidump enablement for eva Enabled FW static dump. Enabled VA_MD for CMD and MSG queues, both for CPU and DSP. Enabled VA_MD for debug structs. Change-Id: I9a5a2418620cd0608b90301eefe0726a462c1ce3 Signed-off-by: Aniruddh Sharma --- msm/Kbuild | 1 + msm/Makefile | 1 + msm/eva/cvp_dump.c | 330 +++++++++++++++++++++++++++++++++++++ msm/eva/cvp_dump.h | 97 +++++++++++ msm/eva/cvp_fw_load.c | 6 + msm/eva/cvp_hfi.c | 9 + msm/eva/msm_cvp_debug.c | 2 + msm/eva/msm_cvp_debug.h | 1 + msm/eva/msm_cvp_dsp.c | 5 + msm/eva/msm_cvp_internal.h | 1 - 10 files changed, 452 insertions(+), 1 deletion(-) create mode 100644 msm/eva/cvp_dump.c create mode 100644 msm/eva/cvp_dump.h diff --git a/msm/Kbuild b/msm/Kbuild index f950634c31..39efb6ced9 100644 --- a/msm/Kbuild +++ b/msm/Kbuild @@ -23,6 +23,7 @@ msm-eva-objs := eva/cvp.o \ eva/msm_smem.o \ eva/msm_cvp_debug.o \ eva/msm_cvp_res_parse.o \ + eva/cvp_dump.o \ eva/cvp_hfi.o \ eva/hfi_response_handler.o \ eva/hfi_packetization.o \ diff --git a/msm/Makefile b/msm/Makefile index 8f1ec95c6f..620090032e 100644 --- a/msm/Makefile +++ b/msm/Makefile @@ -11,6 +11,7 @@ msm-eva-objs := eva/cvp.o \ eva/msm_smem.o \ eva/msm_cvp_debug.o \ eva/msm_cvp_res_parse.o \ + eva/cvp_dump.o \ eva/cvp_hfi.o \ eva/hfi_response_handler.o \ eva/hfi_packetization.o \ diff --git a/msm/eva/cvp_dump.c b/msm/eva/cvp_dump.c new file mode 100644 index 0000000000..d8c8cb1a4d --- /dev/null +++ b/msm/eva/cvp_dump.c @@ -0,0 +1,330 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hfi_packetization.h" +#include "msm_cvp_debug.h" +#include "cvp_core_hfi.h" +#include "cvp_hfi_helper.h" +#include "cvp_hfi_io.h" +#include "msm_cvp_dsp.h" +#include "msm_cvp_clocks.h" +#include "cvp_dump.h" + +/*Declare and init the head node of the linked list +for queue va_md dump*/ +LIST_HEAD(head_node_hfi_queue); + +/*Declare and init the head node of the linked list + for debug struct va_md dump*/ +LIST_HEAD(head_node_dbg_struct); + +int md_eva_dump(const char* name, u64 virt, u64 phys, u64 size) +{ + struct md_region md_entry; + if (msm_minidump_enabled()) + { + dprintk(CVP_INFO, "Minidump is enabled!\n"); + + // add minidump region for EVA-FW image + strlcpy(md_entry.name, name, sizeof(md_entry.name)); + md_entry.virt_addr = (uintptr_t)virt; + md_entry.phys_addr = phys; + md_entry.size = size; + if (msm_minidump_add_region(&md_entry) < 0) + { + dprintk(CVP_ERR, "Failed to add \"%s\" data in \ + Minidump\n", name); + return 1; + } + else + { + dprintk(CVP_INFO, + "add region success for \"%s\" with virt addr:\ + 0x%x, phy addr: 0x%x, size: %d", + md_entry.name, md_entry.virt_addr, + md_entry.phys_addr, md_entry.size); + return 0; + } + } + else + { + dprintk(CVP_ERR, "Minidump is NOT enabled!\n"); + return 1; + } +} + +void cvp_va_md_register(char* name, void* notf_blk_ptr) +{ + int rc = 0; + struct notifier_block* notf_blk = (struct notifier_block*)notf_blk_ptr; + rc = qcom_va_md_register(name, notf_blk); + if (rc) { + dprintk(CVP_ERR, + "\"%s\" : qcom_va_md_register failed rc = %d\n", + name, rc); + } + else { + dprintk(CVP_INFO, + "\"%s\" : eva_queue qcom_va_md_register success rc = %d\n", + name, rc); + } +} + +void cvp_register_va_md_region() +{ + if(qcom_va_md_enabled()) + { + cvp_va_md_register("eva_queues", &eva_hfiq_list_notif_blk); + cvp_va_md_register("dbg_struct", &eva_struct_list_notif_blk); + } + else + dprintk(CVP_ERR, "VA_Minidump is NOT enabled!\n"); +} + +void cvp_free_va_md_list(void) +{ + struct eva_va_md_queue *cursor, *temp; + + /* Iterate over each item of the hfi quesue va_md_list and add del the node */ + list_for_each_entry_safe(cursor, temp, &head_node_hfi_queue, list) + { + list_del(&cursor->list); + kfree(cursor); + } + + /* Iterate over each item of the hfi debug_struct + va_md_list and add del the node */ + list_for_each_entry_safe(cursor, temp, &head_node_dbg_struct, list) + { + list_del(&cursor->list); + kfree(cursor); + } +} + +void add_va_node_to_list(void *list_head_node, void *buff_va, u32 buff_size, + const char *region_name, bool copy) +{ + struct list_head *head_node = (struct list_head *)list_head_node; + struct eva_va_md_queue *temp_node = NULL; + /*Creating Node*/ + temp_node = kzalloc(sizeof(struct eva_va_md_queue), GFP_KERNEL); + if (!temp_node) + { + dprintk(CVP_ERR, "Memory allocation failed for list node\n"); + return; + } + + /*Init the list within the struct*/ + INIT_LIST_HEAD(&temp_node->list); + + /* Store back the data to linked list node data */ + temp_node->va_md_buff = buff_va; + temp_node->va_md_buff_size = buff_size; + strlcpy(temp_node->region_name, region_name, + sizeof(temp_node->region_name)); + temp_node->copy = copy; + + /*Add Node to Linked List*/ + list_add_tail(&temp_node->list, head_node); + dprintk(CVP_INFO, + "\"%s\" added to buffer list, vaddr: %px size: 0x%x\n", + temp_node->region_name, temp_node->va_md_buff, + temp_node->va_md_buff_size); +} + +void add_hfi_queue_to_va_md_list(void *device) +{ + struct cvp_iface_q_info *iface_q; + struct iris_hfi_device *dev; + + dev = (struct iris_hfi_device*)device; + + /* Adding CPU QUEUES*/ + iface_q = &dev->iface_queues[CVP_IFACEQ_CMDQ_IDX]; + add_va_node_to_list(&head_node_hfi_queue, + iface_q->q_array.align_virtual_addr, + iface_q->q_array.mem_size, + "eva_cmdq_cpu", false); + iface_q = &dev->iface_queues[CVP_IFACEQ_MSGQ_IDX]; + add_va_node_to_list(&head_node_hfi_queue, + iface_q->q_array.align_virtual_addr, + iface_q->q_array.mem_size, + "eva_msgq_cpu", false); + + /* Adding DSP QUEUES*/ + iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_CMDQ_IDX]; + add_va_node_to_list(&head_node_hfi_queue, + iface_q->q_array.align_virtual_addr, + iface_q->q_array.mem_size, + "eva_cmdq_dsp", false); + iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_MSGQ_IDX]; + add_va_node_to_list(&head_node_hfi_queue, + iface_q->q_array.align_virtual_addr, + iface_q->q_array.mem_size, + "eva_msgq_dsp", false); +} + +void add_queue_header_to_va_md_list(void *device) +{ + struct cvp_iface_q_info *iface_q; + struct iris_hfi_device *dev; + struct cvp_hfi_queue_header *queue; + + dev = (struct iris_hfi_device*)device; + + // Add node for cvp_hfi_queue_header: cpucmdQ + iface_q = &dev->iface_queues[CVP_IFACEQ_CMDQ_IDX]; + queue = (struct cvp_hfi_queue_header *)iface_q->q_hdr; + add_va_node_to_list(&head_node_dbg_struct, + queue, sizeof(struct cvp_hfi_queue_header), + "cvp_hfi_queue_header-cpucmdQ", false); + + // Add node for cvp_hfi_queue_header: cpumsgQ + iface_q = &dev->iface_queues[CVP_IFACEQ_MSGQ_IDX]; + queue = (struct cvp_hfi_queue_header *)iface_q->q_hdr; + add_va_node_to_list(&head_node_dbg_struct, + queue, sizeof(struct cvp_hfi_queue_header), + "cvp_hfi_queue_header-cpumsgQ", false); + + // Add node for cvp_hfi_queue_header: dspcmdQ + iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_CMDQ_IDX]; + queue = (struct cvp_hfi_queue_header *)iface_q->q_hdr; + add_va_node_to_list(&head_node_dbg_struct, + queue, sizeof(struct cvp_hfi_queue_header), + "cvp_hfi_queue_header-dspcmdQ", false); + + // Add node for cvp_hfi_queue_header: dspmsgQ + iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_MSGQ_IDX]; + queue = (struct cvp_hfi_queue_header *)iface_q->q_hdr; + add_va_node_to_list(&head_node_dbg_struct, + queue, sizeof(struct cvp_hfi_queue_header), + "cvp_hfi_queue_header-dspmsgQ", false); +} + +int eva_hfiq_list_notif_handler(struct notifier_block *this, + unsigned long event, void *ptr) +{ + struct va_md_entry entry; + struct eva_va_md_queue *cursor, *temp; + int rc = 0; + void *temp_data; + + /* Iterate over each item of the list and + add that data to va_md_entry */ + list_for_each_entry_safe(cursor, temp, &head_node_hfi_queue, list) + { + if(cursor->copy) + { + //Copying the content to local kzmalloc buffer... + dprintk(CVP_INFO, "Copying \"%s\"(%d Bytes)\ + to intermediate buffer\n", + cursor->region_name, cursor->va_md_buff_size); + temp_data = kzalloc(cursor->va_md_buff_size, + GFP_KERNEL); + memcpy(temp_data, cursor->va_md_buff, + cursor->va_md_buff_size); + + entry.vaddr = (unsigned long)temp_data; + } + else + entry.vaddr = (unsigned long)cursor->va_md_buff; + entry.size = cursor->va_md_buff_size; + strlcpy(entry.owner, cursor->region_name, sizeof(entry.owner)); + entry.cb = NULL; + + if(msm_cvp_minidump_enable) + { + rc = qcom_va_md_add_region(&entry); + if(rc) + dprintk(CVP_ERR, "Add region \"failed\" for \ + \"%s\", vaddr: %px size: 0x%x\n", entry.owner, + cursor->va_md_buff, entry.size); + else + dprintk(CVP_INFO, "Add region \"success\" for \ + \"%s\", vaddr: %px size: 0x%x\n", entry.owner, + cursor->va_md_buff, entry.size); + } + } + return NOTIFY_OK; +} + +int eva_struct_list_notif_handler(struct notifier_block *this, + unsigned long event, void *ptr) +{ + struct va_md_entry entry; + struct eva_va_md_queue *cursor, *temp; + int rc = 0; + void *temp_data; + + /* Iterate over each item of the list + and add that data to va_md_entry */ + list_for_each_entry_safe(cursor, temp, &head_node_dbg_struct, list) + { + if(cursor->copy) + { + //Copying the content to local kzmalloc buffer... + dprintk(CVP_INFO, "Copying \"%s\"(%d Bytes) to \ + intermediate buffer\n", cursor->region_name, + cursor->va_md_buff_size); + temp_data = kzalloc(cursor->va_md_buff_size, + GFP_KERNEL); + memcpy(temp_data, cursor->va_md_buff, + cursor->va_md_buff_size); + + entry.vaddr = (unsigned long)temp_data; + } + else + entry.vaddr = (unsigned long)cursor->va_md_buff; + entry.size = cursor->va_md_buff_size; + strlcpy(entry.owner, cursor->region_name, sizeof(entry.owner)); + entry.cb = NULL; + + if(msm_cvp_minidump_enable) + { + rc = qcom_va_md_add_region(&entry); + if(rc) + dprintk(CVP_ERR, "Add region \"failed\" for \ + \"%s\", vaddr: %px size: 0x%x\n", + entry.owner, cursor->va_md_buff, + entry.size); + else + dprintk(CVP_INFO, "Add region \"success\" for \ + \"%s\", vaddr: %px size: 0x%x\n", entry.owner, + cursor->va_md_buff, entry.size); + } + } + return NOTIFY_OK; +} + +struct notifier_block eva_struct_list_notif_blk = { + .notifier_call = eva_struct_list_notif_handler, + .priority = INT_MAX-1, +}; + +struct notifier_block eva_hfiq_list_notif_blk = { + .notifier_call = eva_hfiq_list_notif_handler, + .priority = INT_MAX, +}; diff --git a/msm/eva/cvp_dump.h b/msm/eva/cvp_dump.h new file mode 100644 index 0000000000..d1679e0b4a --- /dev/null +++ b/msm/eva/cvp_dump.h @@ -0,0 +1,97 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2021, The Linux Foundation. All rights reserved. + */ + +#ifndef __H_CVP_MINIDUMP_H__ +#define __H_CVP_MINIDUMP_H__ + +#include +#include +#include + +#define MAX_REGION_NAME_LEN 32 +#define EVAFW_IMAGE_SIZE 7*1024*1024 + +extern struct list_head head_node_hfi_queue; +extern struct list_head head_node_dbg_struct; +extern struct notifier_block eva_hfiq_list_notif_blk; +extern struct notifier_block eva_struct_list_notif_blk; + +/* notifier handler function for list of eva hfi queues */ +int eva_hfiq_list_notif_handler(struct notifier_block *this, + unsigned long event, void *ptr); + +/* notifier handler function for list of eva global structures */ +int eva_struct_list_notif_handler(struct notifier_block *this, + unsigned long event, void *ptr); + +/* + * wrapper for static minidump + + * @name: Dump will be collected with this name + * @virt: Virtual address of the buffer which needs to be dumped + * @phys: Physical address of the buffer which needs to be dumped + * @size: Size of the buffer which needs to be dumped +*/ +int md_eva_dump(const char* name, u64 virt, u64 phys, u64 size); + +/* + * Fucntion to add dump region to queue + + * @list_head_node: Head node of the list which needs to be updated + * @buff_va: Virtual address of the buffer which needs to be dumped + * @buff_size: Size of the buffer which needs to be dumped + * @region_name: Dump will be collected with this name + * @copy: Flag to indicate if the buffer data needs to be copied + * to the intermidiate buffer allocated by kzmalloc. +*/ +void add_va_node_to_list(void *list_head_node, void *buff_va, + u32 buff_size, const char *region_name, bool copy); + +/* + * Registers subsystem to minidump driver + + * @name: Subsytem name which will get registered + * @notf_blk_ptr: notifier block pointer. + * notifier_call mentioned in this block will be triggered by + * minidump driver in case of crash +*/ +void cvp_va_md_register(char *name, void* notf_blk_ptr); + +/* One function where we will register all the regions */ +void cvp_register_va_md_region(void); + +/* + * Free up the memory allocated for different va_md_list + * Do not forget to add code for any new list in this function +*/ +void cvp_free_va_md_list(void); + +/* Adds the HFI queues(both for CPU and DSP) to the global hfi list head*/ +void add_hfi_queue_to_va_md_list(void *device); + +/*Add queue header structures(both for CPU and DSP) +to the global struct list head*/ +void add_queue_header_to_va_md_list(void *device); + +/* + * Node structure for VA_MD Linked List + + * @list: linux kernel list implementation + * @va_md_buff: Virtual address of the buffer which needs to be dumped + * @va_md_buff_size: Size of the buffer which needs to be dumped + * @region_name: Dump will be collected with this name + * @copy: Flag to indicate if the buffer data needs to be copied + * to the intermidiate buffer allocated by kzmalloc. +*/ +struct eva_va_md_queue +{ + struct list_head list; + void *va_md_buff; + u32 va_md_buff_size; + char region_name[MAX_REGION_NAME_LEN]; + bool copy; +}; + +#endif \ No newline at end of file diff --git a/msm/eva/cvp_fw_load.c b/msm/eva/cvp_fw_load.c index 85c825684f..0a3840ce41 100644 --- a/msm/eva/cvp_fw_load.c +++ b/msm/eva/cvp_fw_load.c @@ -14,6 +14,7 @@ #include #include #include +#include "cvp_dump.h" #define MAX_FIRMWARE_NAME_SIZE 128 @@ -104,6 +105,11 @@ static int __load_fw_to_memory(struct platform_device *pdev, __func__, rc, firmware_name); goto exit; } + rc = md_eva_dump("evafwdata", (uintptr_t)virt, phys, EVAFW_IMAGE_SIZE); + if (rc) { + dprintk(CVP_ERR, "%s: error %d in dumping \"%s\"\n", + __func__, rc, firmware_name); + } memunmap(virt); release_firmware(firmware); diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index c982d7efd6..4ea32f2438 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -30,6 +30,7 @@ #include "cvp_hfi_io.h" #include "msm_cvp_dsp.h" #include "msm_cvp_clocks.h" +#include "cvp_dump.h" #define FIRMWARE_SIZE 0X00A00000 #define REG_ADDR_OFFSET_BITMASK 0x000FFFFF @@ -1798,6 +1799,13 @@ static int iris_hfi_core_init(void *device) rc = -ENOMEM; goto err_core_init; } + cvp_register_va_md_region(); + + // Add node for dev struct + add_va_node_to_list(&head_node_dbg_struct, dev, + sizeof(struct iris_hfi_device), "iris_hfi_device-dev", false); + add_queue_header_to_va_md_list((void*)dev); + add_hfi_queue_to_va_md_list((void*)dev); rc = msm_cvp_map_ipcc_regs(&ipcc_iova); if (!rc) { @@ -1941,6 +1949,7 @@ static int iris_hfi_core_trigger_ssr(void *device, int rc = 0; struct iris_hfi_device *dev; + cvp_free_va_md_list(); if (!device) { dprintk(CVP_ERR, "invalid device\n"); return -ENODEV; diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 4bf257418a..aab0b64e88 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -30,6 +30,7 @@ bool msm_cvp_syscache_disable = !true; bool msm_cvp_dsp_disable = !true; bool msm_cvp_mmrm_enabled = true; bool msm_cvp_dcvs_disable = !true; +int msm_cvp_minidump_enable = !1; #define MAX_DBG_BUF_SIZE 4096 @@ -247,6 +248,7 @@ struct dentry *msm_cvp_debugfs_init_drv(void) debugfs_create_u32("fw_low_power_mode", 0644, dir, &msm_cvp_fw_low_power_mode); debugfs_create_u32("debug_output", 0644, dir, &msm_cvp_debug_out); + debugfs_create_u32("minidump_enable", 0644, dir, &msm_cvp_minidump_enable); f = debugfs_create_bool("fw_coverage", 0644, dir, &msm_cvp_fw_coverage); if (IS_ERR_OR_NULL(f)) goto failed_create_dir; diff --git a/msm/eva/msm_cvp_debug.h b/msm/eva/msm_cvp_debug.h index 23912b9023..e9f8df605b 100644 --- a/msm/eva/msm_cvp_debug.h +++ b/msm/eva/msm_cvp_debug.h @@ -65,6 +65,7 @@ extern bool msm_cvp_syscache_disable; extern bool msm_cvp_dsp_disable; extern bool msm_cvp_mmrm_enabled; extern bool msm_cvp_dcvs_disable; +extern int msm_cvp_minidump_enable; #define dprintk(__level, __fmt, arg...) \ do { \ diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index b14b90b331..e4fc319215 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -10,6 +10,7 @@ #include "msm_cvp_core.h" #include "msm_cvp.h" #include "cvp_hfi.h" +#include "cvp_dump.h" struct cvp_dsp_apps gfa_cv; static int hlosVM[HLOS_VM_NUM] = {VMID_HLOS}; @@ -1915,6 +1916,10 @@ int cvp_dsp_device_init(void) int i; char name[CVP_FASTRPC_DRIVER_NAME_SIZE] = "qcom,fastcv0\0"; + add_va_node_to_list(&head_node_dbg_struct, + &gfa_cv, sizeof(struct cvp_dsp_apps), + "cvp_dsp_apps-gfa_cv", false); + mutex_init(&me->tx_lock); mutex_init(&me->rx_lock); me->state = DSP_INVALID; diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index 53da1544bc..ef94cd4724 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -26,7 +26,6 @@ #include #define MAX_SUPPORTED_INSTANCES 16 -#define MAX_NAME_LENGTH 64 #define MAX_DEBUGFS_NAME 50 #define MAX_DSP_INIT_ATTEMPTS 16 #define FENCE_WAIT_SIGNAL_TIMEOUT 100 From f8e8640ce2340aacc1bc246eddc449132489e6ae Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 15 Sep 2021 14:09:57 -0700 Subject: [PATCH 090/317] msm: eva: Add NoC QoS setting The setting will be target specific and used to set correct priority of EVA DDR traffic. Change-Id: I165a761393bf9dfb4ef08482d1439959cd46baa4 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 22 ++++++++++++++++++++-- msm/eva/cvp_hfi_io.h | 15 +++++++++++++-- msm/eva/msm_cvp_internal.h | 10 ++++++++++ msm/eva/msm_cvp_platform.c | 11 +++++++++++ 4 files changed, 54 insertions(+), 4 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 4ea32f2438..2a13a4cc9a 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -745,6 +745,8 @@ static int __read_register(struct iris_hfi_device *device, u32 reg) static void __set_registers(struct iris_hfi_device *device) { + struct msm_cvp_core *core; + struct msm_cvp_platform_data *pdata; struct reg_set *reg_set; int i; @@ -754,6 +756,9 @@ static void __set_registers(struct iris_hfi_device *device) return; } + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + pdata = core->platform_data; + reg_set = &device->res->reg_set; for (i = 0; i < reg_set->count; i++) { __write_register(device, reg_set->reg_tbl[i].reg, @@ -762,6 +767,19 @@ static void __set_registers(struct iris_hfi_device *device) reg_set->reg_tbl[i].reg, reg_set->reg_tbl[i].value); } + + __write_register(device, CVP_CPU_CS_AXI4_QOS, + pdata->noc_qos->axi_qos); + __write_register(device, CVP_NOC_PRIORITYLUT_LOW, + pdata->noc_qos->prioritylut_low); + __write_register(device, CVP_NOC_PRIORITYLUT_HIGH, + pdata->noc_qos->prioritylut_high); + __write_register(device, CVP_NOC_URGENCY_LOW, + pdata->noc_qos->urgency_low); + __write_register(device, CVP_NOC_DANGERLUT_LOW, + pdata->noc_qos->dangerlut_low); + __write_register(device, CVP_NOC_SAFELUT_LOW, + pdata->noc_qos->safelut_low); } /* @@ -3889,11 +3907,11 @@ static int __power_off_controller(struct iris_hfi_device *device) __write_register(device, CVP_CPU_CS_X2RPMh, 0x3); /* HPG 6.2.2 Step 2, noc to low power */ - __write_register(device, CVP_AON_WRAPPER_MVP_NOC_LPI_CONTROL, 0x1); + __write_register(device, CVP_AON_WRAPPER_CVP_NOC_LPI_CONTROL, 0x1); while (!reg_status && count < max_count) { lpi_status = __read_register(device, - CVP_AON_WRAPPER_MVP_NOC_LPI_STATUS); + CVP_AON_WRAPPER_CVP_NOC_LPI_STATUS); reg_status = lpi_status & BIT(0); /* Wait for Core noc lpi status to be set */ usleep_range(50, 100); diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index 67bcc5cf34..2dc935278a 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -24,6 +24,7 @@ #define CVP_CPU_CS_VMIMSGAG2 (CVP_CPU_BASE_OFFS + 0x40) #define CVP_CPU_CS_VMIMSGAG3 (CVP_CPU_BASE_OFFS + 0x44) #define CVP_CPU_CS_SCIACMD (CVP_CPU_BASE_OFFS + 0x48) +#define CVP_CPU_CS_AXI4_QOS (CVP_CPU_BASE_OFFS + 0x13C) #define CVP_CPU_CS_H2XSOFTINTEN (CVP_CPU_BASE_OFFS + 0x148) /* CVP_CTRL_STATUS */ @@ -221,14 +222,24 @@ (CVP_NOC_CORE_BASE_OFFS + 0x1238) #define CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS \ (CVP_NOC_CORE_BASE_OFFS + 0x123C) +#define CVP_NOC_PRIORITYLUT_LOW \ + (CVP_NOC_CORE_BASE_OFFS + 0x3030) +#define CVP_NOC_PRIORITYLUT_HIGH \ + (CVP_NOC_CORE_BASE_OFFS + 0x3034) +#define CVP_NOC_URGENCY_LOW \ + (CVP_NOC_CORE_BASE_OFFS + 0x3038) +#define CVP_NOC_DANGERLUT_LOW \ + (CVP_NOC_CORE_BASE_OFFS + 0x3040) +#define CVP_NOC_SAFELUT_LOW \ + (CVP_NOC_CORE_BASE_OFFS + 0x3048) #define CVP_NOC_RESET_REQ \ (CVP_NOC_CORE_BASE_OFFS + 0xf000) #define CVP_NOC_RESET_ACK \ (CVP_NOC_CORE_BASE_OFFS + 0xf004) -#define CVP_AON_WRAPPER_MVP_NOC_LPI_CONTROL (CVP_AON_BASE_OFFS) -#define CVP_AON_WRAPPER_MVP_NOC_LPI_STATUS (CVP_AON_BASE_OFFS + 0x4) +#define CVP_AON_WRAPPER_CVP_NOC_LPI_CONTROL (CVP_AON_BASE_OFFS + 0x8) +#define CVP_AON_WRAPPER_CVP_NOC_LPI_STATUS (CVP_AON_BASE_OFFS + 0xC) #define CVP_CC_BASE_OFFS 0x000F8000 #define CVP_CC_MVS1C_GDSCR (CVP_CC_BASE_OFFS + 0x74) diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index ef94cd4724..6938886965 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -121,12 +121,22 @@ struct msm_cvp_ubwc_config_data { u32 bank_spreading; }; +struct msm_cvp_qos_setting { + u32 axi_qos; + u32 prioritylut_low; + u32 prioritylut_high; + u32 urgency_low; + u32 dangerlut_low; + u32 safelut_low; +}; + struct msm_cvp_platform_data { struct msm_cvp_common_data *common_data; unsigned int common_data_length; unsigned int sku_version; uint32_t vpu_ver; struct msm_cvp_ubwc_config_data *ubwc_config; + struct msm_cvp_qos_setting *noc_qos; }; struct msm_cvp_drv { diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 302f563951..d4176f81ad 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -162,6 +162,14 @@ static struct msm_cvp_ubwc_config_data kona_ubwc_data[] = { UBWC_CONFIG(1, 1, 1, 0, 0, 0, 8, 32, 16, 0, 0), }; +static struct msm_cvp_qos_setting waipio_noc_qos = { + .axi_qos = 0x99, + .prioritylut_low = 0x22222222, + .prioritylut_high = 0x33333333, + .urgency_low = 0x1022, + .dangerlut_low = 0x0, + .safelut_low = 0xffff, +}; static struct msm_cvp_platform_data default_data = { .common_data = default_common_data, @@ -169,6 +177,7 @@ static struct msm_cvp_platform_data default_data = { .sku_version = 0, .vpu_ver = VPU_VERSION_5, .ubwc_config = 0x0, + .noc_qos = 0x0, }; static struct msm_cvp_platform_data sm8450_data = { @@ -177,6 +186,7 @@ static struct msm_cvp_platform_data sm8450_data = { .sku_version = 0, .vpu_ver = VPU_VERSION_5, .ubwc_config = kona_ubwc_data, + .noc_qos = &waipio_noc_qos, }; static struct msm_cvp_platform_data sm8550_data = { @@ -185,6 +195,7 @@ static struct msm_cvp_platform_data sm8550_data = { .sku_version = 0, .vpu_ver = VPU_VERSION_5, .ubwc_config = kona_ubwc_data, + .noc_qos = 0x0, }; static const struct of_device_id msm_cvp_dt_match[] = { From daca0bb70e3fdd2b921e29deaa945ae3fd89d9fd Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 17 Sep 2021 09:55:21 -0700 Subject: [PATCH 091/317] msm: eva: Fixed dma_buf_vunmap failure Use correct function signature. Change-Id: I2975598e7366bf3a7387652f030009084a8602ff Signed-off-by: George Shen --- msm/eva/msm_smem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/msm_smem.c b/msm/eva/msm_smem.c index 66a4dc8a67..d91625f7c2 100644 --- a/msm/eva/msm_smem.c +++ b/msm/eva/msm_smem.c @@ -39,7 +39,7 @@ static void * __cvp_dma_buf_vmap(struct dma_buf *dbuf) #endif } -static void __cvp_dma_buf_vunmap(void *vaddr, struct dma_buf *dbuf) +static void __cvp_dma_buf_vunmap(struct dma_buf *dbuf, void *vaddr) { #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 13, 0)) dma_buf_vunmap(dbuf, vaddr); From d20d1298e2d0fbc99171171c2e1f069a7276d23e Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 14 Sep 2021 10:56:00 -0700 Subject: [PATCH 092/317] msm: eva: reset AXI and CTRL clocks Avoid pending transaction after EVA is power off. The transactions may be introduced by PDX FIFO CX side pointer not reset after EVA power collapsed. PMU can turn on AXI clock on CX side. It may trigger spurious DDR transactions that are abnormal, in our case, the write transaction has header, but not data. Change-Id: I1374aa5ddf64ecc56c6c806cf096bed2761fd9a7 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 26 +++++++++++++++++++------- msm/eva/msm_cvp_resources.h | 2 +- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 2a13a4cc9a..48022e2818 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -3072,7 +3072,8 @@ static int __handle_reset_clk(struct msm_cvp_platform_resources *res, goto failed_to_reset; } - if (pwr_state != rst_info.required_state) + if (pwr_state != CVP_POWER_IGNORED && + pwr_state != rst_info.required_state) break; rc = reset_control_assert(rst); @@ -3083,7 +3084,8 @@ static int __handle_reset_clk(struct msm_cvp_platform_resources *res, goto failed_to_reset; } - if (pwr_state != rst_info.required_state) + if (pwr_state != CVP_POWER_IGNORED && + pwr_state != rst_info.required_state) break; rc = reset_control_deassert(rst); @@ -3117,6 +3119,8 @@ static int reset_ahb2axi_bridge(struct iris_hfi_device *device) else s = CVP_POWER_OFF; + s = CVP_POWER_IGNORED; + for (i = 0; i < device->res->reset_set.count; i++) { rc = __handle_reset_clk(device->res, i, ASSERT, s); if (rc) { @@ -3124,10 +3128,12 @@ static int reset_ahb2axi_bridge(struct iris_hfi_device *device) "failed to assert reset clocks\n"); goto failed_to_reset; } + } - /* wait for deassert */ - usleep_range(1000, 1050); + /* wait for deassert */ + usleep_range(1000, 1050); + for (i = 0; i < device->res->reset_set.count; i++) { rc = __handle_reset_clk(device->res, i, DEASSERT, s); if (rc) { dprintk(CVP_ERR, @@ -3902,6 +3908,7 @@ static int __power_off_controller(struct iris_hfi_device *device) { u32 lpi_status, reg_status = 0, count = 0, max_count = 1000; u32 sbm_ln0_low; + int rc; /* HPG 6.2.2 Step 1 */ __write_register(device, CVP_CPU_CS_X2RPMh, 0x3); @@ -3988,12 +3995,17 @@ static int __power_off_controller(struct iris_hfi_device *device) /* HPG 6.2.2 Step 5 */ msm_cvp_disable_unprepare_clk(device, "cvp_clk"); - /* HPG 6.2.2 Step 6 */ - __disable_regulator(device, "cvp"); - /* HPG 6.2.2 Step 7 */ msm_cvp_disable_unprepare_clk(device, "gcc_video_axi1"); + /* Added to avoid pending transaction after power off */ + rc = call_iris_op(device, reset_ahb2axi_bridge, device); + if (rc) + dprintk(CVP_ERR, "Off: Failed to reset ahb2axi: %d\n", rc); + + /* HPG 6.2.2 Step 6 */ + __disable_regulator(device, "cvp"); + return 0; } diff --git a/msm/eva/msm_cvp_resources.h b/msm/eva/msm_cvp_resources.h index 03940d3813..9c8840e6fb 100644 --- a/msm/eva/msm_cvp_resources.h +++ b/msm/eva/msm_cvp_resources.h @@ -88,7 +88,7 @@ enum power_state { CVP_POWER_INIT, CVP_POWER_ON, CVP_POWER_OFF, - CVP_POWER_INVALID, + CVP_POWER_IGNORED, }; struct reset_info { From 0e72292d7132f89a67e4d21eecc96b8b9b4e8228 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 20 Sep 2021 13:55:19 -0700 Subject: [PATCH 093/317] msm: eva: Avoid dereference NULL smem Check and return error in case of NULL smem. Change-Id: I0f1f6a0746fe2110e0f5f306c22133caba6f2d63 Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 19 ++++++++++++++----- msm/eva/msm_cvp_buf.h | 2 +- msm/eva/msm_cvp_common.c | 10 +++++----- msm/eva/msm_cvp_res_parse.c | 2 ++ 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index e18ac92ad4..aa7430cced 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -33,11 +33,17 @@ } while (0) -void print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, +int print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, struct msm_cvp_smem *smem) { - if (!(tag & msm_cvp_debug) || !inst || !smem) - return; + if (!(tag & msm_cvp_debug)) + return 0; + + if (!inst || !smem) { + dprintk(CVP_ERR, "Invalid inst 0x%llx or smem 0x%llx\n", + inst, smem); + return -EINVAL; + } if (smem->dma_buf) { dprintk(tag, @@ -46,6 +52,7 @@ void print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, smem->size, smem->flags, smem->device_addr, smem->bitmap_index, smem->refcount); } + return 0; } static void print_internal_buffer(u32 tag, const char *str, @@ -78,7 +85,9 @@ void print_cvp_buffer(u32 tag, const char *str, struct msm_cvp_inst *inst, static void _log_smem(struct inst_snapshot *snapshot, struct msm_cvp_inst *inst, struct msm_cvp_smem *smem, bool logging) { - print_smem(CVP_ERR, "bufdump", inst, smem); + + if (print_smem(CVP_ERR, "bufdump", inst, smem)) + return; if (!logging || !snapshot) return; if (snapshot && snapshot->smem_index < MAX_ENTRIES) { @@ -941,7 +950,7 @@ void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) "---Buffer details for inst: %pK of type: %d---\n", inst, inst->session_type); mutex_lock(&inst->dma_cache.lock); - dprintk(CVP_ERR, "dma cache:\n"); + dprintk(CVP_ERR, "dma cache: %d\n", inst->dma_cache.nr); if (inst->dma_cache.nr <= MAX_DMABUF_NUMS) for (i = 0; i < inst->dma_cache.nr; i++) _log_smem(snap, inst, inst->dma_cache.entries[i], log); diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index 3897816d01..703b45b1e1 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -146,7 +146,7 @@ void print_cvp_buffer(u32 tag, const char *str, void print_client_buffer(u32 tag, const char *str, struct msm_cvp_inst *inst, struct eva_kmd_buffer *cbuf); -void print_smem(u32 tag, const char *str, +int print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, struct msm_cvp_smem *smem); diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 73f7ec56ba..f52dfaaf35 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -646,7 +646,11 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) cur_state = core->state; core->state = CVP_CORE_UNINIT; dprintk(CVP_WARN, "SYS_ERROR received for core %pK\n", core); - msm_cvp_noc_error_info(core); + if (response->status == CVP_ERR_NOC_ERROR) { + dprintk(CVP_WARN, "Got NOC error"); + msm_cvp_noc_error_info(core); + MSM_CVP_ERROR(true); + } call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data); list_for_each_entry(inst, &core->instances, list) { dprintk(CVP_WARN, @@ -672,10 +676,6 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) /* handle the hw error before core released to get full debug info */ msm_cvp_handle_hw_error(core); - if (response->status == CVP_ERR_NOC_ERROR) { - dprintk(CVP_WARN, "Got NOC error"); - MSM_CVP_ERROR(true); - } dprintk(CVP_CORE, "Calling core_release\n"); rc = call_hfi_op(hdev, core_release, hdev->hfi_device_data); diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index 5999ce941c..86288e90e9 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -962,6 +962,8 @@ int msm_cvp_smmu_fault_handler(struct iommu_domain *domain, } core->smmu_fault_count++; + if (!core->last_fault_addr) + core->last_fault_addr = iova; dprintk(CVP_ERR, "%s - faulting address: %lx, %d\n", __func__, iova, core->smmu_fault_count); From bcde27147a74ceecaa11e7ada6a2586a17228d88 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 22 Sep 2021 10:39:52 -0700 Subject: [PATCH 094/317] msm: eva: Flush DSP frames at session close Without the fix, there is chance ARP buffer was accessed after it's unmapped in the cases DSP PD is killed unexpectedly. Change-Id: I3480120ce95b7cde0aac5ac95f0e369e6da8ba87 Signed-off-by: George Shen --- msm/eva/msm_cvp_core.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 5800cae815..a25733f0e3 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -279,9 +279,25 @@ static void msm_cvp_cleanup_instance(struct msm_cvp_inst *inst) sqf = &inst->session_queue_fence; sq = &inst->session_queue; - max_retries = inst->core->resources.msm_cvp_hw_rsp_timeout >> 1; + max_retries = inst->core->resources.msm_cvp_hw_rsp_timeout >> 5; msm_cvp_session_queue_stop(inst); +wait_dsp: + mutex_lock(&inst->cvpdspbufs.lock); + empty = list_empty(&inst->cvpdspbufs.list); + if (!empty && max_retries > 0) { + mutex_unlock(&inst->cvpdspbufs.lock); + usleep_range(1000, 2000); + max_retries--; + goto wait_dsp; + } + mutex_unlock(&inst->cvpdspbufs.lock); + + if (!empty) + dprintk(CVP_WARN, "Failed flush DSP frame retried %d\n", + (inst->core->resources.msm_cvp_hw_rsp_timeout >> 5) + - max_retries); + max_retries = inst->core->resources.msm_cvp_hw_rsp_timeout >> 1; wait: mutex_lock(&inst->frames.lock); empty = list_empty(&inst->frames.list); From 61ea9c1a38dc327d03bdf98f8edc2ea9da26ac57 Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 21 Sep 2021 13:42:07 -0700 Subject: [PATCH 095/317] msm: eva: Do not allow suspend during fw loading Use kernel power management API to block suspend during fw loading. Change-Id: I28e0c658d148ddf2bdb971b6a07242e1f1ff9a3c Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 48022e2818..15b6b613d9 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "hfi_packetization.h" #include "msm_cvp_debug.h" #include "cvp_core_hfi.h" @@ -1786,6 +1787,7 @@ static int iris_hfi_core_init(void *device) goto err_no_mem; } + pm_stay_awake(dev->res->pdev->dev.parent); dev->bus_vote.data_count = 1; dev->bus_vote.data->power_mode = CVP_POWER_TURBO; @@ -1871,6 +1873,7 @@ static int iris_hfi_core_init(void *device) cvp_dsp_send_hfi_queue(); + pm_relax(dev->res->pdev->dev.parent); dprintk(CVP_CORE, "Core inited successfully\n"); return 0; @@ -1886,6 +1889,7 @@ err_load_fw: err_no_mem: dprintk(CVP_ERR, "Core init failed\n"); mutex_unlock(&dev->lock); + pm_relax(dev->res->pdev->dev.parent); return rc; } From 58dc1515239adf247bcdd49bd8d0e9466e02cba9 Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 21 Sep 2021 14:38:15 -0700 Subject: [PATCH 096/317] msm: eva: Restart EVA in case warmboot fails Firmware cannot recover by power cycling EVA. Try cold boot. Change-Id: I83778941f8626d4a3ee7e1f7670a64186ccde831 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 15b6b613d9..ee938d4c0d 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -4144,6 +4144,7 @@ static inline int __resume(struct iris_hfi_device *device) { int rc = 0; u32 flags = 0, reg_gdsc, reg_cbcr; + struct msm_cvp_core *core; if (!device) { dprintk(CVP_ERR, "Invalid params: %pK\n", device); @@ -4155,6 +4156,8 @@ static inline int __resume(struct iris_hfi_device *device) return -EINVAL; } + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + dprintk(CVP_PWR, "Resuming from power collapse\n"); rc = __iris_power_on(device); if (rc) { @@ -4181,6 +4184,7 @@ static inline int __resume(struct iris_hfi_device *device) rc = __boot_firmware(device); if (rc) { dprintk(CVP_ERR, "Failed to reset cvp core\n"); + msm_cvp_trigger_ssr(core, SSR_ERR_FATAL); goto err_reset_core; } From 2b303bbbf4c7190f2e6973317479e09844d85be9 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 23 Sep 2021 12:53:12 -0700 Subject: [PATCH 097/317] msm: eva: Validate instance before deleting The change will avoid panic during DSP session deletion in case an invaid instance pointer passed in. Disable suspend early during core init. Change-Id: I0ec1e95d17a65b26fb29c970889926d9507bf554 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 2 +- msm/eva/msm_cvp_common.c | 20 ++++++++++++++++++++ msm/eva/msm_cvp_common.h | 1 + msm/eva/msm_cvp_dsp.c | 2 +- 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index ee938d4c0d..0cbdac4dcd 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1777,6 +1777,7 @@ static int iris_hfi_core_init(void *device) dprintk(CVP_CORE, "Core initializing\n"); + pm_stay_awake(dev->res->pdev->dev.parent); mutex_lock(&dev->lock); dev->bus_vote.data = @@ -1787,7 +1788,6 @@ static int iris_hfi_core_init(void *device) goto err_no_mem; } - pm_stay_awake(dev->res->pdev->dev.parent); dev->bus_vote.data_count = 1; dev->bus_vote.data->power_mode = CVP_POWER_TURBO; diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index f52dfaaf35..4384860fb4 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -1591,5 +1591,25 @@ error: } +bool is_cvp_inst_valid(struct msm_cvp_inst *inst) +{ + struct msm_cvp_core *core; + struct msm_cvp_inst *sess; + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (!core) + return false; + + mutex_lock(&core->lock); + list_for_each_entry(sess, &core->instances, list) { + if (inst == sess) { + if (kref_read(&inst->kref)) { + mutex_unlock(&core->lock); + return true; + } + } + } + mutex_unlock(&core->lock); + return false; +} diff --git a/msm/eva/msm_cvp_common.h b/msm/eva/msm_cvp_common.h index 3b9209490e..5ea32913fe 100644 --- a/msm/eva/msm_cvp_common.h +++ b/msm/eva/msm_cvp_common.h @@ -13,6 +13,7 @@ struct msm_cvp_inst *cvp_get_inst(struct msm_cvp_core *core, void *session_id); struct msm_cvp_inst *cvp_get_inst_validate(struct msm_cvp_core *core, void *session_id); +bool is_cvp_inst_valid(struct msm_cvp_inst *inst); void cvp_change_inst_state(struct msm_cvp_inst *inst, enum instance_state state); struct msm_cvp_core *get_cvp_core(int core_id); diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index e4fc319215..9da9c09915 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1403,7 +1403,7 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) inst = (struct msm_cvp_inst *)ptr_dsp2cpu( dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->session_cpu_low); - if (!inst) { + if (!inst || !is_cvp_inst_valid(inst)) { dprintk(CVP_ERR, "%s incorrect session ID\n", __func__); cmd->ret = -1; goto dsp_fail_delete; From 05c4f32b29387021accbd13a5e41a1cf5b1d793a Mon Sep 17 00:00:00 2001 From: Aniruddh Sharma Date: Wed, 29 Sep 2021 21:30:57 +0530 Subject: [PATCH 098/317] msm: eva: KW Fixes for minidump Some code cleanup to follow linux coding standards.. Change-Id: I6412ebba97646f027354944ae939004bd121feeb Signed-off-by: Aniruddh Sharma --- msm/eva/cvp_dump.c | 171 ++++++++++++++++++--------------------------- msm/eva/cvp_dump.h | 6 +- 2 files changed, 70 insertions(+), 107 deletions(-) diff --git a/msm/eva/cvp_dump.c b/msm/eva/cvp_dump.c index d8c8cb1a4d..bb5e5c6a78 100644 --- a/msm/eva/cvp_dump.c +++ b/msm/eva/cvp_dump.c @@ -44,33 +44,26 @@ LIST_HEAD(head_node_dbg_struct); int md_eva_dump(const char* name, u64 virt, u64 phys, u64 size) { struct md_region md_entry; - if (msm_minidump_enabled()) - { + if (msm_minidump_enabled()) { dprintk(CVP_INFO, "Minidump is enabled!\n"); - // add minidump region for EVA-FW image strlcpy(md_entry.name, name, sizeof(md_entry.name)); md_entry.virt_addr = (uintptr_t)virt; md_entry.phys_addr = phys; md_entry.size = size; - if (msm_minidump_add_region(&md_entry) < 0) - { + if (msm_minidump_add_region(&md_entry) < 0) { dprintk(CVP_ERR, "Failed to add \"%s\" data in \ - Minidump\n", name); + Minidump\n", name); return 1; - } - else - { + } else { dprintk(CVP_INFO, "add region success for \"%s\" with virt addr:\ - 0x%x, phy addr: 0x%x, size: %d", + 0x%x, phy addr: 0x%x, size: %d", md_entry.name, md_entry.virt_addr, md_entry.phys_addr, md_entry.size); return 0; } - } - else - { + } else { dprintk(CVP_ERR, "Minidump is NOT enabled!\n"); return 1; } @@ -85,69 +78,57 @@ void cvp_va_md_register(char* name, void* notf_blk_ptr) dprintk(CVP_ERR, "\"%s\" : qcom_va_md_register failed rc = %d\n", name, rc); - } - else { - dprintk(CVP_INFO, - "\"%s\" : eva_queue qcom_va_md_register success rc = %d\n", - name, rc); + } else { + dprintk(CVP_INFO, "\"%s\" : eva_queue qcom_va_md_register \ + success rc = %d\n", name, rc); } } void cvp_register_va_md_region() { - if(qcom_va_md_enabled()) - { + if (qcom_va_md_enabled()) { cvp_va_md_register("eva_queues", &eva_hfiq_list_notif_blk); cvp_va_md_register("dbg_struct", &eva_struct_list_notif_blk); - } - else + } else { dprintk(CVP_ERR, "VA_Minidump is NOT enabled!\n"); + } } void cvp_free_va_md_list(void) { struct eva_va_md_queue *cursor, *temp; - /* Iterate over each item of the hfi quesue va_md_list and add del the node */ - list_for_each_entry_safe(cursor, temp, &head_node_hfi_queue, list) - { + list_for_each_entry_safe(cursor, temp, &head_node_hfi_queue, list) { list_del(&cursor->list); kfree(cursor); } - /* Iterate over each item of the hfi debug_struct - va_md_list and add del the node */ - list_for_each_entry_safe(cursor, temp, &head_node_dbg_struct, list) - { + list_for_each_entry_safe(cursor, temp, &head_node_dbg_struct, list) { list_del(&cursor->list); kfree(cursor); } } void add_va_node_to_list(void *list_head_node, void *buff_va, u32 buff_size, - const char *region_name, bool copy) + const char *region_name, bool copy) { struct list_head *head_node = (struct list_head *)list_head_node; struct eva_va_md_queue *temp_node = NULL; - /*Creating Node*/ + temp_node = kzalloc(sizeof(struct eva_va_md_queue), GFP_KERNEL); - if (!temp_node) - { + if (!temp_node) { dprintk(CVP_ERR, "Memory allocation failed for list node\n"); return; } - /*Init the list within the struct*/ INIT_LIST_HEAD(&temp_node->list); - /* Store back the data to linked list node data */ temp_node->va_md_buff = buff_va; temp_node->va_md_buff_size = buff_size; strlcpy(temp_node->region_name, region_name, - sizeof(temp_node->region_name)); + sizeof(temp_node->region_name)); temp_node->copy = copy; - /*Add Node to Linked List*/ list_add_tail(&temp_node->list, head_node); dprintk(CVP_INFO, "\"%s\" added to buffer list, vaddr: %px size: 0x%x\n", @@ -162,29 +143,27 @@ void add_hfi_queue_to_va_md_list(void *device) dev = (struct iris_hfi_device*)device; - /* Adding CPU QUEUES*/ iface_q = &dev->iface_queues[CVP_IFACEQ_CMDQ_IDX]; add_va_node_to_list(&head_node_hfi_queue, - iface_q->q_array.align_virtual_addr, - iface_q->q_array.mem_size, - "eva_cmdq_cpu", false); + iface_q->q_array.align_virtual_addr, + iface_q->q_array.mem_size, + "eva_cmdq_cpu", false); iface_q = &dev->iface_queues[CVP_IFACEQ_MSGQ_IDX]; add_va_node_to_list(&head_node_hfi_queue, - iface_q->q_array.align_virtual_addr, - iface_q->q_array.mem_size, - "eva_msgq_cpu", false); + iface_q->q_array.align_virtual_addr, + iface_q->q_array.mem_size, + "eva_msgq_cpu", false); - /* Adding DSP QUEUES*/ iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_CMDQ_IDX]; add_va_node_to_list(&head_node_hfi_queue, - iface_q->q_array.align_virtual_addr, - iface_q->q_array.mem_size, - "eva_cmdq_dsp", false); + iface_q->q_array.align_virtual_addr, + iface_q->q_array.mem_size, + "eva_cmdq_dsp", false); iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_MSGQ_IDX]; add_va_node_to_list(&head_node_hfi_queue, - iface_q->q_array.align_virtual_addr, - iface_q->q_array.mem_size, - "eva_msgq_dsp", false); + iface_q->q_array.align_virtual_addr, + iface_q->q_array.mem_size, + "eva_msgq_dsp", false); } void add_queue_header_to_va_md_list(void *device) @@ -195,28 +174,24 @@ void add_queue_header_to_va_md_list(void *device) dev = (struct iris_hfi_device*)device; - // Add node for cvp_hfi_queue_header: cpucmdQ iface_q = &dev->iface_queues[CVP_IFACEQ_CMDQ_IDX]; queue = (struct cvp_hfi_queue_header *)iface_q->q_hdr; add_va_node_to_list(&head_node_dbg_struct, queue, sizeof(struct cvp_hfi_queue_header), "cvp_hfi_queue_header-cpucmdQ", false); - // Add node for cvp_hfi_queue_header: cpumsgQ iface_q = &dev->iface_queues[CVP_IFACEQ_MSGQ_IDX]; queue = (struct cvp_hfi_queue_header *)iface_q->q_hdr; add_va_node_to_list(&head_node_dbg_struct, queue, sizeof(struct cvp_hfi_queue_header), "cvp_hfi_queue_header-cpumsgQ", false); - // Add node for cvp_hfi_queue_header: dspcmdQ iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_CMDQ_IDX]; queue = (struct cvp_hfi_queue_header *)iface_q->q_hdr; add_va_node_to_list(&head_node_dbg_struct, queue, sizeof(struct cvp_hfi_queue_header), "cvp_hfi_queue_header-dspcmdQ", false); - // Add node for cvp_hfi_queue_header: dspmsgQ iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_MSGQ_IDX]; queue = (struct cvp_hfi_queue_header *)iface_q->q_hdr; add_va_node_to_list(&head_node_dbg_struct, @@ -225,95 +200,83 @@ void add_queue_header_to_va_md_list(void *device) } int eva_hfiq_list_notif_handler(struct notifier_block *this, - unsigned long event, void *ptr) + unsigned long event, void *ptr) { struct va_md_entry entry; struct eva_va_md_queue *cursor, *temp; int rc = 0; void *temp_data; - /* Iterate over each item of the list and - add that data to va_md_entry */ - list_for_each_entry_safe(cursor, temp, &head_node_hfi_queue, list) - { - if(cursor->copy) - { - //Copying the content to local kzmalloc buffer... + list_for_each_entry_safe(cursor, temp, &head_node_hfi_queue, list) { + entry.vaddr = (unsigned long)cursor->va_md_buff; + if (cursor->copy) { dprintk(CVP_INFO, "Copying \"%s\"(%d Bytes)\ - to intermediate buffer\n", - cursor->region_name, cursor->va_md_buff_size); + to intermediate buffer\n", + cursor->region_name, cursor->va_md_buff_size); temp_data = kzalloc(cursor->va_md_buff_size, - GFP_KERNEL); - memcpy(temp_data, cursor->va_md_buff, - cursor->va_md_buff_size); - - entry.vaddr = (unsigned long)temp_data; + GFP_KERNEL); + if (temp_data) { + memcpy(temp_data, cursor->va_md_buff, + cursor->va_md_buff_size); + entry.vaddr = (unsigned long)temp_data; + } } - else - entry.vaddr = (unsigned long)cursor->va_md_buff; entry.size = cursor->va_md_buff_size; strlcpy(entry.owner, cursor->region_name, sizeof(entry.owner)); entry.cb = NULL; - if(msm_cvp_minidump_enable) - { + if (msm_cvp_minidump_enable) { rc = qcom_va_md_add_region(&entry); - if(rc) + if (rc) dprintk(CVP_ERR, "Add region \"failed\" for \ - \"%s\", vaddr: %px size: 0x%x\n", entry.owner, - cursor->va_md_buff, entry.size); + \"%s\", vaddr: %px size: 0x%x\n", entry.owner, + cursor->va_md_buff, entry.size); else dprintk(CVP_INFO, "Add region \"success\" for \ - \"%s\", vaddr: %px size: 0x%x\n", entry.owner, - cursor->va_md_buff, entry.size); + \"%s\", vaddr: %px size: 0x%x\n", entry.owner, + cursor->va_md_buff, entry.size); } } return NOTIFY_OK; } int eva_struct_list_notif_handler(struct notifier_block *this, - unsigned long event, void *ptr) + unsigned long event, void *ptr) { struct va_md_entry entry; struct eva_va_md_queue *cursor, *temp; int rc = 0; void *temp_data; - /* Iterate over each item of the list - and add that data to va_md_entry */ - list_for_each_entry_safe(cursor, temp, &head_node_dbg_struct, list) - { - if(cursor->copy) - { - //Copying the content to local kzmalloc buffer... + list_for_each_entry_safe(cursor, temp, &head_node_dbg_struct, list) { + entry.vaddr = (unsigned long)cursor->va_md_buff; + if (cursor->copy) { dprintk(CVP_INFO, "Copying \"%s\"(%d Bytes) to \ - intermediate buffer\n", cursor->region_name, - cursor->va_md_buff_size); + intermediate buffer\n", cursor->region_name, + cursor->va_md_buff_size); temp_data = kzalloc(cursor->va_md_buff_size, - GFP_KERNEL); - memcpy(temp_data, cursor->va_md_buff, - cursor->va_md_buff_size); - - entry.vaddr = (unsigned long)temp_data; + GFP_KERNEL); + if (temp_data) { + memcpy(temp_data, cursor->va_md_buff, + cursor->va_md_buff_size); + entry.vaddr = (unsigned long)temp_data; + } } - else - entry.vaddr = (unsigned long)cursor->va_md_buff; entry.size = cursor->va_md_buff_size; strlcpy(entry.owner, cursor->region_name, sizeof(entry.owner)); entry.cb = NULL; - if(msm_cvp_minidump_enable) - { + if (msm_cvp_minidump_enable) { rc = qcom_va_md_add_region(&entry); - if(rc) + if (rc) dprintk(CVP_ERR, "Add region \"failed\" for \ - \"%s\", vaddr: %px size: 0x%x\n", - entry.owner, cursor->va_md_buff, - entry.size); + \"%s\", vaddr: %px size: 0x%x\n", + entry.owner, cursor->va_md_buff, + entry.size); else dprintk(CVP_INFO, "Add region \"success\" for \ - \"%s\", vaddr: %px size: 0x%x\n", entry.owner, - cursor->va_md_buff, entry.size); + \"%s\", vaddr: %px size: 0x%x\n", entry.owner, + cursor->va_md_buff, entry.size); } } return NOTIFY_OK; diff --git a/msm/eva/cvp_dump.h b/msm/eva/cvp_dump.h index d1679e0b4a..0076bffdad 100644 --- a/msm/eva/cvp_dump.h +++ b/msm/eva/cvp_dump.h @@ -20,11 +20,11 @@ extern struct notifier_block eva_struct_list_notif_blk; /* notifier handler function for list of eva hfi queues */ int eva_hfiq_list_notif_handler(struct notifier_block *this, - unsigned long event, void *ptr); + unsigned long event, void *ptr); /* notifier handler function for list of eva global structures */ int eva_struct_list_notif_handler(struct notifier_block *this, - unsigned long event, void *ptr); + unsigned long event, void *ptr); /* * wrapper for static minidump @@ -47,7 +47,7 @@ int md_eva_dump(const char* name, u64 virt, u64 phys, u64 size); * to the intermidiate buffer allocated by kzmalloc. */ void add_va_node_to_list(void *list_head_node, void *buff_va, - u32 buff_size, const char *region_name, bool copy); + u32 buff_size, const char *region_name, bool copy); /* * Registers subsystem to minidump driver From 49818857601ecacb101b59b9d473fe19ff23af68 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Wed, 27 Oct 2021 18:01:43 -0700 Subject: [PATCH 099/317] msm: eva: merged tip from eva-kernel.lnx.1.0 merged tip source code from eva-kernel.lnx.1.0, and verify the promotion flow. Change-Id: I031508fd8a23995a166506f3d190e5e228eb13c2 Signed-off-by: Yu SI --- msm/Kbuild | 14 +++ msm/eva/cvp_comm_def.h | 4 + msm/eva/cvp_dump.c | 69 ++++++++---- msm/eva/cvp_dump.h | 59 +++++++--- msm/eva/cvp_hfi.c | 117 ++++++++++++++++--- msm/eva/cvp_hfi_api.h | 1 + msm/eva/cvp_hfi_helper.h | 89 +++++++++------ msm/eva/hfi_response_handler.c | 2 - msm/eva/msm_cvp.c | 199 ++++----------------------------- msm/eva/msm_cvp_buf.c | 5 - msm/eva/msm_cvp_buf.h | 1 - msm/eva/msm_cvp_clocks.c | 16 +++ msm/eva/msm_cvp_clocks.h | 1 + msm/eva/msm_cvp_common.c | 151 ++++++++----------------- msm/eva/msm_cvp_common.h | 1 - msm/eva/msm_cvp_core.c | 24 +++- msm/eva/msm_cvp_core.h | 1 - msm/eva/msm_cvp_debug.c | 25 ++--- msm/eva/msm_cvp_dsp.c | 36 +++++- msm/eva/msm_cvp_internal.h | 5 +- msm/eva/msm_cvp_platform.c | 20 ++-- msm/eva/msm_cvp_res_parse.c | 12 +- msm/eva/msm_cvp_resources.h | 17 ++- msm/eva/msm_cvp_synx.c | 6 +- msm/eva/msm_smem.c | 1 - 25 files changed, 445 insertions(+), 431 deletions(-) diff --git a/msm/Kbuild b/msm/Kbuild index 39efb6ced9..97843063e4 100644 --- a/msm/Kbuild +++ b/msm/Kbuild @@ -14,6 +14,20 @@ KBUILD_CPPFLAGS += -DCONFIG_MSM_MMRM # ported from Android.mk $(info within KBUILD file KBUILD_EXTRA_SYMBOLS = $(KBUILD_EXTRA_SYMBOLS)) +ifeq ($(CONFIG_ARCH_WAIPIO), y) +$(info within KBUILD file CONFIG_ARCH_WAIPIO = $(CONFIG_ARCH_WAIPIO)) +# include $(EVA_ROOT)/config/waipio.mk +KBUILD_CPPFLAGS += -DCONFIG_EVA_WAIPIO=1 +ccflags-y += -DCONFIG_EVA_WAIPIO=1 +endif + +ifeq ($(CONFIG_ARCH_KALAMA), y) +$(info within KBUILD file CONFIG_ARCH_KALAMA = $(CONFIG_ARCH_KALAMA)) +# include $(EVA_ROOT)/config/waipio.mk +KBUILD_CPPFLAGS += -DCONFIG_EVA_KALAMA=1 +ccflags-y += -DCONFIG_EVA_KALAMA=1 +endif + msm-eva-objs := eva/cvp.o \ eva/msm_cvp_ioctl.o \ eva/msm_cvp_platform.o \ diff --git a/msm/eva/cvp_comm_def.h b/msm/eva/cvp_comm_def.h index 7f86433adf..3ccf16dc8c 100644 --- a/msm/eva/cvp_comm_def.h +++ b/msm/eva/cvp_comm_def.h @@ -23,7 +23,11 @@ enum queue_state { QUEUE_INVALID, }; +#ifdef CONFIG_EVA_WAIPIO #define CVP_SYNX_ENABLED 1 #define CVP_MMRM_ENABLED 1 #define CVP_FASTRPC_ENABLED 1 +#define CVP_MINIDUMP_ENABLED 1 +#endif + #endif diff --git a/msm/eva/cvp_dump.c b/msm/eva/cvp_dump.c index bb5e5c6a78..5799f72e73 100644 --- a/msm/eva/cvp_dump.c +++ b/msm/eva/cvp_dump.c @@ -23,7 +23,6 @@ #include #include #include -#include #include "hfi_packetization.h" #include "msm_cvp_debug.h" #include "cvp_core_hfi.h" @@ -33,17 +32,40 @@ #include "msm_cvp_clocks.h" #include "cvp_dump.h" +#ifdef CVP_MINIDUMP_ENABLED /*Declare and init the head node of the linked list for queue va_md dump*/ -LIST_HEAD(head_node_hfi_queue); +static LIST_HEAD(head_node_hfi_queue); /*Declare and init the head node of the linked list for debug struct va_md dump*/ -LIST_HEAD(head_node_dbg_struct); +static LIST_HEAD(head_node_dbg_struct); + +static int eva_struct_list_notif_handler(struct notifier_block *this, + unsigned long event, void *ptr); + +static int eva_hfiq_list_notif_handler(struct notifier_block *this, + unsigned long event, void *ptr); + +static struct notifier_block eva_struct_list_notif_blk = { + .notifier_call = eva_struct_list_notif_handler, + .priority = INT_MAX-1, +}; + +static struct notifier_block eva_hfiq_list_notif_blk = { + .notifier_call = eva_hfiq_list_notif_handler, + .priority = INT_MAX, +}; + +struct list_head *dump_array[CVP_MAX_DUMP] = { + [CVP_QUEUE_DUMP] = &head_node_hfi_queue, + [CVP_DBG_DUMP] = &head_node_dbg_struct, +}; int md_eva_dump(const char* name, u64 virt, u64 phys, u64 size) { struct md_region md_entry; + if (msm_minidump_enabled()) { dprintk(CVP_INFO, "Minidump is enabled!\n"); @@ -73,6 +95,7 @@ void cvp_va_md_register(char* name, void* notf_blk_ptr) { int rc = 0; struct notifier_block* notf_blk = (struct notifier_block*)notf_blk_ptr; + rc = qcom_va_md_register(name, notf_blk); if (rc) { dprintk(CVP_ERR, @@ -109,12 +132,18 @@ void cvp_free_va_md_list(void) } } -void add_va_node_to_list(void *list_head_node, void *buff_va, u32 buff_size, +void add_va_node_to_list(enum cvp_dump_type type, void *buff_va, u32 buff_size, const char *region_name, bool copy) { - struct list_head *head_node = (struct list_head *)list_head_node; + struct list_head *head_node; struct eva_va_md_queue *temp_node = NULL; + if (type >= CVP_MAX_DUMP) + return; + + head_node = dump_array[type]; + + /*Creating Node*/ temp_node = kzalloc(sizeof(struct eva_va_md_queue), GFP_KERNEL); if (!temp_node) { dprintk(CVP_ERR, "Memory allocation failed for list node\n"); @@ -144,23 +173,23 @@ void add_hfi_queue_to_va_md_list(void *device) dev = (struct iris_hfi_device*)device; iface_q = &dev->iface_queues[CVP_IFACEQ_CMDQ_IDX]; - add_va_node_to_list(&head_node_hfi_queue, + add_va_node_to_list(CVP_QUEUE_DUMP, iface_q->q_array.align_virtual_addr, iface_q->q_array.mem_size, "eva_cmdq_cpu", false); iface_q = &dev->iface_queues[CVP_IFACEQ_MSGQ_IDX]; - add_va_node_to_list(&head_node_hfi_queue, + add_va_node_to_list(CVP_QUEUE_DUMP, iface_q->q_array.align_virtual_addr, iface_q->q_array.mem_size, "eva_msgq_cpu", false); iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_CMDQ_IDX]; - add_va_node_to_list(&head_node_hfi_queue, + add_va_node_to_list(CVP_QUEUE_DUMP, iface_q->q_array.align_virtual_addr, iface_q->q_array.mem_size, "eva_cmdq_dsp", false); iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_MSGQ_IDX]; - add_va_node_to_list(&head_node_hfi_queue, + add_va_node_to_list(CVP_QUEUE_DUMP, iface_q->q_array.align_virtual_addr, iface_q->q_array.mem_size, "eva_msgq_dsp", false); @@ -176,30 +205,30 @@ void add_queue_header_to_va_md_list(void *device) iface_q = &dev->iface_queues[CVP_IFACEQ_CMDQ_IDX]; queue = (struct cvp_hfi_queue_header *)iface_q->q_hdr; - add_va_node_to_list(&head_node_dbg_struct, + add_va_node_to_list(CVP_DBG_DUMP, queue, sizeof(struct cvp_hfi_queue_header), "cvp_hfi_queue_header-cpucmdQ", false); iface_q = &dev->iface_queues[CVP_IFACEQ_MSGQ_IDX]; queue = (struct cvp_hfi_queue_header *)iface_q->q_hdr; - add_va_node_to_list(&head_node_dbg_struct, + add_va_node_to_list(CVP_DBG_DUMP, queue, sizeof(struct cvp_hfi_queue_header), "cvp_hfi_queue_header-cpumsgQ", false); iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_CMDQ_IDX]; queue = (struct cvp_hfi_queue_header *)iface_q->q_hdr; - add_va_node_to_list(&head_node_dbg_struct, + add_va_node_to_list(CVP_DBG_DUMP, queue, sizeof(struct cvp_hfi_queue_header), "cvp_hfi_queue_header-dspcmdQ", false); iface_q = &dev->dsp_iface_queues[CVP_IFACEQ_MSGQ_IDX]; queue = (struct cvp_hfi_queue_header *)iface_q->q_hdr; - add_va_node_to_list(&head_node_dbg_struct, + add_va_node_to_list(CVP_DBG_DUMP, queue, sizeof(struct cvp_hfi_queue_header), "cvp_hfi_queue_header-dspmsgQ", false); } -int eva_hfiq_list_notif_handler(struct notifier_block *this, +static int eva_hfiq_list_notif_handler(struct notifier_block *this, unsigned long event, void *ptr) { struct va_md_entry entry; @@ -240,7 +269,7 @@ int eva_hfiq_list_notif_handler(struct notifier_block *this, return NOTIFY_OK; } -int eva_struct_list_notif_handler(struct notifier_block *this, +static int eva_struct_list_notif_handler(struct notifier_block *this, unsigned long event, void *ptr) { struct va_md_entry entry; @@ -282,12 +311,4 @@ int eva_struct_list_notif_handler(struct notifier_block *this, return NOTIFY_OK; } -struct notifier_block eva_struct_list_notif_blk = { - .notifier_call = eva_struct_list_notif_handler, - .priority = INT_MAX-1, -}; - -struct notifier_block eva_hfiq_list_notif_blk = { - .notifier_call = eva_hfiq_list_notif_handler, - .priority = INT_MAX, -}; +#endif diff --git a/msm/eva/cvp_dump.h b/msm/eva/cvp_dump.h index 0076bffdad..21477c5436 100644 --- a/msm/eva/cvp_dump.h +++ b/msm/eva/cvp_dump.h @@ -8,23 +8,19 @@ #include #include -#include +#include "cvp_comm_def.h" + +enum cvp_dump_type { + CVP_QUEUE_DUMP, + CVP_DBG_DUMP, + CVP_MAX_DUMP, +}; #define MAX_REGION_NAME_LEN 32 #define EVAFW_IMAGE_SIZE 7*1024*1024 -extern struct list_head head_node_hfi_queue; -extern struct list_head head_node_dbg_struct; -extern struct notifier_block eva_hfiq_list_notif_blk; -extern struct notifier_block eva_struct_list_notif_blk; - -/* notifier handler function for list of eva hfi queues */ -int eva_hfiq_list_notif_handler(struct notifier_block *this, - unsigned long event, void *ptr); - -/* notifier handler function for list of eva global structures */ -int eva_struct_list_notif_handler(struct notifier_block *this, - unsigned long event, void *ptr); +#ifdef CVP_MINIDUMP_ENABLED +#include /* * wrapper for static minidump @@ -39,14 +35,14 @@ int md_eva_dump(const char* name, u64 virt, u64 phys, u64 size); /* * Fucntion to add dump region to queue - * @list_head_node: Head node of the list which needs to be updated + * @type: Type of the list node which needs to be updated * @buff_va: Virtual address of the buffer which needs to be dumped * @buff_size: Size of the buffer which needs to be dumped * @region_name: Dump will be collected with this name * @copy: Flag to indicate if the buffer data needs to be copied * to the intermidiate buffer allocated by kzmalloc. */ -void add_va_node_to_list(void *list_head_node, void *buff_va, +void add_va_node_to_list(enum cvp_dump_type type, void *buff_va, u32 buff_size, const char *region_name, bool copy); /* @@ -93,5 +89,36 @@ struct eva_va_md_queue char region_name[MAX_REGION_NAME_LEN]; bool copy; }; +#else +static inline int md_eva_dump(const char* name, u64 virt, u64 phys, u64 size) +{ + return 0; +} -#endif \ No newline at end of file +static inline void add_va_node_to_list(enum cvp_dump_type type, void *buff_va, + u32 buff_size, const char *region_name, bool copy) +{ +} + +static inline void cvp_va_md_register(char *name, void* notf_blk_ptr) +{ +} + +static inline void cvp_register_va_md_region(void) +{ +} + +static inline void cvp_free_va_md_list(void) +{ +} + +static inline void add_hfi_queue_to_va_md_list(void *device) +{ +} + +static inline void add_queue_header_to_va_md_list(void *device) +{ +} + +#endif /* End of CVP_MINIDUMP_ENABLED */ +#endif diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 0cbdac4dcd..3ad885ad4e 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -812,7 +812,7 @@ static int __unvote_buses(struct iris_hfi_device *device) device->bus_vote.data_count = 0; iris_hfi_for_each_bus(device, bus) { - rc = icc_set_bw(bus->client, 0, 0); + rc = msm_cvp_set_bw(bus, 0); if (rc) { dprintk(CVP_ERR, "%s: Failed unvoting bus\n", __func__); @@ -853,7 +853,7 @@ no_data_count: iris_hfi_for_each_bus(device, bus) { if (bus) { - rc = icc_set_bw(bus->client, bus->range[1], 0); + rc = msm_cvp_set_bw(bus, bus->range[1]); if (rc) dprintk(CVP_ERR, "Failed voting bus %s to ab %u\n", @@ -1760,6 +1760,53 @@ static int __sys_set_power_control(struct iris_hfi_device *device, return 0; } +static void cvp_pm_qos_update(struct iris_hfi_device *device, bool vote_on) +{ + u32 latency, off_vote_cnt; + int i, err = 0; + + spin_lock(&device->res->pm_qos.lock); + off_vote_cnt = device->res->pm_qos.off_vote_cnt; + spin_unlock(&device->res->pm_qos.lock); + + if (vote_on && off_vote_cnt) + return; + + latency = vote_on ? device->res->pm_qos.latency_us : + PM_QOS_RESUME_LATENCY_DEFAULT_VALUE; + + if (device->res->pm_qos.latency_us && device->res->pm_qos.pm_qos_hdls) + for (i = 0; i < device->res->pm_qos.silver_count; i++) { + err = dev_pm_qos_update_request( + &device->res->pm_qos.pm_qos_hdls[i], + latency); + if (err < 0) { + if (vote_on) { + dprintk(CVP_WARN, + "pm qos on failed %d\n", err); + } else { + dprintk(CVP_WARN, + "pm qos off failed %d\n", err); + } + } + } +} +static int iris_pm_qos_update(void *device) +{ + struct iris_hfi_device *dev; + + if (!device) { + dprintk(CVP_ERR, "%s Invalid device\n", __func__); + return -ENODEV; + } + + dev = device; + + cvp_pm_qos_update(dev, true); + + return 0; +} + static int iris_hfi_core_init(void *device) { int rc = 0; @@ -1822,8 +1869,9 @@ static int iris_hfi_core_init(void *device) cvp_register_va_md_region(); // Add node for dev struct - add_va_node_to_list(&head_node_dbg_struct, dev, - sizeof(struct iris_hfi_device), "iris_hfi_device-dev", false); + add_va_node_to_list(CVP_QUEUE_DUMP, dev, + sizeof(struct iris_hfi_device), + "iris_hfi_device-dev", false); add_queue_header_to_va_md_list((void*)dev); add_hfi_queue_to_va_md_list((void*)dev); @@ -1865,10 +1913,35 @@ static int iris_hfi_core_init(void *device) __set_ubwc_config(device); __sys_set_idle_indicator(device, true); - if (dev->res->pm_qos_latency_us) - cpu_latency_qos_add_request(&dev->qos, - dev->res->pm_qos_latency_us); + if (dev->res->pm_qos.latency_us) { + int err = 0; + u32 i, cpu; + dev->res->pm_qos.pm_qos_hdls = kcalloc( + dev->res->pm_qos.silver_count, + sizeof(struct dev_pm_qos_request), + GFP_KERNEL); + + if (!dev->res->pm_qos.pm_qos_hdls) { + dprintk(CVP_WARN, "Failed allocate pm_qos_hdls\n"); + goto pm_qos_bail; + } + + for (i = 0; i < dev->res->pm_qos.silver_count; i++) { + cpu = dev->res->pm_qos.silver_cores[i]; + err = dev_pm_qos_add_request( + get_cpu_device(cpu), + &dev->res->pm_qos.pm_qos_hdls[i], + DEV_PM_QOS_RESUME_LATENCY, + dev->res->pm_qos.latency_us); + if (err < 0) + dprintk(CVP_WARN, + "%s pm_qos_add_req %d failed\n", + __func__, i); + } + } + +pm_qos_bail: mutex_unlock(&dev->lock); cvp_dsp_send_hfi_queue(); @@ -1895,9 +1968,10 @@ err_no_mem: static int iris_hfi_core_release(void *dev) { - int rc = 0; + int rc = 0, i; struct iris_hfi_device *device = dev; struct cvp_hal_session *session, *next; + struct dev_pm_qos_request *qos_hdl; if (!device) { dprintk(CVP_ERR, "invalid device\n"); @@ -1906,9 +1980,16 @@ static int iris_hfi_core_release(void *dev) mutex_lock(&device->lock); dprintk(CVP_WARN, "Core releasing\n"); - if (device->res->pm_qos_latency_us && - cpu_latency_qos_request_active(&device->qos)) - cpu_latency_qos_remove_request(&device->qos); + if (device->res->pm_qos.latency_us && + device->res->pm_qos.pm_qos_hdls) { + for (i = 0; i < device->res->pm_qos.silver_count; i++) { + qos_hdl = &device->res->pm_qos.pm_qos_hdls[i]; + if ((qos_hdl != NULL) && dev_pm_qos_request_active(qos_hdl)) + dev_pm_qos_remove_request(qos_hdl); + } + kfree(device->res->pm_qos.pm_qos_hdls); + device->res->pm_qos.pm_qos_hdls = NULL; + } __resume(device); __set_state(device, IRIS_STATE_DEINIT); @@ -3844,10 +3925,6 @@ static inline int __suspend(struct iris_hfi_device *device) dprintk(CVP_PWR, "Entering suspend\n"); - if (device->res->pm_qos_latency_us && - cpu_latency_qos_request_active(&device->qos)) - cpu_latency_qos_remove_request(&device->qos); - rc = __tzbsp_set_cvp_state(TZ_SUBSYS_STATE_SUSPEND); if (rc) { dprintk(CVP_WARN, "Failed to suspend cvp core %d\n", rc); @@ -3857,6 +3934,10 @@ static inline int __suspend(struct iris_hfi_device *device) __disable_subcaches(device); call_iris_op(device, power_off, device); + + if (device->res->pm_qos.latency_us && device->res->pm_qos.pm_qos_hdls) + cvp_pm_qos_update(device, false); + return rc; err_tzbsp_suspend: @@ -4194,9 +4275,8 @@ static inline int __resume(struct iris_hfi_device *device) */ __set_threshold_registers(device); - if (device->res->pm_qos_latency_us) - cpu_latency_qos_add_request(&device->qos, - device->res->pm_qos_latency_us); + if (device->res->pm_qos.latency_us && device->res->pm_qos.pm_qos_hdls) + cvp_pm_qos_update(device, true); __sys_set_debug(device, msm_cvp_fw_debug); @@ -4684,6 +4764,7 @@ static void iris_init_hfi_callbacks(struct cvp_hfi_device *hdev) hdev->flush_debug_queue = iris_hfi_flush_debug_queue; hdev->noc_error_info = iris_hfi_noc_error_info; hdev->validate_session = iris_hfi_validate_session; + hdev->pm_qos_update = iris_pm_qos_update; } int cvp_iris_hfi_initialize(struct cvp_hfi_device *hdev, u32 device_id, diff --git a/msm/eva/cvp_hfi_api.h b/msm/eva/cvp_hfi_api.h index 09abd55fa0..81f01d8f28 100644 --- a/msm/eva/cvp_hfi_api.h +++ b/msm/eva/cvp_hfi_api.h @@ -265,6 +265,7 @@ struct cvp_hfi_device { int (*flush_debug_queue)(void *dev); int (*noc_error_info)(void *dev); int (*validate_session)(void *sess, const char *func); + int (*pm_qos_update)(void *device); }; typedef void (*hfi_cmd_response_callback) (enum hal_command_response cmd, diff --git a/msm/eva/cvp_hfi_helper.h b/msm/eva/cvp_hfi_helper.h index 4b2ad11cfc..6c547cd313 100644 --- a/msm/eva/cvp_hfi_helper.h +++ b/msm/eva/cvp_hfi_helper.h @@ -15,40 +15,63 @@ #define HFI_CMD_START_OFFSET (0x00010000) #define HFI_MSG_START_OFFSET (0x00020000) -#define HFI_ERR_NONE HFI_COMMON_BASE -#define HFI_ERR_SYS_FATAL (HFI_COMMON_BASE + 0x1) -#define HFI_ERR_SYS_INVALID_PARAMETER (HFI_COMMON_BASE + 0x2) -#define HFI_ERR_SYS_VERSION_MISMATCH (HFI_COMMON_BASE + 0x3) -#define HFI_ERR_SYS_INSUFFICIENT_RESOURCES (HFI_COMMON_BASE + 0x4) -#define HFI_ERR_SYS_MAX_SESSIONS_REACHED (HFI_COMMON_BASE + 0x5) -#define HFI_ERR_SYS_UNSUPPORTED_CODEC (HFI_COMMON_BASE + 0x6) -#define HFI_ERR_SYS_SESSION_IN_USE (HFI_COMMON_BASE + 0x7) -#define HFI_ERR_SYS_SESSION_ID_OUT_OF_RANGE (HFI_COMMON_BASE + 0x8) -#define HFI_ERR_SYS_UNSUPPORTED_DOMAIN (HFI_COMMON_BASE + 0x9) -#define HFI_ERR_SYS_NOC_ERROR (HFI_COMMON_BASE + 0x11) -#define HFI_ERR_SESSION_FATAL (HFI_COMMON_BASE + 0x1001) -#define HFI_ERR_SESSION_INVALID_PARAMETER (HFI_COMMON_BASE + 0x1002) -#define HFI_ERR_SESSION_BAD_POINTER (HFI_COMMON_BASE + 0x1003) -#define HFI_ERR_SESSION_INVALID_SESSION_ID (HFI_COMMON_BASE + 0x1004) -#define HFI_ERR_SESSION_INVALID_STREAM_ID (HFI_COMMON_BASE + 0x1005) -#define HFI_ERR_SESSION_INCORRECT_STATE_OPERATION \ - (HFI_COMMON_BASE + 0x1006) -#define HFI_ERR_SESSION_UNSUPPORTED_PROPERTY (HFI_COMMON_BASE + 0x1007) +#define HFI_ERR_NONE (HFI_COMMON_BASE) /**< Status: No error */ +#define HFI_ERR_SYS_FATAL (HFI_COMMON_BASE + 0x1) /**< Fatal system error */ +#define HFI_ERR_SYS_INVALID_PARAMETER (HFI_COMMON_BASE + 0x2) /**< Invalid system parameter encountered */ +#define HFI_ERR_SYS_VERSION_MISMATCH (HFI_COMMON_BASE + 0x3) /**< Interface version mismatch */ +#define HFI_ERR_SYS_INSUFFICIENT_RESOURCES (HFI_COMMON_BASE + 0x4) /**< Insufficient system resources */ +#define HFI_ERR_SYS_MAX_SESSIONS_REACHED (HFI_COMMON_BASE + 0x5) /**< Maximum number of sessions reached */ +#define HFI_ERR_SYS_SESSION_IN_USE (HFI_COMMON_BASE + 0x7) /**< Session ID specified is in use */ +#define HFI_ERR_SYS_SESSION_ID_OUT_OF_RANGE (HFI_COMMON_BASE + 0x8) /**< ID is out of range */ +#define HFI_ERR_SYS_UNSUPPORTED_TRIGCMD (HFI_COMMON_BASE + 0xA) /**< Unsupported TRIGCMD command*/ +#define HFI_ERR_SYS_UNSUPPORTED_RESOURCES (HFI_COMMON_BASE + 0xB) /**< Unsupported resource*/ +#define HFI_ERR_SYS_UNSUPPORT_CMD (HFI_COMMON_BASE + 0xC) /**< Command is not supported*/ +#define HFI_ERR_SYS_CMDSIZE (HFI_COMMON_BASE + 0xD) /**< command size err*/ +#define HFI_ERR_SYS_UNSUPPORT_PROPERTY (HFI_COMMON_BASE + 0xE) /**< Unsupported property*/ +#define HFI_ERR_SYS_INIT_EXPECTED (HFI_COMMON_BASE + 0xF) /**< Upon FW start, first command must be SYS_INIT*/ +#define HFI_ERR_SYS_INIT_IGNORED (HFI_COMMON_BASE + 0x10) /**< After FW started, SYS_INIT will be ignored*/ +#define HFI_ERR_SYS_MAX_DME_SESSIONS_REACHED (HFI_COMMON_BASE + 0x11) /**< Maximum DME sessions Reached */ +#define HFI_ERR_SYS_MAX_FD_SESSIONS_REACHED (HFI_COMMON_BASE + 0x12) /**< Maximum FD sessions Reached */ +#define HFI_ERR_SYS_MAX_ODT_SESSIONS_REACHED (HFI_COMMON_BASE + 0x13) /**< Maximum ODT sessions Reached*/ +#define HFI_ERR_SYS_MAX_CV_SESSIONS_REACHED (HFI_COMMON_BASE + 0x14) /**< Maximum CV sessions Reached*/ +#define HFI_ERR_SYS_INVALID_SESSION_TYPE (HFI_COMMON_BASE + 0x15) /**< Invalid session TYPE. */ +#define HFI_ERR_SYS_NOC_ERROR (HFI_COMMON_BASE + 0x16) /**< NOC Error encountered */ -#define HFI_ERR_SESSION_UNSUPPORTED_SETTING (HFI_COMMON_BASE + 0x1008) - -#define HFI_ERR_SESSION_INSUFFICIENT_RESOURCES (HFI_COMMON_BASE + 0x1009) - -#define HFI_ERR_SESSION_STREAM_CORRUPT (HFI_COMMON_BASE + 0x100B) -#define HFI_ERR_SESSION_ENC_OVERFLOW (HFI_COMMON_BASE + 0x100C) -#define HFI_ERR_SESSION_UNSUPPORTED_STREAM (HFI_COMMON_BASE + 0x100D) -#define HFI_ERR_SESSION_CMDSIZE (HFI_COMMON_BASE + 0x100E) -#define HFI_ERR_SESSION_UNSUPPORT_CMD (HFI_COMMON_BASE + 0x100F) -#define HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE (HFI_COMMON_BASE + 0x1010) -#define HFI_ERR_SESSION_BUFFERCOUNT_TOOSMALL (HFI_COMMON_BASE + 0x1011) -#define HFI_ERR_SESSION_INVALID_SCALE_FACTOR (HFI_COMMON_BASE + 0x1012) -#define HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED (HFI_COMMON_BASE + 0x1013) -#define HFI_ERR_SESSION_FLUSHED (HFI_COMMON_BASE + 0x101C) + /** + Level 2 Comment: "Session Level Error types" + Common HFI_ERROR_SESSION_X values to be used as session level error/warning + for event and messages + */ +#define HFI_ERR_SESSION_FATAL (HFI_COMMON_BASE + 0x1001) /**< Fatal session error */ +#define HFI_ERR_SESSION_INVALID_PARAMETER (HFI_COMMON_BASE + 0x1002) /**< Invalid session parameter */ +#define HFI_ERR_SESSION_BAD_POINTER (HFI_COMMON_BASE + 0x1003) /**< Bad pointer encountered */ +#define HFI_ERR_SESSION_INVALID_SESSION_ID (HFI_COMMON_BASE + 0x1004) /**< Invalid session ID. eventData2 specifies the session ID. */ +#define HFI_ERR_SESSION_INVALID_STREAM_ID (HFI_COMMON_BASE + 0x1005) /**< Invalid stream ID. eventData2 specifies the stream ID. */ +#define HFI_ERR_SESSION_INCORRECT_STATE_OPERATION (HFI_COMMON_BASE + 0x1006) /**< Incorrect state for specified operation */ +#define HFI_ERR_SESSION_UNSUPPORTED_PROPERTY (HFI_COMMON_BASE + 0x1007) /**< Unsupported property. eventData2 specifies the property index. */ +#define HFI_ERR_SESSION_UNSUPPORTED_SETTING (HFI_COMMON_BASE + 0x1008) /**< Unsupported property setting. eventData2 specifies the property index. */ +#define HFI_ERR_SESSION_INSUFFICIENT_RESOURCES (HFI_COMMON_BASE + 0x1009) /**< Insufficient resources for session */ +#define HFI_ERR_SESSION_STREAM_CORRUPT_OUTPUT_STALLED (HFI_COMMON_BASE + 0x100A) /**< Stream is found to be corrupt; processing is stalled */ +#define HFI_ERR_SESSION_STREAM_CORRUPT (HFI_COMMON_BASE + 0x100B) /**< Stream is found to be corrupt; processing is recoverable */ +#define HFI_ERR_SESSION_RESERVED (HFI_COMMON_BASE + 0x100C) /**< Reserved */ +#define HFI_ERR_SESSION_UNSUPPORTED_STREAM (HFI_COMMON_BASE + 0x100D) /**< Unsupported stream */ +#define HFI_ERR_SESSION_CMDSIZE (HFI_COMMON_BASE + 0x100E) /**< Command packet size err*/ +#define HFI_ERR_SESSION_UNSUPPORT_CMD (HFI_COMMON_BASE + 0x100F) /**< Command is not supported*/ +#define HFI_ERR_SESSION_UNSUPPORT_BUFFERTYPE (HFI_COMMON_BASE + 0x1010) /**< BufferType is not supported*/ +#define HFI_ERR_SESSION_BUFFERCOUNT_TOOSMALL (HFI_COMMON_BASE + 0x1011) /**< Buffer Count is less than default*/ +#define HFI_ERR_SESSION_INVALID_SCALE_FACTOR (HFI_COMMON_BASE + 0x1012) /**< Downscaling not possible */ +#define HFI_ERR_SESSION_UPSCALE_NOT_SUPPORTED (HFI_COMMON_BASE + 0x1013) /**< Upscaling not possible */ +#define HFI_ERR_SESSION_CANNOT_KEEP_ASPECT_RATIO (HFI_COMMON_BASE + 0x1014) /**< Cannot maintain aspect ratio */ +#define HFI_ERR_SESSION_ADDRESS_NOT_ALIGNED (HFI_COMMON_BASE + 0x1016) /**Address is not aligned */ +#define HFI_ERR_SESSION_BUFFERSIZE_TOOSMALL (HFI_COMMON_BASE + 0x1017) /**< Buffer Count is less than default*/ +#define HFI_ERR_SESSION_ABORTED (HFI_COMMON_BASE + 0x1018) /**< error caused by session abort*/ +#define HFI_ERR_SESSION_BUFFER_ALREADY_SET (HFI_COMMON_BASE + 0x1019) /**< Cannot set buffer multiple times without releasing in between. */ +#define HFI_ERR_SESSION_BUFFER_ALREADY_RELEASED (HFI_COMMON_BASE + 0x101A) /**< Cannot release buffer multiple times without setting in between. */ +#define HFI_ERR_SESSION_END_BUFFER_NOT_RELEASED (HFI_COMMON_BASE + 0x101B) /**< Session was ended without properly releasing all buffers */ +#define HFI_ERR_SESSION_FLUSHED (HFI_COMMON_BASE + 0x101C) /**< Cannot set buffer multiple times without releasing in between. */ +#define HFI_ERR_SESSION_KERNEL_MAX_STREAMS_REACHED (HFI_COMMON_BASE + 0x101D) /*Maximum Streams per Kernel reached in a session*/ +#define HFI_ERR_SESSION_MAX_STREAMS_REACHED (HFI_COMMON_BASE + 0x101E) /*Maximum Streams Reached in a session*/ +#define HFI_ERR_SESSION_HW_HANG_DETECTED (HFI_COMMON_BASE + 0x101F) /*HW hang was detected in one of the HW blocks for a frame*/ #define HFI_EVENT_SYS_ERROR (HFI_COMMON_BASE + 0x1) #define HFI_EVENT_SESSION_ERROR (HFI_COMMON_BASE + 0x2) diff --git a/msm/eva/hfi_response_handler.c b/msm/eva/hfi_response_handler.c index e8d35b8f5f..9c093d4fab 100644 --- a/msm/eva/hfi_response_handler.c +++ b/msm/eva/hfi_response_handler.c @@ -40,8 +40,6 @@ static enum cvp_status hfi_map_err_status(u32 hfi_err) cvp_err = CVP_ERR_BAD_PARAM; break; case HFI_ERR_SYS_INSUFFICIENT_RESOURCES: - case HFI_ERR_SYS_UNSUPPORTED_DOMAIN: - case HFI_ERR_SYS_UNSUPPORTED_CODEC: case HFI_ERR_SESSION_UNSUPPORTED_PROPERTY: case HFI_ERR_SESSION_UNSUPPORTED_SETTING: case HFI_ERR_SESSION_INSUFFICIENT_RESOURCES: diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 94861b9707..605d6142e2 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -28,11 +28,9 @@ int msm_cvp_get_session_info(struct msm_cvp_inst *inst, u32 *session) if (!s) return -ECONNRESET; - s->cur_cmd_type = EVA_KMD_GET_SESSION_INFO; *session = hash32_ptr(inst->session); dprintk(CVP_SESS, "%s: id 0x%x\n", __func__, *session); - s->cur_cmd_type = 0; cvp_put_inst(s); return rc; } @@ -143,13 +141,11 @@ static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst, if (!s) return -ECONNRESET; - s->cur_cmd_type = EVA_KMD_RECEIVE_MSG_PKT; wait_time = msecs_to_jiffies(CVP_MAX_WAIT_TIME); sq = &inst->session_queue; rc = cvp_wait_process_message(inst, sq, NULL, wait_time, out_pkt); - s->cur_cmd_type = 0; cvp_put_inst(inst); return rc; } @@ -178,7 +174,6 @@ static int msm_cvp_session_process_hfi( if (!s) return -ECONNRESET; - inst->cur_cmd_type = EVA_KMD_SEND_CMD_PKT; hdev = inst->core->device; pkt_idx = get_pkt_index((struct cvp_hal_session_cmd_pkt *)in_pkt); @@ -251,7 +246,6 @@ static int msm_cvp_session_process_hfi( __func__, signal); exit: - inst->cur_cmd_type = 0; cvp_put_inst(inst); return rc; } @@ -985,10 +979,7 @@ static int adjust_bw_freqs(void) } hdev->clk_freq = core->curr_freq; - rc = icc_set_bw(bus->client, bw_sum, 0); - if (rc) - dprintk(CVP_ERR, "Failed voting bus %s to ab %u\n", - bus->name, bw_sum); + rc = msm_cvp_set_bw(bus, bw_sum); return rc; } @@ -1008,13 +999,11 @@ int msm_cvp_update_power(struct msm_cvp_inst *inst) if (!s) return -ECONNRESET; - inst->cur_cmd_type = EVA_KMD_UPDATE_POWER; core = inst->core; mutex_lock(&core->clk_lock); rc = adjust_bw_freqs(); mutex_unlock(&core->clk_lock); - inst->cur_cmd_type = 0; cvp_put_inst(s); return rc; @@ -1157,6 +1146,7 @@ static int msm_cvp_session_start(struct msm_cvp_inst *inst, struct eva_kmd_arg *arg) { struct cvp_session_queue *sq; + struct cvp_hfi_device *hdev; sq = &inst->session_queue; spin_lock(&sq->lock); @@ -1169,6 +1159,14 @@ static int msm_cvp_session_start(struct msm_cvp_inst *inst, sq->state = QUEUE_START; spin_unlock(&sq->lock); + if (inst->prop.type == HFI_SESSION_FD + || inst->prop.type == HFI_SESSION_DMM) { + spin_lock(&inst->core->resources.pm_qos.lock); + inst->core->resources.pm_qos.off_vote_cnt++; + spin_unlock(&inst->core->resources.pm_qos.lock); + hdev = inst->core->device; + call_hfi_op(hdev, pm_qos_update, hdev->hfi_device_data); + } return cvp_fence_thread_start(inst); } @@ -1500,63 +1498,6 @@ static int msm_cvp_set_sysprop(struct msm_cvp_inst *inst, return rc; } -static int cvp_drain_fence_cmd_queue_partial(struct msm_cvp_inst *inst) -{ - unsigned long wait_time; - struct cvp_fence_queue *q; - struct cvp_fence_command *f; - int rc = 0; - int count = 0, max_count = 0; - - q = &inst->fence_cmd_queue; - - mutex_lock(&q->lock); - - list_for_each_entry(f, &q->sched_list, list) { - if (f->mode == OP_FLUSH) - continue; - ++count; - } - - list_for_each_entry(f, &q->wait_list, list) { - if (f->mode == OP_FLUSH) - continue; - ++count; - } - - mutex_unlock(&q->lock); - wait_time = count * CVP_MAX_WAIT_TIME * 1000; - - dprintk(CVP_SYNX, "%s: wait %d us for %d fence command\n", - __func__, wait_time, count); - - count = 0; - max_count = wait_time / 100; - -retry: - mutex_lock(&q->lock); - f = list_first_entry(&q->sched_list, struct cvp_fence_command, list); - - /* Wait for all normal frames to finish before return */ - if ((f && f->mode == OP_FLUSH) || - (list_empty(&q->sched_list) && list_empty(&q->wait_list))) { - mutex_unlock(&q->lock); - return rc; - } - - mutex_unlock(&q->lock); - usleep_range(100, 200); - ++count; - if (count < max_count) { - goto retry; - } else { - rc = -ETIMEDOUT; - dprintk(CVP_ERR, "%s: timed out!\n", __func__); - } - - return rc; -} - static int cvp_drain_fence_sched_list(struct msm_cvp_inst *inst) { unsigned long wait_time; @@ -1645,11 +1586,20 @@ int cvp_clean_session_queues(struct msm_cvp_inst *inst) struct cvp_session_queue *sq; u32 count = 0, max_retries = 100; + q = &inst->fence_cmd_queue; + mutex_lock(&q->lock); + if (q->state == QUEUE_START) { + mutex_unlock(&q->lock); cvp_clean_fence_queue(inst, SYNX_STATE_SIGNALED_ERROR); + } else { + dprintk(CVP_WARN, "Incorrect fence cmd queue state %d\n", + q->state); + mutex_unlock(&q->lock); + } + cvp_fence_thread_stop(inst); /* Waiting for all output synx sent */ - q = &inst->fence_cmd_queue; retry: mutex_lock(&q->lock); if (list_empty(&q->sched_list)) { @@ -1667,11 +1617,6 @@ retry: spin_lock(&sq->lock); sq->state = QUEUE_INVALID; spin_unlock(&sq->lock); - - sq = &inst->session_queue_fence; - spin_lock(&sq->lock); - sq->state = QUEUE_INVALID; - spin_unlock(&sq->lock); } static int cvp_flush_all(struct msm_cvp_inst *inst) @@ -1728,107 +1673,6 @@ exit: return rc; } -static void cvp_mark_fence_command(struct msm_cvp_inst *inst, u64 frame_id) -{ - int found = false; - struct cvp_fence_queue *q; - struct cvp_fence_command *f; - - q = &inst->fence_cmd_queue; - - list_for_each_entry(f, &q->sched_list, list) { - if (found) { - f->mode = OP_FLUSH; - continue; - } - - if (f->frame_id >= frame_id) { - found = true; - f->mode = OP_FLUSH; - } - } - - list_for_each_entry(f, &q->wait_list, list) { - if (found) { - f->mode = OP_FLUSH; - continue; - } - - if (f->frame_id >= frame_id) { - found = true; - f->mode = OP_FLUSH; - } - } -} - -static int cvp_flush_frame(struct msm_cvp_inst *inst, u64 frame_id) -{ - int rc = 0; - struct msm_cvp_inst *s; - struct cvp_fence_queue *q; - struct cvp_fence_command *f, *d; - u64 ktid; - - if (!inst || !inst->core) { - dprintk(CVP_ERR, "%s: invalid params\n", __func__); - return -EINVAL; - } - - s = cvp_get_inst_validate(inst->core, inst); - if (!s) - return -ECONNRESET; - - dprintk(CVP_SESS, "Session %llx, flush frame with id %llu\n", - inst, frame_id); - q = &inst->fence_cmd_queue; - - mutex_lock(&q->lock); - q->mode = OP_DRAINING; - - cvp_mark_fence_command(inst, frame_id); - - list_for_each_entry_safe(f, d, &q->wait_list, list) { - if (f->mode != OP_FLUSH) - continue; - - ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1); - - dprintk(CVP_SYNX, "%s: flush frame %llu %llu from wait_list\n", - __func__, ktid, f->frame_id); - - list_del_init(&f->list); - msm_cvp_unmap_frame(inst, f->pkt->client_data.kdata); - cvp_cancel_synx(inst, CVP_OUTPUT_SYNX, f, - SYNX_STATE_SIGNALED_CANCEL); - cvp_release_synx(inst, f); - cvp_free_fence_data(f); - } - - list_for_each_entry(f, &q->sched_list, list) { - if (f->mode != OP_FLUSH) - continue; - - ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1); - - dprintk(CVP_SYNX, "%s: flush frame %llu %llu from sched_list\n", - __func__, ktid, f->frame_id); - cvp_cancel_synx(inst, CVP_INPUT_SYNX, f, - SYNX_STATE_SIGNALED_CANCEL); - } - - mutex_unlock(&q->lock); - - rc = cvp_drain_fence_cmd_queue_partial(inst); - if (rc) - dprintk(CVP_WARN, "%s: continue flush. rc %d\n", - __func__, rc); - - rc = cvp_flush_all(inst); - - cvp_put_inst(s); - return rc; -} - int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct eva_kmd_arg *arg) { int rc = 0; @@ -1916,7 +1760,8 @@ int msm_cvp_handle_syscall(struct msm_cvp_inst *inst, struct eva_kmd_arg *arg) rc = cvp_flush_all(inst); break; case EVA_KMD_FLUSH_FRAME: - rc = cvp_flush_frame(inst, arg->data.frame_id); + dprintk(CVP_WARN, "EVA_KMD_FLUSH_FRAME IOCTL deprecated\n"); + rc = 0; break; default: dprintk(CVP_HFI, "%s: unknown arg type %#x\n", diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index aa7430cced..fd3c3b2dd4 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -945,7 +945,6 @@ void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) return; } - dprintk(CVP_ERR, "active session cmd %d\n", inst->cur_cmd_type); dprintk(CVP_ERR, "---Buffer details for inst: %pK of type: %d---\n", inst, inst->session_type); @@ -1221,7 +1220,6 @@ int msm_cvp_register_buffer(struct msm_cvp_inst *inst, if (!s) return -ECONNRESET; - inst->cur_cmd_type = EVA_KMD_REGISTER_BUFFER; session = (struct cvp_hal_session *)inst->session; if (!session) { dprintk(CVP_ERR, "%s: invalid session\n", __func__); @@ -1235,7 +1233,6 @@ int msm_cvp_register_buffer(struct msm_cvp_inst *inst, dprintk(CVP_DSP, "%s: fd %d, iova 0x%x\n", __func__, buf->fd, buf->reserved[0]); exit: - inst->cur_cmd_type = 0; cvp_put_inst(s); return rc; } @@ -1258,11 +1255,9 @@ int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst, if (!s) return -ECONNRESET; - inst->cur_cmd_type = EVA_KMD_UNREGISTER_BUFFER; print_client_buffer(CVP_HFI, "unregister", inst, buf); rc = msm_cvp_unmap_buf_dsp(inst, buf); - inst->cur_cmd_type = 0; cvp_put_inst(s); return rc; } diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index 703b45b1e1..28de546401 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -10,7 +10,6 @@ #include #include #include -#include #include #include diff --git a/msm/eva/msm_cvp_clocks.c b/msm/eva/msm_cvp_clocks.c index ceb678522e..b03389df73 100644 --- a/msm/eva/msm_cvp_clocks.c +++ b/msm/eva/msm_cvp_clocks.c @@ -417,3 +417,19 @@ void msm_cvp_deinit_clocks(struct iris_hfi_device *device) } } } + +int msm_cvp_set_bw(struct bus_info *bus, unsigned long bw) +{ + int rc = 0; + + if (!bus->client) + return -EINVAL; + + rc = icc_set_bw(bus->client, bw, 0); + if (rc) + dprintk(CVP_ERR, "Failed voting bus %s to ab %u\n", + bus->name, bw); + + return rc; +} + diff --git a/msm/eva/msm_cvp_clocks.h b/msm/eva/msm_cvp_clocks.h index 0cd95546dd..48ffea055b 100644 --- a/msm/eva/msm_cvp_clocks.h +++ b/msm/eva/msm_cvp_clocks.h @@ -22,4 +22,5 @@ int msm_cvp_disable_unprepare_clk(struct iris_hfi_device *device, const char *name); int msm_cvp_init_clocks(struct iris_hfi_device *device); void msm_cvp_deinit_clocks(struct iris_hfi_device *device); +int msm_cvp_set_bw(struct bus_info *bus, unsigned long bw); #endif diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 4384860fb4..19f2dddfdc 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -22,6 +22,11 @@ static void handle_session_error(enum hal_command_response cmd, void *data); +static void msm_cvp_comm_generate_session_error(struct msm_cvp_inst *inst) +{ + dprintk(CVP_WARN, "%s function is deprecated\n"); +} + static void dump_hfi_queue(struct iris_hfi_device *device) { struct cvp_hfi_queue_header *queue; @@ -36,10 +41,12 @@ static void dump_hfi_queue(struct iris_hfi_device *device) * main memory. */ mb(); + mutex_lock(&device->lock); for (i = 0; i <= CVP_IFACEQ_DBGQ_IDX; i++) { qinfo = &device->iface_queues[i]; queue = (struct cvp_hfi_queue_header *)qinfo->q_hdr; if (!queue) { + mutex_unlock(&device->lock); dprintk(CVP_ERR, "HFI queue not init, fail to dump\n"); return; } @@ -55,6 +62,7 @@ static void dump_hfi_queue(struct iris_hfi_device *device) } } + mutex_unlock(&device->lock); } struct msm_cvp_core *get_cvp_core(int core_id) @@ -280,6 +288,11 @@ static void handle_session_release_buf_done(enum hal_command_response cmd, } mutex_unlock(&inst->persistbufs.lock); + if (response->status) + dprintk(CVP_ERR, "HFI release persist buf err 0x%x\n", + response->status); + inst->error_code = response->status; + if (IS_HAL_SESSION_CMD(cmd)) complete(&inst->completions[SESSION_MSG_INDEX(cmd)]); else @@ -364,11 +377,13 @@ int wait_for_sess_signal_receipt(struct msm_cvp_inst *inst, SESSION_MSG_INDEX(cmd)); call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data); dump_hfi_queue(hdev->hfi_device_data); - rc = -EIO; + rc = -ETIMEDOUT; } else if (inst->state == MSM_CVP_CORE_INVALID) { rc = -ECONNRESET; } else { - rc = 0; + rc = inst->error_code; + inst->prev_error_code = inst->error_code; + inst->error_code = CVP_ERR_NONE; } return rc; } @@ -393,25 +408,6 @@ err_same_state: return rc; } -void msm_cvp_notify_event(struct msm_cvp_inst *inst, int event_type) -{ -} - -static void msm_cvp_comm_generate_max_clients_error(struct msm_cvp_inst *inst) -{ - enum hal_command_response cmd = HAL_SESSION_ERROR; - struct msm_cvp_cb_cmd_done response = {0}; - - if (!inst) { - dprintk(CVP_ERR, "%s: invalid input parameters\n", __func__); - return; - } - dprintk(CVP_ERR, "%s: Too many clients\n", __func__); - response.session_id = inst; - response.status = CVP_ERR_MAX_CLIENTS; - handle_session_error(cmd, (void *)&response); -} - static void handle_session_init_done(enum hal_command_response cmd, void *data) { struct msm_cvp_cb_cmd_done *response = data; @@ -432,23 +428,16 @@ static void handle_session_init_done(enum hal_command_response cmd, void *data) return; } - if (response->status) { + if (response->status) dprintk(CVP_ERR, - "Session init response from FW : %#x\n", - response->status); - if (response->status == CVP_ERR_MAX_CLIENTS) - msm_cvp_comm_generate_max_clients_error(inst); - else - msm_cvp_comm_generate_session_error(inst); + "Session %#x init err response from FW : 0x%x\n", + hash32_ptr(inst->session), response->status); - signal_session_msg_receipt(cmd, inst); - cvp_put_inst(inst); - return; - } - - dprintk(CVP_SESS, "%s: cvp session %#x\n", __func__, - hash32_ptr(inst->session)); + else + dprintk(CVP_SESS, "%s: cvp session %#x\n", __func__, + hash32_ptr(inst->session)); + inst->error_code = response->status; signal_session_msg_receipt(cmd, inst); cvp_put_inst(inst); return; @@ -530,6 +519,11 @@ static void handle_session_flush(enum hal_command_response cmd, void *data) return; } + if (response->status) + dprintk(CVP_ERR, "HFI sess flush err 0x%x\n", + response->status); + + inst->error_code = response->status; signal_session_msg_receipt(cmd, inst); cvp_put_inst(inst); } @@ -539,7 +533,6 @@ static void handle_session_error(enum hal_command_response cmd, void *data) struct msm_cvp_cb_cmd_done *response = data; struct cvp_hfi_device *hdev = NULL; struct msm_cvp_inst *inst = NULL; - int event = CVP_SYS_ERROR_EVENT; if (!response) { dprintk(CVP_ERR, @@ -556,33 +549,9 @@ static void handle_session_error(enum hal_command_response cmd, void *data) } hdev = inst->core->device; - dprintk(CVP_ERR, "Session error received for inst %pK session %x\n", - inst, hash32_ptr(inst->session)); + dprintk(CVP_ERR, "Sess error 0x%x received for inst %pK sess %x\n", + response->status, inst, hash32_ptr(inst->session)); - if (response->status == CVP_ERR_MAX_CLIENTS) { - dprintk(CVP_WARN, "Too many clients, rejecting %pK", inst); - event = CVP_MAX_CLIENTS_EVENT; - - /* - * Clean the HFI session now. Since inst->state is moved to - * INVALID, forward thread doesn't know FW has valid session - * or not. This is the last place driver knows that there is - * no session in FW. Hence clean HFI session now. - */ - - msm_cvp_comm_session_clean(inst); - } else if (response->status == CVP_ERR_NOT_SUPPORTED) { - dprintk(CVP_WARN, "Unsupported bitstream in %pK", inst); - event = CVP_HW_UNSUPPORTED_EVENT; - } else { - dprintk(CVP_WARN, "Unknown session error (%d) for %pK\n", - response->status, inst); - event = CVP_SYS_ERROR_EVENT; - } - - /* change state before sending error to client */ - change_cvp_inst_state(inst, MSM_CVP_CORE_INVALID); - msm_cvp_notify_event(inst, event); cvp_put_inst(inst); } @@ -604,8 +573,6 @@ static void msm_comm_clean_notify_client(struct msm_cvp_core *core) mutex_unlock(&inst->lock); dprintk(CVP_WARN, "%s Send sys error for inst %pK\n", __func__, inst); - msm_cvp_notify_event(inst, - CVP_SYS_ERROR_EVENT); } mutex_unlock(&core->lock); } @@ -645,6 +612,7 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) cur_state = core->state; core->state = CVP_CORE_UNINIT; + mutex_lock(&core->clk_lock); dprintk(CVP_WARN, "SYS_ERROR received for core %pK\n", core); if (response->status == CVP_ERR_NOC_ERROR) { dprintk(CVP_WARN, "Got NOC error"); @@ -654,9 +622,9 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data); list_for_each_entry(inst, &core->instances, list) { dprintk(CVP_WARN, - "%s: sys error inst %#x kref %x, cmd %x state %x\n", + "%s: sys error inst %#x kref %x, state %x\n", __func__, inst, kref_read(&inst->kref), - inst->cur_cmd_type, inst->state); + inst->state); if (inst->state != MSM_CVP_CORE_INVALID) { change_cvp_inst_state(inst, MSM_CVP_CORE_INVALID); if (cvp_clean_session_queues(inst)) @@ -682,9 +650,11 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) if (rc) { dprintk(CVP_ERR, "core_release failed\n"); core->state = cur_state; + mutex_unlock(&core->clk_lock); mutex_unlock(&core->lock); return; } + mutex_unlock(&core->clk_lock); mutex_unlock(&core->lock); dprintk(CVP_WARN, "SYS_ERROR handled.\n"); @@ -738,6 +708,11 @@ static void handle_session_close(enum hal_command_response cmd, void *data) return; } + if (response->status) + dprintk(CVP_ERR, "HFI sess close fail 0x%x\n", + response->status); + + inst->error_code = response->status; signal_session_msg_receipt(cmd, inst); show_stats(inst); cvp_put_inst(inst); @@ -920,8 +895,6 @@ static void handle_thermal_event(struct msm_cvp_core *core) dprintk(CVP_WARN, "%s Send sys error for inst %pK\n", __func__, inst); - msm_cvp_notify_event(inst, - CVP_SYS_ERROR_EVENT); } else { msm_cvp_comm_generate_session_error(inst); } @@ -1071,23 +1044,6 @@ int msm_cvp_deinit_core(struct msm_cvp_inst *inst) goto core_already_uninited; } - if (!core->resources.never_unload_fw) { - cancel_delayed_work(&core->fw_unload_work); - - /* - * Delay unloading of firmware. This is useful - * in avoiding firmware download delays in cases where we - * will have a burst of back to back cvp sessions - */ - schedule_delayed_work(&core->fw_unload_work, - msecs_to_jiffies(core->state == CVP_CORE_INIT_DONE ? - core->resources.msm_cvp_firmware_unload_delay : 0)); - - dprintk(CVP_CORE, "firmware unload delayed by %u ms\n", - core->state == CVP_CORE_INIT_DONE ? - core->resources.msm_cvp_firmware_unload_delay : 0); - } - core_already_uninited: change_cvp_inst_state(inst, MSM_CVP_CORE_UNINIT); mutex_unlock(&core->lock); @@ -1104,7 +1060,6 @@ static int msm_comm_session_init_done(int flipped_state, HAL_SESSION_INIT_DONE); if (rc) { dprintk(CVP_ERR, "Session init failed for inst %pK\n", inst); - msm_cvp_comm_generate_sys_error(inst); return rc; } @@ -1289,9 +1244,9 @@ int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state) mutex_unlock(&inst->sync_lock); - if (rc) { + if (rc == -ETIMEDOUT) { dprintk(CVP_ERR, - "Failed to move from state: %d to %d\n", + "Timedout move from state: %d to %d\n", inst->state, state); msm_cvp_comm_kill_session(inst); } @@ -1358,9 +1313,8 @@ void msm_cvp_ssr_handler(struct work_struct *work) dprintk(CVP_ERR, "Session abort triggered\n"); list_for_each_entry(inst, &core->instances, list) { dprintk(CVP_WARN, - "Session to abort: inst %#x cmd %x ref %x\n", - inst, inst->cur_cmd_type, - kref_read(&inst->kref)); + "Session to abort: inst %#x ref %x\n", + inst, kref_read(&inst->kref)); break; } @@ -1414,21 +1368,6 @@ send_again: mutex_unlock(&core->lock); } -void msm_cvp_comm_generate_session_error(struct msm_cvp_inst *inst) -{ - enum hal_command_response cmd = HAL_SESSION_ERROR; - struct msm_cvp_cb_cmd_done response = {0}; - - if (!inst || !inst->core) { - dprintk(CVP_ERR, "%s: invalid input parameters\n", __func__); - return; - } - dprintk(CVP_WARN, "%s: inst %pK\n", __func__, inst); - response.session_id = inst; - response.status = CVP_ERR_FAIL; - handle_session_error(cmd, (void *)&response); -} - void msm_cvp_comm_generate_sys_error(struct msm_cvp_inst *inst) { struct msm_cvp_core *core; diff --git a/msm/eva/msm_cvp_common.h b/msm/eva/msm_cvp_common.h index 5ea32913fe..e3fd84770d 100644 --- a/msm/eva/msm_cvp_common.h +++ b/msm/eva/msm_cvp_common.h @@ -22,7 +22,6 @@ int msm_cvp_deinit_core(struct msm_cvp_inst *inst); int msm_cvp_comm_suspend(int core_id); void msm_cvp_comm_session_clean(struct msm_cvp_inst *inst); int msm_cvp_comm_kill_session(struct msm_cvp_inst *inst); -void msm_cvp_comm_generate_session_error(struct msm_cvp_inst *inst); void msm_cvp_comm_generate_sys_error(struct msm_cvp_inst *inst); int msm_cvp_comm_smem_cache_operations(struct msm_cvp_inst *inst, struct msm_cvp_smem *mem, enum smem_cache_ops cache_ops); diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index a25733f0e3..c2e24208e1 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -154,9 +154,8 @@ void *msm_cvp_open(int core_id, int session_type) dprintk(CVP_ERR, "Instance num reached Max, rejecting session"); mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) - dprintk(CVP_ERR, "inst %pK, cmd %d id %d\n", - inst, inst->cur_cmd_type, - hash32_ptr(inst->session)); + dprintk(CVP_ERR, "inst %pK, id %d\n", + inst, hash32_ptr(inst->session)); mutex_unlock(&core->lock); return NULL; @@ -225,6 +224,7 @@ void *msm_cvp_open(int core_id, int session_type) return inst; fail_init: __deinit_session_queue(inst); + __deinit_fence_queue(inst); mutex_lock(&core->lock); list_del(&inst->list); mutex_unlock(&core->lock); @@ -270,6 +270,7 @@ static void msm_cvp_cleanup_instance(struct msm_cvp_inst *inst) int max_retries; struct msm_cvp_frame *frame; struct cvp_session_queue *sq, *sqf; + struct cvp_hfi_device *hdev; if (!inst) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); @@ -325,6 +326,20 @@ wait: if (cvp_release_arp_buffers(inst)) dprintk(CVP_ERR, "Failed to release persist buffers\n"); + + if (inst->prop.type == HFI_SESSION_FD + || inst->prop.type == HFI_SESSION_DMM) { + spin_lock(&inst->core->resources.pm_qos.lock); + if (inst->core->resources.pm_qos.off_vote_cnt > 0) + inst->core->resources.pm_qos.off_vote_cnt--; + else + dprintk(CVP_WARN, "%s Unexpected pm_qos off vote %d\n", + __func__, + inst->core->resources.pm_qos.off_vote_cnt); + spin_unlock(&inst->core->resources.pm_qos.lock); + hdev = inst->core->device; + call_hfi_op(hdev, pm_qos_update, hdev->hfi_device_data); + } } int msm_cvp_destroy(struct msm_cvp_inst *inst) @@ -362,9 +377,6 @@ int msm_cvp_destroy(struct msm_cvp_inst *inst) pr_info(CVP_DBG_TAG "Closed cvp instance: %pK session_id = %d\n", "sess", inst, hash32_ptr(inst->session)); - if (inst->cur_cmd_type) - dprintk(CVP_ERR, "deleted instance has pending cmd %d\n", - inst->cur_cmd_type); inst->session = (void *)0xdeadbeef; kfree(inst); return 0; diff --git a/msm/eva/msm_cvp_core.h b/msm/eva/msm_cvp_core.h index c00fd102f6..1e27728903 100644 --- a/msm/eva/msm_cvp_core.h +++ b/msm/eva/msm_cvp_core.h @@ -9,7 +9,6 @@ #include #include #include -#include #include #include #include "msm_cvp_buf.h" diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index aab0b64e88..efeaebc312 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -234,7 +234,7 @@ DEFINE_DEBUGFS_ATTRIBUTE(cvp_pwr_fops, cvp_power_get, cvp_power_set, "%llu\n"); struct dentry *msm_cvp_debugfs_init_drv(void) { - struct dentry *dir = NULL, *f; + struct dentry *dir = NULL; dir = debugfs_create_dir("msm_cvp", NULL); if (IS_ERR_OR_NULL(dir)) { @@ -248,26 +248,17 @@ struct dentry *msm_cvp_debugfs_init_drv(void) debugfs_create_u32("fw_low_power_mode", 0644, dir, &msm_cvp_fw_low_power_mode); debugfs_create_u32("debug_output", 0644, dir, &msm_cvp_debug_out); - debugfs_create_u32("minidump_enable", 0644, dir, &msm_cvp_minidump_enable); - f = debugfs_create_bool("fw_coverage", 0644, dir, &msm_cvp_fw_coverage); - if (IS_ERR_OR_NULL(f)) - goto failed_create_dir; - f = debugfs_create_bool("disable_thermal_mitigation", 0644, dir, + debugfs_create_u32("minidump_enable", 0644, dir, + &msm_cvp_minidump_enable); + debugfs_create_bool("fw_coverage", 0644, dir, &msm_cvp_fw_coverage); + debugfs_create_bool("disable_thermal_mitigation", 0644, dir, &msm_cvp_thermal_mitigation_disabled); - if (IS_ERR_OR_NULL(f)) - goto failed_create_dir; - f = debugfs_create_bool("enable_cacheop", 0644, dir, + debugfs_create_bool("enable_cacheop", 0644, dir, &msm_cvp_cacheop_enabled); - if (IS_ERR_OR_NULL(f)) - goto failed_create_dir; - f = debugfs_create_bool("disable_cvp_syscache", 0644, dir, + debugfs_create_bool("disable_cvp_syscache", 0644, dir, &msm_cvp_syscache_disable); - if (IS_ERR_OR_NULL(f)) - goto failed_create_dir; - f = debugfs_create_bool("disable_dcvs", 0644, dir, + debugfs_create_bool("disable_dcvs", 0644, dir, &msm_cvp_dcvs_disable); - if (IS_ERR_OR_NULL(f)) - goto failed_create_dir; debugfs_create_file("cvp_power", 0644, dir, NULL, &cvp_pwr_fops); diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 9da9c09915..2308f2a9c1 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -215,6 +215,7 @@ static int delete_dsp_session(struct msm_cvp_inst *inst, struct list_head *ptr_dsp_buf = NULL, *next_dsp_buf = NULL; struct cvp_internal_buf *buf = NULL; struct task_struct *task = NULL; + struct cvp_hfi_device *hdev; int rc; if (!inst) @@ -265,6 +266,18 @@ static int delete_dsp_session(struct msm_cvp_inst *inst, task = inst->task; + spin_lock(&inst->core->resources.pm_qos.lock); + if (inst->core->resources.pm_qos.off_vote_cnt > 0) + inst->core->resources.pm_qos.off_vote_cnt--; + else + dprintk(CVP_WARN, "%s Unexpected pm_qos off vote %d\n", + __func__, + inst->core->resources.pm_qos.off_vote_cnt); + spin_unlock(&inst->core->resources.pm_qos.lock); + + hdev = inst->core->device; + call_hfi_op(hdev, pm_qos_update, hdev->hfi_device_data); + rc = msm_cvp_close(inst); if (rc) dprintk(CVP_ERR, "Warning: Failed to close cvp instance\n"); @@ -1287,6 +1300,7 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; struct pid *pid_s = NULL; struct task_struct *task = NULL; + struct cvp_hfi_device *hdev; cmd->ret = 0; @@ -1361,6 +1375,12 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) __func__, cmd->session_id, cmd->session_cpu_low, cmd->session_cpu_high); + spin_lock(&inst->core->resources.pm_qos.lock); + inst->core->resources.pm_qos.off_vote_cnt++; + spin_unlock(&inst->core->resources.pm_qos.lock); + hdev = inst->core->device; + call_hfi_op(hdev, pm_qos_update, hdev->hfi_device_data); + return; fail_get_pid: @@ -1382,6 +1402,7 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; struct task_struct *task = NULL; + struct cvp_hfi_device *hdev; cmd->ret = 0; @@ -1418,6 +1439,18 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) task = inst->task; + spin_lock(&inst->core->resources.pm_qos.lock); + if (inst->core->resources.pm_qos.off_vote_cnt > 0) + inst->core->resources.pm_qos.off_vote_cnt--; + else + dprintk(CVP_WARN, "%s Unexpected pm_qos off vote %d\n", + __func__, + inst->core->resources.pm_qos.off_vote_cnt); + spin_unlock(&inst->core->resources.pm_qos.lock); + + hdev = inst->core->device; + call_hfi_op(hdev, pm_qos_update, hdev->hfi_device_data); + rc = msm_cvp_close(inst); if (rc) { dprintk(CVP_ERR, "Warning: Failed to close cvp instance\n"); @@ -1916,8 +1949,7 @@ int cvp_dsp_device_init(void) int i; char name[CVP_FASTRPC_DRIVER_NAME_SIZE] = "qcom,fastcv0\0"; - add_va_node_to_list(&head_node_dbg_struct, - &gfa_cv, sizeof(struct cvp_dsp_apps), + add_va_node_to_list(CVP_DBG_DUMP, &gfa_cv, sizeof(struct cvp_dsp_apps), "cvp_dsp_apps-gfa_cv", false); mutex_init(&me->tx_lock); diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index 6938886965..e4d3078cc5 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -398,7 +398,10 @@ struct msm_cvp_inst { struct msm_cvp_capability capability; struct kref kref; struct cvp_session_prop prop; - u32 cur_cmd_type; + /* error_code will be cleared after being returned to user mode */ + u32 error_code; + /* prev_error_code saves value of error_code before it's cleared */ + u32 prev_error_code; struct synx_session synx_session_id; struct cvp_fence_queue fence_cmd_queue; }; diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index d4176f81ad..90c6520396 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -15,7 +15,7 @@ #include #include #include -#include +#include #include "msm_cvp_internal.h" #include "msm_cvp_debug.h" #include "cvp_hfi_api.h" @@ -38,7 +38,7 @@ static struct msm_cvp_common_data default_common_data[] = { { - .key = "qcom,never-unload-fw", + .key = "qcom,auto-pil", .value = 1, }, }; @@ -49,8 +49,8 @@ static struct msm_cvp_common_data sm8450_common_data[] = { .value = 1, }, { - .key = "qcom,never-unload-fw", - .value = 1, + .key = "qcom,pm-qos-latency-us", + .value = 50, }, { .key = "qcom,sw-power-collapse", @@ -102,11 +102,11 @@ static struct msm_cvp_common_data sm8450_common_data[] = { static struct msm_cvp_common_data sm8550_common_data[] = { { .key = "qcom,auto-pil", - .value = 0, + .value = 1, }, { - .key = "qcom,never-unload-fw", - .value = 1, + .key = "qcom,pm-qos-latency-us", + .value = 50, }, { .key = "qcom,sw-power-collapse", @@ -194,8 +194,8 @@ static struct msm_cvp_platform_data sm8550_data = { .common_data_length = ARRAY_SIZE(sm8550_common_data), .sku_version = 0, .vpu_ver = VPU_VERSION_5, - .ubwc_config = kona_ubwc_data, - .noc_qos = 0x0, + .ubwc_config = kona_ubwc_data, /*Reuse Kona setting*/ + .noc_qos = &waipio_noc_qos, /*Reuse Waipio setting*/ }; static const struct of_device_id msm_cvp_dt_match[] = { @@ -204,7 +204,7 @@ static const struct of_device_id msm_cvp_dt_match[] = { .data = &sm8450_data, }, { - .compatible = "qcom,kailua-cvp", + .compatible = "qcom,kalama-cvp", .data = &sm8550_data, }, diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index 86288e90e9..3b3b7e9254 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -750,7 +750,7 @@ int cvp_read_platform_resources_from_drv_data( { struct msm_cvp_platform_data *platform_data; struct msm_cvp_platform_resources *res; - int rc = 0; + int rc = 0, i; if (!core || !core->platform_data) { dprintk(CVP_ERR, "%s Invalid data\n", __func__); @@ -777,14 +777,16 @@ int cvp_read_platform_resources_from_drv_data( res->sw_power_collapsible = find_key_value(platform_data, "qcom,sw-power-collapse"); - res->never_unload_fw = find_key_value(platform_data, - "qcom,never-unload-fw"); - res->debug_timeout = find_key_value(platform_data, "qcom,debug-timeout"); - res->pm_qos_latency_us = find_key_value(platform_data, + res->pm_qos.latency_us = find_key_value(platform_data, "qcom,pm-qos-latency-us"); + res->pm_qos.silver_count = 4; + for (i = 0; i < res->pm_qos.silver_count; i++) + res->pm_qos.silver_cores[i] = i; + res->pm_qos.off_vote_cnt = 0; + spin_lock_init(&res->pm_qos.lock); res->max_secure_inst_count = find_key_value(platform_data, "qcom,max-secure-instances"); diff --git a/msm/eva/msm_cvp_resources.h b/msm/eva/msm_cvp_resources.h index 9c8840e6fb..cc093dd710 100644 --- a/msm/eva/msm_cvp_resources.h +++ b/msm/eva/msm_cvp_resources.h @@ -8,6 +8,7 @@ #include #include +#include #include "msm_cvp_core.h" #include @@ -134,6 +135,19 @@ struct msm_cvp_mem_cdsp { struct device *dev; }; +#define MAX_SILVER_CORE_NUM 8 +#define HFI_SESSION_FD 4 +#define HFI_SESSION_DMM 2 + +struct cvp_pm_qos { + u32 silver_count; + u32 latency_us; + u32 off_vote_cnt; + spinlock_t lock; + int silver_cores[MAX_SILVER_CORE_NUM]; + struct dev_pm_qos_request *pm_qos_hdls; +}; + struct msm_cvp_platform_resources { phys_addr_t firmware_base; phys_addr_t register_base; @@ -166,9 +180,8 @@ struct msm_cvp_platform_resources { bool thermal_mitigable; const char *fw_name; const char *hfi_version; - bool never_unload_fw; bool debug_timeout; - uint32_t pm_qos_latency_us; + struct cvp_pm_qos pm_qos; uint32_t max_inst_count; uint32_t max_secure_inst_count; int msm_cvp_hw_rsp_timeout; diff --git a/msm/eva/msm_cvp_synx.c b/msm/eva/msm_cvp_synx.c index 084e7300a4..c5715415c1 100644 --- a/msm/eva/msm_cvp_synx.c +++ b/msm/eva/msm_cvp_synx.c @@ -71,7 +71,7 @@ void cvp_dump_fence_queue(struct msm_cvp_inst *inst) int cvp_import_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, u32 *fence) { - int rc = 0; + int rc = 0, rr = 0; int i; struct cvp_fence_type *fs; struct synx_import_params params; @@ -99,12 +99,12 @@ int cvp_import_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, dprintk(CVP_ERR, "%s: %d synx_import failed\n", __func__, h_synx); - return rc; + rr = rc; } } } - return 0; + return rr; } int cvp_release_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc) diff --git a/msm/eva/msm_smem.c b/msm/eva/msm_smem.c index d91625f7c2..8466bd43a3 100644 --- a/msm/eva/msm_smem.c +++ b/msm/eva/msm_smem.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include From 40716f1fe7d69ac8543d0e541022bbdb74798b8e Mon Sep 17 00:00:00 2001 From: Yu SI Date: Thu, 11 Nov 2021 11:21:10 -0800 Subject: [PATCH 100/317] msm: eva: Move eva event header to vendor The change makes EVA kernel driver more self-contained after removing one more dependency from kernel component. propagated from 3858889. Change-Id: I20d34b631f516ee917d50329081f5135a1c4bec6 Signed-off-by: Yu SI --- msm/eva/msm_cvp_debug.h | 2 +- msm/eva/msm_cvp_events.h | 363 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 364 insertions(+), 1 deletion(-) create mode 100644 msm/eva/msm_cvp_events.h diff --git a/msm/eva/msm_cvp_debug.h b/msm/eva/msm_cvp_debug.h index e9f8df605b..5a8d36474c 100644 --- a/msm/eva/msm_cvp_debug.h +++ b/msm/eva/msm_cvp_debug.h @@ -8,7 +8,7 @@ #include #include #include "msm_cvp_internal.h" -#include "trace/events/msm_cvp_events.h" +#include "msm_cvp_events.h" #ifndef CVP_DBG_LABEL #define CVP_DBG_LABEL "msm_cvp" diff --git a/msm/eva/msm_cvp_events.h b/msm/eva/msm_cvp_events.h new file mode 100644 index 0000000000..dbe3a2843a --- /dev/null +++ b/msm/eva/msm_cvp_events.h @@ -0,0 +1,363 @@ +/* SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2020 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM msm_cvp_events + +#if !defined(_TRACE_MSM_CVP_H_) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_MSM_CVP_H +#include +#include + +TRACE_EVENT(tracing_mark_write_cvp, + TP_PROTO(int pid, const char *name, bool trace_begin), + TP_ARGS(pid, name, trace_begin), + TP_STRUCT__entry( + __field(int, pid) + __string(trace_name, name) + __field(bool, trace_begin) + ), + TP_fast_assign( + __entry->pid = pid; + __assign_str(trace_name, name); + __entry->trace_begin = trace_begin; + ), + TP_printk("%s|%d|%s", __entry->trace_begin ? "B" : "E", + __entry->pid, __get_str(trace_name)) +) +#define CVPKERNEL_ATRACE_END(name) \ + trace_tracing_mark_write_cvp(current->tgid, name, 0) +#define CVPKERNEL_ATRACE_BEGIN(name) \ + trace_tracing_mark_write_cvp(current->tgid, name, 1) + + +DECLARE_EVENT_CLASS(msm_v4l2_cvp, + + TP_PROTO(char *dummy), + + TP_ARGS(dummy), + + TP_STRUCT__entry( + __field(char *, dummy) + ), + + TP_fast_assign( + __entry->dummy = dummy; + ), + + TP_printk("%s", __entry->dummy) +); + +DEFINE_EVENT(msm_v4l2_cvp, msm_v4l2_cvp_open_start, + + TP_PROTO(char *dummy), + + TP_ARGS(dummy) +); + +DEFINE_EVENT(msm_v4l2_cvp, msm_v4l2_cvp_open_end, + + TP_PROTO(char *dummy), + + TP_ARGS(dummy) +); + +DEFINE_EVENT(msm_v4l2_cvp, msm_v4l2_cvp_close_start, + + TP_PROTO(char *dummy), + + TP_ARGS(dummy) +); + +DEFINE_EVENT(msm_v4l2_cvp, msm_v4l2_cvp_close_end, + + TP_PROTO(char *dummy), + + TP_ARGS(dummy) +); + +DEFINE_EVENT(msm_v4l2_cvp, msm_v4l2_cvp_fw_load_start, + + TP_PROTO(char *dummy), + + TP_ARGS(dummy) +); + +DEFINE_EVENT(msm_v4l2_cvp, msm_v4l2_cvp_fw_load_end, + + TP_PROTO(char *dummy), + + TP_ARGS(dummy) +); + +DECLARE_EVENT_CLASS(msm_cvp_common, + + TP_PROTO(void *instp, int old_state, int new_state), + + TP_ARGS(instp, old_state, new_state), + + TP_STRUCT__entry( + __field(void *, instp) + __field(int, old_state) + __field(int, new_state) + ), + + TP_fast_assign( + __entry->instp = instp; + __entry->old_state = old_state; + __entry->new_state = new_state; + ), + + TP_printk("Moved inst: %p from 0x%x to 0x%x", + __entry->instp, + __entry->old_state, + __entry->new_state) +); + +DEFINE_EVENT(msm_cvp_common, msm_cvp_common_state_change, + + TP_PROTO(void *instp, int old_state, int new_state), + + TP_ARGS(instp, old_state, new_state) +); + +DECLARE_EVENT_CLASS(cvp_venus_hfi_var, + + TP_PROTO(u32 cp_start, u32 cp_size, + u32 cp_nonpixel_start, u32 cp_nonpixel_size), + + TP_ARGS(cp_start, cp_size, cp_nonpixel_start, cp_nonpixel_size), + + TP_STRUCT__entry( + __field(u32, cp_start) + __field(u32, cp_size) + __field(u32, cp_nonpixel_start) + __field(u32, cp_nonpixel_size) + ), + + TP_fast_assign( + __entry->cp_start = cp_start; + __entry->cp_size = cp_size; + __entry->cp_nonpixel_start = cp_nonpixel_start; + __entry->cp_nonpixel_size = cp_nonpixel_size; + ), + + TP_printk( + "TZBSP_MEM_PROTECT_VIDEO_VAR done, cp_start : 0x%x, cp_size : 0x%x, cp_nonpixel_start : 0x%x, cp_nonpixel_size : 0x%x", + __entry->cp_start, + __entry->cp_size, + __entry->cp_nonpixel_start, + __entry->cp_nonpixel_size) +); + +DEFINE_EVENT(cvp_venus_hfi_var, cvp_venus_hfi_var_done, + + TP_PROTO(u32 cp_start, u32 cp_size, + u32 cp_nonpixel_start, u32 cp_nonpixel_size), + + TP_ARGS(cp_start, cp_size, cp_nonpixel_start, cp_nonpixel_size) +); + +DECLARE_EVENT_CLASS(msm_v4l2_cvp_buffer_events, + + TP_PROTO(char *event_type, u32 device_addr, int64_t timestamp, + u32 alloc_len, u32 filled_len, u32 offset), + + TP_ARGS(event_type, device_addr, timestamp, alloc_len, + filled_len, offset), + + TP_STRUCT__entry( + __field(char *, event_type) + __field(u32, device_addr) + __field(int64_t, timestamp) + __field(u32, alloc_len) + __field(u32, filled_len) + __field(u32, offset) + ), + + TP_fast_assign( + __entry->event_type = event_type; + __entry->device_addr = device_addr; + __entry->timestamp = timestamp; + __entry->alloc_len = alloc_len; + __entry->filled_len = filled_len; + __entry->offset = offset; + ), + + TP_printk( + "%s, device_addr : 0x%x, timestamp : %lld, alloc_len : 0x%x, filled_len : 0x%x, offset : 0x%x", + __entry->event_type, + __entry->device_addr, + __entry->timestamp, + __entry->alloc_len, + __entry->filled_len, + __entry->offset) +); + +DEFINE_EVENT(msm_v4l2_cvp_buffer_events, msm_v4l2_cvp_buffer_event_start, + + TP_PROTO(char *event_type, u32 device_addr, int64_t timestamp, + u32 alloc_len, u32 filled_len, u32 offset), + + TP_ARGS(event_type, device_addr, timestamp, alloc_len, + filled_len, offset) +); + +DEFINE_EVENT(msm_v4l2_cvp_buffer_events, msm_v4l2_cvp_buffer_event_end, + + TP_PROTO(char *event_type, u32 device_addr, int64_t timestamp, + u32 alloc_len, u32 filled_len, u32 offset), + + TP_ARGS(event_type, device_addr, timestamp, alloc_len, + filled_len, offset) +); + +DECLARE_EVENT_CLASS(msm_cvp_smem_buffer_dma_ops, + + TP_PROTO(char *buffer_op, u32 buffer_type, u32 heap_mask, + size_t size, u32 align, u32 flags, int map_kernel), + + TP_ARGS(buffer_op, buffer_type, heap_mask, size, align, + flags, map_kernel), + + TP_STRUCT__entry( + __field(char *, buffer_op) + __field(u32, buffer_type) + __field(u32, heap_mask) + __field(u32, size) + __field(u32, align) + __field(u32, flags) + __field(int, map_kernel) + ), + + TP_fast_assign( + __entry->buffer_op = buffer_op; + __entry->buffer_type = buffer_type; + __entry->heap_mask = heap_mask; + __entry->size = size; + __entry->align = align; + __entry->flags = flags; + __entry->map_kernel = map_kernel; + ), + + TP_printk( + "%s, buffer_type : 0x%x, heap_mask : 0x%x, size : 0x%x, align : 0x%x, flags : 0x%x, map_kernel : %d", + __entry->buffer_op, + __entry->buffer_type, + __entry->heap_mask, + __entry->size, + __entry->align, + __entry->flags, + __entry->map_kernel) +); + +DEFINE_EVENT(msm_cvp_smem_buffer_dma_ops, msm_cvp_smem_buffer_dma_op_start, + + TP_PROTO(char *buffer_op, u32 buffer_type, u32 heap_mask, + size_t size, u32 align, u32 flags, int map_kernel), + + TP_ARGS(buffer_op, buffer_type, heap_mask, size, align, + flags, map_kernel) +); + +DEFINE_EVENT(msm_cvp_smem_buffer_dma_ops, msm_cvp_smem_buffer_dma_op_end, + + TP_PROTO(char *buffer_op, u32 buffer_type, u32 heap_mask, + size_t size, u32 align, u32 flags, int map_kernel), + + TP_ARGS(buffer_op, buffer_type, heap_mask, size, align, + flags, map_kernel) +); + +DECLARE_EVENT_CLASS(msm_cvp_smem_buffer_iommu_ops, + + TP_PROTO(char *buffer_op, int domain_num, int partition_num, + unsigned long align, unsigned long iova, + unsigned long buffer_size), + + TP_ARGS(buffer_op, domain_num, partition_num, align, iova, buffer_size), + + TP_STRUCT__entry( + __field(char *, buffer_op) + __field(int, domain_num) + __field(int, partition_num) + __field(unsigned long, align) + __field(unsigned long, iova) + __field(unsigned long, buffer_size) + ), + + TP_fast_assign( + __entry->buffer_op = buffer_op; + __entry->domain_num = domain_num; + __entry->partition_num = partition_num; + __entry->align = align; + __entry->iova = iova; + __entry->buffer_size = buffer_size; + ), + + TP_printk( + "%s, domain : %d, partition : %d, align : %lx, iova : 0x%lx, buffer_size=%lx", + __entry->buffer_op, + __entry->domain_num, + __entry->partition_num, + __entry->align, + __entry->iova, + __entry->buffer_size) +); + +DEFINE_EVENT(msm_cvp_smem_buffer_iommu_ops, msm_cvp_smem_buffer_iommu_op_start, + + TP_PROTO(char *buffer_op, int domain_num, int partition_num, + unsigned long align, unsigned long iova, + unsigned long buffer_size), + + TP_ARGS(buffer_op, domain_num, partition_num, align, iova, buffer_size) +); + +DEFINE_EVENT(msm_cvp_smem_buffer_iommu_ops, msm_cvp_smem_buffer_iommu_op_end, + + TP_PROTO(char *buffer_op, int domain_num, int partition_num, + unsigned long align, unsigned long iova, + unsigned long buffer_size), + + TP_ARGS(buffer_op, domain_num, partition_num, align, iova, buffer_size) +); + +DECLARE_EVENT_CLASS(msm_cvp_perf, + + TP_PROTO(const char *name, unsigned long value), + + TP_ARGS(name, value), + + TP_STRUCT__entry( + __field(const char *, name) + __field(unsigned long, value) + ), + + TP_fast_assign( + __entry->name = name; + __entry->value = value; + ), + + TP_printk("%s %lu", __entry->name, __entry->value) +); + +DEFINE_EVENT(msm_cvp_perf, msm_cvp_perf_clock_scale, + + TP_PROTO(const char *clock_name, unsigned long frequency), + + TP_ARGS(clock_name, frequency) +); + +DEFINE_EVENT(msm_cvp_perf, msm_cvp_perf_bus_vote, + + TP_PROTO(const char *governor_mode, unsigned long ab), + + TP_ARGS(governor_mode, ab) +); + +#endif + +#include From 250bb8b4e18fb95197367c47227a5029a0171329 Mon Sep 17 00:00:00 2001 From: George Shen Date: Sun, 28 Nov 2021 14:41:07 -0800 Subject: [PATCH 101/317] msm: eva: Propagate tip of 1.0 to 2.0 For Kailua SoD bring up. Change-Id: I69e41850b55c688caf40f2066ed2628c2df274a3 Signed-off-by: George Shen --- msm/eva/cvp_core_hfi.h | 1 + msm/eva/cvp_hfi.c | 19 +++++++++++++++++-- msm/eva/cvp_hfi_io.h | 4 ++++ msm/eva/hfi_response_handler.c | 1 + msm/eva/msm_cvp_clocks.c | 32 ++++++++++++++++++++++++++++++-- msm/eva/msm_cvp_common.c | 8 ++++++-- msm/eva/msm_cvp_debug.c | 4 ++++ msm/eva/msm_cvp_dsp.c | 13 +++++++++---- msm/eva/msm_cvp_events.h | 2 +- msm/eva/msm_cvp_internal.h | 1 + msm/eva/msm_cvp_platform.c | 2 +- msm/eva/msm_cvp_res_parse.c | 5 +++++ 12 files changed, 80 insertions(+), 12 deletions(-) diff --git a/msm/eva/cvp_core_hfi.h b/msm/eva/cvp_core_hfi.h index e56e4a8eea..e4ca6b6549 100644 --- a/msm/eva/cvp_core_hfi.h +++ b/msm/eva/cvp_core_hfi.h @@ -232,6 +232,7 @@ struct iris_hfi_device { u32 device_id; u32 clk_freq; u32 last_packet_type; + u32 error; unsigned long clk_bitrate; unsigned long scaled_rate; struct msm_cvp_gov_data bus_vote; diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 3ad885ad4e..54b20c883b 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1802,7 +1802,9 @@ static int iris_pm_qos_update(void *device) dev = device; + mutex_lock(&dev->lock); cvp_pm_qos_update(dev, true); + mutex_unlock(&dev->lock); return 0; } @@ -3204,7 +3206,9 @@ static int reset_ahb2axi_bridge(struct iris_hfi_device *device) else s = CVP_POWER_OFF; +#ifdef CONFIG_EVA_WAIPIO s = CVP_POWER_IGNORED; +#endif for (i = 0; i < device->res->reset_set.count; i++) { rc = __handle_reset_clk(device->res, i, ASSERT, s); @@ -4077,6 +4081,13 @@ static int __power_off_controller(struct iris_hfi_device *device) "DBLP Release: lpi_status %x\n", lpi_status); } + /* PDXFIFO reset: addition for Kailua */ +#ifdef CONFIG_EVA_KALAMA + __write_register(device, CVP_WRAPPER_AXI_CLOCK_CONFIG, 0x3); + __write_register(device, CVP_WRAPPER_QNS4PDXFIFO_RESET, 0x1); + __write_register(device, CVP_WRAPPER_QNS4PDXFIFO_RESET, 0x0); + __write_register(device, CVP_WRAPPER_AXI_CLOCK_CONFIG, 0x0); +#endif /* HPG 6.2.2 Step 5 */ msm_cvp_disable_unprepare_clk(device, "cvp_clk"); @@ -4454,6 +4465,12 @@ static void __noc_error_info_iris2(struct iris_hfi_device *device) noc_log = &core->log.noc_log; + if (noc_log->used) { + dprintk(CVP_WARN, "Data already in NoC log, skip logging\n"); + return; + } + noc_log->used = 1; + val = __read_register(device, CVP_NOC_ERR_SWID_LOW_OFFS); __err_log(log_required, &noc_log->err_ctrl_swid_low, "CVP_NOC_ERL_MAIN_SWID_LOW", val); @@ -4550,7 +4567,6 @@ static void __noc_error_info_iris2(struct iris_hfi_device *device) __write_register(device, CVP_SS_ARP_TEST_BUS_CONTROL, regi); val = __read_register(device, CVP_SS_ARP_TEST_BUS_REGISTER); noc_log->arp_test_bus[i] = val; - dprintk(CVP_ERR, "ARP_CTL:%x - %x\n", regi, val); } for (i = 0; i < 512; i++) { @@ -4558,7 +4574,6 @@ static void __noc_error_info_iris2(struct iris_hfi_device *device) __write_register(device, CVP_DMA_TEST_BUS_CONTROL, regi); val = __read_register(device, CVP_DMA_TEST_BUS_REGISTER); noc_log->dma_test_bus[i] = val; - dprintk(CVP_ERR, "DMA_CTL:%x - %x\n", regi, val); } } diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index 2dc935278a..513e45dd07 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -105,12 +105,16 @@ #define CVP_WRAPPER_INTR_MASK_A2HCPU_SHFT 0x2 #define CVP_WRAPPER_INTR_CLEAR (CVP_WRAPPER_BASE_OFFS + 0x14) + #define CVP_WRAPPER_TZ_BASE_OFFS 0x000C0000 + #define CVP_WRAPPER_INTR_CLEAR_A2HWD_BMSK 0x10 #define CVP_WRAPPER_INTR_CLEAR_A2HWD_SHFT 0x4 #define CVP_WRAPPER_INTR_CLEAR_A2H_BMSK 0x4 #define CVP_WRAPPER_INTR_CLEAR_A2H_SHFT 0x2 #define CVP_WRAPPER_CPU_STATUS (CVP_WRAPPER_TZ_BASE_OFFS + 0x10) +#define CVP_WRAPPER_AXI_CLOCK_CONFIG (CVP_WRAPPER_TZ_BASE_OFFS + 0x14) +#define CVP_WRAPPER_QNS4PDXFIFO_RESET (CVP_WRAPPER_TZ_BASE_OFFS + 0x18) #define CVP_WRAPPER_CPU_CGC_DIS (CVP_WRAPPER_BASE_OFFS + 0x2010) #define CVP_WRAPPER_CPU_CLOCK_CONFIG (CVP_WRAPPER_BASE_OFFS + 0x50) diff --git a/msm/eva/hfi_response_handler.c b/msm/eva/hfi_response_handler.c index 9c093d4fab..1347d61be3 100644 --- a/msm/eva/hfi_response_handler.c +++ b/msm/eva/hfi_response_handler.c @@ -79,6 +79,7 @@ static int hfi_process_sys_error(u32 device_id, info->response_type = HAL_SYS_ERROR; info->response.cmd = cmd_done; + dprintk(CVP_ERR, "Received FW sys error %#x\n", pkt->event_data1); return 0; } diff --git a/msm/eva/msm_cvp_clocks.c b/msm/eva/msm_cvp_clocks.c index b03389df73..b61fd359a5 100644 --- a/msm/eva/msm_cvp_clocks.c +++ b/msm/eva/msm_cvp_clocks.c @@ -8,6 +8,18 @@ #include "msm_cvp_debug.h" #include "msm_cvp_clocks.h" +static bool __mmrm_client_check_scaling_supported( + struct mmrm_client_desc *client) +{ +#ifdef CVP_MMRM_ENABLED + return mmrm_client_check_scaling_supported( + client->client_type, + client->client_info.desc.client_domain); +#else + return false; +#endif +} + static struct mmrm_client *__mmrm_client_register( struct mmrm_client_desc *client) { @@ -87,6 +99,7 @@ int msm_cvp_mmrm_register(struct iris_hfi_device *device) int rc = 0; struct clock_info *cl = NULL; char *name; + bool isSupport; if (!device) { dprintk(CVP_ERR, "%s invalid device\n", __func__); @@ -110,6 +123,14 @@ int msm_cvp_mmrm_register(struct iris_hfi_device *device) } } + isSupport = __mmrm_client_check_scaling_supported(&(device->mmrm_desc)); + + if (!isSupport) { + dprintk(CVP_PWR, "%s: mmrm not supported, flag: %d\n", + __func__, isSupport); + return rc; + } + dprintk(CVP_PWR, "%s: Register for %s, clk_id %d\n", __func__, device->mmrm_desc.client_info.desc.name, @@ -137,13 +158,20 @@ int msm_cvp_mmrm_deregister(struct iris_hfi_device *device) int rc = 0; struct clock_info *cl = NULL; - if (!device || !device->mmrm_cvp) { + if (!device) { dprintk(CVP_ERR, - "%s invalid args: device %pK, or device->mmrm_cvp \n", + "%s invalid args: device %pK \n", __func__, device); return -EINVAL; } + if (!device->mmrm_cvp) { // when mmrm not supported + dprintk(CVP_ERR, + "%s device->mmrm_cvp not initialized \n", + __func__); + return rc; + } + /* set clk value to 0 before deregister */ iris_hfi_for_each_clock(device, cl) { if ((cl->has_scaling) && (__clk_is_enabled(cl->clk))){ diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 19f2dddfdc..8160d9a442 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -582,6 +582,7 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) struct msm_cvp_cb_cmd_done *response = data; struct msm_cvp_core *core = NULL; struct cvp_hfi_device *hdev = NULL; + struct iris_hfi_device *hfi_device; struct msm_cvp_inst *inst = NULL; int i, rc = 0; unsigned long flags = 0; @@ -612,11 +613,14 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) cur_state = core->state; core->state = CVP_CORE_UNINIT; + dprintk(CVP_WARN, "SYS_ERROR received for core %pK cmd %x\n", + core, cmd); mutex_lock(&core->clk_lock); - dprintk(CVP_WARN, "SYS_ERROR received for core %pK\n", core); - if (response->status == CVP_ERR_NOC_ERROR) { + hfi_device = hdev->hfi_device_data; + if (hfi_device->error == CVP_ERR_NOC_ERROR) { dprintk(CVP_WARN, "Got NOC error"); msm_cvp_noc_error_info(core); + hfi_device->error = 0xdead; MSM_CVP_ERROR(true); } call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data); diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index efeaebc312..3dd365adb9 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -28,7 +28,11 @@ bool msm_cvp_cacheop_disabled = !true; int msm_cvp_clock_voting = !1; bool msm_cvp_syscache_disable = !true; bool msm_cvp_dsp_disable = !true; +#ifdef CVP_MMRM_ENABLED bool msm_cvp_mmrm_enabled = true; +#else +bool msm_cvp_mmrm_enabled = !true; +#endif bool msm_cvp_dcvs_disable = !true; int msm_cvp_minidump_enable = !1; diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 2308f2a9c1..ebb6941036 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -337,6 +337,7 @@ static void cvp_dsp_rpmsg_remove(struct rpmsg_device *rpdev) mutex_unlock(&me->tx_lock); ptr = &me->fastrpc_driver_list.list; + mutex_lock(&me->fastrpc_driver_list.lock); list_for_each_safe(ptr, next, &me->fastrpc_driver_list.list) { frpc_node = list_entry(ptr, struct cvp_dsp_fastrpc_driver_entry, list); @@ -368,7 +369,7 @@ static void cvp_dsp_rpmsg_remove(struct rpmsg_device *rpdev) frpc_node = NULL; } } - + mutex_unlock(&me->fastrpc_driver_list.lock); dprintk(CVP_WARN, "%s: CDSP SSR handled\n", __func__); } @@ -1023,6 +1024,7 @@ static int eva_fastrpc_driver_register(uint32_t handle) struct cvp_dsp_apps *me = &gfa_cv; int rc = 0; struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; + bool skip_deregister = true; dprintk(CVP_DSP, "%s -> cvp_find_fastrpc_node_with_handle pid 0x%x\n", __func__, handle); @@ -1067,6 +1069,7 @@ static int eva_fastrpc_driver_register(uint32_t handle) if (rc) { dprintk(CVP_ERR, "%s fastrpc driver reg fail err %d\n", __func__, rc); + skip_deregister = true; goto fail_fastrpc_driver_register; } @@ -1076,7 +1079,8 @@ static int eva_fastrpc_driver_register(uint32_t handle) msecs_to_jiffies(CVP_DSP_RESPONSE_TIMEOUT))) { dprintk(CVP_ERR, "%s fastrpc driver_register timeout\n", __func__); - goto fail_fastrpc_driver_timeout; + skip_deregister = false; + goto fail_fastrpc_driver_register; } } else { dprintk(CVP_DSP, "%s fastrpc probe hndl %pK pid 0x%x\n", @@ -1085,14 +1089,15 @@ static int eva_fastrpc_driver_register(uint32_t handle) return rc; -fail_fastrpc_driver_timeout: - __fastrpc_driver_unregister(&frpc_node->cvp_fastrpc_driver); fail_fastrpc_driver_register: /* remove list if this is the last session */ mutex_lock(&me->fastrpc_driver_list.lock); list_del(&frpc_node->list); mutex_unlock(&me->fastrpc_driver_list.lock); + if (!skip_deregister) + __fastrpc_driver_unregister(&frpc_node->cvp_fastrpc_driver); + mutex_lock(&me->driver_name_lock); eva_fastrpc_driver_release_name(frpc_node); mutex_unlock(&me->driver_name_lock); diff --git a/msm/eva/msm_cvp_events.h b/msm/eva/msm_cvp_events.h index dbe3a2843a..aca1e87bfa 100644 --- a/msm/eva/msm_cvp_events.h +++ b/msm/eva/msm_cvp_events.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only * - * Copyright (c) 2020 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2020, The Linux Foundation. All rights reserved. */ #undef TRACE_SYSTEM diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index e4d3078cc5..05b1e47793 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -304,6 +304,7 @@ struct inst_snapshot { }; struct cvp_noc_log { + u32 used; u32 err_ctrl_swid_low; u32 err_ctrl_swid_high; u32 err_ctrl_mainctl_low; diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 90c6520396..b7c106032e 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -58,7 +58,7 @@ static struct msm_cvp_common_data sm8450_common_data[] = { }, { .key = "qcom,domain-attr-non-fatal-faults", - .value = 0, + .value = 1, }, { .key = "qcom,max-secure-instances", diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index 3b3b7e9254..f3b797d6cb 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -11,6 +11,7 @@ #include "msm_cvp_debug.h" #include "msm_cvp_resources.h" #include "msm_cvp_res_parse.h" +#include "cvp_core_hfi.h" #include "soc/qcom/secure_buffer.h" enum clock_properties { @@ -954,6 +955,7 @@ int msm_cvp_smmu_fault_handler(struct iommu_domain *domain, struct device *dev, unsigned long iova, int flags, void *token) { struct msm_cvp_core *core = token; + struct iris_hfi_device *hdev; struct msm_cvp_inst *inst; bool log = false; @@ -974,6 +976,9 @@ int msm_cvp_smmu_fault_handler(struct iommu_domain *domain, list_for_each_entry(inst, &core->instances, list) { msm_cvp_print_inst_bufs(inst, log); } + hdev = core->device->hfi_device_data; + if (hdev) + hdev->error = CVP_ERR_NOC_ERROR; mutex_unlock(&core->lock); /* * Return -EINVAL to elicit the default behaviour of smmu driver. From 447717360287def06fa8b13b3d32c56e1331534e Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 30 Nov 2021 12:40:02 -0800 Subject: [PATCH 102/317] msm: eva: Enable full debug traces for BU To speed up debugging and problem fixes. Change-Id: Ieb013696f2e33ef2781be03005ff6fedc46ab1d6 Signed-off-by: George Shen --- msm/eva/msm_cvp_debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 3dd365adb9..4c8b245a54 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -12,7 +12,7 @@ #define CREATE_TRACE_POINTS #define MAX_SSR_STRING_LEN 10 -int msm_cvp_debug = CVP_ERR | CVP_WARN | CVP_FW; +int msm_cvp_debug = CVP_ERR | CVP_WARN | CVP_FW | CVP_DBG; EXPORT_SYMBOL(msm_cvp_debug); int msm_cvp_debug_out = CVP_OUT_PRINTK; From c52d728376698495fca0a7e5fb0321a059723b48 Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 7 Dec 2021 10:41:34 -0800 Subject: [PATCH 103/317] msm: eva: Load FW as single image The change also allows runtime change of auto-pil setting. It will help presilicon bring up. Change-Id: I9fd97a09e6730a2e13ae4503c74f8a2962c614c5 Signed-off-by: George Shen --- msm/eva/cvp_fw_load.c | 2 +- msm/eva/msm_cvp_core.c | 2 +- msm/eva/msm_cvp_debug.c | 2 ++ msm/eva/msm_cvp_debug.h | 1 + msm/eva/msm_cvp_platform.c | 8 -------- msm/eva/msm_cvp_res_parse.c | 3 --- msm/eva/msm_cvp_resources.h | 1 - 7 files changed, 5 insertions(+), 14 deletions(-) diff --git a/msm/eva/cvp_fw_load.c b/msm/eva/cvp_fw_load.c index 0a3840ce41..45019d9f87 100644 --- a/msm/eva/cvp_fw_load.c +++ b/msm/eva/cvp_fw_load.c @@ -40,7 +40,7 @@ static int __load_fw_to_memory(struct platform_device *pdev, dprintk(CVP_ERR, "%s: Invalid fw name\n", __func__); return -EINVAL; } - scnprintf(firmware_name, ARRAY_SIZE(firmware_name), "%s.mdt", fw_name); + scnprintf(firmware_name, ARRAY_SIZE(firmware_name), "%s.mbn", fw_name); rc = of_property_read_u32(pdev->dev.of_node, "pas-id", &pas_id); if (rc) { diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index c2e24208e1..20f523813c 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -144,7 +144,7 @@ void *msm_cvp_open(int core_id, int session_type) goto err_invalid_core; } - if (!core->resources.auto_pil && session_type == MSM_CVP_BOOT) { + if (!msm_cvp_auto_pil && session_type == MSM_CVP_BOOT) { dprintk(CVP_SESS, "Auto PIL disabled, bypass CVP init at boot"); goto err_invalid_core; } diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 4c8b245a54..8de5736a5b 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -22,6 +22,7 @@ int msm_cvp_fw_debug = 0x18; int msm_cvp_fw_debug_mode = 1; int msm_cvp_fw_low_power_mode = 1; bool msm_cvp_fw_coverage = !true; +bool msm_cvp_auto_pil = true; bool msm_cvp_cacheop_enabled = true; bool msm_cvp_thermal_mitigation_disabled = !true; bool msm_cvp_cacheop_disabled = !true; @@ -255,6 +256,7 @@ struct dentry *msm_cvp_debugfs_init_drv(void) debugfs_create_u32("minidump_enable", 0644, dir, &msm_cvp_minidump_enable); debugfs_create_bool("fw_coverage", 0644, dir, &msm_cvp_fw_coverage); + debugfs_create_bool("auto_pil", 0644, dir, &msm_cvp_auto_pil); debugfs_create_bool("disable_thermal_mitigation", 0644, dir, &msm_cvp_thermal_mitigation_disabled); debugfs_create_bool("enable_cacheop", 0644, dir, diff --git a/msm/eva/msm_cvp_debug.h b/msm/eva/msm_cvp_debug.h index 5a8d36474c..842eee3da4 100644 --- a/msm/eva/msm_cvp_debug.h +++ b/msm/eva/msm_cvp_debug.h @@ -58,6 +58,7 @@ extern int msm_cvp_fw_debug; extern int msm_cvp_fw_debug_mode; extern int msm_cvp_fw_low_power_mode; extern bool msm_cvp_fw_coverage; +extern bool msm_cvp_auto_pil; extern bool msm_cvp_thermal_mitigation_disabled; extern bool msm_cvp_cacheop_disabled; extern int msm_cvp_clock_voting; diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index b7c106032e..1038a8a11e 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -44,10 +44,6 @@ static struct msm_cvp_common_data default_common_data[] = { }; static struct msm_cvp_common_data sm8450_common_data[] = { - { - .key = "qcom,auto-pil", - .value = 1, - }, { .key = "qcom,pm-qos-latency-us", .value = 50, @@ -100,10 +96,6 @@ static struct msm_cvp_common_data sm8450_common_data[] = { }; static struct msm_cvp_common_data sm8550_common_data[] = { - { - .key = "qcom,auto-pil", - .value = 1, - }, { .key = "qcom,pm-qos-latency-us", .value = 50, diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index f3b797d6cb..41fcc5431f 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -766,9 +766,6 @@ int cvp_read_platform_resources_from_drv_data( dprintk(CVP_CORE, "Firmware filename: %s\n", res->fw_name); - res->auto_pil = find_key_value(platform_data, - "qcom,auto-pil"); - res->dsp_enabled = find_key_value(platform_data, "qcom,dsp-enabled"); diff --git a/msm/eva/msm_cvp_resources.h b/msm/eva/msm_cvp_resources.h index cc093dd710..a087349b40 100644 --- a/msm/eva/msm_cvp_resources.h +++ b/msm/eva/msm_cvp_resources.h @@ -174,7 +174,6 @@ struct msm_cvp_platform_resources { struct reset_set reset_set; bool use_non_secure_pil; bool sw_power_collapsible; - bool auto_pil; bool dsp_enabled; struct list_head context_banks; bool thermal_mitigable; From 364e984422576c7ee5a08d9a4051c7ebbd71dc34 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 29 Dec 2021 12:20:48 -0800 Subject: [PATCH 104/317] msm: eva: Extend timeout to wait for F/W boot Only applicable on Pre-sil platform. Restore silicon setting later. Change-Id: Ib1e3f4e3a5de7521e7bb36540fe8bc2c6a4342ee Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 54b20c883b..78ddd6ae26 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -993,8 +993,8 @@ static inline int __boot_firmware(struct iris_hfi_device *device) break; } - /* Reduce to 1/100th and x100 of max_tries */ - usleep_range(500, 1000); + /* Reduce to 500, 1000 on silicon */ + usleep_range(5000, 10000); count++; } From 6ca205da5424c76d7e6a85991faff9ba75d60392 Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 4 Jan 2022 13:51:54 -0800 Subject: [PATCH 105/317] msm: eva: Enable all feature dependencies Except minidump for kailua. Change-Id: I8e0d5fe57f05a027f47088111811f362f7bf0c2f Signed-off-by: George Shen --- msm/eva/cvp_comm_def.h | 2 +- msm/eva/cvp_hfi.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/eva/cvp_comm_def.h b/msm/eva/cvp_comm_def.h index 3ccf16dc8c..2edacca9b1 100644 --- a/msm/eva/cvp_comm_def.h +++ b/msm/eva/cvp_comm_def.h @@ -23,10 +23,10 @@ enum queue_state { QUEUE_INVALID, }; -#ifdef CONFIG_EVA_WAIPIO #define CVP_SYNX_ENABLED 1 #define CVP_MMRM_ENABLED 1 #define CVP_FASTRPC_ENABLED 1 +#ifdef CONFIG_EVA_WAIPIO #define CVP_MINIDUMP_ENABLED 1 #endif diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 78ddd6ae26..c1bcbd7887 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -994,7 +994,7 @@ static inline int __boot_firmware(struct iris_hfi_device *device) } /* Reduce to 500, 1000 on silicon */ - usleep_range(5000, 10000); + usleep_range(50000, 100000); count++; } From 9bb07ce06c67fa6d526a510a9af0302fba52b9a3 Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 7 Jan 2022 15:33:35 -0800 Subject: [PATCH 106/317] msm: eva: Enable EVA kernel DSP interface Unblock DSP EVA bring up. Change-Id: I1f8fa147c6b33799187fd3cb449f46983589b87d Signed-off-by: George Shen --- msm/eva/msm_cvp_platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 1038a8a11e..5b18a34029 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -143,7 +143,7 @@ static struct msm_cvp_common_data sm8550_common_data[] = { }, { .key = "qcom,dsp-enabled", - .value = 0, + .value = 1, } }; From 8886fdf213f73fb6c70b5884bbea917a684e898a Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 19 Jan 2022 09:34:01 -0800 Subject: [PATCH 107/317] msm: eva: Update tracing header file's copyright To comply with company requirement. Change-Id: I2fa5061bac74d0ba4e962aafb8787559763e3b4e Signed-off-by: George Shen --- msm/eva/msm_cvp_events.h | 1 + 1 file changed, 1 insertion(+) diff --git a/msm/eva/msm_cvp_events.h b/msm/eva/msm_cvp_events.h index aca1e87bfa..97d26da6b2 100644 --- a/msm/eva/msm_cvp_events.h +++ b/msm/eva/msm_cvp_events.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only * * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. */ #undef TRACE_SYSTEM From 2a36ba8c00d4bf334c8817e80006f92c97db4032 Mon Sep 17 00:00:00 2001 From: apreetam Date: Mon, 24 Jan 2022 14:34:26 +0530 Subject: [PATCH 108/317] msm: eva: create debugfs root inside driver probe To correctly place the core0 directory at debugfs root Signed-off-by: Aakash Preetam Change-Id: Ib08798e93b202dd07dc02a9b9034397199767900 --- msm/eva/cvp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index ea1a965ada..a47f53eca8 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -419,6 +419,10 @@ static int msm_probe_cvp_device(struct platform_device *pdev) list_add_tail(&core->list, &cvp_driver->cores); mutex_unlock(&cvp_driver->lock); + cvp_driver->debugfs_root = msm_cvp_debugfs_init_drv(); + if (!cvp_driver->debugfs_root) + dprintk(CVP_ERR, "Failed to create debugfs for msm_cvp\n"); + core->debugfs_root = msm_cvp_debugfs_init_core( core, cvp_driver->debugfs_root); @@ -601,10 +605,6 @@ static int __init msm_cvp_init(void) INIT_LIST_HEAD(&cvp_driver->cores); mutex_init(&cvp_driver->lock); - cvp_driver->debugfs_root = msm_cvp_debugfs_init_drv(); - if (!cvp_driver->debugfs_root) - dprintk(CVP_ERR, - "Failed to create debugfs for msm_cvp\n"); rc = platform_driver_register(&msm_cvp_driver); if (rc) { From 01c34574ca973e8f40cab68e6d5d8e4723e680e7 Mon Sep 17 00:00:00 2001 From: Sabharsh Sidhu Date: Thu, 27 Jan 2022 17:10:22 -0800 Subject: [PATCH 109/317] msm: eva: Add WarpNCC CPU support Adds Out-of-Band (OOB) functionality. Adds WarpNCC OOB processing for metadata buffer IOVA population. Adds WarpNCC source buffer registration that does IOVA book-keeping and returns buffer ID to UMD. Change-Id: I182c270454eec194f28a31c494bae0ad9eface02 Signed-off-by: Sabharsh Sidhu --- include/uapi/eva/media/msm_eva_private.h | 51 ++ msm/eva/msm_cvp.c | 7 + msm/eva/msm_cvp_buf.c | 701 ++++++++++++++++++++++- msm/eva/msm_cvp_buf.h | 12 + msm/eva/msm_cvp_core.c | 9 + msm/eva/msm_cvp_internal.h | 3 + msm/eva/msm_cvp_ioctl.c | 12 + 7 files changed, 781 insertions(+), 14 deletions(-) diff --git a/include/uapi/eva/media/msm_eva_private.h b/include/uapi/eva/media/msm_eva_private.h index 3950279133..95b84d3c99 100644 --- a/include/uapi/eva/media/msm_eva_private.h +++ b/include/uapi/eva/media/msm_eva_private.h @@ -120,11 +120,61 @@ struct eva_kmd_client_data { __u32 client_data2; }; +/** + * Structures and macros for Out-of-Band (OOB) buffer + * that may accompany HFI packet data + */ + +#define EVA_KMD_WNCC_MAX_LAYERS 4 +#define EVA_KMD_WNCC_MAX_ADDRESSES 4095 +#define EVA_KMD_WNCC_MAX_SRC_BUFS 2400 +#define EVA_KMD_WNCC_SRC_BUF_ID_OFFSET 1 +#define EVA_KMD_WNCC_HFI_METADATA_BUFS_OFFSET 44 + +struct eva_kmd_wncc_metadata { + __u64 loc_x_dec : 12; + __u64 loc_x_frac : 9; + __u64 loc_y_dec : 12; + __u64 loc_y_frac : 9; + __u64 iova_lsb : 22; /* Populated in KMD */ + __u64 iova_msb : 10; /* Populated in KMD */ + __u64 scale_idx : 2; + __s64 aff_coeff_3 : 13; + __s64 aff_coeff_2 : 13; + __s64 aff_coeff_1 : 13; + __s64 aff_coeff_0 : 13; +}; + +struct eva_kmd_oob_wncc { + __u32 num_layers; + struct eva_kmd_wncc_layer { + __u32 num_addrs; + struct eva_kmd_wncc_addr { + __u32 buffer_id; + __u32 offset; + } addrs[EVA_KMD_WNCC_MAX_ADDRESSES]; + } layers[EVA_KMD_WNCC_MAX_LAYERS]; +}; + +#define EVA_KMD_OOB_INVALID 0 +#define EVA_KMD_OOB_WNCC 1 + +struct eva_kmd_oob_buf { + __u32 oob_type; + union { + struct eva_kmd_oob_wncc wncc; + }; +}; + +/** + * Structures and macros for KMD arg data + */ #define MAX_HFI_PKT_SIZE 490 struct eva_kmd_hfi_packet { __u32 pkt_data[MAX_HFI_PKT_SIZE]; + struct eva_kmd_oob_buf *oob_buf; }; #define EVA_KMD_PROP_HFI_VERSION 1 @@ -209,6 +259,7 @@ struct eva_kmd_hfi_synx_packet { __u32 fence_data[MAX_FENCE_DATA_SIZE]; struct eva_kmd_fence_ctrl fc; }; + struct eva_kmd_oob_buf* oob_buf; }; /** diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 605d6142e2..245043c56e 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -216,6 +216,13 @@ static int msm_cvp_session_process_hfi( dprintk(CVP_ERR, "Incorrect buffer num and offset in cmd\n"); return -EINVAL; } + + rc = msm_cvp_proc_oob(inst, in_pkt); + if (rc) { + dprintk(CVP_ERR, "%s: failed to process OOB buffer", __func__); + goto exit; + } + pkt_type = in_pkt->pkt_data[1]; map_type = cvp_find_map_type(pkt_type); diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index fd3c3b2dd4..93e3b8ae12 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -32,6 +32,9 @@ inst->dma_cache.usage_bitmap); \ } while (0) +static void _wncc_print_cvpwnccbufs_table(struct msm_cvp_inst* inst); +static int _wncc_unmap_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, + unsigned int num_layers, struct eva_kmd_wncc_metadata** wncc_metadata); int print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, struct msm_cvp_smem *smem) @@ -132,13 +135,15 @@ static void _log_buf(struct inst_snapshot *snapshot, enum smem_prop prop, void print_client_buffer(u32 tag, const char *str, struct msm_cvp_inst *inst, struct eva_kmd_buffer *cbuf) { - if (!(tag & msm_cvp_debug) || !inst || !cbuf) + if (!(tag & msm_cvp_debug) || !str || !inst || !cbuf) return; dprintk(tag, - "%s: %x : idx %2d fd %d off %d size %d type %d flags 0x%x\n", + "%s: %x : idx %2d fd %d off %d size %d type %d flags 0x%x" + " reserved[0] %u\n", str, hash32_ptr(inst->session), cbuf->index, cbuf->fd, - cbuf->offset, cbuf->size, cbuf->type, cbuf->flags); + cbuf->offset, cbuf->size, cbuf->type, cbuf->flags, + cbuf->reserved[0]); } static bool __is_buf_valid(struct msm_cvp_inst *inst, @@ -359,6 +364,655 @@ int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) return rc; } +int msm_cvp_map_buf_wncc(struct msm_cvp_inst *inst, + struct eva_kmd_buffer *buf) +{ + int rc = 0, i; + bool found = false; + struct cvp_internal_buf* cbuf; + struct msm_cvp_smem* smem = NULL; + struct dma_buf* dma_buf = NULL; + + if (!inst || !inst->core || !buf) { + dprintk(CVP_ERR, "%s: invalid params", __func__); + return -EINVAL; + } + + if (!inst->session) { + dprintk(CVP_ERR, "%s: invalid session", __func__); + return -EINVAL; + } + + if (buf->index) { + dprintk(CVP_ERR, "%s: buf index is NOT 0 fd=%d", + __func__, buf->fd); + return -EINVAL; + } + + if (buf->fd < 0) { + dprintk(CVP_ERR, "%s: invalid fd = %d", __func__, buf->fd); + return -EINVAL; + } + + if (buf->offset) { + dprintk(CVP_ERR, "%s: offset is not supported, set to 0.", + __func__); + return -EINVAL; + } + + mutex_lock(&inst->cvpwnccbufs.lock); + list_for_each_entry(cbuf, &inst->cvpwnccbufs.list, list) { + if (cbuf->fd == buf->fd) { + if (cbuf->size != buf->size) { + dprintk(CVP_ERR, "%s: buf size mismatch", + __func__); + mutex_unlock(&inst->cvpwnccbufs.lock); + return -EINVAL; + } + found = true; + break; + } + } + mutex_unlock(&inst->cvpwnccbufs.lock); + if (found) { + print_internal_buffer(CVP_ERR, "duplicate", inst, cbuf); + return -EINVAL; + } + + dma_buf = msm_cvp_smem_get_dma_buf(buf->fd); + if (!dma_buf) { + dprintk(CVP_ERR, "%s: invalid fd = %d", __func__, buf->fd); + return -EINVAL; + } + + cbuf = kmem_cache_zalloc(cvp_driver->buf_cache, GFP_KERNEL); + if (!cbuf) { + msm_cvp_smem_put_dma_buf(dma_buf); + return -ENOMEM; + } + + smem = kmem_cache_zalloc(cvp_driver->smem_cache, GFP_KERNEL); + if (!smem) { + kmem_cache_free(cvp_driver->buf_cache, cbuf); + msm_cvp_smem_put_dma_buf(dma_buf); + return -ENOMEM; + } + + smem->dma_buf = dma_buf; + smem->bitmap_index = MAX_DMABUF_NUMS; + dprintk(CVP_MEM, "%s: dma_buf = %llx", __func__, dma_buf); + rc = msm_cvp_map_smem(inst, smem, "map wncc"); + if (rc) { + dprintk(CVP_ERR, "%s: map failed", __func__); + print_client_buffer(CVP_ERR, __func__, inst, buf); + goto exit; + } + + cbuf->smem = smem; + cbuf->fd = buf->fd; + cbuf->size = buf->size; + cbuf->offset = buf->offset; + cbuf->ownership = CLIENT; + cbuf->index = buf->index; + + /* Added for PreSil/RUMI testing */ +#ifdef USE_PRESIL + dprintk(CVP_DBG, + "wncc buffer is %x for cam_presil_send_buffer" + " with MAP_ADDR_OFFSET %x", + (u64)(smem->device_addr) - MAP_ADDR_OFFSET, MAP_ADDR_OFFSET); + cam_presil_send_buffer((u64)smem->dma_buf, 0, + (u32)cbuf->offset, (u32)cbuf->size, + (u64)(smem->device_addr) - MAP_ADDR_OFFSET); +#endif + + mutex_lock(&inst->cvpwnccbufs.lock); + if (inst->cvpwnccbufs_table == NULL) { + inst->cvpwnccbufs_table = + (struct msm_cvp_wncc_buffer*) kzalloc( + sizeof(struct msm_cvp_wncc_buffer) * + EVA_KMD_WNCC_MAX_SRC_BUFS, + GFP_KERNEL); + } + + list_add_tail(&cbuf->list, &inst->cvpwnccbufs.list); + for (i = 0; i < EVA_KMD_WNCC_MAX_SRC_BUFS; i++) + { + if (inst->cvpwnccbufs_table[i].iova == 0) + { + inst->cvpwnccbufs_num++; + inst->cvpwnccbufs_table[i].fd = buf->fd; + inst->cvpwnccbufs_table[i].iova = smem->device_addr; + inst->cvpwnccbufs_table[i].size = smem->size; + + /* buf reserved[0] used to store wncc src buf id */ + buf->reserved[0] = i + EVA_KMD_WNCC_SRC_BUF_ID_OFFSET; + /* cbuf ktid used to store wncc src buf id */ + cbuf->ktid = i + EVA_KMD_WNCC_SRC_BUF_ID_OFFSET; + + dprintk(CVP_MEM, "%s: wncc buf iova: 0x%08X", + __func__, inst->cvpwnccbufs_table[i].iova); + break; + } + } + if (i == EVA_KMD_WNCC_MAX_SRC_BUFS) { + dprintk(CVP_ERR, + "%s: wncc buf table full - max (%u) already registered", + __func__, EVA_KMD_WNCC_MAX_SRC_BUFS); + /* _wncc_print_cvpwnccbufs_table(inst); */ + mutex_unlock(&inst->cvpwnccbufs.lock); + rc = -EDQUOT; + goto exit; + } + mutex_unlock(&inst->cvpwnccbufs.lock); + + return rc; + +exit: + if (smem->device_addr) { + msm_cvp_unmap_smem(inst, smem, "unmap wncc"); + msm_cvp_smem_put_dma_buf(smem->dma_buf); + } + kmem_cache_free(cvp_driver->buf_cache, cbuf); + cbuf = NULL; + kmem_cache_free(cvp_driver->smem_cache, smem); + smem = NULL; + return rc; +} + +int msm_cvp_unmap_buf_wncc(struct msm_cvp_inst *inst, + struct eva_kmd_buffer *buf) +{ + int rc = 0; + bool found; + struct cvp_internal_buf *cbuf; + uint32_t buf_id, buf_idx; + + if (!inst || !inst->core || !buf) { + dprintk(CVP_ERR, "%s: invalid params", __func__); + return -EINVAL; + } + + if (!inst->session) { + dprintk(CVP_ERR, "%s: invalid session", __func__); + return -EINVAL; + } + + if (buf->index) { + dprintk(CVP_ERR, "%s: buf index is NOT 0 fd=%d", + __func__, buf->fd); + return -EINVAL; + } + + buf_id = buf->reserved[0]; + if (buf_id < EVA_KMD_WNCC_SRC_BUF_ID_OFFSET || buf_id >= + (EVA_KMD_WNCC_MAX_SRC_BUFS + EVA_KMD_WNCC_SRC_BUF_ID_OFFSET)) { + dprintk(CVP_ERR, "%s: invalid buffer id %d", + __func__, buf->reserved[0]); + return -EINVAL; + } + + mutex_lock(&inst->cvpwnccbufs.lock); + if (inst->cvpwnccbufs_num == 0) { + dprintk(CVP_ERR, "%s: no wncc buffers currently mapped", __func__); + mutex_unlock(&inst->cvpwnccbufs.lock); + return -EINVAL; + } + + buf_idx = buf_id - EVA_KMD_WNCC_SRC_BUF_ID_OFFSET; + if (inst->cvpwnccbufs_table[buf_idx].iova == 0) { + dprintk(CVP_ERR, "%s: buffer id %d not found", + __func__, buf_id); + mutex_unlock(&inst->cvpwnccbufs.lock); + return -EINVAL; + } + + buf->fd = inst->cvpwnccbufs_table[buf_idx].fd; + found = false; + list_for_each_entry(cbuf, &inst->cvpwnccbufs.list, list) { + if (cbuf->fd == buf->fd) { + found = true; + break; + } + } + if (!found) { + dprintk(CVP_ERR, "%s: buffer id %d not found", + __func__, buf_id); + print_client_buffer(CVP_ERR, __func__, inst, buf); + _wncc_print_cvpwnccbufs_table(inst); + mutex_unlock(&inst->cvpwnccbufs.lock); + return -EINVAL; + } + mutex_unlock(&inst->cvpwnccbufs.lock); + + if (cbuf->smem->device_addr) { + msm_cvp_unmap_smem(inst, cbuf->smem, "unmap wncc"); + msm_cvp_smem_put_dma_buf(cbuf->smem->dma_buf); + } + + mutex_lock(&inst->cvpwnccbufs.lock); + list_del(&cbuf->list); + inst->cvpwnccbufs_table[buf_idx].fd = 0; + inst->cvpwnccbufs_table[buf_idx].iova = 0; + inst->cvpwnccbufs_table[buf_idx].size = 0; + inst->cvpwnccbufs_num--; + if (inst->cvpwnccbufs_num == 0) { + kfree(inst->cvpwnccbufs_table); + inst->cvpwnccbufs_table = NULL; + } + mutex_unlock(&inst->cvpwnccbufs.lock); + + kmem_cache_free(cvp_driver->smem_cache, cbuf->smem); + kmem_cache_free(cvp_driver->buf_cache, cbuf); + return rc; +} + +static void _wncc_print_oob(struct eva_kmd_oob_wncc* wncc_oob) +{ + u32 i, j; + + if (!wncc_oob) { + dprintk(CVP_ERR, "%s: invalid params", __func__); + return; + } + + dprintk(CVP_DBG, "%s: wncc OOB --", __func__); + dprintk(CVP_DBG, "%s: num_layers: %u", __func__, wncc_oob->num_layers); + for (i = 0; i < wncc_oob->num_layers; i++) { + dprintk(CVP_DBG, "%s: layers[%u].num_addrs: %u", + __func__, i, wncc_oob->layers[i].num_addrs); + + for (j = 0; j < wncc_oob->layers[i].num_addrs; j++) { + dprintk(CVP_DBG, + "%s: layers[%u].addrs[%u]: %04u 0x%08x", + __func__, i, j, + wncc_oob->layers[i].addrs[j].buffer_id, + wncc_oob->layers[i].addrs[j].offset); + } + } +} + +static void _wncc_print_cvpwnccbufs_table(struct msm_cvp_inst* inst) +{ + u32 i, entries = 0; + + if (!inst) { + dprintk(CVP_ERR, "%s: invalid params", __func__); + return; + } + + if (inst->cvpwnccbufs_num == 0) { + dprintk(CVP_DBG, "%s: wncc buffer look-up table is empty", + __func__); + return; + } + + if (!inst->cvpwnccbufs_table) { + dprintk(CVP_ERR, "%s: invalid params", __func__); + return; + } + + dprintk(CVP_DBG, "%s: wncc buffer table:"); + for (i = 0; i < EVA_KMD_WNCC_MAX_SRC_BUFS && + entries < inst->cvpwnccbufs_num; i++) { + if (inst->cvpwnccbufs_table[i].iova != 0) { + dprintk(CVP_DBG, + "%s: buf_idx=%04d --> " + "fd=%03d, iova=0x%08x, size=%d", + __func__, i, + inst->cvpwnccbufs_table[i].fd, + inst->cvpwnccbufs_table[i].iova, + inst->cvpwnccbufs_table[i].size); + entries++; + } + } +} + +static void _wncc_print_metadata_buf(u32 num_layers, u32 num_addrs, + struct eva_kmd_wncc_metadata** wncc_metadata) +{ + u32 i, j, iova; + + if (num_layers < 1 || num_layers > EVA_KMD_WNCC_MAX_LAYERS || + !wncc_metadata) { + dprintk(CVP_ERR, "%s: invalid params", __func__); + return; + } + + dprintk(CVP_DBG, "%s: wncc metadata buffers --", __func__); + dprintk(CVP_DBG, "%s: num_layers: %u", __func__, num_layers); + dprintk(CVP_DBG, "%s: num_addrs: %u", __func__, num_addrs); + for (i = 0; i < num_layers; i++) { + for (j = 0; j < num_addrs; j++) { + iova = (wncc_metadata[i][j].iova_msb << 22) | + wncc_metadata[i][j].iova_lsb; + dprintk(CVP_DBG, + "%s: wncc_metadata[%u][%u]: " + "%4u %3u %4u %3u 0x%08x %1u %4d %4d %4d %4d", + __func__, i, j, + wncc_metadata[i][j].loc_x_dec, + wncc_metadata[i][j].loc_x_frac, + wncc_metadata[i][j].loc_y_dec, + wncc_metadata[i][j].loc_y_frac, + iova, + wncc_metadata[i][j].scale_idx, + wncc_metadata[i][j].aff_coeff_3, + wncc_metadata[i][j].aff_coeff_2, + wncc_metadata[i][j].aff_coeff_1, + wncc_metadata[i][j].aff_coeff_0); + } + } +} + +static int _wncc_copy_oob_from_user(struct eva_kmd_hfi_packet* in_pkt, + struct eva_kmd_oob_wncc* wncc_oob) +{ + int rc = 0; + u32 oob_type; + struct eva_kmd_oob_wncc* wncc_oob_u; + struct eva_kmd_oob_wncc* wncc_oob_k; + unsigned int i; + u32 num_addrs; + + if (!in_pkt || !wncc_oob) { + dprintk(CVP_ERR, "%s: invalid params", __func__); + return -EINVAL; + } + + if (!access_ok(in_pkt->oob_buf, sizeof(*in_pkt->oob_buf))) { + dprintk(CVP_ERR, "%s: invalid OOB buf pointer", __func__); + return -EINVAL; + } + + rc = get_user(oob_type, &in_pkt->oob_buf->oob_type); + if (rc) + return rc; + if (oob_type != EVA_KMD_OOB_WNCC) { + dprintk(CVP_ERR, "%s: incorrect OOB type (%d) for wncc", + __func__, oob_type); + return -EINVAL; + } + + wncc_oob_u = &in_pkt->oob_buf->wncc; + wncc_oob_k = wncc_oob; + + rc = get_user(wncc_oob_k->num_layers, &wncc_oob_u->num_layers); + if (rc) + return rc; + if (wncc_oob_k->num_layers < 1 || + wncc_oob_k->num_layers > EVA_KMD_WNCC_MAX_LAYERS) { + dprintk(CVP_ERR, "%s: invalid wncc num layers", __func__); + return -EINVAL; + } + + for (i = 0; i < wncc_oob_k->num_layers; i++) { + + rc = get_user(wncc_oob_k->layers[i].num_addrs, + &wncc_oob_u->layers[i].num_addrs); + if (rc) + break; + + num_addrs = wncc_oob_k->layers[i].num_addrs; + if (num_addrs < 1 || num_addrs > EVA_KMD_WNCC_MAX_ADDRESSES) { + dprintk(CVP_ERR, + "%s: invalid wncc num addrs for layer %u", + __func__, i); + rc = -EINVAL; + break; + } + + rc = copy_from_user(wncc_oob_k->layers[i].addrs, + wncc_oob_u->layers[i].addrs, + wncc_oob_k->layers[i].num_addrs * + sizeof(struct eva_kmd_wncc_addr)); + if (rc) + break; + } + + if (false) + _wncc_print_oob(wncc_oob); + + return rc; +} + +static int _wncc_map_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, + unsigned int num_layers, struct eva_kmd_wncc_metadata** wncc_metadata) +{ + int rc = 0, i; + struct cvp_buf_type* wncc_metadata_bufs; + struct dma_buf* dmabuf; + struct dma_buf_map map; + + if (!in_pkt || !wncc_metadata || + num_layers < 1 || num_layers > EVA_KMD_WNCC_MAX_LAYERS) { + dprintk(CVP_ERR, "%s: invalid params", __func__); + return -EINVAL; + } + + wncc_metadata_bufs = (struct cvp_buf_type*) + &in_pkt->pkt_data[EVA_KMD_WNCC_HFI_METADATA_BUFS_OFFSET]; + for (i = 0; i < num_layers; i++) { + dmabuf = dma_buf_get(wncc_metadata_bufs[i].fd); + if (IS_ERR(dmabuf)) { + rc = PTR_ERR(dmabuf); + dprintk(CVP_ERR, + "%s: dma_buf_get() failed for " + "wncc_metadata_bufs[%d], rc %d", + __func__, i, rc); + break; + } + + rc = dma_buf_begin_cpu_access(dmabuf, DMA_TO_DEVICE); + if (rc) { + dprintk(CVP_ERR, + "%s: dma_buf_begin_cpu_access() failed " + "for wncc_metadata_bufs[%d], rc %d", + __func__, i, rc); + dma_buf_put(dmabuf); + break; + } + + rc = dma_buf_vmap(dmabuf, &map); + if (rc) { + dprintk(CVP_ERR, + "%s: dma_buf_vmap() failed for " + "wncc_metadata_bufs[%d]", + __func__, i); + dma_buf_end_cpu_access(dmabuf, DMA_TO_DEVICE); + dma_buf_put(dmabuf); + break; + } + dprintk(CVP_DBG, + "%s: wncc_metadata_bufs[%d] map.is_iomem is %d", + __func__, i, map.is_iomem); + wncc_metadata[i] = (struct eva_kmd_wncc_metadata*)map.vaddr; + + dma_buf_put(dmabuf); + } + + if (rc) + _wncc_unmap_metadata_bufs(in_pkt, i, wncc_metadata); + + return rc; +} + +static int _wncc_unmap_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, + unsigned int num_layers, struct eva_kmd_wncc_metadata** wncc_metadata) +{ + int rc = 0, i; + struct cvp_buf_type* wncc_metadata_bufs; + struct dma_buf* dmabuf; + struct dma_buf_map map; + + if (!in_pkt || !wncc_metadata || + num_layers < 1 || num_layers > EVA_KMD_WNCC_MAX_LAYERS) { + dprintk(CVP_ERR, "%s: invalid params", __func__); + return -EINVAL; + } + + wncc_metadata_bufs = (struct cvp_buf_type*) + &in_pkt->pkt_data[EVA_KMD_WNCC_HFI_METADATA_BUFS_OFFSET]; + for (i = 0; i < num_layers; i++) { + if (!wncc_metadata[i]) { + rc = -EINVAL; + break; + } + + dmabuf = dma_buf_get(wncc_metadata_bufs[i].fd); + if (IS_ERR(dmabuf)) { + rc = -PTR_ERR(dmabuf); + dprintk(CVP_ERR, + "%s: dma_buf_get() failed for " + "wncc_metadata_bufs[%d], rc %d", + __func__, i, rc); + break; + } + + dma_buf_map_set_vaddr(&map, wncc_metadata[i]); + dma_buf_vunmap(dmabuf, &map); + wncc_metadata[i] = NULL; + + rc = dma_buf_end_cpu_access(dmabuf, DMA_TO_DEVICE); + dma_buf_put(dmabuf); + if (rc) { + dprintk(CVP_ERR, + "%s: dma_buf_end_cpu_access() failed " + "for wncc_metadata_bufs[%d], rc %d", + __func__, i, rc); + break; + } + } + + return rc; +} + +static int msm_cvp_proc_oob_wncc(struct msm_cvp_inst* inst, + struct eva_kmd_hfi_packet* in_pkt) +{ + int rc = 0; + struct eva_kmd_oob_wncc* wncc_oob; + struct eva_kmd_wncc_metadata* wncc_metadata[EVA_KMD_WNCC_MAX_LAYERS]; + unsigned int i, j; + bool empty = false; + u32 buf_id, buf_idx, buf_offset, iova; + + if (!inst || !inst->core || !in_pkt) { + dprintk(CVP_ERR, "%s: invalid params", __func__); + return -EINVAL; + } + + wncc_oob = (struct eva_kmd_oob_wncc*)kzalloc( + sizeof(struct eva_kmd_oob_wncc), GFP_KERNEL); + if (!wncc_oob) + return -ENOMEM; + rc = _wncc_copy_oob_from_user(in_pkt, wncc_oob); + if (rc) { + dprintk(CVP_ERR, "%s: OOB buf copying failed", __func__); + goto exit; + } + + rc = _wncc_map_metadata_bufs(in_pkt, + wncc_oob->num_layers, wncc_metadata); + if (rc) { + dprintk(CVP_ERR, "%s: failed to map wncc metadata bufs", + __func__); + goto exit; + } + + mutex_lock(&inst->cvpwnccbufs.lock); + if (inst->cvpwnccbufs_num == 0 || inst->cvpwnccbufs_table == NULL) { + dprintk(CVP_ERR, "%s: no wncc bufs currently mapped", __func__); + empty = true; + rc = -EINVAL; + } + + for (i = 0; !empty && i < wncc_oob->num_layers; i++) { + for (j = 0; j < wncc_oob->layers[i].num_addrs; j++) { + buf_id = wncc_oob->layers[i].addrs[j].buffer_id; + if (buf_id < EVA_KMD_WNCC_SRC_BUF_ID_OFFSET || + buf_id >= (EVA_KMD_WNCC_SRC_BUF_ID_OFFSET + + EVA_KMD_WNCC_MAX_SRC_BUFS)) { + dprintk(CVP_ERR, + "%s: invalid wncc buf id %u " + "in layer #%u address #%u", + __func__, buf_id, i, j); + rc = -EINVAL; + break; + } + + buf_idx = buf_id - EVA_KMD_WNCC_SRC_BUF_ID_OFFSET; + if (inst->cvpwnccbufs_table[buf_idx].iova == 0) { + dprintk(CVP_ERR, + "%s: unmapped wncc buf id %u " + "in layer #%u address #%u", + __func__, buf_id, i, j); + /* _wncc_print_cvpwnccbufs_table(inst); */ + rc = -EINVAL; + break; + } + + buf_offset = wncc_oob->layers[i].addrs[j].offset; + if (buf_offset >= + inst->cvpwnccbufs_table[buf_idx].size) { + /* NOTE: This buffer offset validation is + * not comprehensive since wncc src image + * resolution information is not known to + * KMD. UMD is responsible for comprehensive + * validation. + */ + dprintk(CVP_ERR, + "%s: invalid wncc buf offset %u " + "in layer #%u address #%u", + __func__, buf_offset, i, j); + rc = -EINVAL; + break; + } + + iova = inst->cvpwnccbufs_table[buf_idx].iova + + buf_offset; + wncc_metadata[i][j].iova_lsb = iova; + wncc_metadata[i][j].iova_msb = iova >> 22; + } + } + mutex_unlock(&inst->cvpwnccbufs.lock); + + if (false) + _wncc_print_metadata_buf(wncc_oob->num_layers, + wncc_oob->layers[0].num_addrs, wncc_metadata); + + if (_wncc_unmap_metadata_bufs(in_pkt, + wncc_oob->num_layers, wncc_metadata)) { + dprintk(CVP_ERR, "%s: failed to unmap wncc metadata bufs", + __func__); + } + +exit: + kfree(wncc_oob); + return rc; +} + +int msm_cvp_proc_oob(struct msm_cvp_inst* inst, + struct eva_kmd_hfi_packet* in_pkt) +{ + int rc = 0; + struct cvp_hfi_cmd_session_hdr* cmd_hdr = + (struct cvp_hfi_cmd_session_hdr*)in_pkt; + + if (!inst || !inst->core || !in_pkt) { + dprintk(CVP_ERR, "%s: invalid params", __func__); + return -EINVAL; + } + + switch (cmd_hdr->packet_type) { + case HFI_CMD_SESSION_CVP_WARP_NCC_FRAME: + rc = msm_cvp_proc_oob_wncc(inst, in_pkt); + break; + default: + break; + } + + return rc; +} void msm_cvp_cache_operations(struct msm_cvp_smem *smem, u32 type, u32 offset, u32 size) @@ -865,6 +1519,7 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) struct msm_cvp_frame *frame, *dummy1; struct msm_cvp_smem *smem; struct cvp_hal_session *session; + struct eva_kmd_buffer buf; session = (struct cvp_hal_session *)inst->session; @@ -922,6 +1577,21 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) } mutex_unlock(&inst->cvpdspbufs.lock); + mutex_lock(&inst->cvpwnccbufs.lock); + if (inst->cvpwnccbufs_num != 0) + dprintk(CVP_WARN, "%s: cvpwnccbufs not empty, contains %d bufs", + __func__, inst->cvpwnccbufs_num); + list_for_each_entry_safe(cbuf, dummy, &inst->cvpwnccbufs.list, list) { + print_internal_buffer(CVP_MEM, "remove wnccbufs", inst, cbuf); + buf.fd = cbuf->fd; + buf.reserved[0] = cbuf->ktid; + + mutex_unlock(&inst->cvpwnccbufs.lock); + msm_cvp_unmap_buf_wncc(inst, &buf); + mutex_lock(&inst->cvpwnccbufs.lock); + } + mutex_unlock(&inst->cvpwnccbufs.lock); + return rc; } @@ -961,6 +1631,12 @@ void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) _log_buf(snap, SMEM_ADSP, inst, buf, log); mutex_unlock(&inst->cvpdspbufs.lock); + mutex_lock(&inst->cvpwnccbufs.lock); + dprintk(CVP_ERR, "wncc buffer list:\n"); + list_for_each_entry(buf, &inst->cvpwnccbufs.list, list) + print_cvp_buffer(CVP_ERR, "bufdump", inst, buf); + mutex_unlock(&inst->cvpwnccbufs.lock); + mutex_lock(&inst->persistbufs.lock); dprintk(CVP_ERR, "persist buffer list:\n"); list_for_each_entry(buf, &inst->persistbufs.list, list) @@ -1213,9 +1889,6 @@ int msm_cvp_register_buffer(struct msm_cvp_inst *inst, return -EINVAL; } - if (!buf->index) - return 0; - s = cvp_get_inst_validate(inst->core, inst); if (!s) return -ECONNRESET; @@ -1229,7 +1902,10 @@ int msm_cvp_register_buffer(struct msm_cvp_inst *inst, hdev = inst->core->device; print_client_buffer(CVP_HFI, "register", inst, buf); - rc = msm_cvp_map_buf_dsp(inst, buf); + if (buf->index) + rc = msm_cvp_map_buf_dsp(inst, buf); + else + rc = msm_cvp_map_buf_wncc(inst, buf); dprintk(CVP_DSP, "%s: fd %d, iova 0x%x\n", __func__, buf->fd, buf->reserved[0]); exit: @@ -1248,19 +1924,16 @@ int msm_cvp_unregister_buffer(struct msm_cvp_inst *inst, return -EINVAL; } - if (!buf->index) - return 0; - s = cvp_get_inst_validate(inst->core, inst); if (!s) return -ECONNRESET; print_client_buffer(CVP_HFI, "unregister", inst, buf); - rc = msm_cvp_unmap_buf_dsp(inst, buf); + if (buf->index) + rc = msm_cvp_unmap_buf_dsp(inst, buf); + else + rc = msm_cvp_unmap_buf_wncc(inst, buf); cvp_put_inst(s); return rc; } - - - diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index 28de546401..dfb637896c 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -75,6 +75,12 @@ struct msm_cvp_smem { struct cvp_dma_mapping_info mapping_info; }; +struct msm_cvp_wncc_buffer { + u32 fd; + u32 iova; + u32 size; +}; + struct cvp_dmamap_cache { unsigned long usage_bitmap; struct mutex lock; @@ -184,6 +190,12 @@ int msm_cvp_map_buf_dsp_new(struct msm_cvp_inst *inst, uint32_t *iova); int msm_cvp_unmap_buf_dsp_new(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf); +int msm_cvp_map_buf_wncc(struct msm_cvp_inst* inst, + struct eva_kmd_buffer* buf); +int msm_cvp_unmap_buf_wncc(struct msm_cvp_inst* inst, + struct eva_kmd_buffer* buf); +int msm_cvp_proc_oob(struct msm_cvp_inst* inst, + struct eva_kmd_hfi_packet* in_pkt); void msm_cvp_cache_operations(struct msm_cvp_smem *smem, u32 type, u32 offset, u32 size); u32 msm_cvp_map_frame_buf(struct msm_cvp_inst *inst, diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 20f523813c..4a04a1f020 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -176,8 +176,12 @@ void *msm_cvp_open(int core_id, int session_type) INIT_MSM_CVP_LIST(&inst->persistbufs); INIT_DMAMAP_CACHE(&inst->dma_cache); INIT_MSM_CVP_LIST(&inst->cvpdspbufs); + INIT_MSM_CVP_LIST(&inst->cvpwnccbufs); INIT_MSM_CVP_LIST(&inst->frames); + inst->cvpwnccbufs_num = 0; + inst->cvpwnccbufs_table = NULL; + init_waitqueue_head(&inst->event_handler.wq); kref_init(&inst->kref); @@ -234,6 +238,7 @@ fail_init: DEINIT_MSM_CVP_LIST(&inst->persistbufs); DEINIT_DMAMAP_CACHE(&inst->dma_cache); DEINIT_MSM_CVP_LIST(&inst->cvpdspbufs); + DEINIT_MSM_CVP_LIST(&inst->cvpwnccbufs); DEINIT_MSM_CVP_LIST(&inst->frames); kfree(inst); @@ -364,8 +369,12 @@ int msm_cvp_destroy(struct msm_cvp_inst *inst) DEINIT_MSM_CVP_LIST(&inst->persistbufs); DEINIT_DMAMAP_CACHE(&inst->dma_cache); DEINIT_MSM_CVP_LIST(&inst->cvpdspbufs); + DEINIT_MSM_CVP_LIST(&inst->cvpwnccbufs); DEINIT_MSM_CVP_LIST(&inst->frames); + kfree(inst->cvpwnccbufs_table); + inst->cvpwnccbufs_table = NULL; + mutex_destroy(&inst->sync_lock); mutex_destroy(&inst->lock); diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index 05b1e47793..fffb5f5e23 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -390,7 +390,10 @@ struct msm_cvp_inst { struct msm_cvp_list persistbufs; struct cvp_dmamap_cache dma_cache; struct msm_cvp_list cvpdspbufs; + struct msm_cvp_list cvpwnccbufs; struct msm_cvp_list frames; + u32 cvpwnccbufs_num; + struct msm_cvp_wncc_buffer* cvpwnccbufs_table; struct completion completions[SESSION_MSG_END - SESSION_MSG_START + 1]; struct dentry *debugfs_root; struct msm_cvp_debug debug; diff --git a/msm/eva/msm_cvp_ioctl.c b/msm/eva/msm_cvp_ioctl.c index 9197cd6e6f..e273b92821 100644 --- a/msm/eva/msm_cvp_ioctl.c +++ b/msm/eva/msm_cvp_ioctl.c @@ -74,6 +74,9 @@ static int _copy_pkt_from_user(struct eva_kmd_arg *kp, if (get_user(k->pkt_data[i], &u->pkt_data[i])) return -EFAULT; + if (get_user(k->oob_buf, &u->oob_buf)) + return -EFAULT; + return 0; } @@ -88,6 +91,9 @@ static int _copy_synx_data_from_user( return -EFAULT; } + if (get_user(k->oob_buf, &u->oob_buf)) + return -EFAULT; + return 0; } @@ -180,6 +186,9 @@ static int _copy_pkt_to_user(struct eva_kmd_arg *kp, if (put_user(k->pkt_data[i], &u->pkt_data[i])) return -EFAULT; + if (put_user(k->oob_buf, &u->oob_buf)) + return -EFAULT; + return 0; } @@ -197,6 +206,9 @@ static int _copy_fence_pkt_to_user(struct eva_kmd_arg *kp, return -EFAULT; } + if (put_user(k->oob_buf, &u->oob_buf)) + return -EFAULT; + return 0; } From adcab3bd3bfdb14211ef89e8eaa9977d1f519752 Mon Sep 17 00:00:00 2001 From: apreetam Date: Mon, 24 Jan 2022 14:34:26 +0530 Subject: [PATCH 110/317] msm: eva: Clean-up debugfs root To remove debugfs root in case of failure Change-Id: I8a9a03a45c3a2c1f5b620f55ae0f5745debf3881 Signed-off-by: Aakash Preetam --- msm/eva/cvp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index a47f53eca8..a5f045268e 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -456,6 +456,7 @@ static int msm_probe_cvp_device(struct platform_device *pdev) err_fail_sub_device_probe: cvp_hfi_deinitialize(core->hfi_type, core->device); + debugfs_remove_recursive(cvp_driver->debugfs_root); err_hfi_initialize: err_cores_exceeded: cdev_del(&core->cdev); @@ -610,7 +611,6 @@ static int __init msm_cvp_init(void) if (rc) { dprintk(CVP_ERR, "Failed to register platform driver\n"); - debugfs_remove_recursive(cvp_driver->debugfs_root); kfree(cvp_driver); cvp_driver = NULL; return rc; From 26396dd79a9d76c66d8b0749ef02afb39fba48c9 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 17 Feb 2022 10:08:39 -0800 Subject: [PATCH 111/317] msm: eva: Enable EVA power colapse Remove temporary changes for RUMI bring up. Change-Id: Ibad6025fcc9b18d062cd46bf33f6c7e051dbf91d Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 2 +- msm/eva/msm_cvp_debug.c | 2 +- msm/eva/msm_cvp_platform.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index c1bcbd7887..92378ba281 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -994,7 +994,7 @@ static inline int __boot_firmware(struct iris_hfi_device *device) } /* Reduce to 500, 1000 on silicon */ - usleep_range(50000, 100000); + usleep_range(500, 1000); count++; } diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 8de5736a5b..52b866aaed 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -12,7 +12,7 @@ #define CREATE_TRACE_POINTS #define MAX_SSR_STRING_LEN 10 -int msm_cvp_debug = CVP_ERR | CVP_WARN | CVP_FW | CVP_DBG; +int msm_cvp_debug = CVP_ERR | CVP_WARN | CVP_FW; EXPORT_SYMBOL(msm_cvp_debug); int msm_cvp_debug_out = CVP_OUT_PRINTK; diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 5b18a34029..24a438af7d 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -102,7 +102,7 @@ static struct msm_cvp_common_data sm8550_common_data[] = { }, { .key = "qcom,sw-power-collapse", - .value = 0, + .value = 1, }, { .key = "qcom,domain-attr-non-fatal-faults", From 8205a08975c354518829cc485a7b74726ef7c9df Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 14 Mar 2022 14:32:26 -0700 Subject: [PATCH 112/317] msm: eva: Support synx version update The change makes it easier for eva driver to support backward and forwardcompatibility of SynX versions. Change-Id: I6382d5c904d30bd38692ce74e747749e113be621 Signed-off-by: George Shen --- msm/eva/cvp.c | 2 ++ msm/eva/msm_cvp.c | 20 +++++++----- msm/eva/msm_cvp_core.c | 4 +-- msm/eva/msm_cvp_internal.h | 1 + msm/eva/msm_cvp_synx.c | 33 +++++++++++++++---- msm/eva/msm_cvp_synx.h | 65 +++++++++----------------------------- 6 files changed, 58 insertions(+), 67 deletions(-) diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index a5f045268e..2231997d05 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -415,6 +415,8 @@ static int msm_probe_cvp_device(struct platform_device *pdev) goto err_hfi_initialize; } + cvp_synx_ftbl_init(core); + mutex_lock(&cvp_driver->lock); list_add_tail(&core->list, &cvp_driver->cores); mutex_unlock(&cvp_driver->lock); diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 245043c56e..b76ea67f9c 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -473,7 +473,8 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, sq = &inst->session_queue_fence; ktid = pkt->client_data.kdata; - rc = cvp_synx_ops(inst, CVP_INPUT_SYNX, fc, &synx_state); + rc = inst->core->synx_ftbl->cvp_synx_ops(inst, CVP_INPUT_SYNX, + fc, &synx_state); if (rc) { msm_cvp_unmap_frame(inst, pkt->client_data.kdata); goto exit; @@ -538,7 +539,8 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, } exit: - rc = cvp_synx_ops(inst, CVP_OUTPUT_SYNX, fc, &synx_state); + rc = inst->core->synx_ftbl->cvp_synx_ops(inst, CVP_OUTPUT_SYNX, + fc, &synx_state); if (clock_check) cvp_check_clock(inst, (struct cvp_hfi_msg_session_hdr_ext *)&hdr); @@ -616,7 +618,7 @@ wait: rc = cvp_fence_proc(inst, f, pkt); mutex_lock(&q->lock); - cvp_release_synx(inst, f); + inst->core->synx_ftbl->cvp_release_synx(inst, f); list_del_init(&f->list); state = q->state; mutex_unlock(&q->lock); @@ -733,7 +735,7 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst, f->pkt->client_data.kdata |= FENCE_BIT; - rc = cvp_import_synx(inst, f, fence); + rc = inst->core->synx_ftbl->cvp_import_synx(inst, f, fence); if (rc) { kfree(f); goto exit; @@ -1054,7 +1056,7 @@ int msm_cvp_session_create(struct msm_cvp_inst *inst) goto fail_init; } - cvp_sess_init_synx(inst); + inst->core->synx_ftbl->cvp_sess_init_synx(inst); sq = &inst->session_queue; spin_lock(&sq->lock); sq->state = QUEUE_ACTIVE; @@ -1571,8 +1573,9 @@ static void cvp_clean_fence_queue(struct msm_cvp_inst *inst, int synx_state) list_del_init(&f->list); msm_cvp_unmap_frame(inst, f->pkt->client_data.kdata); - cvp_cancel_synx(inst, CVP_OUTPUT_SYNX, f, synx_state); - cvp_release_synx(inst, f); + inst->core->synx_ftbl->cvp_cancel_synx(inst, CVP_OUTPUT_SYNX, + f, synx_state); + inst->core->synx_ftbl->cvp_release_synx(inst, f); cvp_free_fence_data(f); } @@ -1581,7 +1584,8 @@ static void cvp_clean_fence_queue(struct msm_cvp_inst *inst, int synx_state) dprintk(CVP_SYNX, "%s: (%#x)flush frame %llu %llu sched_list\n", __func__, hash32_ptr(inst->session), ktid, f->frame_id); - cvp_cancel_synx(inst, CVP_INPUT_SYNX, f, synx_state); + inst->core->synx_ftbl->cvp_cancel_synx(inst, CVP_INPUT_SYNX, + f, synx_state); } mutex_unlock(&q->lock); diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 4a04a1f020..96280d2397 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -325,7 +325,7 @@ wait: dprintk(CVP_WARN, "Unprocessed frame %d\n", frame->pkt_type); mutex_unlock(&inst->frames.lock); - cvp_dump_fence_queue(inst); + inst->core->synx_ftbl->cvp_dump_fence_queue(inst); } if (cvp_release_arp_buffers(inst)) @@ -382,7 +382,7 @@ int msm_cvp_destroy(struct msm_cvp_inst *inst) __deinit_session_queue(inst); __deinit_fence_queue(inst); - cvp_sess_deinit_synx(inst); + core->synx_ftbl->cvp_sess_deinit_synx(inst); pr_info(CVP_DBG_TAG "Closed cvp instance: %pK session_id = %d\n", "sess", inst, hash32_ptr(inst->session)); diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index fffb5f5e23..fb4f9dcb0f 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -352,6 +352,7 @@ struct msm_cvp_core { struct device *dev; struct cvp_hfi_device *device; struct msm_cvp_platform_data *platform_data; + struct msm_cvp_synx_ops *synx_ftbl; struct list_head instances; struct dentry *debugfs_root; enum cvp_core_state state; diff --git a/msm/eva/msm_cvp_synx.c b/msm/eva/msm_cvp_synx.c index c5715415c1..66b8c8d733 100644 --- a/msm/eva/msm_cvp_synx.c +++ b/msm/eva/msm_cvp_synx.c @@ -10,7 +10,7 @@ #include "msm_cvp_dsp.h" #ifdef CVP_SYNX_ENABLED -int cvp_sess_init_synx(struct msm_cvp_inst *inst) +static int cvp_sess_init_synx_v1(struct msm_cvp_inst *inst) { struct synx_initialization_params params; @@ -23,7 +23,7 @@ int cvp_sess_init_synx(struct msm_cvp_inst *inst) return 0; } -int cvp_sess_deinit_synx(struct msm_cvp_inst *inst) +static int cvp_sess_deinit_synx(struct msm_cvp_inst *inst) { if (!inst) { dprintk(CVP_ERR, "Used invalid sess in deinit_synx\n"); @@ -33,7 +33,7 @@ int cvp_sess_deinit_synx(struct msm_cvp_inst *inst) return 0; } -void cvp_dump_fence_queue(struct msm_cvp_inst *inst) +static void cvp_dump_fence_queue_v1(struct msm_cvp_inst *inst) { struct cvp_fence_queue *q; struct cvp_fence_command *f; @@ -68,7 +68,7 @@ void cvp_dump_fence_queue(struct msm_cvp_inst *inst) mutex_unlock(&q->lock); } -int cvp_import_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, +static int cvp_import_synx_v1(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, u32 *fence) { int rc = 0, rr = 0; @@ -107,7 +107,7 @@ int cvp_import_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, return rr; } -int cvp_release_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc) +static int cvp_release_synx_v1(struct msm_cvp_inst *inst, struct cvp_fence_command *fc) { int rc = 0; int i; @@ -175,7 +175,7 @@ static int cvp_cancel_synx_impl(struct msm_cvp_inst *inst, } -int cvp_cancel_synx(struct msm_cvp_inst *inst, enum cvp_synx_type type, +static int cvp_cancel_synx(struct msm_cvp_inst *inst, enum cvp_synx_type type, struct cvp_fence_command *fc, int synx_state) { if (fc->signature != 0xFEEDFACE) { @@ -242,7 +242,7 @@ static int cvp_signal_synx(struct synx_session ssid, u32 *synx, u32 num_synx, return rc; } -int cvp_synx_ops(struct msm_cvp_inst *inst, enum cvp_synx_type type, +static int cvp_synx_ops_v1(struct msm_cvp_inst *inst, enum cvp_synx_type type, struct cvp_fence_command *fc, u32 *synx_state) { struct synx_session ssid; @@ -267,3 +267,22 @@ int cvp_synx_ops(struct msm_cvp_inst *inst, enum cvp_synx_type type, } } #endif + +struct msm_cvp_synx_ops cvp_synx_v1 = { + .cvp_sess_init_synx = cvp_sess_init_synx_v1, + .cvp_sess_deinit_synx = cvp_sess_deinit_synx, + .cvp_release_synx = cvp_release_synx_v1, + .cvp_import_synx = cvp_import_synx_v1, + .cvp_synx_ops = cvp_synx_ops_v1, + .cvp_cancel_synx = cvp_cancel_synx, + .cvp_dump_fence_queue = cvp_dump_fence_queue_v1, +}; + +void cvp_synx_ftbl_init(struct msm_cvp_core *core) +{ + if (!core) + return; + + /* Synx API version check below if needed */ + core->synx_ftbl = &cvp_synx_v1; +} diff --git a/msm/eva/msm_cvp_synx.h b/msm/eva/msm_cvp_synx.h index 59c5c5ac65..b2af60af52 100644 --- a/msm/eva/msm_cvp_synx.h +++ b/msm/eva/msm_cvp_synx.h @@ -10,6 +10,7 @@ #include #include "cvp_comm_def.h" +struct msm_cvp_core; struct cvp_fence_queue { struct mutex lock; @@ -44,60 +45,24 @@ enum cvp_synx_type { CVP_INVALID_SYNX, }; -#ifdef CVP_SYNX_ENABLED -int cvp_sess_init_synx(struct msm_cvp_inst *inst); -int cvp_sess_deinit_synx(struct msm_cvp_inst *inst); -int cvp_import_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, - u32 *fence); -int cvp_release_synx(struct msm_cvp_inst *inst, struct cvp_fence_command *fc); -int cvp_cancel_synx(struct msm_cvp_inst *inst, enum cvp_synx_type type, - struct cvp_fence_command *fc, int synx_state); -int cvp_synx_ops(struct msm_cvp_inst *inst, enum cvp_synx_type type, - struct cvp_fence_command *fc, u32 *synx_state); -void cvp_dump_fence_queue(struct msm_cvp_inst *inst); -#else -static inline int cvp_sess_init_synx(struct msm_cvp_inst *inst) -{ - return -ENODEV; -} - -static inline int cvp_sess_deinit_synx(struct msm_cvp_inst *inst) -{ - return -ENODEV; -} - -static inline int cvp_import_synx(struct msm_cvp_inst *inst, +struct msm_cvp_synx_ops { + int (*cvp_sess_init_synx)(struct msm_cvp_inst *inst); + int (*cvp_sess_deinit_synx)(struct msm_cvp_inst *inst); + int (*cvp_release_synx)(struct msm_cvp_inst *inst, + struct cvp_fence_command *fc); + int (*cvp_import_synx)(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, - u32 *fence) -{ - return -ENODEV; -} - -static inline int cvp_release_synx(struct msm_cvp_inst *inst, - struct cvp_fence_command *fc) -{ - return -ENODEV; -} - -static inline int cvp_cancel_synx(struct msm_cvp_inst *inst, + u32 *fence); + int (*cvp_synx_ops)(struct msm_cvp_inst *inst, enum cvp_synx_type type, struct cvp_fence_command *fc, - int synx_state) -{ - return -ENODEV; -} - -static inline int cvp_synx_ops(struct msm_cvp_inst *inst, + u32 *synx_state); + int (*cvp_cancel_synx)(struct msm_cvp_inst *inst, enum cvp_synx_type type, struct cvp_fence_command *fc, - u32 *synx_state) -{ - return -ENODEV; -} + int synx_state); + void (*cvp_dump_fence_queue)(struct msm_cvp_inst *inst); +}; -static inline void cvp_dump_fence_queue(struct msm_cvp_inst *inst) -{ - return; -} -#endif +void cvp_synx_ftbl_init(struct msm_cvp_core *core); #endif From 9d9b6bcc4fae933a24994352ae424e888f0a1718 Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 15 Mar 2022 22:12:49 -0700 Subject: [PATCH 113/317] msm: eva: Update VIDEOCC register offset CFG_SREGR is added for all cores in Kailua. Some of EVA registers in VIDEOCC have offset down-shfited. Change-Id: Ibd5d5153e4c633209a65abea74d97c5b39b7ea5d Signed-off-by: George Shen --- msm/eva/cvp_hfi_io.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index 513e45dd07..1dff20eb25 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -246,10 +246,10 @@ #define CVP_AON_WRAPPER_CVP_NOC_LPI_STATUS (CVP_AON_BASE_OFFS + 0xC) #define CVP_CC_BASE_OFFS 0x000F8000 -#define CVP_CC_MVS1C_GDSCR (CVP_CC_BASE_OFFS + 0x74) -#define CVP_CC_MVS1C_CBCR (CVP_CC_BASE_OFFS + 0x8C) -#define CVP_CC_MVS1_GDSCR (CVP_CC_BASE_OFFS + 0xC0) -#define CVP_CC_MVS1_CBCR (CVP_CC_BASE_OFFS + 0xD4) +#define CVP_CC_MVS1C_GDSCR (CVP_CC_BASE_OFFS + 0x78) +#define CVP_CC_MVS1C_CBCR (CVP_CC_BASE_OFFS + 0x90) +#define CVP_CC_MVS1_GDSCR (CVP_CC_BASE_OFFS + 0xCC) +#define CVP_CC_MVS1_CBCR (CVP_CC_BASE_OFFS + 0xE0) #define CVP_GCC_VIDEO_AXI1_CBCR (0x32020) #endif From 7cc6e333d2bdfe88fa2829dea1c6d99e58874834 Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 15 Mar 2022 17:02:12 -0700 Subject: [PATCH 114/317] msm: eva: Use rate limited printk API Avoid potential system level RT throttling issue. Change-Id: I0fbe198957ef9e5c21435fef2c6e8b6df551da5b Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 4 ++-- msm/eva/msm_cvp.c | 2 +- msm/eva/msm_cvp_core.c | 6 ++++-- msm/eva/msm_cvp_debug.h | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 92378ba281..77d1600967 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -3903,7 +3903,7 @@ static int __iris_power_on(struct iris_hfi_device *device) enable_irq(device->cvp_hal_data->irq); __write_register(device, CVP_WRAPPER_DEBUG_BRIDGE_LPI_CONTROL, 0x7); - pr_info(CVP_DBG_TAG "cvp (eva) powered on\n", "pwr"); + pr_info_ratelimited(CVP_DBG_TAG "cvp (eva) powered on\n", "pwr"); return 0; fail_enable_core: @@ -4229,7 +4229,7 @@ static void power_off_iris2(struct iris_hfi_device *device) /*Do not access registers after this point!*/ device->power_enabled = false; - pr_info(CVP_DBG_TAG "cvp (eva) power collapsed\n", "pwr"); + pr_info_ratelimited(CVP_DBG_TAG "cvp (eva) power collapsed\n", "pwr"); } static inline int __resume(struct iris_hfi_device *device) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index b76ea67f9c..b6c22a2391 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -1197,7 +1197,7 @@ static int msm_cvp_session_stop(struct msm_cvp_inst *inst, } sq->state = QUEUE_STOP; - pr_info(CVP_DBG_TAG "Stop session: %pK session_id = %d\n", + pr_info_ratelimited(CVP_DBG_TAG "Stop session: %pK session_id = %d\n", "sess", inst, hash32_ptr(inst->session)); spin_unlock(&sq->lock); diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 96280d2397..757f11b510 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -168,7 +168,8 @@ void *msm_cvp_open(int core_id, int session_type) goto err_invalid_core; } - pr_info(CVP_DBG_TAG "Opening cvp instance: %pK\n", "sess", inst); + pr_info_ratelimited( + CVP_DBG_TAG "Opening cvp instance: %pK\n", "sess", inst); mutex_init(&inst->sync_lock); mutex_init(&inst->lock); spin_lock_init(&inst->event_handler.lock); @@ -384,7 +385,8 @@ int msm_cvp_destroy(struct msm_cvp_inst *inst) __deinit_fence_queue(inst); core->synx_ftbl->cvp_sess_deinit_synx(inst); - pr_info(CVP_DBG_TAG "Closed cvp instance: %pK session_id = %d\n", + pr_info_ratelimited( + CVP_DBG_TAG "Closed cvp instance: %pK session_id = %d\n", "sess", inst, hash32_ptr(inst->session)); inst->session = (void *)0xdeadbeef; kfree(inst); diff --git a/msm/eva/msm_cvp_debug.h b/msm/eva/msm_cvp_debug.h index 842eee3da4..838fa33fa5 100644 --- a/msm/eva/msm_cvp_debug.h +++ b/msm/eva/msm_cvp_debug.h @@ -72,7 +72,7 @@ extern int msm_cvp_minidump_enable; do { \ if (msm_cvp_debug & __level) { \ if (msm_cvp_debug_out == CVP_OUT_PRINTK) { \ - pr_info(CVP_DBG_TAG __fmt, \ + pr_info_ratelimited(CVP_DBG_TAG __fmt, \ get_debug_level_str(__level), \ ## arg); \ } \ From 0c7f40b3230bcc87efc9b36efe78c52b59be8fe9 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 23 Mar 2022 14:17:33 -0700 Subject: [PATCH 115/317] msm: eva: Validate WNCC table pointer before use Reliably handle Kernel memory allocation failure. Change-Id: I27fac01bf5ec45cc8d54757e245ef799f5459d1f Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 93e3b8ae12..0633a61379 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -307,10 +307,9 @@ int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) exit: fput(file); if (smem) { - if (smem->device_addr) { + if (smem->device_addr) msm_cvp_unmap_smem(inst, smem, "unmap dsp"); - msm_cvp_smem_put_dma_buf(smem->dma_buf); - } + msm_cvp_smem_put_dma_buf(smem->dma_buf); kmem_cache_free(cvp_driver->smem_cache, smem); } if (cbuf) @@ -473,6 +472,10 @@ int msm_cvp_map_buf_wncc(struct msm_cvp_inst *inst, sizeof(struct msm_cvp_wncc_buffer) * EVA_KMD_WNCC_MAX_SRC_BUFS, GFP_KERNEL); + if (!inst->cvpwnccbufs_table) { + mutex_unlock(&inst->cvpwnccbufs.lock); + goto exit; + } } list_add_tail(&cbuf->list, &inst->cvpwnccbufs.list); @@ -509,10 +512,9 @@ int msm_cvp_map_buf_wncc(struct msm_cvp_inst *inst, return rc; exit: - if (smem->device_addr) { + if (smem->device_addr) msm_cvp_unmap_smem(inst, smem, "unmap wncc"); - msm_cvp_smem_put_dma_buf(smem->dma_buf); - } + msm_cvp_smem_put_dma_buf(smem->dma_buf); kmem_cache_free(cvp_driver->buf_cache, cbuf); cbuf = NULL; kmem_cache_free(cvp_driver->smem_cache, smem); From 6492155cccbbae7eee8d6bbf353d013b564cc0e8 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 21 Mar 2022 22:46:34 -0700 Subject: [PATCH 116/317] msm: eva: Add LE support Define CONFIG_EVA_LE compiler flag. Add separate VM support module. Define stub functions to initialize synx function table in case SYNX is disabled. Change-Id: I0f6b28cbd2a43cbb7f464629a329581a73c4de89 Signed-off-by: George Shen --- msm/Kbuild | 7 ++++++- msm/eva/cvp_comm_def.h | 7 +++++++ msm/eva/msm_cvp_buf.c | 4 +++- msm/eva/msm_cvp_synx.c | 45 ++++++++++++++++++++++++++++++++++++++++-- msm/eva/msm_cvp_vm.c | 13 ++++++++++++ msm/eva/msm_cvp_vm.h | 16 +++++++++++++++ 6 files changed, 88 insertions(+), 4 deletions(-) create mode 100644 msm/eva/msm_cvp_vm.c create mode 100644 msm/eva/msm_cvp_vm.h diff --git a/msm/Kbuild b/msm/Kbuild index 97843063e4..658d2f0cb2 100644 --- a/msm/Kbuild +++ b/msm/Kbuild @@ -28,6 +28,10 @@ KBUILD_CPPFLAGS += -DCONFIG_EVA_KALAMA=1 ccflags-y += -DCONFIG_EVA_KALAMA=1 endif +ifeq ($(CONFIG_EVA_LE), 1) +ccflags-y += -DCONFIG_EVA_LE=1 +endif + msm-eva-objs := eva/cvp.o \ eva/msm_cvp_ioctl.o \ eva/msm_cvp_platform.o \ @@ -46,6 +50,7 @@ msm-eva-objs := eva/cvp.o \ eva/msm_cvp_dsp.o \ eva/msm_cvp_buf.o \ eva/msm_cvp_synx.o \ - eva/cvp_fw_load.o + eva/cvp_fw_load.o \ + eva/msm_cvp_vm.o obj-m += msm-eva.o diff --git a/msm/eva/cvp_comm_def.h b/msm/eva/cvp_comm_def.h index 2edacca9b1..9ddd73cc5d 100644 --- a/msm/eva/cvp_comm_def.h +++ b/msm/eva/cvp_comm_def.h @@ -23,11 +23,18 @@ enum queue_state { QUEUE_INVALID, }; +#ifdef CONFIG_EVA_LE + +#else /* LA target starts here */ + #define CVP_SYNX_ENABLED 1 #define CVP_MMRM_ENABLED 1 #define CVP_FASTRPC_ENABLED 1 + #ifdef CONFIG_EVA_WAIPIO #define CVP_MINIDUMP_ENABLED 1 #endif +#endif /* End CONFIG_EVA_LE */ + #endif diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 0633a61379..a6b10315b4 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1104,7 +1104,9 @@ static int msm_cvp_session_add_smem(struct msm_cvp_inst *inst, smem->bitmap_index = i; SET_USE_BITMAP(i, inst); } else { - dprintk(CVP_WARN, "%s: not enough memory\n", __func__); + dprintk(CVP_WARN, + "%s: reached limit, fallback to frame mapping list\n" + , __func__); mutex_unlock(&inst->dma_cache.lock); return -ENOMEM; } diff --git a/msm/eva/msm_cvp_synx.c b/msm/eva/msm_cvp_synx.c index 66b8c8d733..5801fda7b1 100644 --- a/msm/eva/msm_cvp_synx.c +++ b/msm/eva/msm_cvp_synx.c @@ -68,7 +68,8 @@ static void cvp_dump_fence_queue_v1(struct msm_cvp_inst *inst) mutex_unlock(&q->lock); } -static int cvp_import_synx_v1(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, +static int cvp_import_synx_v1(struct msm_cvp_inst *inst, + struct cvp_fence_command *fc, u32 *fence) { int rc = 0, rr = 0; @@ -107,7 +108,8 @@ static int cvp_import_synx_v1(struct msm_cvp_inst *inst, struct cvp_fence_comman return rr; } -static int cvp_release_synx_v1(struct msm_cvp_inst *inst, struct cvp_fence_command *fc) +static int cvp_release_synx_v1(struct msm_cvp_inst *inst, + struct cvp_fence_command *fc) { int rc = 0; int i; @@ -266,6 +268,45 @@ static int cvp_synx_ops_v1(struct msm_cvp_inst *inst, enum cvp_synx_type type, return -EINVAL; } } +#else +static int cvp_sess_init_synx_v1(struct msm_cvp_inst *inst) +{ + return 0; +} + +static int cvp_sess_deinit_synx(struct msm_cvp_inst *inst) +{ + return 0; +} + +static int cvp_release_synx_v1(struct msm_cvp_inst *inst, + struct cvp_fence_command *fc) +{ + return 0; +} + +static int cvp_import_synx_v1(struct msm_cvp_inst *inst, + struct cvp_fence_command *fc, + u32 *fence) +{ + return 0; +} + +static int cvp_synx_ops_v1(struct msm_cvp_inst *inst, enum cvp_synx_type type, + struct cvp_fence_command *fc, u32 *synx_state) +{ + return 0; +} + +static int cvp_cancel_synx(struct msm_cvp_inst *inst, enum cvp_synx_type type, + struct cvp_fence_command *fc, int synx_state) +{ + return 0; +} + +static void cvp_dump_fence_queue_v1(struct msm_cvp_inst *inst) +{ +} #endif struct msm_cvp_synx_ops cvp_synx_v1 = { diff --git a/msm/eva/msm_cvp_vm.c b/msm/eva/msm_cvp_vm.c new file mode 100644 index 0000000000..9963420083 --- /dev/null +++ b/msm/eva/msm_cvp_vm.c @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include "msm_cvp_vm.h" + +int msm_cvp_vm_init(struct msm_cvp_core *core) +{ + return 0; +} + + diff --git a/msm/eva/msm_cvp_vm.h b/msm/eva/msm_cvp_vm.h new file mode 100644 index 0000000000..c231bf93fd --- /dev/null +++ b/msm/eva/msm_cvp_vm.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _MSM_CVP_VM_H_ +#define _MSM_CVP_VM_H_ + +#include +#include "cvp_comm_def.h" +#include "msm_cvp_core.h" +#include "msm_cvp_internal.h" + +int msm_cvp_vm_init(struct msm_cvp_core *core); + +#endif From 7a7d1cf8b529c366ce41c29fc77b1966b28009eb Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 4 Apr 2022 09:21:01 -0700 Subject: [PATCH 117/317] msm: eva: Add initial drop of VM manager First drop for common code base. Change-Id: If0147395cc946f1cad69c270226b0ff20e11b6ef Signed-off-by: George Shen --- msm/eva/cvp_core_hfi.h | 2 + msm/eva/cvp_hfi.c | 115 +-------------------------- msm/eva/msm_cvp_internal.h | 1 + msm/eva/msm_cvp_platform.c | 69 ++++++++++++++++- msm/eva/msm_cvp_vm.c | 155 ++++++++++++++++++++++++++++++++++++- msm/eva/msm_cvp_vm.h | 27 ++++++- 6 files changed, 253 insertions(+), 116 deletions(-) diff --git a/msm/eva/cvp_core_hfi.h b/msm/eva/cvp_core_hfi.h index e4ca6b6549..ed7e04f09f 100644 --- a/msm/eva/cvp_core_hfi.h +++ b/msm/eva/cvp_core_hfi.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include "cvp_hfi_api.h" #include "cvp_hfi_helper.h" @@ -267,6 +268,7 @@ struct iris_hfi_device { struct iris_hfi_vpu_ops *vpu_ops; }; +irqreturn_t cvp_hfi_isr(int irq, void *dev); void cvp_iris_hfi_delete_device(void *device); int cvp_iris_hfi_initialize(struct cvp_hfi_device *hdev, u32 device_id, diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 77d1600967..30dc4f94f8 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -31,9 +30,9 @@ #include "cvp_hfi_io.h" #include "msm_cvp_dsp.h" #include "msm_cvp_clocks.h" +#include "msm_cvp_vm.h" #include "cvp_dump.h" -#define FIRMWARE_SIZE 0X00A00000 #define REG_ADDR_OFFSET_BITMASK 0x000FFFFF #define QDSS_IOVA_START 0x80001000 #define MIN_PAYLOAD_SIZE 3 @@ -2399,48 +2398,6 @@ static int iris_hfi_session_flush(void *sess) return rc; } -static int __check_core_registered(struct iris_hfi_device *device, - phys_addr_t fw_addr, u8 *reg_addr, u32 reg_size, - phys_addr_t irq) -{ - struct cvp_hal_data *cvp_hal_data; - - if (!device) { - dprintk(CVP_INFO, "no device Registered\n"); - return -EINVAL; - } - - cvp_hal_data = device->cvp_hal_data; - if (!cvp_hal_data) - return -EINVAL; - - if (cvp_hal_data->irq == irq && - (CONTAINS(cvp_hal_data->firmware_base, - FIRMWARE_SIZE, fw_addr) || - CONTAINS(fw_addr, FIRMWARE_SIZE, - cvp_hal_data->firmware_base) || - CONTAINS(cvp_hal_data->register_base, - reg_size, reg_addr) || - CONTAINS(reg_addr, reg_size, - cvp_hal_data->register_base) || - OVERLAPS(cvp_hal_data->register_base, - reg_size, reg_addr, reg_size) || - OVERLAPS(reg_addr, reg_size, - cvp_hal_data->register_base, - reg_size) || - OVERLAPS(cvp_hal_data->firmware_base, - FIRMWARE_SIZE, fw_addr, - FIRMWARE_SIZE) || - OVERLAPS(fw_addr, FIRMWARE_SIZE, - cvp_hal_data->firmware_base, - FIRMWARE_SIZE))) { - return 0; - } - - dprintk(CVP_INFO, "Device not registered\n"); - return -EINVAL; -} - static void __process_fatal_error( struct iris_hfi_device *device) { @@ -3049,7 +3006,7 @@ err_no_work: static DECLARE_WORK(iris_hfi_work, iris_hfi_core_work_handler); -static irqreturn_t iris_hfi_isr(int irq, void *dev) +irqreturn_t cvp_hfi_isr(int irq, void *dev) { struct iris_hfi_device *device = dev; @@ -3058,72 +3015,6 @@ static irqreturn_t iris_hfi_isr(int irq, void *dev) return IRQ_HANDLED; } -static int __init_regs_and_interrupts(struct iris_hfi_device *device, - struct msm_cvp_platform_resources *res) -{ - struct cvp_hal_data *hal = NULL; - int rc = 0; - - rc = __check_core_registered(device, res->firmware_base, - (u8 *)(uintptr_t)res->register_base, - res->register_size, res->irq); - if (!rc) { - dprintk(CVP_ERR, "Core present/Already added\n"); - rc = -EEXIST; - goto err_core_init; - } - - hal = kzalloc(sizeof(*hal), GFP_KERNEL); - if (!hal) { - dprintk(CVP_ERR, "Failed to alloc\n"); - rc = -ENOMEM; - goto err_core_init; - } - - hal->irq = res->irq; - hal->firmware_base = res->firmware_base; - hal->register_base = devm_ioremap(&res->pdev->dev, - res->register_base, res->register_size); - hal->register_size = res->register_size; - if (!hal->register_base) { - dprintk(CVP_ERR, - "could not map reg addr %pa of size %d\n", - &res->register_base, res->register_size); - goto error_irq_fail; - } - - if (res->gcc_reg_base) { - hal->gcc_reg_base = devm_ioremap(&res->pdev->dev, - res->gcc_reg_base, res->gcc_reg_size); - hal->gcc_reg_size = res->gcc_reg_size; - if (!hal->gcc_reg_base) - dprintk(CVP_ERR, - "could not map gcc reg addr %pa of size %d\n", - &res->gcc_reg_base, res->gcc_reg_size); - } - - device->cvp_hal_data = hal; - rc = request_irq(res->irq, iris_hfi_isr, IRQF_TRIGGER_HIGH, - "msm_cvp", device); - if (unlikely(rc)) { - dprintk(CVP_ERR, "() :request_irq failed\n"); - goto error_irq_fail; - } - - disable_irq_nosync(res->irq); - dprintk(CVP_INFO, - "firmware_base = %pa, register_base = %pa, register_size = %d\n", - &res->firmware_base, &res->register_base, - res->register_size); - return rc; - -error_irq_fail: - kfree(hal); -err_core_init: - return rc; - -} - static int __handle_reset_clk(struct msm_cvp_platform_resources *res, int reset_index, enum reset_state state, enum power_state pwr_state) @@ -4657,7 +4548,7 @@ static struct iris_hfi_device *__add_device(u32 device_id, goto err_cleanup; } - rc = __init_regs_and_interrupts(hdevice, res); + rc = vm_manager.vm_ops->vm_init_reg_and_irq(hdevice, res); if (rc) goto err_cleanup; diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index fb4f9dcb0f..b6cc53f217 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -135,6 +135,7 @@ struct msm_cvp_platform_data { unsigned int common_data_length; unsigned int sku_version; uint32_t vpu_ver; + unsigned int vm_id; /* pvm: 1; tvm: 2 */ struct msm_cvp_ubwc_config_data *ubwc_config; struct msm_cvp_qos_setting *noc_qos; }; diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 24a438af7d..faf5b4293e 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -147,7 +147,57 @@ static struct msm_cvp_common_data sm8550_common_data[] = { } }; - +static struct msm_cvp_common_data sm8550_tvm_common_data[] = { + { + .key = "qcom,pm-qos-latency-us", + .value = 50, + }, + { + .key = "qcom,sw-power-collapse", + .value = 0, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 0, + }, + { + .key = "qcom,max-secure-instances", + .value = 2, /* + * As per design driver allows 3rd + * instance as well since the secure + * flags were updated later for the + * current instance. Hence total + * secure sessions would be + * max-secure-instances + 1. + */ + }, + { + .key = "qcom,max-ssr-allowed", + .value = 1, /* + * Maxinum number of SSR before BUG_ON + */ + }, + { + .key = "qcom,power-collapse-delay", + .value = 3000, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 2000, + }, + { + .key = "qcom,dsp-resp-timeout", + .value = 1000, + }, + { + .key = "qcom,debug-timeout", + .value = 0, + }, + { + .key = "qcom,dsp-enabled", + .value = 0, + } +}; /* Default UBWC config for LPDDR5 */ static struct msm_cvp_ubwc_config_data kona_ubwc_data[] = { @@ -170,6 +220,7 @@ static struct msm_cvp_platform_data default_data = { .vpu_ver = VPU_VERSION_5, .ubwc_config = 0x0, .noc_qos = 0x0, + .vm_id = 1, }; static struct msm_cvp_platform_data sm8450_data = { @@ -179,6 +230,7 @@ static struct msm_cvp_platform_data sm8450_data = { .vpu_ver = VPU_VERSION_5, .ubwc_config = kona_ubwc_data, .noc_qos = &waipio_noc_qos, + .vm_id = 1, }; static struct msm_cvp_platform_data sm8550_data = { @@ -188,6 +240,17 @@ static struct msm_cvp_platform_data sm8550_data = { .vpu_ver = VPU_VERSION_5, .ubwc_config = kona_ubwc_data, /*Reuse Kona setting*/ .noc_qos = &waipio_noc_qos, /*Reuse Waipio setting*/ + .vm_id = 1, +}; + +static struct msm_cvp_platform_data sm8550_tvm_data = { + .common_data = sm8550_tvm_common_data, + .common_data_length = ARRAY_SIZE(sm8550_tvm_common_data), + .sku_version = 0, + .vpu_ver = VPU_VERSION_5, + .ubwc_config = kona_ubwc_data, /*Reuse Kona setting*/ + .noc_qos = &waipio_noc_qos, /*Reuse Waipio setting*/ + .vm_id = 2, }; static const struct of_device_id msm_cvp_dt_match[] = { @@ -199,6 +262,10 @@ static const struct of_device_id msm_cvp_dt_match[] = { .compatible = "qcom,kalama-cvp", .data = &sm8550_data, }, + { + .compatible = "qcom,kalama-cvp-tvm", + .data = &sm8550_tvm_data, + }, {}, }; diff --git a/msm/eva/msm_cvp_vm.c b/msm/eva/msm_cvp_vm.c index 9963420083..61aae613e5 100644 --- a/msm/eva/msm_cvp_vm.c +++ b/msm/eva/msm_cvp_vm.c @@ -2,12 +2,163 @@ * * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. */ - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "hfi_packetization.h" +#include "msm_cvp_debug.h" +#include "cvp_core_hfi.h" +#include "cvp_hfi_helper.h" +#include "cvp_hfi_io.h" +#include "msm_cvp_dsp.h" +#include "msm_cvp_clocks.h" +#include "cvp_dump.h" #include "msm_cvp_vm.h" -int msm_cvp_vm_init(struct msm_cvp_core *core) +#define FIRMWARE_SIZE 0X00A00000 + +static int msm_cvp_vm_start(struct msm_cvp_core *core); +static int msm_cvp_vm_init_reg_and_irq(struct iris_hfi_device *device, + struct msm_cvp_platform_resources *res); + +static struct msm_cvp_vm_ops vm_ops = { + .vm_start = msm_cvp_vm_start, + .vm_init_reg_and_irq = msm_cvp_vm_init_reg_and_irq, +}; + +struct msm_cvp_vm_manager vm_manager = { + .vm_ops = &vm_ops, +}; + +static int msm_cvp_vm_start(struct msm_cvp_core *core) { + vm_manager.vm_id = core->platform_data->vm_id; return 0; } +static int __check_core_registered(struct iris_hfi_device *device, + phys_addr_t fw_addr, u8 *reg_addr, u32 reg_size, + phys_addr_t irq) +{ + struct cvp_hal_data *cvp_hal_data; + if (!device) { + dprintk(CVP_INFO, "no device Registered\n"); + return -EINVAL; + } + + cvp_hal_data = device->cvp_hal_data; + if (!cvp_hal_data) + return -EINVAL; + + if (cvp_hal_data->irq == irq && + (CONTAINS(cvp_hal_data->firmware_base, + FIRMWARE_SIZE, fw_addr) || + CONTAINS(fw_addr, FIRMWARE_SIZE, + cvp_hal_data->firmware_base) || + CONTAINS(cvp_hal_data->register_base, + reg_size, reg_addr) || + CONTAINS(reg_addr, reg_size, + cvp_hal_data->register_base) || + OVERLAPS(cvp_hal_data->register_base, + reg_size, reg_addr, reg_size) || + OVERLAPS(reg_addr, reg_size, + cvp_hal_data->register_base, + reg_size) || + OVERLAPS(cvp_hal_data->firmware_base, + FIRMWARE_SIZE, fw_addr, + FIRMWARE_SIZE) || + OVERLAPS(fw_addr, FIRMWARE_SIZE, + cvp_hal_data->firmware_base, + FIRMWARE_SIZE))) { + return 0; + } + + dprintk(CVP_INFO, "Device not registered\n"); + return -EINVAL; +} + +static int msm_cvp_vm_init_reg_and_irq(struct iris_hfi_device *device, + struct msm_cvp_platform_resources *res) +{ + struct cvp_hal_data *hal = NULL; + int rc = 0; + + if (vm_manager.vm_id == VM_TRUSTED) + return 0; + + rc = __check_core_registered(device, res->firmware_base, + (u8 *)(uintptr_t)res->register_base, + res->register_size, res->irq); + if (!rc) { + dprintk(CVP_ERR, "Core present/Already added\n"); + rc = -EEXIST; + goto err_core_init; + } + + hal = kzalloc(sizeof(*hal), GFP_KERNEL); + if (!hal) { + dprintk(CVP_ERR, "Failed to alloc\n"); + rc = -ENOMEM; + goto err_core_init; + } + + hal->irq = res->irq; + hal->firmware_base = res->firmware_base; + hal->register_base = devm_ioremap(&res->pdev->dev, + res->register_base, res->register_size); + hal->register_size = res->register_size; + if (!hal->register_base) { + dprintk(CVP_ERR, + "could not map reg addr %pa of size %d\n", + &res->register_base, res->register_size); + goto error_irq_fail; + } + + if (res->gcc_reg_base) { + hal->gcc_reg_base = devm_ioremap(&res->pdev->dev, + res->gcc_reg_base, res->gcc_reg_size); + hal->gcc_reg_size = res->gcc_reg_size; + if (!hal->gcc_reg_base) + dprintk(CVP_ERR, + "could not map gcc reg addr %pa of size %d\n", + &res->gcc_reg_base, res->gcc_reg_size); + } + + device->cvp_hal_data = hal; + rc = request_irq(res->irq, cvp_hfi_isr, IRQF_TRIGGER_HIGH, + "msm_cvp", device); + if (unlikely(rc)) { + dprintk(CVP_ERR, "() :request_irq failed\n"); + goto error_irq_fail; + } + + disable_irq_nosync(res->irq); + dprintk(CVP_INFO, + "firmware_base = %pa, register_base = %pa, register_size = %d\n", + &res->firmware_base, &res->register_base, + res->register_size); + return rc; + +error_irq_fail: + kfree(hal); +err_core_init: + return rc; +} diff --git a/msm/eva/msm_cvp_vm.h b/msm/eva/msm_cvp_vm.h index c231bf93fd..19450e7c9a 100644 --- a/msm/eva/msm_cvp_vm.h +++ b/msm/eva/msm_cvp_vm.h @@ -10,7 +10,32 @@ #include "cvp_comm_def.h" #include "msm_cvp_core.h" #include "msm_cvp_internal.h" +#include "cvp_core_hfi.h" -int msm_cvp_vm_init(struct msm_cvp_core *core); +enum cvp_vm_id { + VM_PRIMARY = 1, + VM_TRUSTED = 2, + VM_INVALID = 3, +}; +enum cvp_vm_state { + VM_STATE_INIT = 1, + VM_STATE_ACTIVE = 2, + VM_STATE_ERROR = 3, + VM_STATE_INVALID = 4, +}; + +struct msm_cvp_vm_ops { + int (*vm_start)(struct msm_cvp_core *core); + int (*vm_init_reg_and_irq)(struct iris_hfi_device *device, + struct msm_cvp_platform_resources *res); +}; + +struct msm_cvp_vm_manager { + enum cvp_vm_state vm_state; + enum cvp_vm_id vm_id; + struct msm_cvp_vm_ops *vm_ops; +}; + +extern struct msm_cvp_vm_manager vm_manager; #endif From 30f964242d092301267c31f575bb6975f567d463 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 4 Apr 2022 21:38:14 -0700 Subject: [PATCH 118/317] msm: eva: Remove unnecessary suspend warning It always happen in TVM. Change-Id: If77c1799cbeb7f331e2c13db1ceb9e38b1162def Signed-off-by: George Shen --- msm/eva/cvp.c | 4 ++++ msm/eva/msm_cvp_common.c | 2 -- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index 2231997d05..43ca66e43b 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -26,6 +26,7 @@ #include "msm_cvp_clocks.h" #include "msm_cvp_dsp.h" #include "msm_cvp.h" +#include "msm_cvp_vm.h" #define CLASS_NAME "cvp" #define DRIVER_NAME "cvp" @@ -400,6 +401,9 @@ static int msm_probe_cvp_device(struct platform_device *pdev) goto err_cores_exceeded; } + /* VM manager shall be started before HFI init */ + vm_manager.vm_ops->vm_start(core); + core->device = cvp_hfi_initialize(core->hfi_type, core->id, &core->resources, &cvp_handle_cmd_response); if (IS_ERR_OR_NULL(core->device)) { diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 8160d9a442..549bd98602 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -1155,8 +1155,6 @@ int msm_cvp_comm_suspend(int core_id) } rc = call_hfi_op(hdev, suspend, hdev->hfi_device_data); - if (rc) - dprintk(CVP_WARN, "Failed to suspend\n"); return rc; } From 81fb7564e77d14f71119803bc92af28e6c9fc241 Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 1 Apr 2022 11:25:17 -0700 Subject: [PATCH 119/317] msm: eva: Reuse HFI/SFR memory after SSR Avoid realloc, remap HFI after SSR. Change-Id: I6801b3cc33643f2936634c94cb5094fc91773348 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 168 ++++++++++++++++++++++++++++------------------ 1 file changed, 103 insertions(+), 65 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 30dc4f94f8..f5d107db56 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1397,6 +1397,7 @@ fail_dma_alloc: static void __interface_queues_release(struct iris_hfi_device *device) { +#ifdef CONFIG_EVA_LE int i; struct cvp_hfi_mem_map_table *qdss; struct cvp_hfi_mem_map *mem_map; @@ -1452,7 +1453,7 @@ static void __interface_queues_release(struct iris_hfi_device *device) device->mem_addr.align_virtual_addr = NULL; device->mem_addr.align_device_addr = 0; - +#endif __interface_dsp_queues_release(device); } @@ -1526,47 +1527,24 @@ static void __setup_ucregion_memory_map(struct iris_hfi_device *device) call_iris_op(device, setup_dsp_uc_memmap, device); } -static int __interface_queues_init(struct iris_hfi_device *dev) +static void __hfi_queue_init(struct iris_hfi_device *dev) { + int i, offset = 0; struct cvp_hfi_queue_table_header *q_tbl_hdr; - struct cvp_hfi_queue_header *q_hdr; - u32 i; - int rc = 0; - struct cvp_hfi_mem_map_table *qdss; - struct cvp_hfi_mem_map *mem_map; struct cvp_iface_q_info *iface_q; - struct cvp_hfi_sfr_struct *vsfr; - struct cvp_mem_addr *mem_addr; - int offset = 0; - int num_entries = dev->res->qdss_addr_set.count; - phys_addr_t fw_bias = 0; - size_t q_size; - unsigned long mem_map_table_base_addr; - struct context_bank_info *cb; + struct cvp_hfi_queue_header *q_hdr; - q_size = SHARED_QSIZE - ALIGNED_SFR_SIZE - ALIGNED_QDSS_SIZE; - mem_addr = &dev->mem_addr; - if (!is_iommu_present(dev->res)) - fw_bias = dev->cvp_hal_data->firmware_base; - rc = __smem_alloc(dev, mem_addr, q_size, 1, SMEM_UNCACHED); - if (rc) { - dprintk(CVP_ERR, "iface_q_table_alloc_fail\n"); - goto fail_alloc_queue; - } + if (!dev) + return; - dev->iface_q_table.align_virtual_addr = mem_addr->align_virtual_addr; - dev->iface_q_table.align_device_addr = mem_addr->align_device_addr - - fw_bias; - dev->iface_q_table.mem_size = CVP_IFACEQ_TABLE_SIZE; - dev->iface_q_table.mem_data = mem_addr->mem_data; offset += dev->iface_q_table.mem_size; for (i = 0; i < CVP_IFACEQ_NUMQ; i++) { iface_q = &dev->iface_queues[i]; - iface_q->q_array.align_device_addr = mem_addr->align_device_addr - + offset - fw_bias; + iface_q->q_array.align_device_addr = + dev->iface_q_table.align_device_addr + offset; iface_q->q_array.align_virtual_addr = - mem_addr->align_virtual_addr + offset; + dev->iface_q_table.align_virtual_addr + offset; iface_q->q_array.mem_size = CVP_IFACEQ_QUEUE_SIZE; offset += iface_q->q_array.mem_size; iface_q->q_hdr = CVP_IFACEQ_GET_QHDR_START_ADDR( @@ -1575,35 +1553,6 @@ static int __interface_queues_init(struct iris_hfi_device *dev) spin_lock_init(&iface_q->hfi_lock); } - if ((msm_cvp_fw_debug_mode & HFI_DEBUG_MODE_QDSS) && num_entries) { - rc = __smem_alloc(dev, mem_addr, ALIGNED_QDSS_SIZE, 1, - SMEM_UNCACHED); - if (rc) { - dprintk(CVP_WARN, - "qdss_alloc_fail: QDSS messages logging will not work\n"); - dev->qdss.align_device_addr = 0; - } else { - dev->qdss.align_device_addr = - mem_addr->align_device_addr - fw_bias; - dev->qdss.align_virtual_addr = - mem_addr->align_virtual_addr; - dev->qdss.mem_size = ALIGNED_QDSS_SIZE; - dev->qdss.mem_data = mem_addr->mem_data; - } - } - - rc = __smem_alloc(dev, mem_addr, ALIGNED_SFR_SIZE, 1, SMEM_UNCACHED); - if (rc) { - dprintk(CVP_WARN, "sfr_alloc_fail: SFR not will work\n"); - dev->sfr.align_device_addr = 0; - } else { - dev->sfr.align_device_addr = mem_addr->align_device_addr - - fw_bias; - dev->sfr.align_virtual_addr = mem_addr->align_virtual_addr; - dev->sfr.mem_size = ALIGNED_SFR_SIZE; - dev->sfr.mem_data = mem_addr->mem_data; - } - q_tbl_hdr = (struct cvp_hfi_queue_table_header *) dev->iface_q_table.align_virtual_addr; q_tbl_hdr->qtbl_version = 0; @@ -1636,6 +1585,98 @@ static int __interface_queues_init(struct iris_hfi_device *dev) */ q_hdr->qhdr_rx_req = 0; +} + +static void __sfr_init(struct iris_hfi_device *dev) +{ + struct cvp_hfi_sfr_struct *vsfr; + + if (!dev) + return; + + vsfr = (struct cvp_hfi_sfr_struct *) dev->sfr.align_virtual_addr; + if (vsfr) + vsfr->bufSize = ALIGNED_SFR_SIZE; + +} + +static int __interface_queues_init(struct iris_hfi_device *dev) +{ + int rc = 0; + struct cvp_hfi_mem_map_table *qdss; + struct cvp_hfi_mem_map *mem_map; + struct cvp_mem_addr *mem_addr; + int num_entries = dev->res->qdss_addr_set.count; + phys_addr_t fw_bias = 0; + size_t q_size; + unsigned long mem_map_table_base_addr; + struct context_bank_info *cb; + + q_size = SHARED_QSIZE - ALIGNED_SFR_SIZE - ALIGNED_QDSS_SIZE; + mem_addr = &dev->mem_addr; + if (!is_iommu_present(dev->res)) + fw_bias = dev->cvp_hal_data->firmware_base; + + if (dev->iface_q_table.align_virtual_addr) { + memset((void *)dev->iface_q_table.align_virtual_addr, + 0, q_size); + goto hfi_queue_init; + } + rc = __smem_alloc(dev, mem_addr, q_size, 1, SMEM_UNCACHED); + if (rc) { + dprintk(CVP_ERR, "iface_q_table_alloc_fail\n"); + goto fail_alloc_queue; + } + + dev->iface_q_table.align_virtual_addr = mem_addr->align_virtual_addr; + dev->iface_q_table.align_device_addr = mem_addr->align_device_addr - + fw_bias; + dev->iface_q_table.mem_size = CVP_IFACEQ_TABLE_SIZE; + dev->iface_q_table.mem_data = mem_addr->mem_data; + +hfi_queue_init: + __hfi_queue_init(dev); + + if (dev->sfr.align_virtual_addr) { + memset((void *)dev->sfr.align_virtual_addr, + 0, ALIGNED_SFR_SIZE); + goto sfr_init; + } + rc = __smem_alloc(dev, mem_addr, ALIGNED_SFR_SIZE, 1, SMEM_UNCACHED); + if (rc) { + dprintk(CVP_WARN, "sfr_alloc_fail: SFR not will work\n"); + dev->sfr.align_device_addr = 0; + } else { + dev->sfr.align_device_addr = mem_addr->align_device_addr - + fw_bias; + dev->sfr.align_virtual_addr = mem_addr->align_virtual_addr; + dev->sfr.mem_size = ALIGNED_SFR_SIZE; + dev->sfr.mem_data = mem_addr->mem_data; + } +sfr_init: + __sfr_init(dev); + + if (dev->qdss.align_virtual_addr) + goto dsp_hfi_queue_init; + + if ((msm_cvp_fw_debug_mode & HFI_DEBUG_MODE_QDSS) && num_entries) { + rc = __smem_alloc(dev, mem_addr, ALIGNED_QDSS_SIZE, 1, + SMEM_UNCACHED); + if (rc) { + dprintk(CVP_WARN, + "qdss_alloc_fail: QDSS messages logging will not work\n"); + dev->qdss.align_device_addr = 0; + } else { + dev->qdss.align_device_addr = + mem_addr->align_device_addr - fw_bias; + dev->qdss.align_virtual_addr = + mem_addr->align_virtual_addr; + dev->qdss.mem_size = ALIGNED_QDSS_SIZE; + dev->qdss.mem_data = mem_addr->mem_data; + } + } + + if (dev->qdss.align_virtual_addr) { qdss = (struct cvp_hfi_mem_map_table *)dev->qdss.align_virtual_addr; @@ -1662,10 +1703,7 @@ static int __interface_queues_init(struct iris_hfi_device *dev) } } - vsfr = (struct cvp_hfi_sfr_struct *) dev->sfr.align_virtual_addr; - if (vsfr) - vsfr->bufSize = ALIGNED_SFR_SIZE; - +dsp_hfi_queue_init: rc = __interface_dsp_queues_init(dev); if (rc) { dprintk(CVP_ERR, "dsp_queues_init failed\n"); From b129cf0b8a30c02bef600756567bfd4a19f13f13 Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 8 Apr 2022 15:26:07 -0700 Subject: [PATCH 120/317] msm: eva: Add vm sub-driver Add framework for future implementation. Change-Id: I2ba070e791320e56339c632120ffa821e57db113 Signed-off-by: George Shen --- msm/Kbuild | 10 +- msm/eva/cvp.c | 2 +- msm/eva/cvp_comm_def.h | 5 +- msm/eva/cvp_hfi.c | 4 +- msm/eva/{msm_smem.c => cvp_smem.c} | 0 msm/eva/msm_cvp_debug.h | 3 +- msm/eva/{msm_cvp_vm.h => vm/cvp_vm.h} | 8 +- msm/eva/{msm_cvp_vm.c => vm/cvp_vm_main.c} | 4 +- msm/eva/vm/cvp_vm_msgq.c | 160 +++++++++++++++++++++ msm/eva/vm/cvp_vm_msgq.h | 72 ++++++++++ msm/eva/vm/cvp_vm_resource.c | 8 ++ msm/eva/vm/cvp_vm_resource.h | 17 +++ 12 files changed, 280 insertions(+), 13 deletions(-) rename msm/eva/{msm_smem.c => cvp_smem.c} (100%) rename msm/eva/{msm_cvp_vm.h => vm/cvp_vm.h} (83%) rename msm/eva/{msm_cvp_vm.c => vm/cvp_vm_main.c} (98%) create mode 100644 msm/eva/vm/cvp_vm_msgq.c create mode 100644 msm/eva/vm/cvp_vm_msgq.h create mode 100644 msm/eva/vm/cvp_vm_resource.c create mode 100644 msm/eva/vm/cvp_vm_resource.h diff --git a/msm/Kbuild b/msm/Kbuild index 658d2f0cb2..ad3949ec6d 100644 --- a/msm/Kbuild +++ b/msm/Kbuild @@ -4,7 +4,7 @@ LINUXINCLUDE += -I$(EVA_ROOT)/include \ #srctree is /kernel_platform/common/ -ccflags-y += -I$(srctree)/techpack/eva/msm/eva/ \ +ccflags-y += -I$(EVA_ROOT)/msm/eva/ \ -I$(srctree)/drivers/media/platform/msm/synx/ # add flag to compile mmrm actual implementatio instead of stub version. @@ -29,7 +29,7 @@ ccflags-y += -DCONFIG_EVA_KALAMA=1 endif ifeq ($(CONFIG_EVA_LE), 1) -ccflags-y += -DCONFIG_EVA_LE=1 +ccflags-y += -DCONFIG_EVA_TVM=1 endif msm-eva-objs := eva/cvp.o \ @@ -38,7 +38,7 @@ msm-eva-objs := eva/cvp.o \ eva/msm_cvp_common.o \ eva/msm_cvp_core.o \ eva/msm_cvp.o \ - eva/msm_smem.o \ + eva/cvp_smem.o \ eva/msm_cvp_debug.o \ eva/msm_cvp_res_parse.o \ eva/cvp_dump.o \ @@ -51,6 +51,8 @@ msm-eva-objs := eva/cvp.o \ eva/msm_cvp_buf.o \ eva/msm_cvp_synx.o \ eva/cvp_fw_load.o \ - eva/msm_cvp_vm.o + eva/vm/cvp_vm_main.o \ + eva/vm/cvp_vm_msgq.o \ + eva/vm/cvp_vm_resource.o obj-m += msm-eva.o diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index 43ca66e43b..b17e658bc8 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -26,7 +26,7 @@ #include "msm_cvp_clocks.h" #include "msm_cvp_dsp.h" #include "msm_cvp.h" -#include "msm_cvp_vm.h" +#include "vm/cvp_vm.h" #define CLASS_NAME "cvp" #define DRIVER_NAME "cvp" diff --git a/msm/eva/cvp_comm_def.h b/msm/eva/cvp_comm_def.h index 9ddd73cc5d..37e204c59c 100644 --- a/msm/eva/cvp_comm_def.h +++ b/msm/eva/cvp_comm_def.h @@ -7,6 +7,7 @@ #define _MSM_COMM_DEF_H_ #include +#include enum op_mode { OP_NORMAL, @@ -23,7 +24,7 @@ enum queue_state { QUEUE_INVALID, }; -#ifdef CONFIG_EVA_LE +#ifdef CONFIG_EVA_TVM #else /* LA target starts here */ @@ -35,6 +36,6 @@ enum queue_state { #define CVP_MINIDUMP_ENABLED 1 #endif -#endif /* End CONFIG_EVA_LE */ +#endif /* End CONFIG_EVA_TVM */ #endif diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index f5d107db56..1325d0910e 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -30,7 +30,7 @@ #include "cvp_hfi_io.h" #include "msm_cvp_dsp.h" #include "msm_cvp_clocks.h" -#include "msm_cvp_vm.h" +#include "vm/cvp_vm.h" #include "cvp_dump.h" #define REG_ADDR_OFFSET_BITMASK 0x000FFFFF @@ -1397,7 +1397,7 @@ fail_dma_alloc: static void __interface_queues_release(struct iris_hfi_device *device) { -#ifdef CONFIG_EVA_LE +#ifdef CONFIG_EVA_TVM int i; struct cvp_hfi_mem_map_table *qdss; struct cvp_hfi_mem_map *mem_map; diff --git a/msm/eva/msm_smem.c b/msm/eva/cvp_smem.c similarity index 100% rename from msm/eva/msm_smem.c rename to msm/eva/cvp_smem.c diff --git a/msm/eva/msm_cvp_debug.h b/msm/eva/msm_cvp_debug.h index 838fa33fa5..08f195ba43 100644 --- a/msm/eva/msm_cvp_debug.h +++ b/msm/eva/msm_cvp_debug.h @@ -37,8 +37,9 @@ enum cvp_msg_prio { CVP_FW = 0x001000, CVP_SESS = 0x002000, CVP_HFI = 0x004000, + CVP_VM = 0x008000, CVP_DBG = CVP_MEM | CVP_SYNX | CVP_CORE | CVP_REG | - CVP_PWR | CVP_DSP | CVP_SESS | CVP_HFI | CVP_PKT, + CVP_PWR | CVP_DSP | CVP_SESS | CVP_HFI | CVP_PKT | CVP_VM, }; enum cvp_msg_out { diff --git a/msm/eva/msm_cvp_vm.h b/msm/eva/vm/cvp_vm.h similarity index 83% rename from msm/eva/msm_cvp_vm.h rename to msm/eva/vm/cvp_vm.h index 19450e7c9a..80967982ec 100644 --- a/msm/eva/msm_cvp_vm.h +++ b/msm/eva/vm/cvp_vm.h @@ -3,14 +3,16 @@ * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. */ -#ifndef _MSM_CVP_VM_H_ -#define _MSM_CVP_VM_H_ +#ifndef _CVP_VM_H_ +#define _CVP_VM_H_ #include #include "cvp_comm_def.h" #include "msm_cvp_core.h" #include "msm_cvp_internal.h" #include "cvp_core_hfi.h" +#include "cvp_vm_msgq.h" +#include "cvp_vm_resource.h" enum cvp_vm_id { VM_PRIMARY = 1, @@ -34,6 +36,8 @@ struct msm_cvp_vm_ops { struct msm_cvp_vm_manager { enum cvp_vm_state vm_state; enum cvp_vm_id vm_id; + struct cvp_msgq_drv *msgq_drv; + struct cvp_vm_resource *vm_rm; struct msm_cvp_vm_ops *vm_ops; }; diff --git a/msm/eva/msm_cvp_vm.c b/msm/eva/vm/cvp_vm_main.c similarity index 98% rename from msm/eva/msm_cvp_vm.c rename to msm/eva/vm/cvp_vm_main.c index 61aae613e5..61f98529fa 100644 --- a/msm/eva/msm_cvp_vm.c +++ b/msm/eva/vm/cvp_vm_main.c @@ -30,7 +30,7 @@ #include "msm_cvp_dsp.h" #include "msm_cvp_clocks.h" #include "cvp_dump.h" -#include "msm_cvp_vm.h" +#include "cvp_vm.h" #define FIRMWARE_SIZE 0X00A00000 @@ -44,6 +44,8 @@ static struct msm_cvp_vm_ops vm_ops = { }; struct msm_cvp_vm_manager vm_manager = { + .msgq_drv = &cvp_ipc_msgq, + .vm_rm = &cvp_vm_rm, .vm_ops = &vm_ops, }; diff --git a/msm/eva/vm/cvp_vm_msgq.c b/msm/eva/vm/cvp_vm_msgq.c new file mode 100644 index 0000000000..bad20e06a7 --- /dev/null +++ b/msm/eva/vm/cvp_vm_msgq.c @@ -0,0 +1,160 @@ +/* SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include "cvp_vm_msgq.h" +#include "msm_cvp_debug.h" + +/** + * cvp_msgq_receiver - thread function that receive msg from gunyah msgq + * data: cvp_msgq_drv pointer + * + * Note: single thread. If the sub-function or global data used in this + * function is also used somehwere else, please add rx_lock. + */ +static int cvp_msgq_receiver(void *data) +{ + struct cvp_msgq_drv *msgq_drv = data; + + if (IS_ERR_OR_NULL(msgq_drv)) + return -EINVAL; + + return 0; +} + +static int cvp_complete_msgq_init(struct cvp_msgq_drv *msgq_drv) +{ + int i; + + msgq_drv->receiver_thread = kthread_run( + cvp_msgq_receiver, + (void *)msgq_drv, + "CVP msgq receiver"); + if (IS_ERR_OR_NULL(msgq_drv->receiver_thread)) { + dprintk(CVP_ERR, "Failed to start msgq receiver thread\n"); + return -EINVAL; + } + + mutex_init(&msgq_drv->ipc_lock); + + for (i = 0; i <= CVP_MAX_IPC_CMD; i++) + init_completion(&msgq_drv->completions[i]); + + return 0; +} + +static int cvp_msgq_cb(struct notifier_block *nb, + unsigned long cmd, void *data) +{ + struct gh_rm_notif_vm_status_payload *vm_status_payload; + struct cvp_gh_msgq_config *msgq_config; + struct cvp_msgq_drv *msgq_drv; + gh_vmid_t peer_vmid; + gh_vmid_t self_vmid; + int rc; + + + if (IS_ERR_OR_NULL(nb)) + return -EINVAL; + + msgq_config = container_of(nb, struct cvp_gh_msgq_config, rm_nb); + msgq_drv = container_of(msgq_config, struct cvp_msgq_drv, config); + + if (cmd != GH_RM_NOTIF_VM_STATUS) + return NOTIFY_DONE; + + /** + * Check VM status, only GH_TRUSTED_VM notification activate + * Gunyah msgq registration + */ + vm_status_payload = (struct gh_rm_notif_vm_status_payload *)data; + + if (vm_status_payload->vm_status != GH_RM_VM_STATUS_READY) + return -12; + + if (gh_rm_get_vmid(msgq_config->peer_id, &peer_vmid)) + return -13; + + if (gh_rm_get_vmid(GH_PRIMARY_VM, &self_vmid)) + return -14; + + if (peer_vmid != vm_status_payload->vmid) + return NOTIFY_DONE; + + dprintk(CVP_VM, "%s vmid=%d, peer_vmid=%d\n", vm_status_payload->vmid, + peer_vmid); + + if (msgq_config->handle) + return -15; + + msgq_config->handle = gh_msgq_register(GH_MSGQ_LABEL_EVA); + if (IS_ERR(msgq_config->handle)) { + rc = PTR_ERR(msgq_drv->config.handle); + dprintk(CVP_ERR, "PVM failed to register msgq %d\n", rc); + return rc; + } + + rc = cvp_complete_msgq_init(msgq_drv); + + return rc; +} + +static int cvp_msgq_init(struct cvp_msgq_drv *msgq_drv) +{ + int rc = 0; + + msgq_drv->config.label = GH_MSGQ_LABEL_EVA; + msgq_drv->config.handle = NULL; +#ifndef CONFIG_EVA_TVM + /* PVM init */ + msgq_drv->config.peer_id = GH_TRUSTED_VM; + msgq_drv->config.rm_nb.notifier_call = cvp_msgq_cb; + rc = gh_rm_register_notifier(&msgq_drv->config.rm_nb); + if (rc) { + dprintk(CVP_ERR, "PVM Fail register msgq notifier %d\n", rc); + return rc; + } +#else + /* TVM init */ + msgq_drv->config.handle = gh_msgq_register(GH_MSGQ_LABEL_EVA); + if (IS_ERR(msgq_drv->config.handle)) { + rc = PTR_ERR(msgq_drv->config.handle); + dprintk(CVP_ERR, "TVM failed to register msgq %d\n", rc); + return rc; + } + rc = cvp_msgq_complete_init(msgq_drv); +#endif + return rc; +} + +static int cvp_msgq_deinit(struct cvp_msgq_drv *msgq_drv) +{ + if (msgq_drv->receiver_thread) + kthread_stop(msgq_drv->receiver_thread); + + return 0; +} + +static int cvp_msgq_send(struct cvp_msgq_drv *msgq_drv, + void *msg, size_t msg_size) +{ + return 0; +} + +static int cvp_msgq_receive(struct cvp_msgq_drv *msgq_drv) +{ + return 0; +} + +static struct cvp_msgq_ops msgq_ops = { + .msgq_init = cvp_msgq_init, + .msgq_deinit = cvp_msgq_deinit, + .msgq_send = cvp_msgq_send, + .msgq_receive = cvp_msgq_receive, +}; + +struct cvp_msgq_drv cvp_ipc_msgq = { + .ops = &msgq_ops, +}; diff --git a/msm/eva/vm/cvp_vm_msgq.h b/msm/eva/vm/cvp_vm_msgq.h new file mode 100644 index 0000000000..91ef3dde98 --- /dev/null +++ b/msm/eva/vm/cvp_vm_msgq.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _CVP_VM_MSGQ_H_ +#define _CVP_VM_MSGQ_H_ + +#include +#include +#include +#include "cvp_comm_def.h" + +#define MAX_CVP_IPC_LEN 16 + +enum CVP_IPC_MSG_TYPE { + REQUEST_SESS_CTRL = 0, + RELEASE_SESS_CTRL = 1, + REQUEST_EVA_RESET = 2, + RECLAIM_SESS_CTRL = 3, /* Only PVM can reclaim sesession control */ + CVP_MAX_IPC_CMD = 4, +}; + +struct cvp_ipc_msg { + /* type format: + * bit 31: 0->PVM initiated; 1->TVM initiated + * bit 2~0: CVP_IPC_MSG_TYPE + */ + uint32_t type; + uint32_t ver; + uint32_t len; + uint32_t resv; + uint32_t data[MAX_CVP_IPC_LEN]; +}; + +struct cvp_gh_msgq_config { + int peer_id; + int label; + void *handle; + struct notifier_block rm_nb; +}; + +struct cvp_msgq_ops; + +struct cvp_msgq_drv { + struct mutex ipc_lock; /* Mutex for sending MSG */ + struct cvp_gh_msgq_config config; + struct task_struct *receiver_thread; + struct completion completions[CVP_MAX_IPC_CMD + 1]; + /* + * pending_local_cmd: the command is being processed locally. + * The command is a request sent from remote VM + */ + struct cvp_ipc_msg pending_local_cmd; + /* + * pending_remote_rsp: the command is being processing remotely. + * The command is a request sent by local VM + */ + struct cvp_ipc_msg pending_remote_rsp; + struct cvp_msgq_ops *ops; +}; + +struct cvp_msgq_ops { + int (*msgq_init)(struct cvp_msgq_drv *msgq_drv); + int (*msgq_send)(struct cvp_msgq_drv *msgq_drv, void *msg, + size_t msg_size); + int (*msgq_receive)(struct cvp_msgq_drv *msgq_drv); + int (*msgq_deinit)(struct cvp_msgq_drv *msgq_drv); +}; + +extern struct cvp_msgq_drv cvp_ipc_msgq; +#endif diff --git a/msm/eva/vm/cvp_vm_resource.c b/msm/eva/vm/cvp_vm_resource.c new file mode 100644 index 0000000000..df382c3171 --- /dev/null +++ b/msm/eva/vm/cvp_vm_resource.c @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include "cvp_vm_resource.h" + +struct cvp_vm_resource cvp_vm_rm; diff --git a/msm/eva/vm/cvp_vm_resource.h b/msm/eva/vm/cvp_vm_resource.h new file mode 100644 index 0000000000..92fb33613b --- /dev/null +++ b/msm/eva/vm/cvp_vm_resource.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _CVP_VM_RESOURCE_H_ +#define _CVP_VM_RESOURCE_H_ + +#include +#include "cvp_comm_def.h" + +struct cvp_vm_resource { + int reserved; +}; + +extern struct cvp_vm_resource cvp_vm_rm; +#endif From 5353ebd4553ae11debfa1d7cb6359eb0bef0da89 Mon Sep 17 00:00:00 2001 From: George Shen Date: Sat, 7 May 2022 14:12:13 -0700 Subject: [PATCH 121/317] msm: eva: Support non-ratelimit pr_info for debug The default debug level in the build supports ratelimit version of kernel print. For debugging purpose, setting bit 31 of debug level node will disable ratelimit of kernel print from EVA driver. Change-Id: I8e43043f1601a2adc10c0aeab79e0fdc94be327f Signed-off-by: George Shen --- msm/eva/msm_cvp_debug.h | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/msm/eva/msm_cvp_debug.h b/msm/eva/msm_cvp_debug.h index 08f195ba43..7a04951a9b 100644 --- a/msm/eva/msm_cvp_debug.h +++ b/msm/eva/msm_cvp_debug.h @@ -69,10 +69,18 @@ extern bool msm_cvp_mmrm_enabled; extern bool msm_cvp_dcvs_disable; extern int msm_cvp_minidump_enable; +/* If bit 31 is set: disabling ratelimit use of pr_info */ +#define RATELIMIT_DISABLE_MASK 0x80000000 + #define dprintk(__level, __fmt, arg...) \ do { \ - if (msm_cvp_debug & __level) { \ - if (msm_cvp_debug_out == CVP_OUT_PRINTK) { \ + if ((msm_cvp_debug & __level) \ + && (msm_cvp_debug_out == CVP_OUT_PRINTK)) { \ + if (msm_cvp_debug & RATELIMIT_DISABLE_MASK) { \ + pr_info(CVP_DBG_TAG __fmt, \ + get_debug_level_str(__level), \ + ## arg); \ + } else { \ pr_info_ratelimited(CVP_DBG_TAG __fmt, \ get_debug_level_str(__level), \ ## arg); \ From 1addadfe9f0043bb1e2a08ab832b3c5f261bdabe Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 12 May 2022 11:57:54 -0700 Subject: [PATCH 122/317] msm: eva: Use Kailua GCC offset GCC_VIDEO_AXI1_CBCR relocated in kailua. The driver print the register in case fail to put NoC into low power. Change-Id: I2fd7fc57f8c7980060a79438355f704654d86f18 Signed-off-by: George Shen --- msm/eva/cvp_hfi_io.h | 4 +++- msm/eva/msm_cvp_debug.h | 14 +++----------- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index 1dff20eb25..de677cedbf 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -251,5 +251,7 @@ #define CVP_CC_MVS1_GDSCR (CVP_CC_BASE_OFFS + 0xCC) #define CVP_CC_MVS1_CBCR (CVP_CC_BASE_OFFS + 0xE0) -#define CVP_GCC_VIDEO_AXI1_CBCR (0x32020) +#ifdef CONFIG_EVA_KALAMA +#define CVP_GCC_VIDEO_AXI1_CBCR (0x22024) +#endif /*End of CONFIG_EVA_KALAMA */ #endif diff --git a/msm/eva/msm_cvp_debug.h b/msm/eva/msm_cvp_debug.h index 7a04951a9b..29fce7997e 100644 --- a/msm/eva/msm_cvp_debug.h +++ b/msm/eva/msm_cvp_debug.h @@ -69,20 +69,12 @@ extern bool msm_cvp_mmrm_enabled; extern bool msm_cvp_dcvs_disable; extern int msm_cvp_minidump_enable; -/* If bit 31 is set: disabling ratelimit use of pr_info */ -#define RATELIMIT_DISABLE_MASK 0x80000000 - #define dprintk(__level, __fmt, arg...) \ do { \ - if ((msm_cvp_debug & __level) \ - && (msm_cvp_debug_out == CVP_OUT_PRINTK)) { \ - if (msm_cvp_debug & RATELIMIT_DISABLE_MASK) { \ + if (msm_cvp_debug & __level) { \ + if (msm_cvp_debug_out == CVP_OUT_PRINTK) { \ pr_info(CVP_DBG_TAG __fmt, \ - get_debug_level_str(__level), \ - ## arg); \ - } else { \ - pr_info_ratelimited(CVP_DBG_TAG __fmt, \ - get_debug_level_str(__level), \ + get_debug_level_str(__level), \ ## arg); \ } \ } \ From 3a0d392d6f6846c03e29a68315544bf4a1382d5c Mon Sep 17 00:00:00 2001 From: Yu SI Date: Wed, 27 Apr 2022 20:02:59 -0700 Subject: [PATCH 123/317] msm: eva: add msgq implementation added msgq send and receive implementation Change-Id: Ib1585096d1d9b48e4c245263e4d68702011b4d0c Signed-off-by: Yu SI --- msm/eva/msm_cvp_debug.h | 2 + msm/eva/vm/cvp_vm_msgq.c | 206 ++++++++++++++++++++++++++++++++++++--- msm/eva/vm/cvp_vm_msgq.h | 17 ++-- 3 files changed, 206 insertions(+), 19 deletions(-) diff --git a/msm/eva/msm_cvp_debug.h b/msm/eva/msm_cvp_debug.h index 29fce7997e..3ff7fccaed 100644 --- a/msm/eva/msm_cvp_debug.h +++ b/msm/eva/msm_cvp_debug.h @@ -127,6 +127,8 @@ static inline char *get_debug_level_str(int level) return "sess"; case CVP_HFI: return "hfi"; + case CVP_VM: + return "vm"; default: return "???"; } diff --git a/msm/eva/vm/cvp_vm_msgq.c b/msm/eva/vm/cvp_vm_msgq.c index bad20e06a7..ea2c9b1b5f 100644 --- a/msm/eva/vm/cvp_vm_msgq.c +++ b/msm/eva/vm/cvp_vm_msgq.c @@ -18,9 +18,122 @@ static int cvp_msgq_receiver(void *data) { struct cvp_msgq_drv *msgq_drv = data; + struct cvp_ipc_msg *msg_ptr; + size_t size; + bool is_resp; + /** + * true: response received from remote VM, cmd initiated from LOCAL VM; + * false: cmd initiated from REMOTE VM; + */ + int rc = -1; if (IS_ERR_OR_NULL(msgq_drv)) return -EINVAL; + msg_ptr = kzalloc(sizeof(*msg_ptr), GFP_KERNEL); + if (!msg_ptr) { + dprintk(CVP_ERR, "%s: fail to allocate mem\n", __func__); + return -ENOMEM; + } + + while (true) { + rc = gh_msgq_recv(msgq_drv->config.handle, msg_ptr, + GH_MSGQ_MAX_MSG_SIZE_BYTES, &size, 0); + + if (rc != 0 ) { + dprintk(CVP_ERR, + "%s: gh_msgq_recv fail rc=%d handle=%#x msg_ptr=%#x\n", + __func__, rc, msgq_drv->config.handle, msg_ptr); + + if (rc != -EAGAIN) { + kfree(msg_ptr); + return rc; + } + continue; + } + + is_resp = (msg_ptr->type & + CVP_IPC_MSG_TYPE_DIR_CHECK) ? true : false; + + if (is_resp == false) { + dprintk(CVP_VM, + "%s: gh_msgq_recv cmd from remote VM\n", + __func__); + + if (msgq_drv->pending_local_cmd.type == 0) { + + /* copy ipc message to local cmd */ + memcpy(&msgq_drv->pending_local_cmd, + msg_ptr, sizeof(struct cvp_ipc_msg)); + + /* toggle the direction bit*/ + msgq_drv->pending_local_cmd.type ^= + CVP_IPC_MSG_TYPE_DIR_CHECK; + + /* TODO: call client function ptr to process */ + + memcpy(msg_ptr, &msgq_drv->pending_local_cmd, + sizeof(struct cvp_ipc_msg)); + + /* 4: elements before actual data in cvp_ipc_msg*/ + size = (4 + msgq_drv->pending_local_cmd.len)<<2; + + /* sanity check on size information */ + if (size > GH_MSGQ_MAX_MSG_SIZE_BYTES) { + dprintk(CVP_ERR, + "%s: msg size %d exceed max size supported %d \n", + __func__, size, GH_MSGQ_MAX_MSG_SIZE_BYTES); + rc = -E2BIG; + msgq_drv->pending_local_cmd.type = 0; + continue; + } + + /* send it back to the remote VM as response */ + rc = gh_msgq_send(msgq_drv->config.handle, + msg_ptr, size, GH_MSGQ_TX_PUSH); + + if (rc < 0) { + dprintk(CVP_ERR, + "%s: failed gh_msgq_send rc %d \n", + __func__, rc); + } + + /* flag the source is released */ + msgq_drv->pending_local_cmd.type = 0; + } + else { + dprintk(CVP_ERR, + "%s: Msg rejected, local cmd in use type %d\n", + __func__, msgq_drv->pending_local_cmd.type); + } + } + else { + dprintk(CVP_VM, + "%s: gh_msgq_recv respond type from remote VM\n", + __func__); + + if ((msg_ptr->type & CVP_IPC_MSG_TYPE_ACT_CHECK) != + msgq_drv->pending_remote_rsp.type) { + + dprintk(CVP_ERR, + "%s: Msg disgard,recv type %d, pend local %d\n", + __func__, msg_ptr->type, + msgq_drv->pending_remote_rsp.type); + } + else { + /* memcpy received data to pending_remote_rsp */ + memcpy(&msgq_drv->pending_remote_rsp, msg_ptr, + sizeof(struct cvp_ipc_msg)); + + /* clear direction bit of pending_remote_rsp */ + msgq_drv->pending_remote_rsp.type &= + (~CVP_IPC_MSG_TYPE_DIR_CHECK); + + /* complete for cmd initiated from local VM */ + complete(&msgq_drv->completions[ + msgq_drv->pending_remote_rsp.type - 1]); + } + } + } return 0; } @@ -39,12 +152,13 @@ static int cvp_complete_msgq_init(struct cvp_msgq_drv *msgq_drv) mutex_init(&msgq_drv->ipc_lock); - for (i = 0; i <= CVP_MAX_IPC_CMD; i++) + for (i = 0; i <= (CVP_MAX_IPC_CMD - 1); i++) init_completion(&msgq_drv->completions[i]); return 0; } +#ifndef CONFIG_EVA_TVM static int cvp_msgq_cb(struct notifier_block *nb, unsigned long cmd, void *data) { @@ -55,7 +169,6 @@ static int cvp_msgq_cb(struct notifier_block *nb, gh_vmid_t self_vmid; int rc; - if (IS_ERR_OR_NULL(nb)) return -EINVAL; @@ -83,8 +196,8 @@ static int cvp_msgq_cb(struct notifier_block *nb, if (peer_vmid != vm_status_payload->vmid) return NOTIFY_DONE; - dprintk(CVP_VM, "%s vmid=%d, peer_vmid=%d\n", vm_status_payload->vmid, - peer_vmid); + dprintk(CVP_VM, "%s: vmid=%d, peer_vmid=%d\n", + __func__, vm_status_payload->vmid, peer_vmid); if (msgq_config->handle) return -15; @@ -95,11 +208,14 @@ static int cvp_msgq_cb(struct notifier_block *nb, dprintk(CVP_ERR, "PVM failed to register msgq %d\n", rc); return rc; } + dprintk(CVP_VM, "%s: gh_msgq_register handle: %x\n", + __func__, msgq_config->handle); rc = cvp_complete_msgq_init(msgq_drv); return rc; } +#endif static int cvp_msgq_init(struct cvp_msgq_drv *msgq_drv) { @@ -111,11 +227,13 @@ static int cvp_msgq_init(struct cvp_msgq_drv *msgq_drv) /* PVM init */ msgq_drv->config.peer_id = GH_TRUSTED_VM; msgq_drv->config.rm_nb.notifier_call = cvp_msgq_cb; + rc = gh_rm_register_notifier(&msgq_drv->config.rm_nb); if (rc) { dprintk(CVP_ERR, "PVM Fail register msgq notifier %d\n", rc); return rc; } + dprintk(CVP_VM, "%s: gh_rm_register_notifier\n", __func__); #else /* TVM init */ msgq_drv->config.handle = gh_msgq_register(GH_MSGQ_LABEL_EVA); @@ -124,7 +242,7 @@ static int cvp_msgq_init(struct cvp_msgq_drv *msgq_drv) dprintk(CVP_ERR, "TVM failed to register msgq %d\n", rc); return rc; } - rc = cvp_msgq_complete_init(msgq_drv); + rc = cvp_complete_msgq_init(msgq_drv); #endif return rc; } @@ -137,22 +255,84 @@ static int cvp_msgq_deinit(struct cvp_msgq_drv *msgq_drv) return 0; } -static int cvp_msgq_send(struct cvp_msgq_drv *msgq_drv, +static int cvp_msgq_send_cmd(struct cvp_msgq_drv *msgq_drv, void *msg, size_t msg_size) { - return 0; -} + int rc = -1; -static int cvp_msgq_receive(struct cvp_msgq_drv *msgq_drv) -{ - return 0; + struct cvp_ipc_msg *msg_ptr = msg; + + if (!msgq_drv->config.handle) { + dprintk(CVP_ERR, "%s: Invalid msgq handle\n", __func__); + rc = -EINVAL; + goto err_param_check; + } + + if (msg_size > GH_MSGQ_MAX_MSG_SIZE_BYTES) { + dprintk(CVP_ERR, + "%s: msg size %d exceed max size supported %d \n", + __func__, msg_size, GH_MSGQ_MAX_MSG_SIZE_BYTES); + rc = -E2BIG; + goto err_param_check; + } + + mutex_lock(&msgq_drv->ipc_lock); + + /* init case: only allow sending msg sequentially */ + if (msgq_drv->pending_remote_rsp.type & + CVP_IPC_MSG_TYPE_ACT_CHECK) { + rc = -EPERM; + dprintk(CVP_ERR, + "%s: Msg rejected, local rsp occupied.\n", + __func__); + + goto err_valid_check; + } + + /* book keeping type bits in pending_remote_rsp */ + msgq_drv->pending_remote_rsp.type = msg_ptr->type; + + rc = gh_msgq_send(msgq_drv->config.handle, + msg_ptr, msg_size, GH_MSGQ_TX_PUSH); + if (rc < 0) { + dprintk(CVP_ERR, + "%s: failed with gh_msgq_send with rc %d \n", + __func__, rc); + goto err_gh_send; + } + + /* wait for completion */ + if (!wait_for_completion_timeout( + &msgq_drv->completions[msgq_drv->pending_remote_rsp.type - 1], + msecs_to_jiffies(CVP_VM_RESPONSE_TIMEOUT))) { + dprintk(CVP_ERR, "%s cvp ipc msg type %d timeout\n", + __func__, msgq_drv->pending_remote_rsp.type-1); + rc = -ETIMEDOUT; + } + + /* copy pending_remote_rsp content to msg (inout param)*/ + memcpy(msg, &msgq_drv->pending_remote_rsp, + sizeof(struct cvp_ipc_msg)); + + /* clear type bits to indicate resource is avaialbel */ + msgq_drv->pending_remote_rsp.type = 0; + + mutex_unlock(&msgq_drv->ipc_lock); + + return rc; + +err_gh_send: +err_valid_check: + mutex_unlock(&msgq_drv->ipc_lock); +err_param_check: + return rc; } static struct cvp_msgq_ops msgq_ops = { .msgq_init = cvp_msgq_init, .msgq_deinit = cvp_msgq_deinit, - .msgq_send = cvp_msgq_send, - .msgq_receive = cvp_msgq_receive, + .msgq_send = cvp_msgq_send_cmd, + .msgq_receive = NULL, }; struct cvp_msgq_drv cvp_ipc_msgq = { diff --git a/msm/eva/vm/cvp_vm_msgq.h b/msm/eva/vm/cvp_vm_msgq.h index 91ef3dde98..b97fb2d396 100644 --- a/msm/eva/vm/cvp_vm_msgq.h +++ b/msm/eva/vm/cvp_vm_msgq.h @@ -13,17 +13,22 @@ #define MAX_CVP_IPC_LEN 16 +#define CVP_VM_RESPONSE_TIMEOUT 300 + +#define CVP_IPC_MSG_TYPE_DIR_CHECK 0x10000000 /* direction check */ +#define CVP_IPC_MSG_TYPE_ACT_CHECK 0x00000011 /* action check */ + enum CVP_IPC_MSG_TYPE { - REQUEST_SESS_CTRL = 0, - RELEASE_SESS_CTRL = 1, - REQUEST_EVA_RESET = 2, - RECLAIM_SESS_CTRL = 3, /* Only PVM can reclaim sesession control */ - CVP_MAX_IPC_CMD = 4, + REQUEST_SESS_CTRL = 1, + RELEASE_SESS_CTRL = 2, + REQUEST_EVA_RESET = 3, + RECLAIM_SESS_CTRL = 4, /* Only PVM can reclaim sesession control */ + CVP_MAX_IPC_CMD = 5, }; struct cvp_ipc_msg { /* type format: - * bit 31: 0->PVM initiated; 1->TVM initiated + * bit 31: 0->Initiated command; 1->Response to remote command * bit 2~0: CVP_IPC_MSG_TYPE */ uint32_t type; From 8f1f20ab0c312ca65486e3397c03b2b15f078826 Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 24 Jun 2022 16:08:00 -0700 Subject: [PATCH 124/317] msm: eva: Workaround of EVA ssr failure in DSP UCs After EVA SSR and shutdown DSP driver, remove all DSP sessions. Change-Id: I23cbd2ab3d5ec8c03ec0f4059be287c28ddb0f9a Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 11 ++++++++- msm/eva/msm_cvp_dsp.c | 57 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 1325d0910e..ec3eb347ef 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1296,6 +1296,10 @@ static void __set_queue_hdr_defaults(struct cvp_hfi_queue_header *q_hdr) q_hdr->qhdr_write_idx = 0x0; } +/* + *Unused, keep for reference + */ +/* static void __interface_dsp_queues_release(struct iris_hfi_device *device) { int i; @@ -1320,6 +1324,7 @@ static void __interface_dsp_queues_release(struct iris_hfi_device *device) device->dsp_iface_q_table.align_virtual_addr = NULL; device->dsp_iface_q_table.align_device_addr = 0; } +*/ static int __interface_dsp_queues_init(struct iris_hfi_device *dev) { @@ -1338,6 +1343,11 @@ static int __interface_dsp_queues_init(struct iris_hfi_device *dev) q_size = ALIGN(QUEUE_SIZE, SZ_1M); mem_data = &dev->dsp_iface_q_table.mem_data; + if (mem_data->kvaddr) { + memset((void *)mem_data->kvaddr, 0, q_size); + cvp_dsp_init_hfi_queue_hdr(dev); + return 0; + } /* Allocate dsp queues from CDSP device memory */ kvaddr = dma_alloc_coherent(dev->res->mem_cdsp.dev, q_size, &dma_handle, GFP_KERNEL); @@ -1454,7 +1464,6 @@ static void __interface_queues_release(struct iris_hfi_device *device) device->mem_addr.align_virtual_addr = NULL; device->mem_addr.align_device_addr = 0; #endif - __interface_dsp_queues_release(device); } static int __get_qdss_iommu_virtual_addr(struct iris_hfi_device *dev, diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index ebb6941036..af24893740 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -260,10 +260,6 @@ static int delete_dsp_session(struct msm_cvp_inst *inst, mutex_unlock(&buf_list->lock); - rc = msm_cvp_session_delete(inst); - if (rc) - dprintk(CVP_ERR, "Warning: send Delete Session failed\n"); - task = inst->task; spin_lock(&inst->core->resources.pm_qos.lock); @@ -496,6 +492,47 @@ exit: return rc; } +static void cvp_remove_dsp_process_sess( + struct cvp_dsp_fastrpc_driver_entry *frpc_node) +{ + struct msm_cvp_inst *inst = NULL; + struct list_head *s = NULL, *next_s = NULL; + + s = &frpc_node->dsp_sessions.list; + list_for_each_safe(s, next_s, &frpc_node->dsp_sessions.list) { + inst = list_entry(s, struct msm_cvp_inst, dsp_list); + delete_dsp_session(inst, frpc_node); + } +} + +static void cvp_remove_dsp_sessions(void) +{ + struct cvp_dsp_apps *me = &gfa_cv; + struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; + struct list_head *ptr = NULL, *next = NULL; + + dprintk(CVP_WARN, "%s: EVA SSR triggered, clean cdsp eva sessions\n", + __func__); + + ptr = &me->fastrpc_driver_list.list; + mutex_lock(&me->fastrpc_driver_list.lock); + list_for_each_safe(ptr, next, &me->fastrpc_driver_list.list) { + frpc_node = list_entry(ptr, + struct cvp_dsp_fastrpc_driver_entry, list); + if (frpc_node) { + cvp_remove_dsp_process_sess(frpc_node); + list_del(&frpc_node->list); + __fastrpc_driver_unregister(&frpc_node->cvp_fastrpc_driver); + mutex_lock(&me->driver_name_lock); + eva_fastrpc_driver_release_name(frpc_node); + mutex_unlock(&me->driver_name_lock); + kfree(frpc_node); + } + } + mutex_unlock(&me->fastrpc_driver_list.lock); + dprintk(CVP_WARN, "%s: EVA SSR handled for CDSP\n", __func__); +} + int cvp_dsp_shutdown(uint32_t session_flag) { struct cvp_dsp_apps *me = &gfa_cv; @@ -769,6 +806,11 @@ static int __reinit_dsp(void) rc = cvp_dsp_shutdown(flag); if (rc) return rc; + /* + * Workaround to force delete DSP session resources + * To be removed after DSP optimization ready + */ + cvp_remove_dsp_sessions(); /* Resend HFI queue */ mutex_lock(&me->tx_lock); @@ -1435,13 +1477,6 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) goto dsp_fail_delete; } - rc = msm_cvp_session_delete(inst); - if (rc) { - dprintk(CVP_ERR, "Warning: send Delete Session failed\n"); - cmd->ret = -1; - goto dsp_fail_delete; - } - task = inst->task; spin_lock(&inst->core->resources.pm_qos.lock); From 4bfd66f039bf4f627a88c83b056aeff5844ea2e1 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 22 Jun 2022 10:07:22 -0700 Subject: [PATCH 125/317] msm: eva: Enhance SMMU fault debugability Changes only applicable on CPU EVA path, including - tracking packet type and buffer index for each dma_buf - print feature config packet type - print session properties in error cases. Change-Id: I938cf463bee9284760145f3fd9e030b3b8134caa Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 2 ++ msm/eva/cvp_hfi_api.h | 3 ++ msm/eva/msm_cvp.c | 16 ++++++++-- msm/eva/msm_cvp_buf.c | 58 +++++++++++++++++++++++++++++++------ msm/eva/msm_cvp_buf.h | 7 ++++- msm/eva/msm_cvp_common.c | 24 +++++++++++---- msm/eva/msm_cvp_common.h | 1 + msm/eva/msm_cvp_core.c | 3 +- msm/eva/msm_cvp_dsp.c | 4 +-- msm/eva/msm_cvp_internal.h | 2 ++ msm/eva/msm_cvp_platform.c | 45 +++++++++++++++++++++++++++- msm/eva/msm_cvp_res_parse.c | 1 + 12 files changed, 144 insertions(+), 22 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index ec3eb347ef..58f2623659 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -626,6 +626,8 @@ static int __smem_alloc(struct iris_hfi_device *dev, struct cvp_mem_addr *mem, mem->mem_size = alloc->size; mem->align_virtual_addr = alloc->kvaddr; mem->align_device_addr = alloc->device_addr; + alloc->pkt_type = 0; + alloc->buf_idx = 0; return rc; fail_smem_alloc: diff --git a/msm/eva/cvp_hfi_api.h b/msm/eva/cvp_hfi_api.h index 81f01d8f28..e759e18db4 100644 --- a/msm/eva/cvp_hfi_api.h +++ b/msm/eva/cvp_hfi_api.h @@ -234,11 +234,14 @@ struct cvp_hal_cmd_sys_get_property_packet { #define call_hfi_op(q, op, args...) \ (((q) && (q)->op) ? ((q)->op(args)) : 0) +#define PKT_NAME_LEN 32 + struct msm_cvp_hfi_defs { unsigned int size; unsigned int type; bool is_config_pkt; enum hal_command_response resp; + char name[PKT_NAME_LEN]; }; struct cvp_hfi_device { diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index b6c22a2391..d56ed96673 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -187,6 +187,10 @@ static int msm_cvp_session_process_hfi( is_config_pkt = cvp_hfi_defs[pkt_idx].is_config_pkt; } + if (is_config_pkt) + pr_info(CVP_DBG_TAG "inst %pK config %s\n", "sess", + inst, cvp_hfi_defs[pkt_idx].name); + if (signal == HAL_NO_RESP) { /* Frame packets are not allowed before session starts*/ sq = &inst->session_queue; @@ -655,6 +659,7 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst, struct cvp_fence_queue *q; u32 *fence; enum op_mode mode; + bool is_config_pkt; if (!inst || !inst->core || !arg || !inst->core->device) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); @@ -689,6 +694,8 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst, dprintk(CVP_ERR, "%s incorrect packet %d %#x\n", __func__, pkt->size, pkt->packet_type); goto exit; + } else { + is_config_pkt = cvp_hfi_defs[idx].is_config_pkt; } if (in_offset && in_buf_num) { @@ -700,6 +707,11 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst, dprintk(CVP_ERR, "Incorrect buf num and offset in cmd\n"); goto exit; } + + if (is_config_pkt) + pr_info(CVP_DBG_TAG "inst %pK config %s\n", + inst, cvp_hfi_defs[idx].name); + rc = msm_cvp_map_frame(inst, (struct eva_kmd_hfi_packet *)pkt, offset, buf_num); if (rc) @@ -1197,8 +1209,8 @@ static int msm_cvp_session_stop(struct msm_cvp_inst *inst, } sq->state = QUEUE_STOP; - pr_info_ratelimited(CVP_DBG_TAG "Stop session: %pK session_id = %d\n", - "sess", inst, hash32_ptr(inst->session)); + dprintk(CVP_SESS, "Stop session: %pK session_id = %d\n", + inst, hash32_ptr(inst->session)); spin_unlock(&sq->lock); wake_up_all(&inst->session_queue.wq); diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index a6b10315b4..af5d7f1365 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -39,6 +39,10 @@ static int _wncc_unmap_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, int print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, struct msm_cvp_smem *smem) { + int i; + char name[PKT_NAME_LEN] = "Unknown"; + + if (!(tag & msm_cvp_debug)) return 0; @@ -49,11 +53,21 @@ int print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, } if (smem->dma_buf) { + if (!atomic_read(&smem->refcount)) + return 0; + + for (i = 0; i < get_pkt_array_size(); i++) + if (cvp_hfi_defs[i].type == smem->pkt_type) { + strlcpy(name, cvp_hfi_defs[i].name, PKT_NAME_LEN); + break; + } + dprintk(tag, - "%s: %x : %s size %d flags %#x iova %#x idx %d ref %d", + "%s: %x : %s size %d flags %#x iova %#x idx %d ref %d pkt_type %s buf_idx %#x", str, hash32_ptr(inst->session), smem->dma_buf->name, smem->size, smem->flags, smem->device_addr, - smem->bitmap_index, smem->refcount); + smem->bitmap_index, atomic_read(&smem->refcount), + name, smem->buf_idx); } return 0; } @@ -81,8 +95,11 @@ static void print_internal_buffer(u32 tag, const char *str, void print_cvp_buffer(u32 tag, const char *str, struct msm_cvp_inst *inst, struct cvp_internal_buf *cbuf) { - dprintk(tag, "%s addr: %x size %u\n", str, - cbuf->smem->device_addr, cbuf->size); + if (!inst || !cbuf) + dprintk(CVP_ERR, + "%s Invalid params inst %pK, cbuf %pK\n", inst, cbuf); + + print_smem(tag, str, inst, cbuf->smem); } static void _log_smem(struct inst_snapshot *snapshot, struct msm_cvp_inst *inst, @@ -102,6 +119,8 @@ static void _log_smem(struct inst_snapshot *snapshot, struct msm_cvp_inst *inst, s->device_addr = smem->device_addr; s->bitmap_index = smem->bitmap_index; s->refcount = atomic_read(&smem->refcount); + s->pkt_type = smem->pkt_type; + s->buf_idx = smem->buf_idx; } } @@ -282,6 +301,8 @@ int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) smem->dma_buf = dma_buf; smem->bitmap_index = MAX_DMABUF_NUMS; + smem->pkt_type = 0; + smem->buf_idx = 0; dprintk(CVP_MEM, "%s: dma_buf = %llx\n", __func__, dma_buf); rc = msm_cvp_map_smem(inst, smem, "map dsp"); if (rc) { @@ -439,6 +460,8 @@ int msm_cvp_map_buf_wncc(struct msm_cvp_inst *inst, smem->dma_buf = dma_buf; smem->bitmap_index = MAX_DMABUF_NUMS; + smem->pkt_type = 0; + smem->buf_idx = 0; dprintk(CVP_MEM, "%s: dma_buf = %llx", __func__, dma_buf); rc = msm_cvp_map_smem(inst, smem, "map wncc"); if (rc) { @@ -1183,7 +1206,8 @@ exit: } static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, - struct cvp_buf_type *buf) + struct cvp_buf_type *buf, + u32 pkt_type, u32 buf_idx) { u32 iova = 0; struct msm_cvp_smem *smem = NULL; @@ -1203,6 +1227,8 @@ static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, goto exit; smem->flags |= SMEM_PERSIST; + smem->pkt_type = pkt_type; + smem->buf_idx = buf_idx; pbuf->smem = smem; pbuf->fd = buf->fd; pbuf->size = buf->size; @@ -1226,7 +1252,8 @@ exit: u32 msm_cvp_map_frame_buf(struct msm_cvp_inst *inst, struct cvp_buf_type *buf, - struct msm_cvp_frame *frame) + struct msm_cvp_frame *frame, + u32 pkt_type, u32 buf_idx) { u32 iova = 0; struct msm_cvp_smem *smem = NULL; @@ -1248,6 +1275,9 @@ u32 msm_cvp_map_frame_buf(struct msm_cvp_inst *inst, if (!smem) return 0; + smem->pkt_type = pkt_type; + smem->buf_idx = buf_idx; + frame->bufs[nr].fd = buf->fd; frame->bufs[nr].smem = smem; frame->bufs[nr].size = buf->size; @@ -1284,6 +1314,7 @@ static void msm_cvp_unmap_frame_buf(struct msm_cvp_inst *inst, /* smem not in dmamap cache */ msm_cvp_unmap_smem(inst, smem, "unmap cpu"); dma_heap_buffer_free(smem->dma_buf); + smem->pkt_type = smem->buf_idx = 0; kmem_cache_free(cvp_driver->smem_cache, smem); buf->smem = NULL; } else { @@ -1292,6 +1323,7 @@ static void msm_cvp_unmap_frame_buf(struct msm_cvp_inst *inst, CLEAR_USE_BITMAP(smem->bitmap_index, inst); print_smem(CVP_MEM, "Map dereference", inst, smem); + smem->pkt_type = smem->buf_idx = 0; } mutex_unlock(&inst->dma_cache.lock); } @@ -1362,16 +1394,19 @@ int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, msm_cvp_unmap_smem(inst, smem, "unmap cpu"); dma_heap_buffer_free(smem->dma_buf); + smem->pkt_type = smem->buf_idx = 0; kmem_cache_free( cvp_driver->smem_cache, smem); pbuf->smem = NULL; } else { mutex_lock(&inst->dma_cache.lock); - if (atomic_dec_and_test(&smem->refcount)) + if (atomic_dec_and_test(&smem->refcount)) { CLEAR_USE_BITMAP( smem->bitmap_index, inst); + smem->pkt_type = smem->buf_idx = 0; + } mutex_unlock(&inst->dma_cache.lock); } @@ -1436,12 +1471,14 @@ int msm_cvp_map_user_persist(struct msm_cvp_inst *inst, unsigned int offset, unsigned int buf_num) { struct cvp_buf_type *buf; + struct cvp_hfi_cmd_session_hdr *cmd_hdr; int i; u32 iova; if (!offset || !buf_num) return 0; + cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; for (i = 0; i < buf_num; i++) { buf = (struct cvp_buf_type *)&in_pkt->pkt_data[offset]; offset += sizeof(*buf) >> 2; @@ -1449,7 +1486,7 @@ int msm_cvp_map_user_persist(struct msm_cvp_inst *inst, if (buf->fd < 0 || !buf->size) continue; - iova = msm_cvp_map_user_persist_buf(inst, buf); + iova = msm_cvp_map_user_persist_buf(inst, buf, cmd_hdr->packet_type, i); if (!iova) { dprintk(CVP_ERR, "%s: buf %d register failed.\n", @@ -1496,7 +1533,7 @@ int msm_cvp_map_frame(struct msm_cvp_inst *inst, if (buf->fd < 0 || !buf->size) continue; - iova = msm_cvp_map_frame_buf(inst, buf, frame); + iova = msm_cvp_map_frame_buf(inst, buf, frame, cmd_hdr->packet_type, i); if (!iova) { dprintk(CVP_ERR, "%s: buf %d register failed.\n", @@ -1690,7 +1727,9 @@ struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, dprintk(CVP_ERR, "Failed to allocate ARP memory\n"); goto err_no_mem; } + buf->smem->pkt_type = buf->smem->buf_idx = 0; + buf->smem->pkt_type = buf->smem->buf_idx = 0; buf->size = buf->smem->size; buf->type = HFI_BUFFER_INTERNAL_PERSIST_1; buf->ownership = DRIVER; @@ -1826,6 +1865,7 @@ int cvp_allocate_dsp_bufs(struct msm_cvp_inst *inst, dprintk(CVP_ERR, "Failed to allocate ARP memory\n"); goto err_no_mem; } + buf->smem->pkt_type = buf->smem->buf_idx = 0; dprintk(CVP_MEM, "%s dma_buf %pK\n", __func__, buf->smem->dma_buf); diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index dfb637896c..801cf8d607 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -72,6 +72,8 @@ struct msm_cvp_smem { u32 size; u32 bitmap_index; u32 flags; + u32 pkt_type; + u32 buf_idx; struct cvp_dma_mapping_info mapping_info; }; @@ -98,6 +100,8 @@ static inline void INIT_DMAMAP_CACHE(struct cvp_dmamap_cache *cache) static inline void DEINIT_DMAMAP_CACHE(struct cvp_dmamap_cache *cache) { mutex_destroy(&cache->lock); + cache->usage_bitmap = 0; + cache->nr = 0; } struct cvp_buf_type { @@ -200,7 +204,8 @@ void msm_cvp_cache_operations(struct msm_cvp_smem *smem, u32 type, u32 offset, u32 size); u32 msm_cvp_map_frame_buf(struct msm_cvp_inst *inst, struct cvp_buf_type *buf, - struct msm_cvp_frame *frame); + struct msm_cvp_frame *frame, + u32 pkt_type, u32 buf_idx); int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst, struct eva_kmd_hfi_packet *in_pkt, unsigned int offset, unsigned int buf_num); diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 549bd98602..3702e07858 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -625,10 +625,7 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) } call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data); list_for_each_entry(inst, &core->instances, list) { - dprintk(CVP_WARN, - "%s: sys error inst %#x kref %x, state %x\n", - __func__, inst, kref_read(&inst->kref), - inst->state); + cvp_print_inst(CVP_WARN, inst); if (inst->state != MSM_CVP_CORE_INVALID) { change_cvp_inst_state(inst, MSM_CVP_CORE_INVALID); if (cvp_clean_session_queues(inst)) @@ -642,8 +639,10 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) wake_up_all(&inst->event_handler.wq); } - if (!core->trigger_ssr) + if (!core->trigger_ssr) { + cvp_print_inst(CVP_WARN, inst); msm_cvp_print_inst_bufs(inst, false); + } } /* handle the hw error before core released to get full debug info */ @@ -1554,3 +1553,18 @@ bool is_cvp_inst_valid(struct msm_cvp_inst *inst) return false; } +int cvp_print_inst(u32 tag, struct msm_cvp_inst *inst) +{ + if (!inst) { + dprintk(CVP_ERR, "%s invalid inst %pK\n", __func__, inst); + return -EINVAL; + } + + dprintk(tag, "inst %pK id = %#x type %#x prio %#x secure %#x kmask %#x dmask %#x, kref %#x state %#x\n", + inst, hash32_ptr(inst->session), + inst->prop.type, inst->prop.priority, inst->prop.is_secure, + inst, inst->prop.kernel_mask, inst->prop.dsp_mask, + kref_read(&inst->kref), inst->state); + + return 0; +} diff --git a/msm/eva/msm_cvp_common.h b/msm/eva/msm_cvp_common.h index e3fd84770d..5320c6766e 100644 --- a/msm/eva/msm_cvp_common.h +++ b/msm/eva/msm_cvp_common.h @@ -31,4 +31,5 @@ int wait_for_sess_signal_receipt(struct msm_cvp_inst *inst, int cvp_comm_set_arp_buffers(struct msm_cvp_inst *inst); int cvp_comm_release_persist_buffers(struct msm_cvp_inst *inst); int msm_cvp_noc_error_info(struct msm_cvp_core *core); +int cvp_print_inst(u32 tag, struct msm_cvp_inst *inst); #endif diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 757f11b510..5945489db9 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -154,8 +154,7 @@ void *msm_cvp_open(int core_id, int session_type) dprintk(CVP_ERR, "Instance num reached Max, rejecting session"); mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) - dprintk(CVP_ERR, "inst %pK, id %d\n", - inst, hash32_ptr(inst->session)); + cvp_print_inst(CVP_ERR, inst); mutex_unlock(&core->lock); return NULL; diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index af24893740..757d1238e6 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1119,8 +1119,8 @@ static int eva_fastrpc_driver_register(uint32_t handle) if (!wait_for_completion_timeout( &frpc_node->fastrpc_probe_completion, msecs_to_jiffies(CVP_DSP_RESPONSE_TIMEOUT))) { - dprintk(CVP_ERR, "%s fastrpc driver_register timeout\n", - __func__); + dprintk(CVP_ERR, "%s fastrpc driver_register timeout %#x\n", + __func__, frpc_node->handle); skip_deregister = false; goto fail_fastrpc_driver_register; } diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index b6cc53f217..4ca2781446 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -287,6 +287,8 @@ struct smem_data { u32 device_addr; u32 bitmap_index; u32 refcount; + u32 pkt_type; + u32 buf_idx; }; struct cvp_buf_data { diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index faf5b4293e..9d23978a4f 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -270,248 +270,291 @@ static const struct of_device_id msm_cvp_dt_match[] = { {}, }; +/* + * WARN: name field can not hold more than 31 chars + * + */ const struct msm_cvp_hfi_defs cvp_hfi_defs[] = { { .size = HFI_DFS_CONFIG_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_DFS_CONFIG, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "DFS", }, { .size = HFI_DFS_FRAME_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_DFS_FRAME, .is_config_pkt = false, .resp = HAL_NO_RESP, + .name = "DFS_FRAME", }, { .size = 0xFFFFFFFF, .type = HFI_CMD_SESSION_CVP_SGM_OF_CONFIG, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "SGM_OF", }, { .size = 0xFFFFFFFF, .type = HFI_CMD_SESSION_CVP_SGM_OF_FRAME, .is_config_pkt = false, .resp = HAL_NO_RESP, + .name = "SGM_OF_FRAME", }, { .size = 0xFFFFFFFF, .type = HFI_CMD_SESSION_CVP_WARP_NCC_CONFIG, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "WARP_NCC", }, { .size = 0xFFFFFFFF, .type = HFI_CMD_SESSION_CVP_WARP_NCC_FRAME, .is_config_pkt = false, .resp = HAL_NO_RESP, + .name = "WARP_NCC_FRAME", }, { .size = 0xFFFFFFFF, .type = HFI_CMD_SESSION_CVP_WARP_CONFIG, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "WARP", }, { .size = 0xFFFFFFFF, .type = HFI_CMD_SESSION_CVP_WARP_DS_PARAMS, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "WARP_DS_PARAMS", }, { .size = 0xFFFFFFFF, .type = HFI_CMD_SESSION_CVP_WARP_FRAME, .is_config_pkt = false, .resp = HAL_NO_RESP, + .name = "WARP_FRAME", }, { .size = HFI_DMM_CONFIG_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_DMM_CONFIG, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "DMM", }, { .size = 0xFFFFFFFF, .type = HFI_CMD_SESSION_CVP_DMM_PARAMS, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "DMM_PARAMS", }, { .size = HFI_DMM_FRAME_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_DMM_FRAME, .is_config_pkt = false, .resp = HAL_NO_RESP, + .name = "DMM_FRAME", }, { .size = HFI_PERSIST_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "SET_PERSIST", }, { .size = 0xffffffff, .type = HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "REL_PERSIST", }, { .size = HFI_DS_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_DS, .is_config_pkt = false, .resp = HAL_NO_RESP, + .name = "DS", }, { .size = HFI_OF_CONFIG_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_CV_TME_CONFIG, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "TME", }, { .size = HFI_OF_FRAME_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_CV_TME_FRAME, .is_config_pkt = false, .resp = HAL_NO_RESP, + .name = "TME_FRAME", }, { .size = HFI_ODT_CONFIG_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_CV_ODT_CONFIG, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "ODT", }, { .size = HFI_ODT_FRAME_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_CV_ODT_FRAME, .is_config_pkt = false, .resp = HAL_NO_RESP, + .name = "ODT_FRAME", }, { .size = HFI_OD_CONFIG_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_CV_OD_CONFIG, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "OD", }, { .size = HFI_OD_FRAME_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_CV_OD_FRAME, .is_config_pkt = false, .resp = HAL_NO_RESP, + .name = "OD_FRAME", }, { .size = HFI_NCC_CONFIG_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_NCC_CONFIG, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "NCC", }, { .size = HFI_NCC_FRAME_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_NCC_FRAME, .is_config_pkt = false, .resp = HAL_NO_RESP, + .name = "NCC_FRAME", }, { .size = HFI_ICA_CONFIG_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_ICA_CONFIG, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "ICA", }, { .size = HFI_ICA_FRAME_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_ICA_FRAME, .is_config_pkt = false, .resp = HAL_NO_RESP, + .name = "ICA_FRAME", }, { .size = HFI_HCD_CONFIG_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_HCD_CONFIG, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "HCD", }, { .size = HFI_HCD_FRAME_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_HCD_FRAME, .is_config_pkt = false, .resp = HAL_NO_RESP, + .name = "HCD_FRAME", }, { .size = HFI_DCM_CONFIG_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_DC_CONFIG, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "DC", }, { .size = HFI_DCM_FRAME_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_DC_FRAME, .is_config_pkt = false, .resp = HAL_NO_RESP, + .name = "DC_FRAME", }, { .size = HFI_DCM_CONFIG_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_DCM_CONFIG, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "DCM", }, { .size = HFI_DCM_FRAME_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_DCM_FRAME, .is_config_pkt = false, .resp = HAL_NO_RESP, + .name = "DCM_FRAME", }, { .size = HFI_PYS_HCD_CONFIG_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_PYS_HCD_CONFIG, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "PYS_HCD", }, { .size = HFI_PYS_HCD_FRAME_CMD_SIZE, .type = HFI_CMD_SESSION_CVP_PYS_HCD_FRAME, .is_config_pkt = false, .resp = HAL_NO_RESP, + .name = "PYS_HCD_FRAME", }, { .size = 0xFFFFFFFF, .type = HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "SET_MODEL", }, { .size = 0xFFFFFFFF, .type = HFI_CMD_SESSION_CVP_SET_SNAPSHOT_BUFFERS, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "SET_SNAPSHOT", }, { .size = 0xFFFFFFFF, .type = HFI_CMD_SESSION_CVP_RELEASE_SNAPSHOT_BUFFERS, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "REL_SNAPSHOT", }, { .size = 0xFFFFFFFF, .type = HFI_CMD_SESSION_CVP_SET_SNAPSHOT_MODE, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "SNAPSHOT_MODE", }, { .size = 0xFFFFFFFF, .type = HFI_CMD_SESSION_CVP_SNAPSHOT_WRITE_DONE, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "SNAPSHOT_DONE", }, { .size = 0xFFFFFFFF, .type = HFI_CMD_SESSION_CVP_FD_CONFIG, .is_config_pkt = true, .resp = HAL_NO_RESP, + .name = "FD", }, { .size = 0xFFFFFFFF, .type = HFI_CMD_SESSION_CVP_FD_FRAME, .is_config_pkt = false, .resp = HAL_NO_RESP, + .name = "FD_FRAME", }, - }; int get_pkt_array_size(void) diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index 41fcc5431f..f69298a96d 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -971,6 +971,7 @@ int msm_cvp_smmu_fault_handler(struct iommu_domain *domain, mutex_lock(&core->lock); log = (core->log.snapshot_index > 0)? false : true; list_for_each_entry(inst, &core->instances, list) { + cvp_print_inst(CVP_ERR, inst); msm_cvp_print_inst_bufs(inst, log); } hdev = core->device->hfi_device_data; From e92994b6b9f83ec97680aec351e419aceedcca86 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 6 Jul 2022 12:47:37 -0700 Subject: [PATCH 126/317] msm: eva: Avoid caching persist buf mapping Remove unused user persist buffer unmap code as the HFI of UNMAP_USER_PERSIST is not supported. Change-Id: If8ca0c24318adb1d33ab525ac0023bc5f8ae4573 Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 131 ++++++++++-------------------------------- msm/eva/msm_cvp_buf.h | 6 +- 2 files changed, 32 insertions(+), 105 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index af5d7f1365..d7031ee0d0 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1143,7 +1143,8 @@ static int msm_cvp_session_add_smem(struct msm_cvp_inst *inst, } static struct msm_cvp_smem *msm_cvp_session_get_smem(struct msm_cvp_inst *inst, - struct cvp_buf_type *buf) + struct cvp_buf_type *buf, + bool is_persist) { int rc = 0, found = 1; struct msm_cvp_smem *smem = NULL; @@ -1160,6 +1161,25 @@ static struct msm_cvp_smem *msm_cvp_session_get_smem(struct msm_cvp_inst *inst, return NULL; } + if (is_persist) { + smem = kmem_cache_zalloc(cvp_driver->smem_cache, GFP_KERNEL); + if (!smem) + return NULL; + + smem->dma_buf = dma_buf; + smem->bitmap_index = MAX_DMABUF_NUMS; + rc = msm_cvp_map_smem(inst, smem, "map cpu"); + if (rc) + goto exit; + if (!IS_CVP_BUF_VALID(buf, smem)) { + dprintk(CVP_ERR, + "%s: invalid offset %d or size %d persist\n", + __func__, buf->offset, buf->size); + goto exit2; + } + return smem; + } + smem = msm_cvp_session_find_smem(inst, dma_buf); if (!smem) { found = 0; @@ -1172,17 +1192,19 @@ static struct msm_cvp_smem *msm_cvp_session_get_smem(struct msm_cvp_inst *inst, rc = msm_cvp_map_smem(inst, smem, "map cpu"); if (rc) goto exit; - if (buf->size > smem->size || buf->size > smem->size - buf->offset) { - dprintk(CVP_ERR, "%s: invalid offset %d or size %d for a new entry\n", + if (!IS_CVP_BUF_VALID(buf, smem)) { + dprintk(CVP_ERR, + "%s: invalid offset %d or size %d new entry\n", __func__, buf->offset, buf->size); goto exit2; } rc = msm_cvp_session_add_smem(inst, smem); if (rc && rc != -ENOMEM) goto exit2; + return smem; } - if (buf->size > smem->size || buf->size > smem->size - buf->offset) { + if (!IS_CVP_BUF_VALID(buf, smem)) { dprintk(CVP_ERR, "%s: invalid offset %d or size %d\n", __func__, buf->offset, buf->size); if (found) { @@ -1222,7 +1244,7 @@ static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, if (!pbuf) return 0; - smem = msm_cvp_session_get_smem(inst, buf); + smem = msm_cvp_session_get_smem(inst, buf, true); if (!smem) goto exit; @@ -1271,7 +1293,7 @@ u32 msm_cvp_map_frame_buf(struct msm_cvp_inst *inst, return 0; } - smem = msm_cvp_session_get_smem(inst, buf); + smem = msm_cvp_session_get_smem(inst, buf, false); if (!smem) return 0; @@ -1363,107 +1385,12 @@ void msm_cvp_unmap_frame(struct msm_cvp_inst *inst, u64 ktid) dprintk(CVP_WARN, "%s frame %llu not found!\n", __func__, ktid); } -int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, - struct eva_kmd_hfi_packet *in_pkt, - unsigned int offset, unsigned int buf_num) -{ - struct cvp_hfi_cmd_session_hdr *cmd_hdr; - struct cvp_internal_buf *pbuf, *dummy; - u64 ktid; - int rc = 0; - struct msm_cvp_smem *smem = NULL; - - if (!offset || !buf_num) - return rc; - - cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; - ktid = cmd_hdr->client_data.kdata & (FENCE_BIT - 1); - - mutex_lock(&inst->persistbufs.lock); - list_for_each_entry_safe(pbuf, dummy, &inst->persistbufs.list, list) { - if (pbuf->ktid == ktid && pbuf->ownership == CLIENT) { - list_del(&pbuf->list); - smem = pbuf->smem; - - dprintk(CVP_MEM, "unmap persist: %x %d %d %#x", - hash32_ptr(inst->session), pbuf->fd, - pbuf->size, smem->device_addr); - - if (smem->bitmap_index >= MAX_DMABUF_NUMS) { - /* smem not in dmamap cache */ - msm_cvp_unmap_smem(inst, smem, - "unmap cpu"); - dma_heap_buffer_free(smem->dma_buf); - smem->pkt_type = smem->buf_idx = 0; - kmem_cache_free( - cvp_driver->smem_cache, - smem); - pbuf->smem = NULL; - } else { - mutex_lock(&inst->dma_cache.lock); - if (atomic_dec_and_test(&smem->refcount)) { - CLEAR_USE_BITMAP( - smem->bitmap_index, - inst); - smem->pkt_type = smem->buf_idx = 0; - } - mutex_unlock(&inst->dma_cache.lock); - } - - kmem_cache_free(cvp_driver->buf_cache, pbuf); - } - } - mutex_unlock(&inst->persistbufs.lock); - return rc; -} - int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst, struct eva_kmd_hfi_packet *in_pkt, unsigned int offset, unsigned int buf_num) { - struct cvp_hfi_cmd_session_hdr *cmd_hdr; - struct cvp_internal_buf *pbuf, *dummy; - u64 ktid; - struct cvp_buf_type *buf; - int i, rc = 0; - - if (!offset || !buf_num) + dprintk(CVP_ERR, "Unexpected user persistent buffer release\n"); return 0; - - cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; - ktid = atomic64_inc_return(&inst->core->kernel_trans_id); - ktid &= (FENCE_BIT - 1); - cmd_hdr->client_data.kdata = ktid; - - for (i = 0; i < buf_num; i++) { - buf = (struct cvp_buf_type *)&in_pkt->pkt_data[offset]; - offset += sizeof(*buf) >> 2; - - if (buf->fd < 0 || !buf->size) - continue; - - mutex_lock(&inst->persistbufs.lock); - list_for_each_entry_safe(pbuf, dummy, &inst->persistbufs.list, - list) { - if (pbuf->ownership == CLIENT) { - if (pbuf->fd == buf->fd && - pbuf->size == buf->size) - buf->fd = pbuf->smem->device_addr; - rc = 1; - break; - } - } - mutex_unlock(&inst->persistbufs.lock); - if (!rc) { - dprintk(CVP_ERR, "%s No persist buf %d found\n", - __func__, buf->fd); - rc = -EFAULT; - break; - } - pbuf->ktid = ktid; - rc = 0; - } - return rc; } int msm_cvp_map_user_persist(struct msm_cvp_inst *inst, diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index 801cf8d607..6bd64b5482 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -15,6 +15,9 @@ #define MAX_FRAME_BUFFER_NUMS 30 #define MAX_DMABUF_NUMS 64 +#define IS_CVP_BUF_VALID(buf, smem) \ + ((buf->size <= smem->size) && \ + (buf->size <= smem->size - buf->offset)) struct msm_cvp_inst; struct msm_cvp_platform_resources; @@ -212,9 +215,6 @@ int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst, int msm_cvp_map_user_persist(struct msm_cvp_inst *inst, struct eva_kmd_hfi_packet *in_pkt, unsigned int offset, unsigned int buf_num); -int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, - struct eva_kmd_hfi_packet *in_pkt, - unsigned int offset, unsigned int buf_num); int msm_cvp_map_frame(struct msm_cvp_inst *inst, struct eva_kmd_hfi_packet *in_pkt, unsigned int offset, unsigned int buf_num); From 6b7cb5f836efbaa24fd660e22c47c3e120ff4762 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 6 Jul 2022 14:05:22 -0700 Subject: [PATCH 127/317] msm: eva: Fix nested mutex lock in DSP SSR rpmsg remove call back hangs with the problem. Change-Id: I60df9d8772f31778051a905197479aa9f9d61e9f Signed-off-by: George Shen --- msm/eva/msm_cvp_dsp.c | 82 ++++++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 33 deletions(-) diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 757d1238e6..01edfcd2bf 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -314,14 +314,33 @@ static void eva_fastrpc_driver_release_name( DRIVER_NAME_AVAILABLE; } +static struct cvp_dsp_fastrpc_driver_entry *dequeue_frpc_node(void) +{ + struct cvp_dsp_apps *me = &gfa_cv; + struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; + struct list_head *ptr = NULL, *next = NULL; + + ptr = &me->fastrpc_driver_list.list; + mutex_lock(&me->fastrpc_driver_list.lock); + list_for_each_safe(ptr, next, &me->fastrpc_driver_list.list) { + frpc_node = list_entry(ptr, + struct cvp_dsp_fastrpc_driver_entry, list); + + if (frpc_node) { + list_del(&frpc_node->list); + break; + } + } + mutex_unlock(&me->fastrpc_driver_list.lock); + return frpc_node; +} + static void cvp_dsp_rpmsg_remove(struct rpmsg_device *rpdev) { struct cvp_dsp_apps *me = &gfa_cv; - struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; - struct list_head *ptr = NULL, *next = NULL; - struct list_head *s = NULL, *next_s = NULL; struct msm_cvp_inst *inst = NULL; + struct list_head *s = NULL, *next_s = NULL; dprintk(CVP_WARN, "%s: CDSP SSR triggered\n", __func__); @@ -332,40 +351,37 @@ static void cvp_dsp_rpmsg_remove(struct rpmsg_device *rpdev) me->state = DSP_UNINIT; mutex_unlock(&me->tx_lock); - ptr = &me->fastrpc_driver_list.list; - mutex_lock(&me->fastrpc_driver_list.lock); - list_for_each_safe(ptr, next, &me->fastrpc_driver_list.list) { - frpc_node = list_entry(ptr, - struct cvp_dsp_fastrpc_driver_entry, list); - - if (frpc_node) { - s = &frpc_node->dsp_sessions.list; - list_for_each_safe(s, next_s, - &frpc_node->dsp_sessions.list) { - inst = list_entry(s, struct msm_cvp_inst, - dsp_list); + while ((frpc_node = dequeue_frpc_node())) { + s = &frpc_node->dsp_sessions.list; + list_for_each_safe(s, next_s, + &frpc_node->dsp_sessions.list) { + inst = list_entry(s, struct msm_cvp_inst, + dsp_list); + if (inst) { delete_dsp_session(inst, frpc_node); + mutex_lock(&frpc_node->dsp_sessions.lock); + list_del(&inst->dsp_list); + frpc_node->session_cnt--; + mutex_unlock(&frpc_node->dsp_sessions.lock); } - - dprintk(CVP_DSP, "%s DEINIT_MSM_CVP_LIST 0x%x\n", - __func__, frpc_node->dsp_sessions); - DEINIT_MSM_CVP_LIST(&frpc_node->dsp_sessions); - dprintk(CVP_DSP, "%s list_del fastrpc node 0x%x\n", - __func__, frpc_node); - list_del(&frpc_node->list); - __fastrpc_driver_unregister( - &frpc_node->cvp_fastrpc_driver); - dprintk(CVP_DSP, - "%s Unregistered fastrpc handle 0x%x\n", - __func__, frpc_node->handle); - mutex_lock(&me->driver_name_lock); - eva_fastrpc_driver_release_name(frpc_node); - mutex_unlock(&me->driver_name_lock); - kfree(frpc_node); - frpc_node = NULL; } + + dprintk(CVP_DSP, "%s DEINIT_MSM_CVP_LIST 0x%x\n", + __func__, frpc_node->dsp_sessions); + DEINIT_MSM_CVP_LIST(&frpc_node->dsp_sessions); + dprintk(CVP_DSP, "%s list_del fastrpc node 0x%x\n", + __func__, frpc_node); + __fastrpc_driver_unregister( + &frpc_node->cvp_fastrpc_driver); + dprintk(CVP_DSP, + "%s Unregistered fastrpc handle 0x%x\n", + __func__, frpc_node->handle); + mutex_lock(&me->driver_name_lock); + eva_fastrpc_driver_release_name(frpc_node); + mutex_unlock(&me->driver_name_lock); + kfree(frpc_node); + frpc_node = NULL; } - mutex_unlock(&me->fastrpc_driver_list.lock); dprintk(CVP_WARN, "%s: CDSP SSR handled\n", __func__); } From 98cd09c61f28fa726a6d1b76401d890fcf86fdd0 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 7 Jul 2022 14:05:29 -0700 Subject: [PATCH 128/317] msm: eva: Fix power collapse failure In case there is a live but unused DSP session. Change-Id: I7dd0d7baeb89365a2d8ba6905ddffd1e5569c872 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 4 ++-- msm/eva/msm_cvp_core.c | 7 ++++--- msm/eva/msm_cvp_dsp.c | 5 +---- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 58f2623659..1308521e03 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -241,8 +241,8 @@ static int __dsp_suspend(struct iris_hfi_device *device, bool force, u32 flags) /* don't suspend if cvp session is not paused */ if (!(temp->flags & SESSION_PAUSE)) { dprintk(CVP_DSP, - "%s: cvp session %x not paused\n", - __func__, hash32_ptr(temp)); + "%s: cvp session %x not paused %d\n", + __func__, hash32_ptr(temp), gfa_cv.state); return -EBUSY; } } diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 5945489db9..6b9dc39b2d 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -168,7 +168,8 @@ void *msm_cvp_open(int core_id, int session_type) } pr_info_ratelimited( - CVP_DBG_TAG "Opening cvp instance: %pK\n", "sess", inst); + CVP_DBG_TAG "Opening cvp instance: %pK type %d\n", + "sess", inst, session_type); mutex_init(&inst->sync_lock); mutex_init(&inst->lock); spin_lock_init(&inst->event_handler.lock); @@ -385,8 +386,8 @@ int msm_cvp_destroy(struct msm_cvp_inst *inst) core->synx_ftbl->cvp_sess_deinit_synx(inst); pr_info_ratelimited( - CVP_DBG_TAG "Closed cvp instance: %pK session_id = %d\n", - "sess", inst, hash32_ptr(inst->session)); + CVP_DBG_TAG "Closed cvp instance: %pK session_id = %d type %d\n", + "sess", inst, hash32_ptr(inst->session), inst->session_type); inst->session = (void *)0xdeadbeef; kfree(inst); return 0; diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 01edfcd2bf..4a8ce61cca 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -500,11 +500,8 @@ int cvp_dsp_resume(uint32_t session_flag) * Probably get rid of this entirely as discussed before */ if (me->state != DSP_SUSPEND) - goto exit; + dprintk(CVP_WARN, "%s DSP not in SUSPEND state\n", __func__); - me->state = DSP_READY; - -exit: return rc; } From 1cb056362c2fce696c9b86f08267b93f499050eb Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 8 Jul 2022 16:49:02 -0700 Subject: [PATCH 129/317] msm: eva: Add process name for debugging Also fix a persistbuf optimization problem that failed multi-loop DMM test. Change-Id: Ib197077a708dea99967f0a9f4ed1c09d12023edc Signed-off-by: George Shen --- msm/eva/cvp.c | 6 ++--- msm/eva/cvp_smem.c | 2 +- msm/eva/msm_cvp_buf.c | 49 +++++++++++++++++++++++++++++--------- msm/eva/msm_cvp_common.c | 4 ++-- msm/eva/msm_cvp_core.c | 21 +++++++++------- msm/eva/msm_cvp_core.h | 3 ++- msm/eva/msm_cvp_dsp.c | 42 ++++++++++++++++---------------- msm/eva/msm_cvp_internal.h | 2 ++ 8 files changed, 82 insertions(+), 47 deletions(-) diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index b17e658bc8..10deb4e7d3 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -41,7 +41,7 @@ static int cvp_open(struct inode *inode, struct file *filp) dprintk(CVP_SESS, "%s: core->id: %d\n", __func__, core->id); - inst = msm_cvp_open(core->id, MSM_CVP_USER); + inst = msm_cvp_open(core->id, MSM_CVP_USER, current); if (!inst) { dprintk(CVP_ERR, "Failed to create cvp instance\n"); return -ENOMEM; @@ -266,7 +266,7 @@ static ssize_t boot_store(struct device *dev, if (val > 0 && booted == 0) { struct msm_cvp_inst *inst; - inst = msm_cvp_open(MSM_CORE_CVP, MSM_CVP_BOOT); + inst = msm_cvp_open(MSM_CORE_CVP, MSM_CVP_BOOT, current); if (!inst) { dprintk(CVP_ERR, "Failed to create cvp instance\n"); @@ -281,7 +281,7 @@ static ssize_t boot_store(struct device *dev, } else if ((val == 2) && booted) { struct msm_cvp_inst *inst; - inst = msm_cvp_open(MSM_CORE_CVP, MSM_CVP_USER); + inst = msm_cvp_open(MSM_CORE_CVP, MSM_CVP_USER, current); if (!inst) { dprintk(CVP_ERR, "Failed to create eva instance\n"); diff --git a/msm/eva/cvp_smem.c b/msm/eva/cvp_smem.c index 8466bd43a3..34ff43ee6b 100644 --- a/msm/eva/cvp_smem.c +++ b/msm/eva/cvp_smem.c @@ -104,8 +104,8 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, u32 align, table = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); if (IS_ERR_OR_NULL(table)) { + dprintk(CVP_ERR, "Failed to map table %d\n", PTR_ERR(table)); rc = PTR_ERR(table) ?: -ENOMEM; - dprintk(CVP_ERR, "Failed to map table\n"); goto mem_map_table_failed; } diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index d7031ee0d0..d1ab8098bd 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -63,8 +63,8 @@ int print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, } dprintk(tag, - "%s: %x : %s size %d flags %#x iova %#x idx %d ref %d pkt_type %s buf_idx %#x", - str, hash32_ptr(inst->session), smem->dma_buf->name, + "%s: %x : %pK size %d flags %#x iova %#x idx %d ref %d pkt_type %s buf_idx %#x", + str, hash32_ptr(inst->session), smem->dma_buf, smem->size, smem->flags, smem->device_addr, smem->bitmap_index, atomic_read(&smem->refcount), name, smem->buf_idx); @@ -80,9 +80,9 @@ static void print_internal_buffer(u32 tag, const char *str, if (cbuf->smem->dma_buf) { dprintk(tag, - "%s: %x : fd %d off %d %s size %d iova %#x", + "%s: %x : fd %d off %d %pK size %d iova %#x", str, hash32_ptr(inst->session), cbuf->fd, - cbuf->offset, cbuf->smem->dma_buf->name, cbuf->size, + cbuf->offset, cbuf->smem->dma_buf, cbuf->size, cbuf->smem->device_addr); } else { dprintk(tag, @@ -1233,6 +1233,7 @@ static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, { u32 iova = 0; struct msm_cvp_smem *smem = NULL; + struct list_head *ptr, *next; struct cvp_internal_buf *pbuf; if (!inst) { @@ -1240,9 +1241,26 @@ static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, return -EINVAL; } + mutex_lock(&inst->persistbufs.lock); + list_for_each_safe(ptr, next, &inst->persistbufs.list) { + pbuf = list_entry(ptr, struct cvp_internal_buf, list); + if (buf->fd == pbuf->fd) { + pbuf->size = + (pbuf->size >= buf->size) ? + pbuf->size : buf->size; + iova = pbuf->smem->device_addr + buf->offset; + mutex_unlock(&inst->persistbufs.lock); + return iova; + } + } + mutex_unlock(&inst->persistbufs.lock); + pbuf = kmem_cache_zalloc(cvp_driver->buf_cache, GFP_KERNEL); - if (!pbuf) + if (!pbuf) { + dprintk(CVP_ERR, "%s failed to allocate kmem obj\n", + __func__); return 0; + } smem = msm_cvp_session_get_smem(inst, buf, true); if (!smem) @@ -1251,6 +1269,7 @@ static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, smem->flags |= SMEM_PERSIST; smem->pkt_type = pkt_type; smem->buf_idx = buf_idx; + atomic_inc(&smem->refcount); pbuf->smem = smem; pbuf->fd = buf->fd; pbuf->size = buf->size; @@ -1657,6 +1676,7 @@ struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, buf->smem->pkt_type = buf->smem->buf_idx = 0; buf->smem->pkt_type = buf->smem->buf_idx = 0; + atomic_inc(&buf->smem->refcount); buf->size = buf->smem->size; buf->type = HFI_BUFFER_INTERNAL_PERSIST_1; buf->ownership = DRIVER; @@ -1729,14 +1749,21 @@ int cvp_release_arp_buffers(struct msm_cvp_inst *inst) list_del(&buf->list); - if (buf->ownership == DRIVER) { + if (buf->ownership == DRIVER) dprintk(CVP_MEM, - "%s: %x : fd %d %s size %d", + "%s: %x : fd %d %pK size %d", "free arp", hash32_ptr(inst->session), buf->fd, - smem->dma_buf->name, buf->size); - msm_cvp_smem_free(smem); - kmem_cache_free(cvp_driver->smem_cache, smem); - } + smem->dma_buf, buf->size); + else + dprintk(CVP_MEM, + "%s: %x : fd %d %pK size %d", + "free user persistent", hash32_ptr(inst->session), buf->fd, + smem->dma_buf, buf->size); + + atomic_dec(&smem->refcount); + msm_cvp_smem_free(smem); + kmem_cache_free(cvp_driver->smem_cache, smem); + buf->smem = NULL; kmem_cache_free(cvp_driver->buf_cache, buf); } diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 3702e07858..a07498c7c8 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -1560,8 +1560,8 @@ int cvp_print_inst(u32 tag, struct msm_cvp_inst *inst) return -EINVAL; } - dprintk(tag, "inst %pK id = %#x type %#x prio %#x secure %#x kmask %#x dmask %#x, kref %#x state %#x\n", - inst, hash32_ptr(inst->session), + dprintk(tag, "%s inst stype %d %pK id = %#x ptype %#x prio %#x secure %#x kmask %#x dmask %#x, kref %#x state %#x\n", + inst->proc_name, inst->session_type, inst, hash32_ptr(inst->session), inst->prop.type, inst->prop.priority, inst->prop.is_secure, inst, inst->prop.kernel_mask, inst->prop.dsp_mask, kref_read(&inst->kref), inst->state); diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 6b9dc39b2d..2d5c04f7e9 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -124,7 +124,7 @@ static void __deinit_session_queue(struct msm_cvp_inst *inst) wake_up_all(&inst->session_queue.wq); } -void *msm_cvp_open(int core_id, int session_type) +void *msm_cvp_open(int core_id, int session_type, struct task_struct *task) { struct msm_cvp_inst *inst = NULL; struct msm_cvp_core *core = NULL; @@ -167,9 +167,9 @@ void *msm_cvp_open(int core_id, int session_type) goto err_invalid_core; } - pr_info_ratelimited( - CVP_DBG_TAG "Opening cvp instance: %pK type %d\n", - "sess", inst, session_type); + pr_info( + CVP_DBG_TAG "%s opening cvp instance: %pK type %d\n", + "sess", task->comm, inst, session_type); mutex_init(&inst->sync_lock); mutex_init(&inst->lock); spin_lock_init(&inst->event_handler.lock); @@ -225,6 +225,7 @@ void *msm_cvp_open(int core_id, int session_type) inst->debugfs_root = msm_cvp_debugfs_init_inst(inst, core->debugfs_root); + strlcpy(inst->proc_name, task->comm, TASK_COMM_LEN); return inst; fail_init: @@ -305,7 +306,7 @@ wait_dsp: (inst->core->resources.msm_cvp_hw_rsp_timeout >> 5) - max_retries); max_retries = inst->core->resources.msm_cvp_hw_rsp_timeout >> 1; -wait: +wait_frame: mutex_lock(&inst->frames.lock); empty = list_empty(&inst->frames.list); if (!empty && max_retries > 0) { @@ -314,7 +315,7 @@ wait: msm_cvp_clean_sess_queue(inst, sqf); msm_cvp_clean_sess_queue(inst, sq); max_retries--; - goto wait; + goto wait_frame; } mutex_unlock(&inst->frames.lock); @@ -385,9 +386,11 @@ int msm_cvp_destroy(struct msm_cvp_inst *inst) __deinit_fence_queue(inst); core->synx_ftbl->cvp_sess_deinit_synx(inst); - pr_info_ratelimited( - CVP_DBG_TAG "Closed cvp instance: %pK session_id = %d type %d\n", - "sess", inst, hash32_ptr(inst->session), inst->session_type); + pr_info( + CVP_DBG_TAG + "%s closed cvp instance: %pK session_id = %d type %d\n", + "sess", inst->proc_name, inst, hash32_ptr(inst->session), + inst->session_type); inst->session = (void *)0xdeadbeef; kfree(inst); return 0; diff --git a/msm/eva/msm_cvp_core.h b/msm/eva/msm_cvp_core.h index 1e27728903..15c12fd8c0 100644 --- a/msm/eva/msm_cvp_core.h +++ b/msm/eva/msm_cvp_core.h @@ -7,6 +7,7 @@ #define _MSM_CVP_CORE_H_ #include +#include #include #include #include @@ -33,7 +34,7 @@ enum session_type { MSM_CVP_MAX_DEVICES = MSM_CVP_UNKNOWN, }; -void *msm_cvp_open(int core_id, int session_type); +void *msm_cvp_open(int core_id, int session_type, struct task_struct *task); int msm_cvp_close(void *instance); int msm_cvp_suspend(int core_id); int msm_cvp_poll(void *instance, struct file *filp, diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 4a8ce61cca..d9d958e6c4 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1372,14 +1372,31 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) dsp2cpu_cmd->is_secure, dsp2cpu_cmd->pid); - rc = eva_fastrpc_driver_register(dsp2cpu_cmd->pid); - if (rc) { - dprintk(CVP_ERR, "%s Register fastrpc driver fail\n", __func__); + pid_s = find_get_pid(dsp2cpu_cmd->pid); + if (pid_s == NULL) { + dprintk(CVP_WARN, "%s incorrect pid\n", __func__); + cmd->ret = -1; + return; + } + dprintk(CVP_DSP, "%s get pid_s 0x%x from pidA 0x%x\n", __func__, + pid_s, dsp2cpu_cmd->pid); + + task = get_pid_task(pid_s, PIDTYPE_TGID); + if (!task) { + dprintk(CVP_WARN, "%s task doesn't exist\n", __func__); cmd->ret = -1; return; } - inst = msm_cvp_open(MSM_CORE_CVP, MSM_CVP_DSP); + rc = eva_fastrpc_driver_register(dsp2cpu_cmd->pid); + if (rc) { + dprintk(CVP_ERR, "%s Register fastrpc driver fail\n", __func__); + put_task_struct(task); + cmd->ret = -1; + return; + } + + inst = msm_cvp_open(MSM_CORE_CVP, MSM_CVP_DSP, task); if (!inst) { dprintk(CVP_ERR, "%s Failed create instance\n", __func__); goto fail_msm_cvp_open; @@ -1415,20 +1432,6 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) if (frpc_node) eva_fastrpc_driver_add_sess(frpc_node, inst); - pid_s = find_get_pid(inst->process_id); - if (pid_s == NULL) { - dprintk(CVP_WARN, "%s incorrect pid\n", __func__); - goto fail_get_pid; - } - dprintk(CVP_DSP, "%s get pid_s 0x%x from pidA 0x%x\n", __func__, - pid_s, inst->process_id); - - task = get_pid_task(pid_s, PIDTYPE_TGID); - if (!task) { - dprintk(CVP_WARN, "%s task doesn't exist\n", __func__); - goto fail_get_task; - } - inst->task = task; dprintk(CVP_DSP, "%s CREATE_SESS id 0x%x, cpu_low 0x%x, cpu_high 0x%x\n", @@ -1443,14 +1446,13 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) return; -fail_get_pid: -fail_get_task: fail_get_session_info: fail_session_create: msm_cvp_close(inst); fail_msm_cvp_open: /* unregister fastrpc driver */ eva_fastrpc_driver_unregister(dsp2cpu_cmd->pid, false); + put_task_struct(task); cmd->ret = -1; } diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index 4ca2781446..968a206f06 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -7,6 +7,7 @@ #define _MSM_CVP_INTERNAL_H_ #include +#include #include #include #include @@ -412,6 +413,7 @@ struct msm_cvp_inst { u32 prev_error_code; struct synx_session synx_session_id; struct cvp_fence_queue fence_cmd_queue; + char proc_name[TASK_COMM_LEN]; }; extern struct msm_cvp_drv *cvp_driver; From 04232ceea4eeceb48e667f6e50a421f06abb561a Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 19 Jul 2022 09:56:37 -0700 Subject: [PATCH 130/317] msm: eva: Fix fd reuse problem. Fix KW issue and fd reuse issue in persistent buffer mapping. Change-Id: I9d971abe14460ac57d9f48ee086f97abec1b6f2b Signed-off-by: George Shen --- msm/eva/hfi_response_handler.c | 5 +++-- msm/eva/msm_cvp.c | 7 +++++-- msm/eva/msm_cvp_buf.c | 14 +++++++++++++- msm/eva/msm_cvp_core.c | 15 ++++++++------- 4 files changed, 29 insertions(+), 12 deletions(-) diff --git a/msm/eva/hfi_response_handler.c b/msm/eva/hfi_response_handler.c index 1347d61be3..e54e8d4226 100644 --- a/msm/eva/hfi_response_handler.c +++ b/msm/eva/hfi_response_handler.c @@ -105,8 +105,9 @@ static int hfi_process_session_error(u32 device_id, break; default: dprintk(CVP_ERR, - "%s: session %x data1 %#x, data2 %#x\n", __func__, - pkt->session_id, pkt->event_data1, pkt->event_data2); + "%s: session %x id %#x, data1 %#x, data2 %#x\n", + __func__, pkt->session_id, pkt->event_id, + pkt->event_data1, pkt->event_data2); info->response_type = HAL_RESPONSE_UNUSED; break; } diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index d56ed96673..0631e061f5 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -473,6 +473,9 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, dprintk(CVP_SYNX, "%s %s\n", current->comm, __func__); + if (!inst || !inst->core) + return -EINVAL; + hdev = inst->core->device; sq = &inst->session_queue_fence; ktid = pkt->client_data.kdata; @@ -509,10 +512,10 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, dprintk(CVP_PWR, "busy cycle %d, total %d\n", fhdr->busy_cycles, fhdr->total_cycles); - if (core && (core->dyn_clk.sum_fps[HFI_HW_FDU] || + if (core->dyn_clk.sum_fps[HFI_HW_FDU] || core->dyn_clk.sum_fps[HFI_HW_MPU] || core->dyn_clk.sum_fps[HFI_HW_OD] || - core->dyn_clk.sum_fps[HFI_HW_ICA])) { + core->dyn_clk.sum_fps[HFI_HW_ICA]) { clock_check = true; } } else { diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index d1ab8098bd..2d659edb49 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1235,26 +1235,38 @@ static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, struct msm_cvp_smem *smem = NULL; struct list_head *ptr, *next; struct cvp_internal_buf *pbuf; + struct dma_buf *dma_buf; if (!inst) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); return -EINVAL; } + dma_buf = msm_cvp_smem_get_dma_buf(buf->fd); + if (!dma_buf) + return -EINVAL; + mutex_lock(&inst->persistbufs.lock); list_for_each_safe(ptr, next, &inst->persistbufs.list) { pbuf = list_entry(ptr, struct cvp_internal_buf, list); - if (buf->fd == pbuf->fd) { + if (dma_buf == pbuf->smem->dma_buf) { pbuf->size = (pbuf->size >= buf->size) ? pbuf->size : buf->size; iova = pbuf->smem->device_addr + buf->offset; mutex_unlock(&inst->persistbufs.lock); + atomic_inc(&pbuf->smem->refcount); + dma_buf_put(dma_buf); + dprintk(CVP_MEM, + "map persist Reuse fd %d, dma_buf %#llx\n", + pbuf->fd, pbuf->smem->dma_buf); return iova; } } mutex_unlock(&inst->persistbufs.lock); + dma_buf_put(dma_buf); + pbuf = kmem_cache_zalloc(cvp_driver->buf_cache, GFP_KERNEL); if (!pbuf) { dprintk(CVP_ERR, "%s failed to allocate kmem obj\n", diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 2d5c04f7e9..497a12e332 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -49,16 +49,16 @@ int msm_cvp_private(void *cvp_inst, unsigned int cmd, } EXPORT_SYMBOL(msm_cvp_private); -static bool msm_cvp_check_for_inst_overload(struct msm_cvp_core *core) +static bool msm_cvp_check_for_inst_overload(struct msm_cvp_core *core, + u32 *instance_count) { - u32 instance_count = 0; u32 secure_instance_count = 0; struct msm_cvp_inst *inst = NULL; bool overload = false; mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) { - instance_count++; + (*instance_count)++; /* This flag is not updated yet for the current instance */ if (inst->flags & CVP_SECURE) secure_instance_count++; @@ -67,7 +67,7 @@ static bool msm_cvp_check_for_inst_overload(struct msm_cvp_core *core) /* Instance count includes current instance as well. */ - if ((instance_count >= core->resources.max_inst_count) || + if ((*instance_count >= core->resources.max_inst_count) || (secure_instance_count >= core->resources.max_secure_inst_count)) overload = true; @@ -130,6 +130,7 @@ void *msm_cvp_open(int core_id, int session_type, struct task_struct *task) struct msm_cvp_core *core = NULL; int rc = 0; int i = 0; + u32 instance_count; if (core_id >= MSM_CVP_CORES_MAX || session_type >= MSM_CVP_MAX_DEVICES) { @@ -150,7 +151,7 @@ void *msm_cvp_open(int core_id, int session_type, struct task_struct *task) } core->resources.max_inst_count = MAX_SUPPORTED_INSTANCES; - if (msm_cvp_check_for_inst_overload(core)) { + if (msm_cvp_check_for_inst_overload(core, &instance_count)) { dprintk(CVP_ERR, "Instance num reached Max, rejecting session"); mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) @@ -168,8 +169,8 @@ void *msm_cvp_open(int core_id, int session_type, struct task_struct *task) } pr_info( - CVP_DBG_TAG "%s opening cvp instance: %pK type %d\n", - "sess", task->comm, inst, session_type); + CVP_DBG_TAG "%s opening cvp instance: %pK type %d cnt %d\n", + "sess", task->comm, inst, session_type, instance_count); mutex_init(&inst->sync_lock); mutex_init(&inst->lock); spin_lock_init(&inst->event_handler.lock); From 2eea29b8253d95b0f0e74b6d61b8beb2df1cef3d Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 28 Jul 2022 15:21:57 -0700 Subject: [PATCH 131/317] msm: eva: Add debug message when suspend dsp fail Check if promoting to LE SI works or not. Change-Id: I6e69cf602d39a6ebd1f99deb565832ccf7494cba Signed-off-by: George Shen --- msm/eva/msm_cvp_dsp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index d9d958e6c4..ffc5996c45 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -461,6 +461,8 @@ retry: goto fatal_exit; if (rsp.ret == CPU2DSP_EFATAL) { + dprintk(CVP_ERR, "%s: suspend dsp got EFATAL error\n", + __func__); if (!retried) { mutex_unlock(&me->tx_lock); retried = true; From dcbb74265f47557cd3e43400c5a7428f48d44ced Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 13 Jul 2022 16:20:20 -0700 Subject: [PATCH 132/317] msm: eva: Add Lanai EVA HFI check Adds XRA, DLFL, DLFD, RGE and ITOF packets sanity check. Optimizes packet type table to avoid linear search during each packet handling. Instead use packet type as index to expedite searching. Packet type table grows to over 60 entries and each entry uses 40B. There will be quite some memory access delay for each packet handling without optimization. Change-Id: I1ee26d0d5d0b83d3c15fbcafa7414017c418b6e3 Signed-off-by: George Shen --- msm/eva/cvp.c | 2 +- msm/eva/cvp_hfi.h | 37 +- msm/eva/cvp_hfi_api.h | 7 +- msm/eva/cvp_smem.c | 29 +- msm/eva/msm_cvp.c | 2 +- msm/eva/msm_cvp_buf.c | 31 +- msm/eva/msm_cvp_buf.h | 5 +- msm/eva/msm_cvp_platform.c | 760 +++++++++++++++++++++++-------------- 8 files changed, 556 insertions(+), 317 deletions(-) diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index 10deb4e7d3..bf1cd9340a 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -448,7 +448,7 @@ static int msm_probe_cvp_device(struct platform_device *pdev) goto err_fail_sub_device_probe; } - atomic64_set(&core->kernel_trans_id, get_pkt_array_size()); + atomic64_set(&core->kernel_trans_id, ARRAY_SIZE(cvp_hfi_defs)); if (core->resources.dsp_enabled) { rc = cvp_dsp_device_init(); diff --git a/msm/eva/cvp_hfi.h b/msm/eva/cvp_hfi.h index 0f1e943dfc..e7fd8a6cfa 100644 --- a/msm/eva/cvp_hfi.h +++ b/msm/eva/cvp_hfi.h @@ -130,6 +130,24 @@ (HFI_CMD_SESSION_CVP_START + 0x064) #define HFI_CMD_SESSION_CVP_WARP_DS_PARAMS\ (HFI_CMD_SESSION_CVP_START + 0x065) +#define HFI_CMD_SESSION_CVP_XRA_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x066) +#define HFI_CMD_SESSION_CVP_XRA_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x067) +#define HFI_CMD_SESSION_CVP_XRA_BLOB_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x069) +#define HFI_CMD_SESSION_CVP_XRA_BLOB_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x06A) +#define HFI_CMD_SESSION_CVP_XRA_PATCH_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x06B) +#define HFI_CMD_SESSION_CVP_XRA_PATCH_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x06C) +#define HFI_CMD_SESSION_CVP_XRA_MATCH_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x06D) +#define HFI_CMD_SESSION_CVP_XRA_MATCH_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x06E) + + #define HFI_CMD_SESSION_CVP_SET_SNAPSHOT_BUFFERS\ (HFI_CMD_SESSION_CVP_START + 0x070) #define HFI_CMD_SESSION_CVP_RELEASE_SNAPSHOT_BUFFERS\ @@ -138,6 +156,22 @@ (HFI_CMD_SESSION_CVP_START + 0x072) #define HFI_CMD_SESSION_CVP_SET_SNAPSHOT_MODE\ (HFI_CMD_SESSION_CVP_START + 0x073) +#define HFI_CMD_SESSION_CVP_RGE_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x076) +#define HFI_CMD_SESSION_CVP_RGE_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x077) +#define HFI_CMD_SESSION_EVA_ITOF_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x078) +#define HFI_CMD_SESSION_EVA_ITOF_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x079) +#define HFI_CMD_SESSION_EVA_DLFD_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x07C) +#define HFI_CMD_SESSION_EVA_DLFD_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x07D) +#define HFI_CMD_SESSION_EVA_DLFL_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x080) +#define HFI_CMD_SESSION_EVA_DLFL_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x081) #define HFI_CMD_SESSION_CVP_ICA_FRAME\ (HFI_CMD_SESSION_CVP_START + 0x100) #define HFI_CMD_SESSION_CVP_ICA_CONFIG\ @@ -312,7 +346,8 @@ static inline enum buf_map_type cvp_find_map_type(int pkt_type) pkt_type == HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS || pkt_type == HFI_CMD_SESSION_CVP_DMM_PARAMS || pkt_type == HFI_CMD_SESSION_CVP_SET_SNAPSHOT_BUFFERS || - pkt_type == HFI_CMD_SESSION_CVP_WARP_DS_PARAMS) + pkt_type == HFI_CMD_SESSION_CVP_WARP_DS_PARAMS || + pkt_type == HFI_CMD_SESSION_EVA_DLFL_CONFIG) return MAP_PERSIST; else if (pkt_type == HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS || pkt_type == diff --git a/msm/eva/cvp_hfi_api.h b/msm/eva/cvp_hfi_api.h index e759e18db4..e3dea9a61d 100644 --- a/msm/eva/cvp_hfi_api.h +++ b/msm/eva/cvp_hfi_api.h @@ -234,7 +234,8 @@ struct cvp_hal_cmd_sys_get_property_packet { #define call_hfi_op(q, op, args...) \ (((q) && (q)->op) ? ((q)->op(args)) : 0) -#define PKT_NAME_LEN 32 +#define PKT_NAME_LEN 24 +#define MAX_PKT_IDX 0x200 struct msm_cvp_hfi_defs { unsigned int size; @@ -297,13 +298,13 @@ void cvp_hfi_deinitialize(enum msm_cvp_hfi_type hfi_type, struct cvp_hfi_device *hdev); int get_pkt_index(struct cvp_hal_session_cmd_pkt *hdr); -int get_pkt_array_size(void); +int get_pkt_index_from_type(u32 pkt_type); int get_hfi_version(void); unsigned int get_msg_size(struct cvp_hfi_msg_session_hdr *hdr); unsigned int get_msg_session_id(void *msg); unsigned int get_msg_errorcode(void *msg); int get_msg_opconfigs(void *msg, unsigned int *session_id, unsigned int *error_type, unsigned int *config_id); -extern const struct msm_cvp_hfi_defs cvp_hfi_defs[]; +extern const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX]; #endif /*__CVP_HFI_API_H__ */ diff --git a/msm/eva/cvp_smem.c b/msm/eva/cvp_smem.c index 34ff43ee6b..6e722b3bb2 100644 --- a/msm/eva/cvp_smem.c +++ b/msm/eva/cvp_smem.c @@ -204,12 +204,13 @@ int msm_cvp_map_smem(struct msm_cvp_inst *inst, int *vmid_list; int *perms_list; int nelems = 0; - int rc = 0; + int i, rc = 0; dma_addr_t iova = 0; u32 temp = 0; u32 align = SZ_4K; struct dma_buf *dma_buf; + bool is_config_pkt = false; if (!inst || !smem) { dprintk(CVP_ERR, "%s: Invalid params: %pK %pK\n", @@ -250,7 +251,33 @@ int msm_cvp_map_smem(struct msm_cvp_inst *inst, smem->size = dma_buf->size; smem->device_addr = (u32)iova; + i = get_pkt_index_from_type(smem->pkt_type); + if (i > 0 && smem->pkt_type != HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS + && smem->pkt_type != HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS + && smem->pkt_type != HFI_CMD_SESSION_EVA_DLFL_CONFIG) + /* User persist buffer has no feature config info */ + is_config_pkt = cvp_hfi_defs[i].is_config_pkt; + /* if (!(smem->flags & SMEM_SECURE) && + is_config_pkt && + (msm_cvp_debug & CVP_MEM)) { + dma_buf_begin_cpu_access(dma_buf, DMA_BIDIRECTIONAL); + smem->kvaddr = __cvp_dma_buf_vmap(dma_buf); + if (!smem->kvaddr) { + dprintk(CVP_WARN, + "Failed to map config buf in kernel\n"); + dma_buf_end_cpu_access(dma_buf, DMA_BIDIRECTIONAL); + goto checksum_done; + } + for (i = 0; i < (dma_buf->size); i++) { + smem->checksum += *(u8 *)(smem->kvaddr + i); + } + __cvp_dma_buf_vunmap(dma_buf, smem->kvaddr); + smem->kvaddr = 0; + dma_buf_end_cpu_access(dma_buf, DMA_BIDIRECTIONAL); + } + +checksum_done:*/ print_smem(CVP_MEM, str, inst, smem); goto success; exit: diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 0631e061f5..0d4a33b581 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -116,7 +116,7 @@ static int cvp_wait_process_message(struct msm_cvp_inst *inst, hdr = (struct cvp_hfi_msg_session_hdr *)&msg->pkt; memcpy(out, &msg->pkt, get_msg_size(hdr)); - if (hdr->client_data.kdata >= get_pkt_array_size()) + if (hdr->client_data.kdata >= ARRAY_SIZE(cvp_hfi_defs)) msm_cvp_unmap_frame(inst, hdr->client_data.kdata); kmem_cache_free(cvp_driver->msg_cache, msg); diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 2d659edb49..a0ccd09613 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -56,18 +56,16 @@ int print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, if (!atomic_read(&smem->refcount)) return 0; - for (i = 0; i < get_pkt_array_size(); i++) - if (cvp_hfi_defs[i].type == smem->pkt_type) { - strlcpy(name, cvp_hfi_defs[i].name, PKT_NAME_LEN); - break; - } + i = get_pkt_index_from_type(smem->pkt_type); + if (i > 0) + strlcpy(name, cvp_hfi_defs[i].name, PKT_NAME_LEN); dprintk(tag, - "%s: %x : %pK size %d flags %#x iova %#x idx %d ref %d pkt_type %s buf_idx %#x", + "%s: %x : %pK size %d flags %#x iova %#x idx %d ref %d pkt_type %s buf_idx %#x chksum %#x", str, hash32_ptr(inst->session), smem->dma_buf, smem->size, smem->flags, smem->device_addr, smem->bitmap_index, atomic_read(&smem->refcount), - name, smem->buf_idx); + name, smem->buf_idx, smem->checksum); } return 0; } @@ -1144,7 +1142,8 @@ static int msm_cvp_session_add_smem(struct msm_cvp_inst *inst, static struct msm_cvp_smem *msm_cvp_session_get_smem(struct msm_cvp_inst *inst, struct cvp_buf_type *buf, - bool is_persist) + bool is_persist, + u32 pkt_type) { int rc = 0, found = 1; struct msm_cvp_smem *smem = NULL; @@ -1168,6 +1167,9 @@ static struct msm_cvp_smem *msm_cvp_session_get_smem(struct msm_cvp_inst *inst, smem->dma_buf = dma_buf; smem->bitmap_index = MAX_DMABUF_NUMS; + smem->pkt_type = pkt_type; + smem->flags |= SMEM_PERSIST; + atomic_inc(&smem->refcount); rc = msm_cvp_map_smem(inst, smem, "map cpu"); if (rc) goto exit; @@ -1189,6 +1191,7 @@ static struct msm_cvp_smem *msm_cvp_session_get_smem(struct msm_cvp_inst *inst, smem->dma_buf = dma_buf; smem->bitmap_index = MAX_DMABUF_NUMS; + smem->pkt_type = pkt_type; rc = msm_cvp_map_smem(inst, smem, "map cpu"); if (rc) goto exit; @@ -1274,14 +1277,12 @@ static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, return 0; } - smem = msm_cvp_session_get_smem(inst, buf, true); + smem = msm_cvp_session_get_smem(inst, buf, true, pkt_type); if (!smem) goto exit; - smem->flags |= SMEM_PERSIST; smem->pkt_type = pkt_type; smem->buf_idx = buf_idx; - atomic_inc(&smem->refcount); pbuf->smem = smem; pbuf->fd = buf->fd; pbuf->size = buf->size; @@ -1303,7 +1304,7 @@ exit: return 0; } -u32 msm_cvp_map_frame_buf(struct msm_cvp_inst *inst, +static u32 msm_cvp_map_frame_buf(struct msm_cvp_inst *inst, struct cvp_buf_type *buf, struct msm_cvp_frame *frame, u32 pkt_type, u32 buf_idx) @@ -1324,11 +1325,10 @@ u32 msm_cvp_map_frame_buf(struct msm_cvp_inst *inst, return 0; } - smem = msm_cvp_session_get_smem(inst, buf, false); + smem = msm_cvp_session_get_smem(inst, buf, false, pkt_type); if (!smem) return 0; - smem->pkt_type = pkt_type; smem->buf_idx = buf_idx; frame->bufs[nr].fd = buf->fd; @@ -1444,7 +1444,8 @@ int msm_cvp_map_user_persist(struct msm_cvp_inst *inst, if (buf->fd < 0 || !buf->size) continue; - iova = msm_cvp_map_user_persist_buf(inst, buf, cmd_hdr->packet_type, i); + iova = msm_cvp_map_user_persist_buf(inst, buf, + cmd_hdr->packet_type, i); if (!iova) { dprintk(CVP_ERR, "%s: buf %d register failed.\n", diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index 6bd64b5482..c9ccb28fbc 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -77,6 +77,7 @@ struct msm_cvp_smem { u32 flags; u32 pkt_type; u32 buf_idx; + u32 checksum; struct cvp_dma_mapping_info mapping_info; }; @@ -205,10 +206,6 @@ int msm_cvp_proc_oob(struct msm_cvp_inst* inst, struct eva_kmd_hfi_packet* in_pkt); void msm_cvp_cache_operations(struct msm_cvp_smem *smem, u32 type, u32 offset, u32 size); -u32 msm_cvp_map_frame_buf(struct msm_cvp_inst *inst, - struct cvp_buf_type *buf, - struct msm_cvp_frame *frame, - u32 pkt_type, u32 buf_idx); int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst, struct eva_kmd_hfi_packet *in_pkt, unsigned int offset, unsigned int buf_num); diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 9d23978a4f..99112caaef 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -271,308 +271,486 @@ static const struct of_device_id msm_cvp_dt_match[] = { }; /* - * WARN: name field can not hold more than 31 chars + * WARN: name field CAN NOT hold more than 23 chars + * excluding the ending '\0' * + * NOTE: the def entry index for the command packet is + * "the packet type - HFI_CMD_SESSION_CVP_START" */ -const struct msm_cvp_hfi_defs cvp_hfi_defs[] = { - { - .size = HFI_DFS_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_DFS_CONFIG, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "DFS", - }, - { - .size = HFI_DFS_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_DFS_FRAME, - .is_config_pkt = false, - .resp = HAL_NO_RESP, - .name = "DFS_FRAME", - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_SGM_OF_CONFIG, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "SGM_OF", - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_SGM_OF_FRAME, - .is_config_pkt = false, - .resp = HAL_NO_RESP, - .name = "SGM_OF_FRAME", - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_WARP_NCC_CONFIG, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "WARP_NCC", - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_WARP_NCC_FRAME, - .is_config_pkt = false, - .resp = HAL_NO_RESP, - .name = "WARP_NCC_FRAME", - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_WARP_CONFIG, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "WARP", - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_WARP_DS_PARAMS, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "WARP_DS_PARAMS", - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_WARP_FRAME, - .is_config_pkt = false, - .resp = HAL_NO_RESP, - .name = "WARP_FRAME", - }, - { - .size = HFI_DMM_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_DMM_CONFIG, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "DMM", - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_DMM_PARAMS, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "DMM_PARAMS", - }, - { - .size = HFI_DMM_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_DMM_FRAME, - .is_config_pkt = false, - .resp = HAL_NO_RESP, - .name = "DMM_FRAME", - }, - { - .size = HFI_PERSIST_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "SET_PERSIST", - }, - { - .size = 0xffffffff, - .type = HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "REL_PERSIST", - }, - { - .size = HFI_DS_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_DS, - .is_config_pkt = false, - .resp = HAL_NO_RESP, - .name = "DS", - }, - { - .size = HFI_OF_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_CV_TME_CONFIG, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "TME", - }, - { - .size = HFI_OF_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_CV_TME_FRAME, - .is_config_pkt = false, - .resp = HAL_NO_RESP, - .name = "TME_FRAME", - }, - { - .size = HFI_ODT_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_CV_ODT_CONFIG, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "ODT", - }, - { - .size = HFI_ODT_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_CV_ODT_FRAME, - .is_config_pkt = false, - .resp = HAL_NO_RESP, - .name = "ODT_FRAME", - }, - { - .size = HFI_OD_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_CV_OD_CONFIG, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "OD", - }, - { - .size = HFI_OD_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_CV_OD_FRAME, - .is_config_pkt = false, - .resp = HAL_NO_RESP, - .name = "OD_FRAME", - }, - { - .size = HFI_NCC_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_NCC_CONFIG, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "NCC", - }, - { - .size = HFI_NCC_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_NCC_FRAME, - .is_config_pkt = false, - .resp = HAL_NO_RESP, - .name = "NCC_FRAME", - }, - { - .size = HFI_ICA_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_ICA_CONFIG, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "ICA", - }, - { - .size = HFI_ICA_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_ICA_FRAME, - .is_config_pkt = false, - .resp = HAL_NO_RESP, - .name = "ICA_FRAME", - }, - { - .size = HFI_HCD_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_HCD_CONFIG, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "HCD", - }, - { - .size = HFI_HCD_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_HCD_FRAME, - .is_config_pkt = false, - .resp = HAL_NO_RESP, - .name = "HCD_FRAME", - }, - { - .size = HFI_DCM_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_DC_CONFIG, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "DC", - }, - { - .size = HFI_DCM_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_DC_FRAME, - .is_config_pkt = false, - .resp = HAL_NO_RESP, - .name = "DC_FRAME", - }, - { - .size = HFI_DCM_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_DCM_CONFIG, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "DCM", - }, - { - .size = HFI_DCM_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_DCM_FRAME, - .is_config_pkt = false, - .resp = HAL_NO_RESP, - .name = "DCM_FRAME", - }, - { - .size = HFI_PYS_HCD_CONFIG_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_PYS_HCD_CONFIG, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "PYS_HCD", - }, - { - .size = HFI_PYS_HCD_FRAME_CMD_SIZE, - .type = HFI_CMD_SESSION_CVP_PYS_HCD_FRAME, - .is_config_pkt = false, - .resp = HAL_NO_RESP, - .name = "PYS_HCD_FRAME", - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "SET_MODEL", - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_SET_SNAPSHOT_BUFFERS, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "SET_SNAPSHOT", - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_RELEASE_SNAPSHOT_BUFFERS, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "REL_SNAPSHOT", - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_SET_SNAPSHOT_MODE, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "SNAPSHOT_MODE", - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_SNAPSHOT_WRITE_DONE, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "SNAPSHOT_DONE", - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_FD_CONFIG, - .is_config_pkt = true, - .resp = HAL_NO_RESP, - .name = "FD", - }, - { - .size = 0xFFFFFFFF, - .type = HFI_CMD_SESSION_CVP_FD_FRAME, - .is_config_pkt = false, - .resp = HAL_NO_RESP, - .name = "FD_FRAME", - }, +const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { + [HFI_CMD_SESSION_CVP_DFS_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_DFS_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DFS_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "DFS", + }, + [HFI_CMD_SESSION_CVP_DFS_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_DFS_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DFS_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "DFS_FRAME", + }, + [HFI_CMD_SESSION_CVP_SGM_OF_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_SGM_OF_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "SGM_OF", + }, + [HFI_CMD_SESSION_CVP_SGM_OF_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_SGM_OF_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "SGM_OF_FRAME", + }, + [HFI_CMD_SESSION_CVP_WARP_NCC_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_WARP_NCC_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "WARP_NCC", + }, + [HFI_CMD_SESSION_CVP_WARP_NCC_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_WARP_NCC_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "WARP_NCC_FRAME", + }, + [HFI_CMD_SESSION_CVP_WARP_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_WARP_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "WARP", + }, + [HFI_CMD_SESSION_CVP_WARP_DS_PARAMS - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_WARP_DS_PARAMS, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "WARP_DS_PARAMS", + }, + [HFI_CMD_SESSION_CVP_WARP_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_WARP_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "WARP_FRAME", + }, + [HFI_CMD_SESSION_CVP_DMM_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_DMM_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DMM_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "DMM", + }, + [HFI_CMD_SESSION_CVP_DMM_PARAMS - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_DMM_PARAMS, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "DMM_PARAMS", + }, + [HFI_CMD_SESSION_CVP_DMM_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_DMM_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DMM_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "DMM_FRAME", + }, + [HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_PERSIST_CMD_SIZE, + .type =HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "SET_PERSIST", + }, + [HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xffffffff, + .type =HFI_CMD_SESSION_CVP_RELEASE_PERSIST_BUFFERS, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "REL_PERSIST", + }, + [HFI_CMD_SESSION_CVP_DS - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_DS_CMD_SIZE, + .type =HFI_CMD_SESSION_CVP_DS, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "DS", + }, + [HFI_CMD_SESSION_CVP_CV_TME_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_OF_CONFIG_CMD_SIZE, + .type =HFI_CMD_SESSION_CVP_CV_TME_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "TME", + }, + [HFI_CMD_SESSION_CVP_CV_TME_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_OF_FRAME_CMD_SIZE, + .type =HFI_CMD_SESSION_CVP_CV_TME_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "TME_FRAME", + }, + [HFI_CMD_SESSION_CVP_CV_ODT_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_ODT_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_CV_ODT_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "ODT", + }, + [HFI_CMD_SESSION_CVP_CV_ODT_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_ODT_FRAME_CMD_SIZE, + .type =HFI_CMD_SESSION_CVP_CV_ODT_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "ODT_FRAME", + }, + [HFI_CMD_SESSION_CVP_CV_OD_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_OD_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_CV_OD_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "OD", + }, + [HFI_CMD_SESSION_CVP_CV_OD_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_OD_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_CV_OD_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "OD_FRAME", + }, + [HFI_CMD_SESSION_CVP_NCC_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_NCC_CONFIG_CMD_SIZE, + .type =HFI_CMD_SESSION_CVP_NCC_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "NCC", + }, + [HFI_CMD_SESSION_CVP_NCC_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_NCC_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_NCC_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "NCC_FRAME", + }, + [HFI_CMD_SESSION_CVP_ICA_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_ICA_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_ICA_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "ICA", + }, + [HFI_CMD_SESSION_CVP_ICA_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_ICA_FRAME_CMD_SIZE, + .type =HFI_CMD_SESSION_CVP_ICA_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "ICA_FRAME", + }, + [HFI_CMD_SESSION_CVP_HCD_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_HCD_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_HCD_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "HCD", + }, + [HFI_CMD_SESSION_CVP_HCD_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_HCD_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_HCD_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "HCD_FRAME", + }, + [HFI_CMD_SESSION_CVP_DC_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_DCM_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DC_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "DC", + }, + [HFI_CMD_SESSION_CVP_DC_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_DCM_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DC_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "DC_FRAME", + }, + [HFI_CMD_SESSION_CVP_DCM_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_DCM_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DCM_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "DCM", + }, + [HFI_CMD_SESSION_CVP_DCM_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_DCM_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DCM_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "DCM_FRAME", + }, + [HFI_CMD_SESSION_CVP_PYS_HCD_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_PYS_HCD_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_PYS_HCD_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "PYS_HCD", + }, + [HFI_CMD_SESSION_CVP_PYS_HCD_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_PYS_HCD_FRAME_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_PYS_HCD_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "PYS_HCD_FRAME", + }, + [HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "SET_MODEL", + }, + [HFI_CMD_SESSION_CVP_SET_SNAPSHOT_BUFFERS - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_SET_SNAPSHOT_BUFFERS, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "SET_SNAPSHOT", + }, + [HFI_CMD_SESSION_CVP_RELEASE_SNAPSHOT_BUFFERS - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_RELEASE_SNAPSHOT_BUFFERS, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "REL_SNAPSHOT", + }, + [HFI_CMD_SESSION_CVP_SET_SNAPSHOT_MODE - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_SET_SNAPSHOT_MODE, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "SNAPSHOT_MODE", + }, + [HFI_CMD_SESSION_CVP_SNAPSHOT_WRITE_DONE - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_SNAPSHOT_WRITE_DONE, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "SNAPSHOT_DONE", + }, + [HFI_CMD_SESSION_CVP_FD_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_FD_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "FD", + }, + [HFI_CMD_SESSION_CVP_FD_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_FD_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "FD_FRAME", + }, + [HFI_CMD_SESSION_CVP_XRA_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_XRA_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "XRA_FRAME", + }, + [HFI_CMD_SESSION_CVP_XRA_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_XRA_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "XRA_CONFIG", + }, + [HFI_CMD_SESSION_CVP_XRA_BLOB_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_XRA_BLOB_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "XRA_BLOB_FRAME", + }, + [HFI_CMD_SESSION_CVP_XRA_BLOB_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_XRA_BLOB_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "XRA_BLOB_CONFIG", + }, + [HFI_CMD_SESSION_CVP_XRA_PATCH_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_XRA_PATCH_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "XRA_PATCH_FRAME", + }, + [HFI_CMD_SESSION_CVP_XRA_PATCH_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_XRA_PATCH_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "XRA_PATCH_CONFIG", + }, + [HFI_CMD_SESSION_CVP_XRA_MATCH_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_XRA_MATCH_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "XRA_MATCH_FRAME", + }, + [HFI_CMD_SESSION_CVP_XRA_MATCH_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_XRA_MATCH_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "XRA_MATCH_CONFIG", + }, + [HFI_CMD_SESSION_CVP_RGE_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_RGE_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "RGE_FRAME", + }, + [HFI_CMD_SESSION_CVP_RGE_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_RGE_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "RGE_CONFIG", + }, + [HFI_CMD_SESSION_EVA_ITOF_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_EVA_ITOF_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "ITOF_FRAME", + }, + [HFI_CMD_SESSION_EVA_ITOF_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_EVA_ITOF_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "ITOF_CONFIG", + }, + [HFI_CMD_SESSION_EVA_DLFD_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_EVA_DLFD_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "DLFD_FRAME", + }, + [HFI_CMD_SESSION_EVA_DLFD_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_EVA_DLFD_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "DLFD_CONFIG", + }, + [HFI_CMD_SESSION_EVA_DLFL_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_EVA_DLFL_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "DLFL_FRAME", + }, + [HFI_CMD_SESSION_EVA_DLFL_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_EVA_DLFL_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "DLFL_CONFIG", + }, }; -int get_pkt_array_size(void) -{ - return ARRAY_SIZE(cvp_hfi_defs); -} - int get_pkt_index(struct cvp_hal_session_cmd_pkt *hdr) { - int i; + if (!hdr || (hdr->packet_type < HFI_CMD_SESSION_CVP_START) + || hdr->packet_type >= (HFI_CMD_SESSION_CVP_START + MAX_PKT_IDX)) + return -EINVAL; - for (i = 0; i < get_pkt_array_size(); i++) - if (cvp_hfi_defs[i].type == hdr->packet_type) - return i; + if (cvp_hfi_defs[hdr->packet_type - HFI_CMD_SESSION_CVP_START].size) + return (hdr->packet_type - HFI_CMD_SESSION_CVP_START); return -EINVAL; } +int get_pkt_index_from_type(u32 pkt_type) +{ + if ((pkt_type < HFI_CMD_SESSION_CVP_START) || + pkt_type >= (HFI_CMD_SESSION_CVP_START + MAX_PKT_IDX)) + return -EINVAL; + + if (cvp_hfi_defs[pkt_type - HFI_CMD_SESSION_CVP_START].size) + return (pkt_type - HFI_CMD_SESSION_CVP_START); + + return -EINVAL; +} MODULE_DEVICE_TABLE(of, msm_cvp_dt_match); int cvp_of_fdt_get_ddrtype(void) From e30e31d72be01a67bf447245ebdf8b15f53ac85b Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 1 Aug 2022 14:49:13 -0700 Subject: [PATCH 133/317] msm: eva: fix DSP session deletion racing The racing to delete DSP session may happen after DSP SSR when EVA DSP driver just sent session deletion command to CPU driver. Change-Id: I252000bc2c04148874db02b50d0a94c10edbb6e6 Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 2 ++ msm/eva/msm_cvp_dsp.c | 27 +++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index a0ccd09613..73c32b7816 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1833,6 +1833,7 @@ int cvp_allocate_dsp_bufs(struct msm_cvp_inst *inst, goto err_no_mem; } buf->smem->pkt_type = buf->smem->buf_idx = 0; + atomic_inc(&buf->smem->refcount); dprintk(CVP_MEM, "%s dma_buf %pK\n", __func__, buf->smem->dma_buf); @@ -1875,6 +1876,7 @@ int cvp_release_dsp_buffers(struct msm_cvp_inst *inst, "%s: %x : fd %x %s size %d", __func__, hash32_ptr(inst->session), buf->fd, smem->dma_buf->name, buf->size); + atomic_dec(&smem->refcount); msm_cvp_smem_free(smem); kmem_cache_free(cvp_driver->smem_cache, smem); } else { diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index ffc5996c45..940f5b027e 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -341,15 +341,33 @@ static void cvp_dsp_rpmsg_remove(struct rpmsg_device *rpdev) struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; struct msm_cvp_inst *inst = NULL; struct list_head *s = NULL, *next_s = NULL; + u32 max_num_retries = 100; dprintk(CVP_WARN, "%s: CDSP SSR triggered\n", __func__); + mutex_lock(&me->rx_lock); + while (max_num_retries > 0) { + if (me->pending_dsp2cpu_cmd.type != + CVP_INVALID_RPMSG_TYPE) { + mutex_unlock(&me->rx_lock); + usleep_range(1000, 5000); + mutex_lock(&me->rx_lock); + } else { + break; + } + max_num_retries--; + } + + if (!max_num_retries) + dprintk(CVP_ERR, "stuck processing pending DSP cmds\n"); + mutex_lock(&me->tx_lock); cvp_hyp_assign_from_dsp(); me->chan = NULL; me->state = DSP_UNINIT; mutex_unlock(&me->tx_lock); + mutex_unlock(&me->rx_lock); while ((frpc_node = dequeue_frpc_node())) { s = &frpc_node->dsp_sessions.list; @@ -1819,8 +1837,6 @@ static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) mutex_lock(&buf_list->lock); list_for_each_safe(ptr, next, &buf_list->list) { buf = list_entry(ptr, struct cvp_internal_buf, list); - dprintk(CVP_DSP, "fd in list 0x%x, fd from dsp 0x%x\n", - buf->fd, dsp2cpu_cmd->sbuf.fd); if (!buf->smem) { dprintk(CVP_DSP, "Empyt smem\n"); @@ -1831,6 +1847,8 @@ static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) if (buf->smem->device_addr == dsp2cpu_cmd->sbuf.iova) { dprintk(CVP_DSP, "%s find device addr 0x%x\n", __func__, buf->smem->device_addr); + dprintk(CVP_DSP, "fd in list 0x%x, fd from dsp 0x%x\n", + buf->fd, dsp2cpu_cmd->sbuf.fd); rc = eva_fastrpc_dev_unmap_dma(frpc_device, buf); if (rc) { @@ -1905,6 +1923,11 @@ wait_dsp: dprintk(CVP_WARN, "%s received interrupt signal\n", __func__); } else { mutex_lock(&me->rx_lock); + if (me->state == DSP_UNINIT) { + /* DSP SSR may have happened */ + mutex_unlock(&me->rx_lock); + goto wait_dsp; + } switch (me->pending_dsp2cpu_cmd.type) { case DSP2CPU_POWERON: { From 18119d76499c97b0b04b29185736ceec36dcf4e3 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 3 Aug 2022 22:53:08 -0700 Subject: [PATCH 134/317] msm: eva: improve frame buf dump info Fix a missing pkt_type dump from dma_cache. Change-Id: I99bbbb7bd6278ecf04c8bfcbba041373ab28826d Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 6 ++++-- msm/eva/msm_cvp_common.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 73c32b7816..b1d69ba07c 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1068,7 +1068,8 @@ void msm_cvp_cache_operations(struct msm_cvp_smem *smem, u32 type, } static struct msm_cvp_smem *msm_cvp_session_find_smem(struct msm_cvp_inst *inst, - struct dma_buf *dma_buf) + struct dma_buf *dma_buf, + u32 pkt_type) { struct msm_cvp_smem *smem; int i; @@ -1082,6 +1083,7 @@ static struct msm_cvp_smem *msm_cvp_session_find_smem(struct msm_cvp_inst *inst, SET_USE_BITMAP(i, inst); smem = inst->dma_cache.entries[i]; smem->bitmap_index = i; + smem->pkt_type = pkt_type; atomic_inc(&smem->refcount); /* * If we find it, it means we already increased @@ -1182,7 +1184,7 @@ static struct msm_cvp_smem *msm_cvp_session_get_smem(struct msm_cvp_inst *inst, return smem; } - smem = msm_cvp_session_find_smem(inst, dma_buf); + smem = msm_cvp_session_find_smem(inst, dma_buf, pkt_type); if (!smem) { found = 0; smem = kmem_cache_zalloc(cvp_driver->smem_cache, GFP_KERNEL); diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index a07498c7c8..f9e860a7d2 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -1563,7 +1563,7 @@ int cvp_print_inst(u32 tag, struct msm_cvp_inst *inst) dprintk(tag, "%s inst stype %d %pK id = %#x ptype %#x prio %#x secure %#x kmask %#x dmask %#x, kref %#x state %#x\n", inst->proc_name, inst->session_type, inst, hash32_ptr(inst->session), inst->prop.type, inst->prop.priority, inst->prop.is_secure, - inst, inst->prop.kernel_mask, inst->prop.dsp_mask, + inst->prop.kernel_mask, inst->prop.dsp_mask, kref_read(&inst->kref), inst->state); return 0; From fcbb3d87ab438c8e130ba4001f1fe5015918a97e Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 27 Sep 2022 12:50:57 -0700 Subject: [PATCH 135/317] msm: eva: Propagate tip of 2.0 to 3.0 Add back all changes made after Aug. 3rd from Kailua to Lanai. Change-Id: I725b77892ab24354014b3d9bbc13d14c710aff5a Signed-off-by: George Shen --- msm/eva/cvp.c | 16 +- msm/eva/cvp_hfi.c | 42 +++++- msm/eva/cvp_hfi.h | 10 ++ msm/eva/cvp_hfi_io.h | 2 + msm/eva/cvp_smem.c | 26 +--- msm/eva/hfi_response_handler.c | 4 +- msm/eva/msm_cvp.c | 4 +- msm/eva/msm_cvp_buf.c | 257 +++++++++++++++++++++++---------- msm/eva/msm_cvp_buf.h | 2 +- msm/eva/msm_cvp_core.c | 50 ++++++- msm/eva/msm_cvp_dsp.c | 257 ++++++++++++++++++++------------- msm/eva/msm_cvp_dsp.h | 2 + msm/eva/msm_cvp_internal.h | 17 ++- 13 files changed, 466 insertions(+), 223 deletions(-) diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index bf1cd9340a..ccfa26a523 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -622,10 +622,10 @@ static int __init msm_cvp_init(void) return rc; } - cvp_driver->msg_cache = KMEM_CACHE(cvp_session_msg, 0); - cvp_driver->frame_cache = KMEM_CACHE(msm_cvp_frame, 0); - cvp_driver->buf_cache = KMEM_CACHE(cvp_internal_buf, 0); - cvp_driver->smem_cache = KMEM_CACHE(msm_cvp_smem, 0); + cvp_driver->msg_cache.cache = KMEM_CACHE(cvp_session_msg, 0); + cvp_driver->frame_cache.cache = KMEM_CACHE(msm_cvp_frame, 0); + cvp_driver->buf_cache.cache = KMEM_CACHE(cvp_internal_buf, 0); + cvp_driver->smem_cache.cache = KMEM_CACHE(msm_cvp_smem, 0); return rc; } @@ -633,10 +633,10 @@ static int __init msm_cvp_init(void) static void __exit msm_cvp_exit(void) { cvp_dsp_device_exit(); - kmem_cache_destroy(cvp_driver->msg_cache); - kmem_cache_destroy(cvp_driver->frame_cache); - kmem_cache_destroy(cvp_driver->buf_cache); - kmem_cache_destroy(cvp_driver->smem_cache); + kmem_cache_destroy(cvp_driver->msg_cache.cache); + kmem_cache_destroy(cvp_driver->frame_cache.cache); + kmem_cache_destroy(cvp_driver->buf_cache.cache); + kmem_cache_destroy(cvp_driver->smem_cache.cache); platform_driver_unregister(&msm_cvp_driver); debugfs_remove_recursive(cvp_driver->debugfs_root); diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 1308521e03..e545b0f0c2 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -956,6 +956,37 @@ static int __tzbsp_set_cvp_state(enum tzbsp_subsys_state state) return 0; } +/* + * Based on fal10_veto, X2RPMh, core_pwr_on and PWAitMode value, infer + * value of xtss_sw_reset. xtss_sw_reset is a TZ register bit. Driver + * cannot access it directly. + * + * In __boot_firmware() function, the caller of this function. It checks + * "core_pwr_on" == false, basically core powered off. So this function + * doesn't check core_pwr_on. Assume core_pwr_on = false. + * + * fal10_veto = VPU_CPU_CS_X2RPMh[2] | + * ( ~VPU_CPU_CS_X2RPMh[1] & core_pwr_on ) | + * ( ~VPU_CPU_CS_X2RPMh[0] & ~( xtss_sw_reset | PWaitMode ) ) ; + */ +static inline void check_tensilica_in_reset(struct iris_hfi_device *device) +{ + u32 X2RPMh, fal10_veto, wait_mode; + + X2RPMh = __read_register(device, CVP_CPU_CS_X2RPMh); + X2RPMh = X2RPMh & 0x7; + + /* wait_mode = 1: Tensilica is in WFI mode (PWaitMode = true) */ + wait_mode = __read_register(device, CVP_WRAPPER_CPU_STATUS); + wait_mode = wait_mode & 0x1; + + fal10_veto = __read_register(device, CVP_CPU_CS_X2RPMh_STATUS); + fal10_veto = fal10_veto & 0x1; + + dprintk(CVP_WARN, "tensilica reset check %#x %#x %#x\n", + X2RPMh, wait_mode, fal10_veto); +} + static inline int __boot_firmware(struct iris_hfi_device *device) { int rc = 0, loop = 10; @@ -1000,8 +1031,11 @@ static inline int __boot_firmware(struct iris_hfi_device *device) } if (!(ctrl_status & CVP_CTRL_INIT_STATUS__M)) { - dprintk(CVP_ERR, "Failed to boot FW status: %x\n", - ctrl_status); + ctrl_init_val = __read_register(device, CVP_CTRL_INIT); + dprintk(CVP_ERR, + "Failed to boot FW status: %x %x\n", + ctrl_status, ctrl_init_val); + check_tensilica_in_reset(device); rc = -ENODEV; } @@ -1098,7 +1132,6 @@ static int iris_hfi_flush_debug_queue(void *dev) return -EINVAL; } - cvp_dump_csr(device); mutex_lock(&device->lock); if (!device->power_enabled) { @@ -1106,6 +1139,7 @@ static int iris_hfi_flush_debug_queue(void *dev) rc = -EINVAL; goto exit; } + cvp_dump_csr(device); __flush_debug_queue(device, NULL); exit: mutex_unlock(&device->lock); @@ -4169,7 +4203,7 @@ static void power_off_iris2(struct iris_hfi_device *device) /*Do not access registers after this point!*/ device->power_enabled = false; - pr_info_ratelimited(CVP_DBG_TAG "cvp (eva) power collapsed\n", "pwr"); + pr_info(CVP_DBG_TAG "cvp (eva) power collapsed\n", "pwr"); } static inline int __resume(struct iris_hfi_device *device) diff --git a/msm/eva/cvp_hfi.h b/msm/eva/cvp_hfi.h index e7fd8a6cfa..bdba4ebae3 100644 --- a/msm/eva/cvp_hfi.h +++ b/msm/eva/cvp_hfi.h @@ -356,4 +356,14 @@ static inline enum buf_map_type cvp_find_map_type(int pkt_type) else return MAP_FRAME; } + +static inline bool is_params_pkt(int pkt_type) +{ + if (pkt_type == HFI_CMD_SESSION_CVP_DMM_PARAMS || + pkt_type == HFI_CMD_SESSION_CVP_WARP_DS_PARAMS) + return true; + + return false; +} + #endif diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index de677cedbf..567b79c29e 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -76,6 +76,8 @@ #define CVP_CPU_CS_X2RPMh_SWOVERRIDE_BMSK 0x4 #define CVP_CPU_CS_X2RPMh_SWOVERRIDE_SHFT 0x3 +#define CVP_CPU_CS_X2RPMh_STATUS (CVP_CPU_BASE_OFFS + 0x170) + /* * -------------------------------------------------------------------------- * MODULE: cvp_wrapper diff --git a/msm/eva/cvp_smem.c b/msm/eva/cvp_smem.c index 6e722b3bb2..173c0fbbca 100644 --- a/msm/eva/cvp_smem.c +++ b/msm/eva/cvp_smem.c @@ -90,7 +90,6 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, u32 align, * Get the scatterlist for the given attachment * Mapping of sg is taken care by map attachment */ - attach->dma_map_attrs = DMA_ATTR_DELAYED_UNMAP; /* * We do not need dma_map function to perform cache operations * on the whole buffer size and hence pass skip sync flag. @@ -105,6 +104,9 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, u32 align, table = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); if (IS_ERR_OR_NULL(table)) { dprintk(CVP_ERR, "Failed to map table %d\n", PTR_ERR(table)); + dprintk(CVP_ERR, + "Mapping detail dma_buf 0x%llx, %s, size %#x\n", + dbuf, dbuf->name, dbuf->size); rc = PTR_ERR(table) ?: -ENOMEM; goto mem_map_table_failed; } @@ -258,27 +260,8 @@ int msm_cvp_map_smem(struct msm_cvp_inst *inst, /* User persist buffer has no feature config info */ is_config_pkt = cvp_hfi_defs[i].is_config_pkt; - /* if (!(smem->flags & SMEM_SECURE) && - is_config_pkt && - (msm_cvp_debug & CVP_MEM)) { - dma_buf_begin_cpu_access(dma_buf, DMA_BIDIRECTIONAL); - smem->kvaddr = __cvp_dma_buf_vmap(dma_buf); - if (!smem->kvaddr) { - dprintk(CVP_WARN, - "Failed to map config buf in kernel\n"); - dma_buf_end_cpu_access(dma_buf, DMA_BIDIRECTIONAL); - goto checksum_done; - } - for (i = 0; i < (dma_buf->size); i++) { - smem->checksum += *(u8 *)(smem->kvaddr + i); - } - __cvp_dma_buf_vunmap(dma_buf, smem->kvaddr); - smem->kvaddr = 0; - dma_buf_end_cpu_access(dma_buf, DMA_BIDIRECTIONAL); - } - -checksum_done:*/ print_smem(CVP_MEM, str, inst, smem); + atomic_inc(&inst->smem_count); goto success; exit: smem->device_addr = 0x0; @@ -308,6 +291,7 @@ int msm_cvp_unmap_smem(struct msm_cvp_inst *inst, } smem->device_addr = 0x0; + atomic_dec(&inst->smem_count); exit: return rc; diff --git a/msm/eva/hfi_response_handler.c b/msm/eva/hfi_response_handler.c index e54e8d4226..8b14cc021f 100644 --- a/msm/eva/hfi_response_handler.c +++ b/msm/eva/hfi_response_handler.c @@ -498,7 +498,7 @@ static int hfi_process_session_cvp_msg(u32 device_id, else sq = &inst->session_queue; - sess_msg = kmem_cache_alloc(cvp_driver->msg_cache, GFP_KERNEL); + sess_msg = cvp_kmem_cache_zalloc(&cvp_driver->msg_cache, GFP_KERNEL); if (sess_msg == NULL) { dprintk(CVP_ERR, "%s runs out msg cache memory\n", __func__); return -ENOMEM; @@ -528,7 +528,7 @@ static int hfi_process_session_cvp_msg(u32 device_id, error_handle_msg: spin_unlock(&sq->lock); - kmem_cache_free(cvp_driver->msg_cache, sess_msg); + cvp_kmem_cache_free(&cvp_driver->msg_cache, sess_msg); return -ENOMEM; } diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 0d4a33b581..076942f309 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -110,7 +110,7 @@ static int cvp_wait_process_message(struct msm_cvp_inst *inst, } if (!out) { - kmem_cache_free(cvp_driver->msg_cache, msg); + cvp_kmem_cache_free(&cvp_driver->msg_cache, msg); goto exit; } @@ -118,7 +118,7 @@ static int cvp_wait_process_message(struct msm_cvp_inst *inst, memcpy(out, &msg->pkt, get_msg_size(hdr)); if (hdr->client_data.kdata >= ARRAY_SIZE(cvp_hfi_defs)) msm_cvp_unmap_frame(inst, hdr->client_data.kdata); - kmem_cache_free(cvp_driver->msg_cache, msg); + cvp_kmem_cache_free(&cvp_driver->msg_cache, msg); exit: return rc; diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index b1d69ba07c..f9540612dd 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -36,6 +36,8 @@ static void _wncc_print_cvpwnccbufs_table(struct msm_cvp_inst* inst); static int _wncc_unmap_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, unsigned int num_layers, struct eva_kmd_wncc_metadata** wncc_metadata); +void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log); + int print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, struct msm_cvp_smem *smem) { @@ -53,19 +55,22 @@ int print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, } if (smem->dma_buf) { - if (!atomic_read(&smem->refcount)) - return 0; - i = get_pkt_index_from_type(smem->pkt_type); if (i > 0) strlcpy(name, cvp_hfi_defs[i].name, PKT_NAME_LEN); - dprintk(tag, - "%s: %x : %pK size %d flags %#x iova %#x idx %d ref %d pkt_type %s buf_idx %#x chksum %#x", - str, hash32_ptr(inst->session), smem->dma_buf, - smem->size, smem->flags, smem->device_addr, - smem->bitmap_index, atomic_read(&smem->refcount), - name, smem->buf_idx, smem->checksum); + if (!atomic_read(&smem->refcount)) + dprintk(tag, + " UNUSED mapping %s: 0x%llx %s size %d iova %#x idx %d pkt_type %s buf_idx %#x fd %d", + str, smem->dma_buf, smem->dma_buf->name, + smem->size, smem->device_addr, smem->bitmap_index, name, smem->buf_idx, smem->fd); + else + dprintk(tag, + "%s: %x : 0x%llx %s size %d flags %#x iova %#x idx %d ref %d pkt_type %s buf_idx %#x fd %d", + str, hash32_ptr(inst->session), smem->dma_buf, smem->dma_buf->name, + smem->size, smem->flags, smem->device_addr, + smem->bitmap_index, atomic_read(&smem->refcount), + name, smem->buf_idx, smem->fd); } return 0; } @@ -78,10 +83,10 @@ static void print_internal_buffer(u32 tag, const char *str, if (cbuf->smem->dma_buf) { dprintk(tag, - "%s: %x : fd %d off %d %pK size %d iova %#x", + "%s: %x : fd %d off %d 0x%llx %s size %d iova %#x", str, hash32_ptr(inst->session), cbuf->fd, - cbuf->offset, cbuf->smem->dma_buf, cbuf->size, - cbuf->smem->device_addr); + cbuf->offset, cbuf->smem->dma_buf, cbuf->smem->dma_buf->name, + cbuf->size, cbuf->smem->device_addr); } else { dprintk(tag, "%s: %x : idx %2d fd %d off %d size %d iova %#x", @@ -285,13 +290,13 @@ int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) dprintk(CVP_MEM, "dma_buf from internal %llu\n", dma_buf); - cbuf = kmem_cache_zalloc(cvp_driver->buf_cache, GFP_KERNEL); + cbuf = cvp_kmem_cache_zalloc(&cvp_driver->buf_cache, GFP_KERNEL); if (!cbuf) { rc = -ENOMEM; goto exit; } - smem = kmem_cache_zalloc(cvp_driver->smem_cache, GFP_KERNEL); + smem = cvp_kmem_cache_zalloc(&cvp_driver->smem_cache, GFP_KERNEL); if (!smem) { rc = -ENOMEM; goto exit; @@ -301,6 +306,7 @@ int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) smem->bitmap_index = MAX_DMABUF_NUMS; smem->pkt_type = 0; smem->buf_idx = 0; + smem->fd = buf->fd; dprintk(CVP_MEM, "%s: dma_buf = %llx\n", __func__, dma_buf); rc = msm_cvp_map_smem(inst, smem, "map dsp"); if (rc) { @@ -329,10 +335,10 @@ exit: if (smem->device_addr) msm_cvp_unmap_smem(inst, smem, "unmap dsp"); msm_cvp_smem_put_dma_buf(smem->dma_buf); - kmem_cache_free(cvp_driver->smem_cache, smem); + cvp_kmem_cache_free(&cvp_driver->smem_cache, smem); } if (cbuf) - kmem_cache_free(cvp_driver->buf_cache, cbuf); + cvp_kmem_cache_free(&cvp_driver->buf_cache, cbuf); return rc; } @@ -377,8 +383,8 @@ int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) list_del(&cbuf->list); mutex_unlock(&inst->cvpdspbufs.lock); - kmem_cache_free(cvp_driver->smem_cache, cbuf->smem); - kmem_cache_free(cvp_driver->buf_cache, cbuf); + cvp_kmem_cache_free(&cvp_driver->smem_cache, cbuf->smem); + cvp_kmem_cache_free(&cvp_driver->buf_cache, cbuf); return rc; } @@ -443,15 +449,15 @@ int msm_cvp_map_buf_wncc(struct msm_cvp_inst *inst, return -EINVAL; } - cbuf = kmem_cache_zalloc(cvp_driver->buf_cache, GFP_KERNEL); + cbuf = cvp_kmem_cache_zalloc(&cvp_driver->buf_cache, GFP_KERNEL); if (!cbuf) { msm_cvp_smem_put_dma_buf(dma_buf); return -ENOMEM; } - smem = kmem_cache_zalloc(cvp_driver->smem_cache, GFP_KERNEL); + smem = cvp_kmem_cache_zalloc(&cvp_driver->smem_cache, GFP_KERNEL); if (!smem) { - kmem_cache_free(cvp_driver->buf_cache, cbuf); + cvp_kmem_cache_free(&cvp_driver->buf_cache, cbuf); msm_cvp_smem_put_dma_buf(dma_buf); return -ENOMEM; } @@ -460,6 +466,7 @@ int msm_cvp_map_buf_wncc(struct msm_cvp_inst *inst, smem->bitmap_index = MAX_DMABUF_NUMS; smem->pkt_type = 0; smem->buf_idx = 0; + smem->fd = buf->fd; dprintk(CVP_MEM, "%s: dma_buf = %llx", __func__, dma_buf); rc = msm_cvp_map_smem(inst, smem, "map wncc"); if (rc) { @@ -536,9 +543,9 @@ exit: if (smem->device_addr) msm_cvp_unmap_smem(inst, smem, "unmap wncc"); msm_cvp_smem_put_dma_buf(smem->dma_buf); - kmem_cache_free(cvp_driver->buf_cache, cbuf); + cvp_kmem_cache_free(&cvp_driver->buf_cache, cbuf); cbuf = NULL; - kmem_cache_free(cvp_driver->smem_cache, smem); + cvp_kmem_cache_free(&cvp_driver->smem_cache, smem); smem = NULL; return rc; } @@ -625,8 +632,8 @@ int msm_cvp_unmap_buf_wncc(struct msm_cvp_inst *inst, } mutex_unlock(&inst->cvpwnccbufs.lock); - kmem_cache_free(cvp_driver->smem_cache, cbuf->smem); - kmem_cache_free(cvp_driver->buf_cache, cbuf); + cvp_kmem_cache_free(&cvp_driver->smem_cache, cbuf->smem); + cvp_kmem_cache_free(&cvp_driver->buf_cache, cbuf); return rc; } @@ -1072,6 +1079,8 @@ static struct msm_cvp_smem *msm_cvp_session_find_smem(struct msm_cvp_inst *inst, u32 pkt_type) { struct msm_cvp_smem *smem; + struct msm_cvp_frame *frame; + struct cvp_internal_buf *buf; int i; if (inst->dma_cache.nr > MAX_DMABUF_NUMS) @@ -1092,12 +1101,41 @@ static struct msm_cvp_smem *msm_cvp_session_find_smem(struct msm_cvp_inst *inst, */ msm_cvp_smem_put_dma_buf(smem->dma_buf); mutex_unlock(&inst->dma_cache.lock); - print_smem(CVP_MEM, "found", inst, smem); + print_smem(CVP_MEM, "found in cache", inst, smem); return smem; } mutex_unlock(&inst->dma_cache.lock); + /* earch persist list */ + mutex_lock(&inst->persistbufs.lock); + list_for_each_entry(buf, &inst->persistbufs.list, list) { + smem = buf->smem; + if (smem && smem->dma_buf == dma_buf) { + atomic_inc(&smem->refcount); + mutex_unlock(&inst->persistbufs.lock); + print_smem(CVP_MEM, "found in persist", inst, smem); + return smem; + } + } + mutex_unlock(&inst->persistbufs.lock); + + /* Search frame list */ + mutex_lock(&inst->frames.lock); + list_for_each_entry(frame, &inst->frames.list, list) { + for (i = 0; i < frame->nr; i++) { + smem = frame->bufs[i].smem; + if (smem && smem->dma_buf == dma_buf) { + atomic_inc(&smem->refcount); + mutex_unlock(&inst->frames.lock); + print_smem(CVP_MEM, "found in frame", + inst, smem); + return smem; + } + } + } + mutex_unlock(&inst->frames.lock); + return NULL; } @@ -1121,15 +1159,16 @@ static int msm_cvp_session_add_smem(struct msm_cvp_inst *inst, smem2 = inst->dma_cache.entries[i]; msm_cvp_unmap_smem(inst, smem2, "unmap cpu"); msm_cvp_smem_put_dma_buf(smem2->dma_buf); - kmem_cache_free(cvp_driver->smem_cache, smem2); + cvp_kmem_cache_free(&cvp_driver->smem_cache, smem2); inst->dma_cache.entries[i] = smem; smem->bitmap_index = i; SET_USE_BITMAP(i, inst); } else { dprintk(CVP_WARN, - "%s: reached limit, fallback to frame mapping list\n" + "%s: reached limit, fallback to buf mapping list\n" , __func__); + atomic_inc(&smem->refcount); mutex_unlock(&inst->dma_cache.lock); return -ENOMEM; } @@ -1163,7 +1202,7 @@ static struct msm_cvp_smem *msm_cvp_session_get_smem(struct msm_cvp_inst *inst, } if (is_persist) { - smem = kmem_cache_zalloc(cvp_driver->smem_cache, GFP_KERNEL); + smem = cvp_kmem_cache_zalloc(&cvp_driver->smem_cache, GFP_KERNEL); if (!smem) return NULL; @@ -1171,6 +1210,7 @@ static struct msm_cvp_smem *msm_cvp_session_get_smem(struct msm_cvp_inst *inst, smem->bitmap_index = MAX_DMABUF_NUMS; smem->pkt_type = pkt_type; smem->flags |= SMEM_PERSIST; + smem->fd = buf->fd; atomic_inc(&smem->refcount); rc = msm_cvp_map_smem(inst, smem, "map cpu"); if (rc) @@ -1187,20 +1227,22 @@ static struct msm_cvp_smem *msm_cvp_session_get_smem(struct msm_cvp_inst *inst, smem = msm_cvp_session_find_smem(inst, dma_buf, pkt_type); if (!smem) { found = 0; - smem = kmem_cache_zalloc(cvp_driver->smem_cache, GFP_KERNEL); + smem = cvp_kmem_cache_zalloc(&cvp_driver->smem_cache, GFP_KERNEL); if (!smem) return NULL; smem->dma_buf = dma_buf; smem->bitmap_index = MAX_DMABUF_NUMS; smem->pkt_type = pkt_type; + smem->fd = buf->fd; rc = msm_cvp_map_smem(inst, smem, "map cpu"); if (rc) goto exit; if (!IS_CVP_BUF_VALID(buf, smem)) { dprintk(CVP_ERR, - "%s: invalid offset %d or size %d new entry\n", - __func__, buf->offset, buf->size); + "%s: invalid buf %d %d fd %d dma 0x%llx %s %d type %#x\n", + __func__, buf->offset, buf->size, buf->fd, + dma_buf, dma_buf->name, dma_buf->size, pkt_type); goto exit2; } rc = msm_cvp_session_add_smem(inst, smem); @@ -1210,7 +1252,7 @@ static struct msm_cvp_smem *msm_cvp_session_get_smem(struct msm_cvp_inst *inst, } if (!IS_CVP_BUF_VALID(buf, smem)) { - dprintk(CVP_ERR, "%s: invalid offset %d or size %d\n", + dprintk(CVP_ERR, "%s: invalid offset %d or size %d found\n", __func__, buf->offset, buf->size); if (found) { mutex_lock(&inst->dma_cache.lock); @@ -1221,13 +1263,16 @@ static struct msm_cvp_smem *msm_cvp_session_get_smem(struct msm_cvp_inst *inst, goto exit2; } + if (smem->fd != buf->fd) + dprintk(CVP_ERR, "%s Failed fd check\n", __func__); + return smem; exit2: msm_cvp_unmap_smem(inst, smem, "unmap cpu"); exit: msm_cvp_smem_put_dma_buf(dma_buf); - kmem_cache_free(cvp_driver->smem_cache, smem); + cvp_kmem_cache_free(&cvp_driver->smem_cache, smem); smem = NULL; return smem; } @@ -1272,19 +1317,24 @@ static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, dma_buf_put(dma_buf); - pbuf = kmem_cache_zalloc(cvp_driver->buf_cache, GFP_KERNEL); + pbuf = cvp_kmem_cache_zalloc(&cvp_driver->buf_cache, GFP_KERNEL); if (!pbuf) { dprintk(CVP_ERR, "%s failed to allocate kmem obj\n", __func__); return 0; } - smem = msm_cvp_session_get_smem(inst, buf, true, pkt_type); + if (is_params_pkt(pkt_type)) + smem = msm_cvp_session_get_smem(inst, buf, false, pkt_type); + else + smem = msm_cvp_session_get_smem(inst, buf, true, pkt_type); + if (!smem) goto exit; smem->pkt_type = pkt_type; smem->buf_idx = buf_idx; + smem->fd = buf->fd; pbuf->smem = smem; pbuf->fd = buf->fd; pbuf->size = buf->size; @@ -1302,7 +1352,7 @@ static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, return iova; exit: - kmem_cache_free(cvp_driver->buf_cache, pbuf); + cvp_kmem_cache_free(&cvp_driver->buf_cache, pbuf); return 0; } @@ -1367,24 +1417,26 @@ static void msm_cvp_unmap_frame_buf(struct msm_cvp_inst *inst, if (smem->bitmap_index >= MAX_DMABUF_NUMS) { /* smem not in dmamap cache */ - msm_cvp_unmap_smem(inst, smem, "unmap cpu"); - dma_heap_buffer_free(smem->dma_buf); - smem->pkt_type = smem->buf_idx = 0; - kmem_cache_free(cvp_driver->smem_cache, smem); - buf->smem = NULL; + if (atomic_dec_and_test(&smem->refcount)) { + msm_cvp_unmap_smem(inst, smem, "unmap cpu"); + dma_heap_buffer_free(smem->dma_buf); + smem->buf_idx |= 0xdead0000; + cvp_kmem_cache_free(&cvp_driver->smem_cache, smem); + buf->smem = NULL; + } } else { mutex_lock(&inst->dma_cache.lock); if (atomic_dec_and_test(&smem->refcount)) { CLEAR_USE_BITMAP(smem->bitmap_index, inst); print_smem(CVP_MEM, "Map dereference", inst, smem); - smem->pkt_type = smem->buf_idx = 0; + smem->buf_idx |= 0x10000000; } mutex_unlock(&inst->dma_cache.lock); } } - kmem_cache_free(cvp_driver->frame_cache, frame); + cvp_kmem_cache_free(&cvp_driver->frame_cache, frame); } void msm_cvp_unmap_frame(struct msm_cvp_inst *inst, u64 ktid) @@ -1470,6 +1522,12 @@ int msm_cvp_map_frame(struct msm_cvp_inst *inst, u64 ktid; struct msm_cvp_frame *frame; struct cvp_hfi_cmd_session_hdr *cmd_hdr; + struct msm_cvp_inst *instance; + struct msm_cvp_core *core = NULL; + + core = get_cvp_core(MSM_CORE_CVP); + if (!core) + return -EINVAL; if (!offset || !buf_num) return 0; @@ -1479,7 +1537,7 @@ int msm_cvp_map_frame(struct msm_cvp_inst *inst, ktid &= (FENCE_BIT - 1); cmd_hdr->client_data.kdata = ktid; - frame = kmem_cache_zalloc(cvp_driver->frame_cache, GFP_KERNEL); + frame = cvp_kmem_cache_zalloc(&cvp_driver->frame_cache, GFP_KERNEL); if (!frame) return -ENOMEM; @@ -1499,7 +1557,12 @@ int msm_cvp_map_frame(struct msm_cvp_inst *inst, dprintk(CVP_ERR, "%s: buf %d register failed.\n", __func__, i); - + dprintk(CVP_ERR, "smem_leak_count %d\n", core->smem_leak_count); + mutex_lock(&core->lock); + list_for_each_entry(instance, &core->instances, list) { + msm_cvp_print_inst_bufs(instance, false); + } + mutex_unlock(&core->lock); msm_cvp_unmap_frame_buf(inst, frame); return -EINVAL; } @@ -1522,6 +1585,7 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) struct msm_cvp_smem *smem; struct cvp_hal_session *session; struct eva_kmd_buffer buf; + struct list_head *ptr, *next; session = (struct cvp_hal_session *)inst->session; @@ -1532,6 +1596,48 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) } mutex_unlock(&inst->frames.lock); + mutex_lock(&inst->persistbufs.lock); + list_for_each_safe(ptr, next, &inst->persistbufs.list) { + cbuf = list_entry(ptr, struct cvp_internal_buf, list); + smem = cbuf->smem; + if (!smem) { + dprintk(CVP_ERR, "%s invalid persist smem\n", __func__); + mutex_unlock(&inst->persistbufs.lock); + return -EINVAL; + } + if (cbuf->ownership != DRIVER) { + dprintk(CVP_MEM, + "%s: %x : fd %d %pK size %d", + "free user persistent", hash32_ptr(inst->session), cbuf->fd, + smem->dma_buf, cbuf->size); + list_del(&cbuf->list); + if (smem->bitmap_index >= MAX_DMABUF_NUMS) { + /* + * don't care refcount, has to remove mapping + * this is user persistent buffer + */ + if (smem->device_addr) { + msm_cvp_unmap_smem(inst, smem, + "unmap persist"); + msm_cvp_smem_put_dma_buf( + cbuf->smem->dma_buf); + smem->device_addr = 0; + } + cvp_kmem_cache_free(&cvp_driver->smem_cache, smem); + cbuf->smem = NULL; + cvp_kmem_cache_free(&cvp_driver->buf_cache, cbuf); + } else { + /* + * DMM_PARAMS and WAP_NCC_PARAMS cases + * Leave dma_cache cleanup to unmap + */ + cbuf->smem = NULL; + cvp_kmem_cache_free(&cvp_driver->buf_cache, cbuf); + } + } + } + mutex_unlock(&inst->persistbufs.lock); + mutex_lock(&inst->dma_cache.lock); for (i = 0; i < inst->dma_cache.nr; i++) { smem = inst->dma_cache.entries[i]; @@ -1542,7 +1648,7 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) } msm_cvp_unmap_smem(inst, smem, "unmap cpu"); msm_cvp_smem_put_dma_buf(smem->dma_buf); - kmem_cache_free(cvp_driver->smem_cache, smem); + cvp_kmem_cache_free(&cvp_driver->smem_cache, smem); inst->dma_cache.entries[i] = NULL; } mutex_unlock(&inst->dma_cache.lock); @@ -1575,7 +1681,7 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) __func__, rc); } list_del(&cbuf->list); - kmem_cache_free(cvp_driver->buf_cache, cbuf); + cvp_kmem_cache_free(&cvp_driver->buf_cache, cbuf); } mutex_unlock(&inst->cvpdspbufs.lock); @@ -1600,9 +1706,10 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) { struct cvp_internal_buf *buf; + struct msm_cvp_frame *frame; struct msm_cvp_core *core; struct inst_snapshot *snap = NULL; - int i; + int i = 0, c = 0; core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); if (log && core->log.snapshot_index < 16) { @@ -1618,15 +1725,26 @@ void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) } dprintk(CVP_ERR, - "---Buffer details for inst: %pK of type: %d---\n", - inst, inst->session_type); + "---Buffer details for inst: %pK %s of type: %d---\n", + inst, inst->proc_name, inst->session_type); + + dprintk(CVP_ERR, "dma_cache entries %d\n", inst->dma_cache.nr); mutex_lock(&inst->dma_cache.lock); - dprintk(CVP_ERR, "dma cache: %d\n", inst->dma_cache.nr); if (inst->dma_cache.nr <= MAX_DMABUF_NUMS) for (i = 0; i < inst->dma_cache.nr; i++) _log_smem(snap, inst, inst->dma_cache.entries[i], log); mutex_unlock(&inst->dma_cache.lock); + i = 0; + dprintk(CVP_ERR, "frame buffer list\n"); + mutex_lock(&inst->frames.lock); + list_for_each_entry(frame, &inst->frames.list, list) { + dprintk(CVP_ERR, "frame no %d tid %llx bufs\n", i++, frame->ktid); + for (c = 0; c < frame->nr; c++) + _log_smem(snap, inst, frame->bufs[c].smem, log); + } + mutex_unlock(&inst->frames.lock); + mutex_lock(&inst->cvpdspbufs.lock); dprintk(CVP_ERR, "dsp buffer list:\n"); list_for_each_entry(buf, &inst->cvpdspbufs.list, list) @@ -1669,13 +1787,13 @@ struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, */ smem_flags |= SMEM_SECURE | SMEM_NON_PIXEL; - buf = kmem_cache_zalloc(cvp_driver->buf_cache, GFP_KERNEL); + buf = cvp_kmem_cache_zalloc(&cvp_driver->buf_cache, GFP_KERNEL); if (!buf) { dprintk(CVP_ERR, "%s Out of memory\n", __func__); goto fail_kzalloc; } - buf->smem = kmem_cache_zalloc(cvp_driver->smem_cache, GFP_KERNEL); + buf->smem = cvp_kmem_cache_zalloc(&cvp_driver->smem_cache, GFP_KERNEL); if (!buf->smem) { dprintk(CVP_ERR, "%s Out of memory\n", __func__); goto fail_kzalloc; @@ -1702,7 +1820,7 @@ struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, return buf; err_no_mem: - kmem_cache_free(cvp_driver->buf_cache, buf); + cvp_kmem_cache_free(&cvp_driver->buf_cache, buf); fail_kzalloc: return NULL; } @@ -1762,25 +1880,18 @@ int cvp_release_arp_buffers(struct msm_cvp_inst *inst) return -EINVAL; } - list_del(&buf->list); - - if (buf->ownership == DRIVER) + if (buf->ownership == DRIVER) { dprintk(CVP_MEM, "%s: %x : fd %d %pK size %d", "free arp", hash32_ptr(inst->session), buf->fd, smem->dma_buf, buf->size); - else - dprintk(CVP_MEM, - "%s: %x : fd %d %pK size %d", - "free user persistent", hash32_ptr(inst->session), buf->fd, - smem->dma_buf, buf->size); - - atomic_dec(&smem->refcount); - msm_cvp_smem_free(smem); - kmem_cache_free(cvp_driver->smem_cache, smem); - - buf->smem = NULL; - kmem_cache_free(cvp_driver->buf_cache, buf); + list_del(&buf->list); + atomic_dec(&smem->refcount); + msm_cvp_smem_free(smem); + cvp_kmem_cache_free(&cvp_driver->smem_cache, smem); + buf->smem = NULL; + cvp_kmem_cache_free(&cvp_driver->buf_cache, buf); + } } mutex_unlock(&inst->persistbufs.lock); return rc; @@ -1821,7 +1932,7 @@ int cvp_allocate_dsp_bufs(struct msm_cvp_inst *inst, } dprintk(CVP_MEM, "%s smem_flags 0x%x\n", __func__, smem_flags); - buf->smem = kmem_cache_zalloc(cvp_driver->smem_cache, GFP_KERNEL); + buf->smem = cvp_kmem_cache_zalloc(&cvp_driver->smem_cache, GFP_KERNEL); if (!buf->smem) { dprintk(CVP_ERR, "%s Out of memory\n", __func__); goto fail_kzalloc_smem_cache; @@ -1846,7 +1957,7 @@ int cvp_allocate_dsp_bufs(struct msm_cvp_inst *inst, return rc; err_no_mem: - kmem_cache_free(cvp_driver->smem_cache, buf->smem); + cvp_kmem_cache_free(&cvp_driver->smem_cache, buf->smem); fail_kzalloc_smem_cache: return rc; } @@ -1880,7 +1991,7 @@ int cvp_release_dsp_buffers(struct msm_cvp_inst *inst, smem->dma_buf->name, buf->size); atomic_dec(&smem->refcount); msm_cvp_smem_free(smem); - kmem_cache_free(cvp_driver->smem_cache, smem); + cvp_kmem_cache_free(&cvp_driver->smem_cache, smem); } else { dprintk(CVP_ERR, "%s: wrong owner %d %x : fd %x %s size %d", diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index c9ccb28fbc..3b83488829 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -77,7 +77,7 @@ struct msm_cvp_smem { u32 flags; u32 pkt_type; u32 buf_idx; - u32 checksum; + u32 fd; struct cvp_dma_mapping_info mapping_info; }; diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 497a12e332..f6ef768357 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -25,6 +25,20 @@ #define NUM_DMM_MAX_FEATURE_POINTS 500 #define CYCLES_MARGIN_IN_POWEROF2 3 +static atomic_t nr_insts; + +void *cvp_kmem_cache_zalloc(struct cvp_kmem_cache *k, gfp_t flags) +{ + atomic_inc(&k->nr_objs); + return kmem_cache_zalloc(k->cache, flags); +} + +void cvp_kmem_cache_free(struct cvp_kmem_cache *k, void *obj) +{ + atomic_dec(&k->nr_objs); + kmem_cache_free(k->cache, obj); +} + int msm_cvp_poll(void *instance, struct file *filp, struct poll_table_struct *wait) { @@ -115,7 +129,7 @@ static void __deinit_session_queue(struct msm_cvp_inst *inst) spin_lock(&inst->session_queue.lock); list_for_each_entry_safe(msg, tmpmsg, &inst->session_queue.msgs, node) { list_del_init(&msg->node); - kmem_cache_free(cvp_driver->msg_cache, msg); + cvp_kmem_cache_free(&cvp_driver->msg_cache, msg); } inst->session_queue.msg_count = 0; inst->session_queue.state = QUEUE_INVALID; @@ -208,6 +222,7 @@ void *msm_cvp_open(int core_id, int session_type, struct task_struct *task) mutex_lock(&core->lock); mutex_lock(&core->clk_lock); list_add_tail(&inst->list, &core->instances); + atomic_inc(&nr_insts); mutex_unlock(&core->clk_lock); mutex_unlock(&core->lock); @@ -255,8 +270,9 @@ static void msm_cvp_clean_sess_queue(struct msm_cvp_inst *inst, struct cvp_session_queue *sq) { struct cvp_session_msg *mptr, *dummy; - u64 ktid; + u64 ktid = 0LL; +check_again: spin_lock(&sq->lock); if (sq->msg_count && sq->state != QUEUE_ACTIVE) { list_for_each_entry_safe(mptr, dummy, &sq->msgs, node) { @@ -264,12 +280,19 @@ static void msm_cvp_clean_sess_queue(struct msm_cvp_inst *inst, if (ktid) { list_del_init(&mptr->node); sq->msg_count--; - msm_cvp_unmap_frame(inst, ktid); - kmem_cache_free(cvp_driver->msg_cache, mptr); + break; } } } spin_unlock(&sq->lock); + + if (ktid) { + msm_cvp_unmap_frame(inst, ktid); + cvp_kmem_cache_free(&cvp_driver->msg_cache, mptr); + mptr = NULL; + ktid = 0LL; + goto check_again; + } } static void msm_cvp_cleanup_instance(struct msm_cvp_inst *inst) @@ -366,6 +389,7 @@ int msm_cvp_destroy(struct msm_cvp_inst *inst) mutex_lock(&core->clk_lock); /* inst->list lives in core->instances */ list_del(&inst->list); + atomic_dec(&nr_insts); mutex_unlock(&core->clk_lock); mutex_unlock(&core->lock); @@ -389,11 +413,23 @@ int msm_cvp_destroy(struct msm_cvp_inst *inst) pr_info( CVP_DBG_TAG - "%s closed cvp instance: %pK session_id = %d type %d\n", - "sess", inst->proc_name, inst, hash32_ptr(inst->session), - inst->session_type); + "closed cvp instance: %pK session_id = %d type %d %d\n", + inst->proc_name, inst, hash32_ptr(inst->session), + inst->session_type, core->smem_leak_count); inst->session = (void *)0xdeadbeef; + if (atomic_read(&inst->smem_count) > 0) { + dprintk(CVP_WARN, "Session closed with %d unmapped smems\n", + atomic_read(&inst->smem_count)); + core->smem_leak_count += atomic_read(&inst->smem_count); + } kfree(inst); + dprintk(CVP_SESS, + "sys-stat: nr_insts %d msgs %d, frames %d, bufs %d, smems %d\n", + atomic_read(&nr_insts), + atomic_read(&cvp_driver->msg_cache.nr_objs), + atomic_read(&cvp_driver->frame_cache.nr_objs), + atomic_read(&cvp_driver->buf_cache.nr_objs), + atomic_read(&cvp_driver->smem_cache.nr_objs)); return 0; } diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 940f5b027e..e46d49ba90 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -12,6 +12,7 @@ #include "cvp_hfi.h" #include "cvp_dump.h" +static atomic_t nr_maps; struct cvp_dsp_apps gfa_cv; static int hlosVM[HLOS_VM_NUM] = {VMID_HLOS}; static int dspVM[DSP_VM_NUM] = {VMID_HLOS, VMID_CDSP_Q6}; @@ -21,6 +22,8 @@ static int hlosVMperm[HLOS_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC }; static int cvp_reinit_dsp(void); +static void cvp_remove_dsp_sessions(void); + static int __fastrpc_driver_register(struct fastrpc_driver *driver) { #ifdef CVP_FASTRPC_ENABLED @@ -254,7 +257,7 @@ static int delete_dsp_session(struct msm_cvp_inst *inst, list_del(&buf->list); - kmem_cache_free(cvp_driver->buf_cache, buf); + cvp_kmem_cache_free(&cvp_driver->buf_cache, buf); } } @@ -314,12 +317,56 @@ static void eva_fastrpc_driver_release_name( DRIVER_NAME_AVAILABLE; } -static struct cvp_dsp_fastrpc_driver_entry *dequeue_frpc_node(void) +/* The function may not return for up to 50ms */ +static bool dequeue_frpc_node(struct cvp_dsp_fastrpc_driver_entry *node) { struct cvp_dsp_apps *me = &gfa_cv; struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; struct list_head *ptr = NULL, *next = NULL; + u32 refcount, max_count = 10; + bool rc = false; + if (!node) + return rc; + +search_again: + ptr = &me->fastrpc_driver_list.list; + mutex_lock(&me->fastrpc_driver_list.lock); + list_for_each_safe(ptr, next, &me->fastrpc_driver_list.list) { + frpc_node = list_entry(ptr, + struct cvp_dsp_fastrpc_driver_entry, list); + + if (frpc_node == node) { + refcount = atomic_read(&frpc_node->refcount); + if (refcount > 0) { + mutex_unlock(&me->fastrpc_driver_list.lock); + usleep_range(5000, 10000); + if (max_count-- == 0) { + dprintk(CVP_ERR, "%s timeout\n", + __func__); + goto exit; + } + goto search_again; + } + list_del(&frpc_node->list); + rc = true; + break; + } + } + mutex_unlock(&me->fastrpc_driver_list.lock); +exit: + return rc; +} + +/* The function may not return for up to 50ms */ +static struct cvp_dsp_fastrpc_driver_entry *pop_frpc_node(void) +{ + struct cvp_dsp_apps *me = &gfa_cv; + struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; + struct list_head *ptr = NULL, *next = NULL; + u32 refcount, max_count = 10; + +search_again: ptr = &me->fastrpc_driver_list.list; mutex_lock(&me->fastrpc_driver_list.lock); list_for_each_safe(ptr, next, &me->fastrpc_driver_list.list) { @@ -327,20 +374,31 @@ static struct cvp_dsp_fastrpc_driver_entry *dequeue_frpc_node(void) struct cvp_dsp_fastrpc_driver_entry, list); if (frpc_node) { + refcount = atomic_read(&frpc_node->refcount); + if (refcount > 0) { + mutex_unlock(&me->fastrpc_driver_list.lock); + usleep_range(5000, 10000); + if (max_count-- == 0) { + dprintk(CVP_ERR, "%s timeout\n", + __func__); + frpc_node = NULL; + goto exit; + } + goto search_again; + } list_del(&frpc_node->list); break; } } + mutex_unlock(&me->fastrpc_driver_list.lock); +exit: return frpc_node; } static void cvp_dsp_rpmsg_remove(struct rpmsg_device *rpdev) { struct cvp_dsp_apps *me = &gfa_cv; - struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; - struct msm_cvp_inst *inst = NULL; - struct list_head *s = NULL, *next_s = NULL; u32 max_num_retries = 100; dprintk(CVP_WARN, "%s: CDSP SSR triggered\n", __func__); @@ -369,38 +427,10 @@ static void cvp_dsp_rpmsg_remove(struct rpmsg_device *rpdev) mutex_unlock(&me->tx_lock); mutex_unlock(&me->rx_lock); - while ((frpc_node = dequeue_frpc_node())) { - s = &frpc_node->dsp_sessions.list; - list_for_each_safe(s, next_s, - &frpc_node->dsp_sessions.list) { - inst = list_entry(s, struct msm_cvp_inst, - dsp_list); - if (inst) { - delete_dsp_session(inst, frpc_node); - mutex_lock(&frpc_node->dsp_sessions.lock); - list_del(&inst->dsp_list); - frpc_node->session_cnt--; - mutex_unlock(&frpc_node->dsp_sessions.lock); - } - } + cvp_remove_dsp_sessions(); - dprintk(CVP_DSP, "%s DEINIT_MSM_CVP_LIST 0x%x\n", - __func__, frpc_node->dsp_sessions); - DEINIT_MSM_CVP_LIST(&frpc_node->dsp_sessions); - dprintk(CVP_DSP, "%s list_del fastrpc node 0x%x\n", - __func__, frpc_node); - __fastrpc_driver_unregister( - &frpc_node->cvp_fastrpc_driver); - dprintk(CVP_DSP, - "%s Unregistered fastrpc handle 0x%x\n", - __func__, frpc_node->handle); - mutex_lock(&me->driver_name_lock); - eva_fastrpc_driver_release_name(frpc_node); - mutex_unlock(&me->driver_name_lock); - kfree(frpc_node); - frpc_node = NULL; - } - dprintk(CVP_WARN, "%s: CDSP SSR handled\n", __func__); + dprintk(CVP_WARN, "%s: CDSP SSR handled nr_maps %d\n", __func__, + atomic_read(&nr_maps)); } static int cvp_dsp_rpmsg_callback(struct rpmsg_device *rpdev, @@ -496,6 +526,7 @@ retry: } me->state = DSP_SUSPEND; + dprintk(CVP_DSP, "DSP suspended, nr_map: %d\n", atomic_read(&nr_maps)); goto exit; fatal_exit: @@ -525,44 +556,45 @@ int cvp_dsp_resume(uint32_t session_flag) return rc; } -static void cvp_remove_dsp_process_sess( - struct cvp_dsp_fastrpc_driver_entry *frpc_node) -{ - struct msm_cvp_inst *inst = NULL; - struct list_head *s = NULL, *next_s = NULL; - - s = &frpc_node->dsp_sessions.list; - list_for_each_safe(s, next_s, &frpc_node->dsp_sessions.list) { - inst = list_entry(s, struct msm_cvp_inst, dsp_list); - delete_dsp_session(inst, frpc_node); - } -} - static void cvp_remove_dsp_sessions(void) { struct cvp_dsp_apps *me = &gfa_cv; struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; - struct list_head *ptr = NULL, *next = NULL; + struct msm_cvp_inst *inst = NULL; + struct list_head *s = NULL, *next_s = NULL; - dprintk(CVP_WARN, "%s: EVA SSR triggered, clean cdsp eva sessions\n", - __func__); - - ptr = &me->fastrpc_driver_list.list; - mutex_lock(&me->fastrpc_driver_list.lock); - list_for_each_safe(ptr, next, &me->fastrpc_driver_list.list) { - frpc_node = list_entry(ptr, - struct cvp_dsp_fastrpc_driver_entry, list); - if (frpc_node) { - cvp_remove_dsp_process_sess(frpc_node); - list_del(&frpc_node->list); - __fastrpc_driver_unregister(&frpc_node->cvp_fastrpc_driver); - mutex_lock(&me->driver_name_lock); - eva_fastrpc_driver_release_name(frpc_node); - mutex_unlock(&me->driver_name_lock); - kfree(frpc_node); + while ((frpc_node = pop_frpc_node())) { + s = &frpc_node->dsp_sessions.list; + list_for_each_safe(s, next_s, + &frpc_node->dsp_sessions.list) { + inst = list_entry(s, struct msm_cvp_inst, + dsp_list); + if (inst) { + delete_dsp_session(inst, frpc_node); + mutex_lock(&frpc_node->dsp_sessions.lock); + list_del(&inst->dsp_list); + frpc_node->session_cnt--; + mutex_unlock(&frpc_node->dsp_sessions.lock); + } } + + dprintk(CVP_DSP, "%s DEINIT_MSM_CVP_LIST 0x%x\n", + __func__, frpc_node->dsp_sessions); + DEINIT_MSM_CVP_LIST(&frpc_node->dsp_sessions); + dprintk(CVP_DSP, "%s list_del fastrpc node 0x%x\n", + __func__, frpc_node); + __fastrpc_driver_unregister( + &frpc_node->cvp_fastrpc_driver); + dprintk(CVP_DSP, + "%s Unregistered fastrpc handle 0x%x\n", + __func__, frpc_node->handle); + mutex_lock(&me->driver_name_lock); + eva_fastrpc_driver_release_name(frpc_node); + mutex_unlock(&me->driver_name_lock); + kfree(frpc_node); + frpc_node = NULL; } - mutex_unlock(&me->fastrpc_driver_list.lock); + dprintk(CVP_WARN, "%s: EVA SSR handled for CDSP\n", __func__); } @@ -845,6 +877,9 @@ static int __reinit_dsp(void) */ cvp_remove_dsp_sessions(); + dprintk(CVP_WARN, "Reinit EVA DSP interface: nr_map %d\n", + atomic_read(&nr_maps)); + /* Resend HFI queue */ mutex_lock(&me->tx_lock); if (!device->dsp_iface_q_table.align_virtual_addr) { @@ -900,7 +935,13 @@ static int cvp_reinit_dsp(void) return rc; } -static struct cvp_dsp_fastrpc_driver_entry *cvp_find_fastrpc_node_with_handle( +static void cvp_put_fastrpc_node(struct cvp_dsp_fastrpc_driver_entry *node) +{ + if (node && (atomic_read(&node->refcount) > 0)) + atomic_dec(&node->refcount); +} + +static struct cvp_dsp_fastrpc_driver_entry *cvp_get_fastrpc_node_with_handle( uint32_t handle) { struct cvp_dsp_apps *me = &gfa_cv; @@ -913,6 +954,7 @@ static struct cvp_dsp_fastrpc_driver_entry *cvp_find_fastrpc_node_with_handle( struct cvp_dsp_fastrpc_driver_entry, list); if (handle == tmp_node->handle) { frpc_node = tmp_node; + atomic_inc(&frpc_node->refcount); dprintk(CVP_DSP, "Find tmp_node with handle 0x%x\n", handle); break; @@ -934,11 +976,12 @@ static int cvp_fastrpc_probe(struct fastrpc_device *rpc_dev) dprintk(CVP_DSP, "%s fastrpc probe handle 0x%x\n", __func__, rpc_dev->handle); - frpc_node = cvp_find_fastrpc_node_with_handle(rpc_dev->handle); + frpc_node = cvp_get_fastrpc_node_with_handle(rpc_dev->handle); if (frpc_node) { frpc_node->cvp_fastrpc_device = rpc_dev; // static structure with signal and pid complete(&frpc_node->fastrpc_probe_completion); + cvp_put_fastrpc_node(frpc_node); } return 0; @@ -992,6 +1035,7 @@ static int eva_fastrpc_dev_map_dma(struct fastrpc_device *frpc_device, } buf->fd = (s32)frpc_map_buf.v_dsp_addr; *v_dsp_addr = frpc_map_buf.v_dsp_addr; + atomic_inc(&nr_maps); } else { dprintk(CVP_DSP, "%s Buffer not mapped to dsp\n", __func__); buf->fd = 0; @@ -1016,6 +1060,8 @@ static int eva_fastrpc_dev_unmap_dma(struct fastrpc_device *frpc_device, __func__, rc); return rc; } + if (atomic_read(&nr_maps) > 0) + atomic_dec(&nr_maps); } else { dprintk(CVP_DSP, "%s buffer not mapped to dsp\n", __func__); } @@ -1043,7 +1089,7 @@ int cvp_dsp_fastrpc_unmap(uint32_t process_id, struct cvp_internal_buf *buf) struct fastrpc_device *frpc_device = NULL; int rc = 0; - frpc_node = cvp_find_fastrpc_node_with_handle(process_id); + frpc_node = cvp_get_fastrpc_node_with_handle(process_id); if (!frpc_node) { dprintk(CVP_ERR, "%s no frpc node for process id %d\n", __func__, process_id); @@ -1051,13 +1097,11 @@ int cvp_dsp_fastrpc_unmap(uint32_t process_id, struct cvp_internal_buf *buf) } frpc_device = frpc_node->cvp_fastrpc_device; rc = eva_fastrpc_dev_unmap_dma(frpc_device, buf); - if (rc) { - dprintk(CVP_ERR, - "%s Fail to unmap buffer 0x%x\n", + if (rc) + dprintk(CVP_ERR, "%s Fail to unmap buffer 0x%x\n", __func__, rc); - return rc; - } + cvp_put_fastrpc_node(frpc_node); return rc; } @@ -1068,7 +1112,7 @@ int cvp_dsp_del_sess(uint32_t process_id, struct msm_cvp_inst *inst) struct msm_cvp_inst *sess; bool found = false; - frpc_node = cvp_find_fastrpc_node_with_handle(process_id); + frpc_node = cvp_get_fastrpc_node_with_handle(process_id); if (!frpc_node) { dprintk(CVP_ERR, "%s no frpc node for process id %d\n", __func__, process_id); @@ -1091,6 +1135,7 @@ int cvp_dsp_del_sess(uint32_t process_id, struct msm_cvp_inst *inst) mutex_unlock(&frpc_node->dsp_sessions.lock); + cvp_put_fastrpc_node(frpc_node); return 0; } @@ -1101,9 +1146,9 @@ static int eva_fastrpc_driver_register(uint32_t handle) struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; bool skip_deregister = true; - dprintk(CVP_DSP, "%s -> cvp_find_fastrpc_node_with_handle pid 0x%x\n", + dprintk(CVP_DSP, "%s -> cvp_get_fastrpc_node_with_handle pid 0x%x\n", __func__, handle); - frpc_node = cvp_find_fastrpc_node_with_handle(handle); + frpc_node = cvp_get_fastrpc_node_with_handle(handle); if (frpc_node == NULL) { dprintk(CVP_DSP, "%s new fastrpc node pid 0x%x\n", @@ -1134,10 +1179,10 @@ static int eva_fastrpc_driver_register(uint32_t handle) init_completion(&frpc_node->fastrpc_probe_completion); mutex_lock(&me->fastrpc_driver_list.lock); - dprintk(CVP_DSP, "Add frpc node 0x%x to list\n", frpc_node); list_add_tail(&frpc_node->list, &me->fastrpc_driver_list.list); - mutex_unlock(&me->fastrpc_driver_list.lock); INIT_MSM_CVP_LIST(&frpc_node->dsp_sessions); + mutex_unlock(&me->fastrpc_driver_list.lock); + dprintk(CVP_DSP, "Add frpc node 0x%x to list\n", frpc_node); /* register fastrpc device to this session */ rc = __fastrpc_driver_register(&frpc_node->cvp_fastrpc_driver); @@ -1160,16 +1205,13 @@ static int eva_fastrpc_driver_register(uint32_t handle) } else { dprintk(CVP_DSP, "%s fastrpc probe hndl %pK pid 0x%x\n", __func__, frpc_node, handle); + cvp_put_fastrpc_node(frpc_node); } return rc; fail_fastrpc_driver_register: - /* remove list if this is the last session */ - mutex_lock(&me->fastrpc_driver_list.lock); - list_del(&frpc_node->list); - mutex_unlock(&me->fastrpc_driver_list.lock); - + dequeue_frpc_node(frpc_node); if (!skip_deregister) __fastrpc_driver_unregister(&frpc_node->cvp_fastrpc_driver); @@ -1187,11 +1229,15 @@ static void eva_fastrpc_driver_unregister(uint32_t handle, bool force_exit) struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; - dprintk(CVP_DSP, "%s Unregister fastrpc driver handle 0x%x, force %d\n", - __func__, handle, (uint32_t)force_exit); + dprintk(CVP_DSP, "%s Unregister fastrpc driver hdl %#x pid %#x, f %d\n", + __func__, handle, dsp2cpu_cmd->pid, (uint32_t)force_exit); + + if (handle != dsp2cpu_cmd->pid) + dprintk(CVP_ERR, "Unregister pid != hndl %#x %#x\n", + handle, dsp2cpu_cmd->pid); /* Foundd fastrpc node */ - frpc_node = cvp_find_fastrpc_node_with_handle(dsp2cpu_cmd->pid); + frpc_node = cvp_get_fastrpc_node_with_handle(handle); if (frpc_node == NULL) { dprintk(CVP_DSP, "%s fastrpc handle 0x%x unregistered\n", @@ -1205,16 +1251,18 @@ static void eva_fastrpc_driver_unregister(uint32_t handle, bool force_exit) DEINIT_MSM_CVP_LIST(&frpc_node->dsp_sessions); - /* remove list if this is the last session */ - mutex_lock(&me->fastrpc_driver_list.lock); - list_del(&frpc_node->list); - mutex_unlock(&me->fastrpc_driver_list.lock); + cvp_put_fastrpc_node(frpc_node); + if (!dequeue_frpc_node(frpc_node)) + /* Don't find the node */ + return; __fastrpc_driver_unregister(&frpc_node->cvp_fastrpc_driver); mutex_lock(&me->driver_name_lock); eva_fastrpc_driver_release_name(frpc_node); mutex_unlock(&me->driver_name_lock); kfree(frpc_node); + } else { + cvp_put_fastrpc_node(frpc_node); } } @@ -1448,9 +1496,11 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) cmd->session_cpu_high = (uint32_t)((inst_handle & HIGH32) >> 32); cmd->session_cpu_low = (uint32_t)(inst_handle & LOW32); - frpc_node = cvp_find_fastrpc_node_with_handle(dsp2cpu_cmd->pid); - if (frpc_node) + frpc_node = cvp_get_fastrpc_node_with_handle(dsp2cpu_cmd->pid); + if (frpc_node) { eva_fastrpc_driver_add_sess(frpc_node, inst); + cvp_put_fastrpc_node(frpc_node); + } inst->task = task; dprintk(CVP_DSP, @@ -1495,7 +1545,7 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->pid); - frpc_node = cvp_find_fastrpc_node_with_handle(dsp2cpu_cmd->pid); + frpc_node = cvp_get_fastrpc_node_with_handle(dsp2cpu_cmd->pid); if (!frpc_node) { dprintk(CVP_ERR, "%s pid 0x%x not registered with fastrpc\n", __func__, dsp2cpu_cmd->pid); @@ -1503,6 +1553,7 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) return; } + cvp_put_fastrpc_node(frpc_node); inst = (struct msm_cvp_inst *)ptr_dsp2cpu( dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->session_cpu_low); @@ -1539,7 +1590,8 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) if (task) put_task_struct(task); - dprintk(CVP_DSP, "%s DSP2CPU_DETELE_SESSION Done\n", __func__); + dprintk(CVP_DSP, "%s DSP2CPU_DETELE_SESSION Done, nr_maps %d\n", + __func__, atomic_read(&nr_maps)); dsp_fail_delete: return; } @@ -1732,7 +1784,7 @@ static void __dsp_cvp_mem_alloc(struct cvp_dsp_cmd_msg *cmd) dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->pid); - frpc_node = cvp_find_fastrpc_node_with_handle(dsp2cpu_cmd->pid); + frpc_node = cvp_get_fastrpc_node_with_handle(dsp2cpu_cmd->pid); if (!frpc_node) { dprintk(CVP_ERR, "%s Failed to find fastrpc node 0x%x\n", __func__, dsp2cpu_cmd->pid); @@ -1744,7 +1796,7 @@ static void __dsp_cvp_mem_alloc(struct cvp_dsp_cmd_msg *cmd) dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->session_cpu_low); - buf = kmem_cache_zalloc(cvp_driver->buf_cache, GFP_KERNEL); + buf = cvp_kmem_cache_zalloc(&cvp_driver->buf_cache, GFP_KERNEL); if (!buf) goto fail_kzalloc_buf; @@ -1779,15 +1831,17 @@ static void __dsp_cvp_mem_alloc(struct cvp_dsp_cmd_msg *cmd) __func__, cmd->sbuf.size, cmd->sbuf.iova, cmd->sbuf.v_dsp_addr); + cvp_put_fastrpc_node(frpc_node); return; fail_fastrpc_dev_map_dma: cvp_release_dsp_buffers(inst, buf); fail_allocate_dsp_buf: - kmem_cache_free(cvp_driver->buf_cache, buf); + cvp_kmem_cache_free(&cvp_driver->buf_cache, buf); fail_kzalloc_buf: fail_fastrpc_node: cmd->ret = -1; + cvp_put_fastrpc_node(frpc_node); return; } @@ -1824,7 +1878,7 @@ static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) return; } - frpc_node = cvp_find_fastrpc_node_with_handle(dsp2cpu_cmd->pid); + frpc_node = cvp_get_fastrpc_node_with_handle(dsp2cpu_cmd->pid); if (!frpc_node) { dprintk(CVP_ERR, "%s Failed to find fastrpc node 0x%x\n", __func__, dsp2cpu_cmd->pid); @@ -1870,7 +1924,7 @@ static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) list_del(&buf->list); - kmem_cache_free(cvp_driver->buf_cache, buf); + cvp_kmem_cache_free(&cvp_driver->buf_cache, buf); break; } } @@ -1878,6 +1932,7 @@ static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) fail_release_buf: fail_fastrpc_dev_unmap_dma: mutex_unlock(&buf_list->lock); + cvp_put_fastrpc_node(frpc_node); } static int cvp_dsp_thread(void *data) diff --git a/msm/eva/msm_cvp_dsp.h b/msm/eva/msm_cvp_dsp.h index f0cb9708cd..80558f31d4 100644 --- a/msm/eva/msm_cvp_dsp.h +++ b/msm/eva/msm_cvp_dsp.h @@ -7,6 +7,7 @@ #define MSM_CVP_DSP_H #include +#include #include "msm_cvp_debug.h" #include "cvp_core_hfi.h" @@ -181,6 +182,7 @@ struct cvp_dsp_fastrpc_driver_entry { uint32_t handle; uint32_t session_cnt; uint32_t driver_name_idx; + atomic_t refcount; struct fastrpc_driver cvp_fastrpc_driver; struct fastrpc_device *cvp_fastrpc_device; struct completion fastrpc_probe_completion; diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index 968a206f06..101f48da58 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -141,6 +141,11 @@ struct msm_cvp_platform_data { struct msm_cvp_qos_setting *noc_qos; }; +struct cvp_kmem_cache { + struct kmem_cache *cache; + atomic_t nr_objs; +}; + struct msm_cvp_drv { struct mutex lock; struct list_head cores; @@ -148,10 +153,10 @@ struct msm_cvp_drv { struct dentry *debugfs_root; int thermal_level; u32 sku_version; - struct kmem_cache *msg_cache; - struct kmem_cache *frame_cache; - struct kmem_cache *buf_cache; - struct kmem_cache *smem_cache; + struct cvp_kmem_cache msg_cache; + struct cvp_kmem_cache frame_cache; + struct cvp_kmem_cache buf_cache; + struct cvp_kmem_cache smem_cache; char fw_version[CVP_VERSION_LENGTH]; }; @@ -370,6 +375,7 @@ struct msm_cvp_core { u32 smmu_fault_count; u32 last_fault_addr; u32 ssr_count; + u32 smem_leak_count; bool trigger_ssr; unsigned long curr_freq; unsigned long orig_core_sum; @@ -386,6 +392,7 @@ struct msm_cvp_inst { enum session_type session_type; u32 process_id; struct task_struct *task; + atomic_t smem_count; struct cvp_session_queue session_queue; struct cvp_session_queue session_queue_fence; struct cvp_session_event event_handler; @@ -432,4 +439,6 @@ void msm_cvp_ssr_handler(struct work_struct *work); */ int msm_cvp_destroy(struct msm_cvp_inst *inst); void *cvp_get_drv_data(struct device *dev); +void *cvp_kmem_cache_zalloc(struct cvp_kmem_cache *k, gfp_t flags); +void cvp_kmem_cache_free(struct cvp_kmem_cache *k, void *obj); #endif From 991125b3b11d8853459e46383b919518da3af018 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 28 Sep 2022 18:27:35 -0700 Subject: [PATCH 136/317] msm: eva: Enable Lanai compiling EVA Kernel driver. Change-Id: Ie415075a05707a20d9eac1e478a2f18c741b3446 Signed-off-by: George Shen --- msm/Kbuild | 9 +++++ msm/eva/cvp.c | 5 +-- msm/eva/cvp_comm_def.h | 7 ++++ msm/eva/cvp_hfi_io.h | 3 +- msm/eva/cvp_smem.c | 20 ++++++----- msm/eva/msm_cvp.c | 1 - msm/eva/msm_cvp_buf.c | 16 ++++++--- msm/eva/msm_cvp_common.c | 8 +++++ msm/eva/msm_cvp_debug.c | 6 ++-- msm/eva/msm_cvp_dsp.c | 15 ++++++--- msm/eva/msm_cvp_dsp.h | 24 ++++++++++++++ msm/eva/msm_cvp_internal.h | 1 - msm/eva/msm_cvp_platform.c | 66 +++++++++++++++++++++++++++++++++++++ msm/eva/msm_cvp_res_parse.c | 12 +++++-- msm/eva/msm_cvp_synx.h | 11 +++++++ msm/eva/vm/cvp_vm_main.c | 8 ++++- 16 files changed, 182 insertions(+), 30 deletions(-) diff --git a/msm/Kbuild b/msm/Kbuild index ad3949ec6d..86670fb757 100644 --- a/msm/Kbuild +++ b/msm/Kbuild @@ -28,6 +28,15 @@ KBUILD_CPPFLAGS += -DCONFIG_EVA_KALAMA=1 ccflags-y += -DCONFIG_EVA_KALAMA=1 endif +ifeq ($(CONFIG_ARCH_PINEAPPLE), y) +$(info within KBUILD file CONFIG_ARCH_PINEAPPLE = $(CONFIG_ARCH_PINEAPPLE)) +KBUILD_CPPFLAGS += -DCONFIG_EVA_PINEAPPLE=1 +ccflags-y += -DCONFIG_EVA_PINEAPPLE=1 +ccflags-y += -I$(EVA_ROOT)/../synx-kernel/msm/synx/ \ + -I$(EVA_ROOT)/../synx-kernel/include/uapi/synx/media/ +endif + + ifeq ($(CONFIG_EVA_LE), 1) ccflags-y += -DCONFIG_EVA_TVM=1 endif diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index ccfa26a523..06a39aec08 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -263,7 +263,7 @@ static ssize_t boot_store(struct device *dev, return -EINVAL; } - if (val > 0 && booted == 0) { + if (val == 1 && booted == 0) { struct msm_cvp_inst *inst; inst = msm_cvp_open(MSM_CORE_CVP, MSM_CVP_BOOT, current); @@ -278,7 +278,7 @@ static ssize_t boot_store(struct device *dev, "Failed to close cvp instance\n"); return rc; } - } else if ((val == 2) && booted) { + } else if (val == 2) { struct msm_cvp_inst *inst; inst = msm_cvp_open(MSM_CORE_CVP, MSM_CVP_USER, current); @@ -650,3 +650,4 @@ module_exit(msm_cvp_exit); MODULE_SOFTDEP("pre: msm-mmrm"); MODULE_LICENSE("GPL v2"); +MODULE_IMPORT_NS(DMA_BUF); diff --git a/msm/eva/cvp_comm_def.h b/msm/eva/cvp_comm_def.h index 37e204c59c..97fe51b7ce 100644 --- a/msm/eva/cvp_comm_def.h +++ b/msm/eva/cvp_comm_def.h @@ -28,9 +28,16 @@ enum queue_state { #else /* LA target starts here */ +#ifdef CONFIG_EVA_KALAMA #define CVP_SYNX_ENABLED 1 #define CVP_MMRM_ENABLED 1 #define CVP_FASTRPC_ENABLED 1 +#endif /* End of CONFIG_EVA_KALAMA */ + +#ifdef CONFIG_EVA_PINEAPPLE +#define CVP_MMRM_ENABLED 1 +#endif /* End of CONFIG_EVA_PINEAPPLE */ + #ifdef CONFIG_EVA_WAIPIO #define CVP_MINIDUMP_ENABLED 1 diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index 567b79c29e..6e3c39fb3d 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -253,7 +253,6 @@ #define CVP_CC_MVS1_GDSCR (CVP_CC_BASE_OFFS + 0xCC) #define CVP_CC_MVS1_CBCR (CVP_CC_BASE_OFFS + 0xE0) -#ifdef CONFIG_EVA_KALAMA #define CVP_GCC_VIDEO_AXI1_CBCR (0x22024) -#endif /*End of CONFIG_EVA_KALAMA */ + #endif diff --git a/msm/eva/cvp_smem.c b/msm/eva/cvp_smem.c index 173c0fbbca..d7f90009f3 100644 --- a/msm/eva/cvp_smem.c +++ b/msm/eva/cvp_smem.c @@ -22,10 +22,11 @@ static void * __cvp_dma_buf_vmap(struct dma_buf *dbuf) { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 13, 0)) - return dma_buf_vmap(dbuf); -#else +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0)) struct dma_buf_map map; +#else + struct iosys_map map; +#endif void *dma_map; int err; @@ -35,22 +36,23 @@ static void * __cvp_dma_buf_vmap(struct dma_buf *dbuf) dprintk(CVP_ERR, "map to kvaddr failed\n"); return dma_map; -#endif } static void __cvp_dma_buf_vunmap(struct dma_buf *dbuf, void *vaddr) { -#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 13, 0)) - dma_buf_vunmap(dbuf, vaddr); -#else +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0)) struct dma_buf_map map = { \ .vaddr = vaddr, \ .is_iomem = false, \ }; - +#else + struct iosys_map map = { \ + .vaddr = vaddr, \ + .is_iomem = false, \ + }; +#endif if (vaddr) dma_buf_vunmap(dbuf, &map); -#endif } static int msm_dma_get_device_address(struct dma_buf *dbuf, u32 align, diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 076942f309..f7cd073580 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -643,7 +643,6 @@ wait: exit: dprintk(CVP_SYNX, "%s exit\n", current->comm); cvp_put_inst(inst); - do_exit(rc); return rc; } diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index f9540612dd..0ac73dada1 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -16,6 +16,14 @@ #include "msm_cvp_core.h" #include "msm_cvp_dsp.h" +#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0)) +#define eva_buf_map dma_buf_map +#define _buf_map_set_vaddr dma_buf_map_set_vaddr +#else +#define eva_buf_map iosys_map +#define _buf_map_set_vaddr iosys_map_set_vaddr +#endif + #define CLEAR_USE_BITMAP(idx, inst) \ do { \ clear_bit(idx, &inst->dma_cache.usage_bitmap); \ @@ -239,7 +247,7 @@ loop: */ if (file->f_mode & mask) file = NULL; - else if (!get_file_rcu_many(file, refs)) + else if (!get_file_rcu(file)) goto loop; } rcu_read_unlock(); @@ -811,7 +819,7 @@ static int _wncc_map_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, int rc = 0, i; struct cvp_buf_type* wncc_metadata_bufs; struct dma_buf* dmabuf; - struct dma_buf_map map; + struct eva_buf_map map; if (!in_pkt || !wncc_metadata || num_layers < 1 || num_layers > EVA_KMD_WNCC_MAX_LAYERS) { @@ -872,7 +880,7 @@ static int _wncc_unmap_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, int rc = 0, i; struct cvp_buf_type* wncc_metadata_bufs; struct dma_buf* dmabuf; - struct dma_buf_map map; + struct eva_buf_map map; if (!in_pkt || !wncc_metadata || num_layers < 1 || num_layers > EVA_KMD_WNCC_MAX_LAYERS) { @@ -898,7 +906,7 @@ static int _wncc_unmap_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, break; } - dma_buf_map_set_vaddr(&map, wncc_metadata[i]); + _buf_map_set_vaddr(&map, wncc_metadata[i]); dma_buf_vunmap(dmabuf, &map); wncc_metadata[i] = NULL; diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index f9e860a7d2..e0e76dc7bb 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -1207,23 +1207,29 @@ int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state) rc = msm_comm_init_core(inst); if (rc || state <= get_flipped_state(inst->state, state)) break; + /* defined in linux/compiler_attributes.h */ + fallthrough; case MSM_CVP_CORE_INIT_DONE: rc = msm_comm_init_core_done(inst); if (rc || state <= get_flipped_state(inst->state, state)) break; + fallthrough; case MSM_CVP_OPEN: rc = msm_comm_session_init(flipped_state, inst); if (rc || state <= get_flipped_state(inst->state, state)) break; + fallthrough; case MSM_CVP_OPEN_DONE: rc = msm_comm_session_init_done(flipped_state, inst); if (rc || state <= get_flipped_state(inst->state, state)) break; + fallthrough; case MSM_CVP_CLOSE: dprintk(CVP_INFO, "to CVP_CLOSE state\n"); rc = msm_comm_session_close(flipped_state, inst); if (rc || state <= get_flipped_state(inst->state, state)) break; + fallthrough; case MSM_CVP_CLOSE_DONE: dprintk(CVP_INFO, "to CVP_CLOSE_DONE state\n"); rc = wait_for_state(inst, flipped_state, MSM_CVP_CLOSE_DONE, @@ -1231,12 +1237,14 @@ int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state) if (rc || state <= get_flipped_state(inst->state, state)) break; msm_cvp_comm_session_clean(inst); + fallthrough; case MSM_CVP_CORE_UNINIT: case MSM_CVP_CORE_INVALID: dprintk(CVP_INFO, "Sending core uninit\n"); rc = msm_cvp_deinit_core(inst); if (rc || state <= get_flipped_state(inst->state, state)) break; + fallthrough; default: dprintk(CVP_ERR, "State not recognized\n"); rc = -EINVAL; diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 52b866aaed..e88015e7b6 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -12,7 +12,7 @@ #define CREATE_TRACE_POINTS #define MAX_SSR_STRING_LEN 10 -int msm_cvp_debug = CVP_ERR | CVP_WARN | CVP_FW; +int msm_cvp_debug = CVP_ERR | CVP_WARN | CVP_FW | CVP_DBG; EXPORT_SYMBOL(msm_cvp_debug); int msm_cvp_debug_out = CVP_OUT_PRINTK; @@ -20,9 +20,9 @@ EXPORT_SYMBOL(msm_cvp_debug_out); int msm_cvp_fw_debug = 0x18; int msm_cvp_fw_debug_mode = 1; -int msm_cvp_fw_low_power_mode = 1; +int msm_cvp_fw_low_power_mode = 0; /*disable during initial stage*/ bool msm_cvp_fw_coverage = !true; -bool msm_cvp_auto_pil = true; +bool msm_cvp_auto_pil = !true; /*disable during initial stage*/ bool msm_cvp_cacheop_enabled = true; bool msm_cvp_thermal_mitigation_disabled = !true; bool msm_cvp_cacheop_disabled = !true; diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index e46d49ba90..b28efb0b43 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -40,16 +40,14 @@ static void __fastrpc_driver_unregister(struct fastrpc_driver *driver) #endif } +#ifdef CVP_FASTRPC_ENABLED static int __fastrpc_driver_invoke(struct fastrpc_device *dev, enum fastrpc_driver_invoke_nums invoke_num, unsigned long invoke_param) { -#ifdef CVP_FASTRPC_ENABLED return fastrpc_driver_invoke(dev, invoke_num, invoke_param); -#else - return -ENODEV; -#endif } +#endif /* End of CVP_FASTRPC_ENABLED */ static int cvp_dsp_send_cmd(struct cvp_dsp_cmd_msg *cmd, uint32_t len) { @@ -1014,6 +1012,7 @@ static int eva_fastrpc_dev_map_dma(struct fastrpc_device *frpc_device, uint32_t dsp_remote_map, uint64_t *v_dsp_addr) { +#ifdef CVP_FASTRPC_ENABLED struct fastrpc_dev_map_dma frpc_map_buf = {0}; int rc = 0; @@ -1042,11 +1041,15 @@ static int eva_fastrpc_dev_map_dma(struct fastrpc_device *frpc_device, } return rc; +#else + return -ENODEV; +#endif /* End of CVP_FASTRPC_ENABLED */ } static int eva_fastrpc_dev_unmap_dma(struct fastrpc_device *frpc_device, struct cvp_internal_buf *buf) { +#ifdef CVP_FASTRPC_ENABLED struct fastrpc_dev_unmap_dma frpc_unmap_buf = {0}; int rc = 0; @@ -1067,6 +1070,9 @@ static int eva_fastrpc_dev_unmap_dma(struct fastrpc_device *frpc_device, } return rc; +#else + return -ENODEV; +#endif /* End of CVP_FASTRPC_ENABLED */ } static void eva_fastrpc_driver_add_sess( @@ -2072,7 +2078,6 @@ wait_dsp: goto wait_dsp; exit: dprintk(CVP_DBG, "dsp thread exit\n"); - do_exit(rc); return rc; } diff --git a/msm/eva/msm_cvp_dsp.h b/msm/eva/msm_cvp_dsp.h index 80558f31d4..5e0e07d494 100644 --- a/msm/eva/msm_cvp_dsp.h +++ b/msm/eva/msm_cvp_dsp.h @@ -13,7 +13,31 @@ #include #include + +#ifdef CVP_FASTRPC_ENABLED #include +#else +struct fastrpc_device { + int handle; +}; + +enum fastrpc_driver_status { + FASTRPC_CVP_B, +}; + +enum fastrpc_driver_invoke_nums { + FASTRPC_DEV_MAP_DMA = 1, + FASTRPC_DEV_UNMAP_DMA, +}; + +struct fastrpc_driver { + struct device_driver driver; + int handle; + int (*probe)(struct fastrpc_device *dev); + int (*callback)(struct fastrpc_device *dev, + enum fastrpc_driver_status status); +}; +#endif /* End of CVP_FASTRPC_ENABLED */ #define CVP_APPS_DSP_GLINK_GUID "cvp-glink-apps-dsp" #define CVP_APPS_DSP_SMD_GUID "cvp-smd-apps-dsp" diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index 101f48da58..40f05b5878 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -24,7 +24,6 @@ #include #include "cvp_hfi_api.h" #include "cvp_hfi_helper.h" -#include #define MAX_SUPPORTED_INSTANCES 16 #define MAX_DEBUGFS_NAME 50 diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 99112caaef..bb18eff1aa 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -199,6 +199,58 @@ static struct msm_cvp_common_data sm8550_tvm_common_data[] = { } }; +static struct msm_cvp_common_data sm8650_common_data[] = { + { + .key = "qcom,pm-qos-latency-us", + .value = 50, + }, + { + .key = "qcom,sw-power-collapse", + .value = 0, /* Disable during initial stage for Rumi 48 bringup */ + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 0, + }, + { + .key = "qcom,max-secure-instances", + .value = 2, /* + * As per design driver allows 3rd + * instance as well since the secure + * flags were updated later for the + * current instance. Hence total + * secure sessions would be + * max-secure-instances + 1. + */ + }, + { + .key = "qcom,max-ssr-allowed", + .value = 1, /* + * Maxinum number of SSR before BUG_ON + */ + }, + { + .key = "qcom,power-collapse-delay", + .value = 3000, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 2000, + }, + { + .key = "qcom,dsp-resp-timeout", + .value = 1000, + }, + { + .key = "qcom,debug-timeout", + .value = 0, + }, + { + .key = "qcom,dsp-enabled", + .value = 0, /* Disable during initial stage for Rumi 48 bringup */ + } +}; + /* Default UBWC config for LPDDR5 */ static struct msm_cvp_ubwc_config_data kona_ubwc_data[] = { UBWC_CONFIG(1, 1, 1, 0, 0, 0, 8, 32, 16, 0, 0), @@ -253,6 +305,16 @@ static struct msm_cvp_platform_data sm8550_tvm_data = { .vm_id = 2, }; +static struct msm_cvp_platform_data sm8650_data = { + .common_data = sm8650_common_data, + .common_data_length = ARRAY_SIZE(sm8650_common_data), + .sku_version = 0, + .vpu_ver = VPU_VERSION_5, + .ubwc_config = kona_ubwc_data, /*Reuse Kona setting*/ + .noc_qos = &waipio_noc_qos, /*Reuse Waipio setting*/ + .vm_id = 1, +}; + static const struct of_device_id msm_cvp_dt_match[] = { { .compatible = "qcom,waipio-cvp", @@ -266,6 +328,10 @@ static const struct of_device_id msm_cvp_dt_match[] = { .compatible = "qcom,kalama-cvp-tvm", .data = &sm8550_tvm_data, }, + { + .compatible = "qcom,pineapple-cvp", + .data = &sm8650_data, + }, {}, }; diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index f69298a96d..e86936f1d8 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -132,6 +132,12 @@ static int msm_cvp_load_ipcc_regs(struct msm_cvp_platform_resources *res) res->ipcc_reg_base = reg_config[0]; res->ipcc_reg_size = reg_config[1]; + dprintk(CVP_CORE, + "ipcc reg_base = %x, reg_size = %x\n", + res->ipcc_reg_base, + res->ipcc_reg_size + ); + return ret; } @@ -830,8 +836,10 @@ int cvp_read_platform_resources_from_dt( res->register_base = kres ? kres->start : -1; res->register_size = kres ? (kres->end + 1 - kres->start) : -1; - kres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - res->irq = kres ? kres->start : -1; + res->irq = platform_get_irq(pdev, 0); + + dprintk(CVP_CORE, "%s: res->irq:%d \n", + __func__, res->irq); rc = msm_cvp_load_subcache_info(res); if (rc) diff --git a/msm/eva/msm_cvp_synx.h b/msm/eva/msm_cvp_synx.h index b2af60af52..1190c06784 100644 --- a/msm/eva/msm_cvp_synx.h +++ b/msm/eva/msm_cvp_synx.h @@ -10,6 +10,17 @@ #include #include "cvp_comm_def.h" +#ifdef CVP_SYNX_ENABLED +#include +#else +#define SYNX_STATE_SIGNALED_SUCCESS 0 +#define SYNX_STATE_SIGNALED_ERROR 0 +#define SYNX_STATE_SIGNALED_CANCEL 0 +struct synx_session { + u32 client_id; +}; +#endif /* end of CVP_SYNX_ENABLED */ + struct msm_cvp_core; struct cvp_fence_queue { diff --git a/msm/eva/vm/cvp_vm_main.c b/msm/eva/vm/cvp_vm_main.c index 61f98529fa..143630dc8c 100644 --- a/msm/eva/vm/cvp_vm_main.c +++ b/msm/eva/vm/cvp_vm_main.c @@ -51,6 +51,12 @@ struct msm_cvp_vm_manager vm_manager = { static int msm_cvp_vm_start(struct msm_cvp_core *core) { + if (!core || !core->platform_data) { + dprintk(CVP_ERR, "%s: Invalid params %pK %pK\n", + __func__, core, core->platform_data); + return -EINVAL; + } + vm_manager.vm_id = core->platform_data->vm_id; return 0; } @@ -148,7 +154,7 @@ static int msm_cvp_vm_init_reg_and_irq(struct iris_hfi_device *device, rc = request_irq(res->irq, cvp_hfi_isr, IRQF_TRIGGER_HIGH, "msm_cvp", device); if (unlikely(rc)) { - dprintk(CVP_ERR, "() :request_irq failed\n"); + dprintk(CVP_ERR, "%s: request_irq failed rc: %d\n", __func__, rc); goto error_irq_fail; } From 98e4c251f6b7a0b0f03ac6fd0a85dd1843a07fc5 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 5 Oct 2022 22:57:47 -0700 Subject: [PATCH 137/317] msm: eva: Increase f/w boot timeout Add HW fence testing command. Change-Id: I8f0b21dd678b06ace25a42fdbaf365d01b61f580 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 2 +- msm/eva/cvp_hfi.h | 2 ++ msm/eva/msm_cvp_platform.c | 8 ++++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index e545b0f0c2..92ad1a7ddb 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1026,7 +1026,7 @@ static inline int __boot_firmware(struct iris_hfi_device *device) } /* Reduce to 500, 1000 on silicon */ - usleep_range(500, 1000); + usleep_range(50000, 100000); count++; } diff --git a/msm/eva/cvp_hfi.h b/msm/eva/cvp_hfi.h index bdba4ebae3..390eb3989b 100644 --- a/msm/eva/cvp_hfi.h +++ b/msm/eva/cvp_hfi.h @@ -172,6 +172,8 @@ (HFI_CMD_SESSION_CVP_START + 0x080) #define HFI_CMD_SESSION_EVA_DLFL_CONFIG\ (HFI_CMD_SESSION_CVP_START + 0x081) +#define HFI_CMD_SESSION_CVP_SYNX\ + (HFI_CMD_SESSION_CVP_START + 0x086) #define HFI_CMD_SESSION_CVP_ICA_FRAME\ (HFI_CMD_SESSION_CVP_START + 0x100) #define HFI_CMD_SESSION_CVP_ICA_CONFIG\ diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index bb18eff1aa..ae44e53d0f 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -792,6 +792,14 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { .resp = HAL_NO_RESP, .name = "DLFL_CONFIG", }, + [HFI_CMD_SESSION_CVP_SYNX - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_CVP_SYNX, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "SYNX_TEST", + }, }; int get_pkt_index(struct cvp_hal_session_cmd_pkt *hdr) From 7597271ddee9a3ceae5b07781567733aad822399 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Thu, 6 Oct 2022 22:20:51 -0700 Subject: [PATCH 138/317] msm: eva: synx v2 support propagated sync v2 support from 2.0 reference 4162025 Change-Id: I3427657e21e7eda92088d828203a330ba3c86335 Signed-off-by: Yu SI Signed-off-by: George Shen --- include/uapi/eva/media/msm_eva_private.h | 4 + msm/Kbuild | 4 +- msm/eva/cvp_comm_def.h | 1 + msm/eva/cvp_hfi.c | 76 +++++ msm/eva/cvp_hfi_helper.h | 15 + msm/eva/msm_cvp.c | 279 +++++++++++++++---- msm/eva/msm_cvp_buf.c | 1 + msm/eva/msm_cvp_buf.h | 18 ++ msm/eva/msm_cvp_debug.c | 2 + msm/eva/msm_cvp_debug.h | 1 + msm/eva/msm_cvp_internal.h | 4 +- msm/eva/msm_cvp_res_parse.c | 36 +++ msm/eva/msm_cvp_resources.h | 6 + msm/eva/msm_cvp_synx.c | 336 +++++++++++++++++++++-- msm/eva/msm_cvp_synx.h | 9 +- 15 files changed, 694 insertions(+), 98 deletions(-) diff --git a/include/uapi/eva/media/msm_eva_private.h b/include/uapi/eva/media/msm_eva_private.h index 95b84d3c99..2e61a12664 100644 --- a/include/uapi/eva/media/msm_eva_private.h +++ b/include/uapi/eva/media/msm_eva_private.h @@ -238,8 +238,12 @@ struct eva_kmd_hfi_fence_packet { }; struct eva_kmd_fence { +#ifdef CVP_CONFIG_SYNX_V2 + __u32 h_synx; +#else __s32 h_synx; __u32 secure_key; +#endif }; struct eva_kmd_fence_ctrl { diff --git a/msm/Kbuild b/msm/Kbuild index 86670fb757..d11b45c343 100644 --- a/msm/Kbuild +++ b/msm/Kbuild @@ -30,8 +30,8 @@ endif ifeq ($(CONFIG_ARCH_PINEAPPLE), y) $(info within KBUILD file CONFIG_ARCH_PINEAPPLE = $(CONFIG_ARCH_PINEAPPLE)) -KBUILD_CPPFLAGS += -DCONFIG_EVA_PINEAPPLE=1 -ccflags-y += -DCONFIG_EVA_PINEAPPLE=1 +KBUILD_CPPFLAGS += -DCONFIG_EVA_PINEAPPLE=1 -DCVP_CONFIG_SYNX_V2=1 +ccflags-y += -DCONFIG_EVA_PINEAPPLE=1 -DCVP_CONFIG_SYNX_V2=1 ccflags-y += -I$(EVA_ROOT)/../synx-kernel/msm/synx/ \ -I$(EVA_ROOT)/../synx-kernel/include/uapi/synx/media/ endif diff --git a/msm/eva/cvp_comm_def.h b/msm/eva/cvp_comm_def.h index 97fe51b7ce..a798a1b65e 100644 --- a/msm/eva/cvp_comm_def.h +++ b/msm/eva/cvp_comm_def.h @@ -36,6 +36,7 @@ enum queue_state { #ifdef CONFIG_EVA_PINEAPPLE #define CVP_MMRM_ENABLED 1 +#define CVP_CONFIG_SYNX_V2 1 #endif /* End of CONFIG_EVA_PINEAPPLE */ diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 92ad1a7ddb..12ae387c18 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -100,6 +100,8 @@ static void __noc_error_info_iris2(struct iris_hfi_device *device); static int __enable_hw_power_collapse(struct iris_hfi_device *device); static int __power_off_controller(struct iris_hfi_device *device); +static int __hwfence_regs_map(struct iris_hfi_device *device); +static int __hwfence_regs_unmap(struct iris_hfi_device *device); static struct iris_hfi_vpu_ops iris2_ops = { .interrupt_init = interrupt_init_iris2, @@ -136,6 +138,15 @@ static inline bool is_sys_cache_present(struct iris_hfi_device *device) return device->res->sys_cache_present; } +static int cvp_synx_recover(void) +{ +#ifdef CVP_SYNX_ENABLED + return synx_recover(SYNX_CLIENT_EVA_CTX0); +#else + return 0; +#endif /* End of CVP_SYNX_ENABLED */ +} + #define ROW_SIZE 32 int get_hfi_version(void) @@ -1891,6 +1902,60 @@ static int iris_pm_qos_update(void *device) return 0; } +static int __hwfence_regs_map(struct iris_hfi_device *device) +{ + int rc = 0; + struct context_bank_info *cb; + + cb = msm_cvp_smem_get_context_bank(device->res, 0); + if (!cb) { + dprintk(CVP_ERR, "%s: fail to get cb\n", __func__); + return -EINVAL; + } + + rc = iommu_map(cb->domain, device->res->ipclite_iova, + device->res->ipclite_phyaddr, + device->res->ipclite_size, + IOMMU_READ | IOMMU_WRITE); + if (rc) { + dprintk(CVP_ERR, "map ipclite fail %d %#x %#x %#x\n", + rc, device->res->ipclite_iova, + device->res->ipclite_phyaddr, + device->res->ipclite_size); + return rc; + } + rc = iommu_map(cb->domain, device->res->hwmutex_iova, + device->res->hwmutex_phyaddr, + device->res->hwmutex_size, + IOMMU_MMIO | IOMMU_READ | IOMMU_WRITE); + if (rc) { + dprintk(CVP_ERR, "map hwmutex fail %d %#x %#x %#x\n", + rc, device->res->hwmutex_iova, + device->res->hwmutex_phyaddr, + device->res->hwmutex_size); + return rc; + } + return rc; +} + +static int __hwfence_regs_unmap(struct iris_hfi_device *device) +{ + int rc = 0; + struct context_bank_info *cb; + + cb = msm_cvp_smem_get_context_bank(device->res, 0); + if (!cb) { + dprintk(CVP_ERR, "%s: fail to get cb\n", __func__); + return -EINVAL; + } + + iommu_unmap(cb->domain, device->res->ipclite_iova, + device->res->ipclite_size); + iommu_unmap(cb->domain, device->res->hwmutex_iova, + device->res->hwmutex_size); + return rc; +} + static int iris_hfi_core_init(void *device) { int rc = 0; @@ -1922,6 +1987,8 @@ static int iris_hfi_core_init(void *device) dev->bus_vote.data_count = 1; dev->bus_vote.data->power_mode = CVP_POWER_TURBO; + __hwfence_regs_map(dev); + rc = __load_fw(dev); if (rc) { dprintk(CVP_ERR, "Failed to load Iris FW\n"); @@ -1997,6 +2064,14 @@ static int iris_hfi_core_init(void *device) __set_ubwc_config(device); __sys_set_idle_indicator(device, true); +#ifdef CVP_CONFIG_SYNX_V2 + rc = cvp_synx_recover(); + if (rc) { + dprintk(CVP_ERR, "Failed to recover synx\n"); + goto err_core_init; + } +#endif + if (dev->res->pm_qos.latency_us) { int err = 0; u32 i, cpu; @@ -2082,6 +2157,7 @@ static int iris_hfi_core_release(void *dev) __disable_subcaches(device); __unload_fw(device); + __hwfence_regs_unmap(device); if (msm_cvp_mmrm_enabled) { rc = msm_cvp_mmrm_deregister(device); diff --git a/msm/eva/cvp_hfi_helper.h b/msm/eva/cvp_hfi_helper.h index 6c547cd313..33b2ad284b 100644 --- a/msm/eva/cvp_hfi_helper.h +++ b/msm/eva/cvp_hfi_helper.h @@ -3,6 +3,7 @@ * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. */ +#include "cvp_comm_def.h" #ifndef __H_CVP_HFI_HELPER_H__ #define __H_CVP_HFI_HELPER_H__ @@ -307,6 +308,19 @@ struct cvp_hfi_client { u32 reserved2; } __packed; +#ifdef CVP_CONFIG_SYNX_V2 +struct cvp_hfi_buf_type { + u32 iova; + u32 size; + u32 offset; + u32 flags; + u32 reserved1; + u32 reserved2; + u32 fence_type; + u32 input_handle; + u32 output_handle; +}; +#else struct cvp_hfi_buf_type { u32 iova; u32 size; @@ -315,6 +329,7 @@ struct cvp_hfi_buf_type { u32 reserved1; u32 reserved2; }; +#endif struct cvp_hfi_cmd_session_set_buffers_packet { u32 size; diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index f7cd073580..22de79f817 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -7,6 +7,7 @@ #include "cvp_hfi.h" #include "cvp_core_hfi.h" #include "msm_cvp_buf.h" +#include "cvp_comm_def.h" struct cvp_power_level { unsigned long core_sum; @@ -14,6 +15,14 @@ struct cvp_power_level { unsigned long bw_sum; }; +static int cvp_enqueue_pkt(struct msm_cvp_inst* inst, + struct eva_kmd_hfi_packet *in_pkt, + unsigned int in_offset, + unsigned int in_buf_num); + +static int cvp_check_clock(struct msm_cvp_inst *inst, + struct cvp_hfi_msg_session_hdr_ext *hdr); + int msm_cvp_get_session_info(struct msm_cvp_inst *inst, u32 *session) { int rc = 0; @@ -124,6 +133,38 @@ exit: return rc; } +static bool check_clock_required(struct msm_cvp_inst *inst, + struct eva_kmd_hfi_packet *hdr) +{ + struct cvp_hfi_msg_session_hdr_ext *ehdr = + (struct cvp_hfi_msg_session_hdr_ext *)hdr; + bool clock_check = false; + + if (!msm_cvp_dcvs_disable && + ehdr->packet_type == HFI_MSG_SESSION_CVP_FD) { + if (ehdr->size == sizeof(struct cvp_hfi_msg_session_hdr_ext) + + sizeof(struct cvp_hfi_buf_type)) { + struct msm_cvp_core *core = inst->core; + + dprintk(CVP_PWR, "busy cycle %d, total %d\n", + ehdr->busy_cycles, ehdr->total_cycles); + + if (core->dyn_clk.sum_fps[HFI_HW_FDU] || + core->dyn_clk.sum_fps[HFI_HW_MPU] || + core->dyn_clk.sum_fps[HFI_HW_OD] || + core->dyn_clk.sum_fps[HFI_HW_ICA]) { + clock_check = true; + } + } else { + dprintk(CVP_WARN, "dcvs is disabled, %d != %d + %d\n", + ehdr->size, sizeof(struct cvp_hfi_msg_session_hdr_ext), + sizeof(struct cvp_hfi_buf_type)); + } + } + + return clock_check; +} + static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst, struct eva_kmd_hfi_packet *out_pkt) { @@ -131,6 +172,7 @@ static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst, struct cvp_session_queue *sq; struct msm_cvp_inst *s; int rc = 0; + bool clock_check = false; if (!inst) { dprintk(CVP_ERR, "%s invalid session\n", __func__); @@ -146,6 +188,11 @@ static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst, rc = cvp_wait_process_message(inst, sq, NULL, wait_time, out_pkt); + clock_check = check_clock_required(inst, out_pkt); + if (clock_check) + cvp_check_clock(inst, + (struct cvp_hfi_msg_session_hdr_ext *)out_pkt); + cvp_put_inst(inst); return rc; } @@ -156,14 +203,13 @@ static int msm_cvp_session_process_hfi( unsigned int in_offset, unsigned int in_buf_num) { - int pkt_idx, pkt_type, rc = 0; - struct cvp_hfi_device *hdev; + int pkt_idx, rc = 0; + unsigned int offset = 0, buf_num = 0, signal; struct cvp_session_queue *sq; struct msm_cvp_inst *s; bool is_config_pkt; - enum buf_map_type map_type; - struct cvp_hfi_cmd_session_hdr *cmd_hdr; + if (!inst || !inst->core || !in_pkt) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); @@ -174,7 +220,6 @@ static int msm_cvp_session_process_hfi( if (!s) return -ECONNRESET; - hdev = inst->core->device; pkt_idx = get_pkt_index((struct cvp_hal_session_cmd_pkt *)in_pkt); if (pkt_idx < 0) { @@ -227,34 +272,7 @@ static int msm_cvp_session_process_hfi( goto exit; } - pkt_type = in_pkt->pkt_data[1]; - map_type = cvp_find_map_type(pkt_type); - - cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; - /* The kdata will be overriden by transaction ID if the cmd has buf */ - cmd_hdr->client_data.kdata = pkt_idx; - - if (map_type == MAP_PERSIST) - rc = msm_cvp_map_user_persist(inst, in_pkt, offset, buf_num); - else if (map_type == UNMAP_PERSIST) - rc = msm_cvp_mark_user_persist(inst, in_pkt, offset, buf_num); - else - rc = msm_cvp_map_frame(inst, in_pkt, offset, buf_num); - - if (rc) - goto exit; - - rc = call_hfi_op(hdev, session_send, (void *)inst->session, in_pkt); - if (rc) { - dprintk(CVP_ERR, - "%s: Failed in call_hfi_op %d, %x\n", - __func__, in_pkt->pkt_data[0], in_pkt->pkt_data[1]); - goto exit; - } - - if (signal != HAL_NO_RESP) - dprintk(CVP_ERR, "%s signal %d from UMD is not HAL_NO_RESP\n", - __func__, signal); + cvp_enqueue_pkt(inst, in_pkt, offset, buf_num); exit: cvp_put_inst(inst); @@ -492,7 +510,7 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, if (rc) { dprintk(CVP_ERR, "%s %s: Failed in call_hfi_op %d, %x\n", current->comm, __func__, pkt->size, pkt->packet_type); - synx_state = SYNX_STATE_SIGNALED_ERROR; + synx_state = SYNX_STATE_SIGNALED_CANCEL; goto exit; } @@ -501,34 +519,14 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, (struct eva_kmd_hfi_packet *)&hdr); /* Only FD support dcvs at certain FW */ - if (!msm_cvp_dcvs_disable && - hdr.packet_type == HFI_MSG_SESSION_CVP_FD) { - if (hdr.size == sizeof(struct cvp_hfi_msg_session_hdr_ext) - + sizeof(struct cvp_hfi_buf_type)) { - struct cvp_hfi_msg_session_hdr_ext *fhdr = - (struct cvp_hfi_msg_session_hdr_ext *)&hdr; - struct msm_cvp_core *core = inst->core; + clock_check = check_clock_required(inst, + (struct eva_kmd_hfi_packet *)&hdr); - dprintk(CVP_PWR, "busy cycle %d, total %d\n", - fhdr->busy_cycles, fhdr->total_cycles); - - if (core->dyn_clk.sum_fps[HFI_HW_FDU] || - core->dyn_clk.sum_fps[HFI_HW_MPU] || - core->dyn_clk.sum_fps[HFI_HW_OD] || - core->dyn_clk.sum_fps[HFI_HW_ICA]) { - clock_check = true; - } - } else { - dprintk(CVP_WARN, "dcvs is disabled, %d != %d + %d\n", - hdr.size, sizeof(struct cvp_hfi_msg_session_hdr_ext), - sizeof(struct cvp_hfi_buf_type)); - } - } hfi_err = hdr.error_type; if (rc) { dprintk(CVP_ERR, "%s %s: cvp_wait_process_message rc %d\n", current->comm, __func__, rc); - synx_state = SYNX_STATE_SIGNALED_ERROR; + synx_state = SYNX_STATE_SIGNALED_CANCEL; goto exit; } if (hfi_err == HFI_ERR_SESSION_FLUSHED) { @@ -584,7 +582,7 @@ static void cvp_free_fence_data(struct cvp_fence_command *f) static int cvp_fence_thread(void *data) { - int rc = 0; + int rc = 0, num_fences; struct msm_cvp_inst *inst; struct cvp_fence_queue *q; enum queue_state state; @@ -618,7 +616,14 @@ wait: pkt = f->pkt; synx = (u32 *)f->synx; - ktid = pkt->client_data.kdata & (FENCE_BIT - 1); + num_fences = f->num_fences - f->output_index; + /* + * If there is output fence, go through fence path + * Otherwise, go through non-fenced path + */ + if (num_fences) + ktid = pkt->client_data.kdata & (FENCE_BIT - 1); + dprintk(CVP_SYNX, "%s pkt type %d on ktid %llu frameID %llu\n", current->comm, pkt->packet_type, ktid, f->frame_id); @@ -751,7 +756,7 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst, rc = inst->core->synx_ftbl->cvp_import_synx(inst, f, fence); if (rc) { - kfree(f); + cvp_free_fence_data(f); goto exit; } @@ -766,6 +771,158 @@ exit: return rc; } + +static int cvp_populate_fences( struct eva_kmd_hfi_packet *in_pkt, + unsigned int offset, unsigned int num, struct msm_cvp_inst *inst) +{ +#ifdef CVP_CONFIG_SYNX_V2 + u32 i, buf_offset; + struct eva_kmd_fence fences[MAX_HFI_FENCE_SIZE >> 2]; + struct cvp_fence_command *f; + struct cvp_hfi_cmd_session_hdr *cmd_hdr; + struct cvp_fence_queue *q; + enum op_mode mode; + struct cvp_buf_type *buf; + + int rc; + rc = 0; + + q = &inst->fence_cmd_queue; + + mutex_lock(&q->lock); + mode = q->mode; + mutex_unlock(&q->lock); + + if (mode == OP_DRAINING) { + dprintk(CVP_SYNX, "%s: flush in progress\n", __func__); + rc = -EBUSY; + goto exit; + } + + cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; + rc = cvp_alloc_fence_data((&f), cmd_hdr->size); + if (rc) + goto exit; + + f->type = cmd_hdr->packet_type; + f->mode = OP_NORMAL; + f->signature = 0xFEEDFACE; + f->num_fences = 0; + + /* First pass to find INPUT synx handles */ + buf_offset = offset; + for (i = 0; i < num; i++) { + buf = (struct cvp_buf_type *)&in_pkt->pkt_data[buf_offset]; + buf_offset += sizeof(*buf) >> 2; + + if (buf->input_handle) { + /* Check fence_type? */ + fences[f->num_fences].h_synx = buf->input_handle; + f->num_fences++; + buf->fence_type &= ~INPUT_FENCE_BITMASK; + buf->input_handle = 0; + } + } + f->output_index = f->num_fences; + + dprintk(CVP_SYNX, "%s:Input Fence passed - Number of Fences is %d\n", + __func__, f->num_fences); + + /* + * Second pass to find OUTPUT synx handle + * If no of fences is 0 dont execute the below portion until line 911, return 0 + */ + buf_offset = offset; + for (i = 0; i < num; i++) { + buf = (struct cvp_buf_type*)&in_pkt->pkt_data[buf_offset]; + buf_offset += sizeof(*buf) >> 2; + + if (buf->output_handle) { + /* Check fence_type? */ + fences[f->num_fences].h_synx = buf->output_handle; + f->num_fences++; + buf->fence_type &= ~OUTPUT_FENCE_BITMASK; + buf->output_handle = 0; + } + } + dprintk(CVP_SYNX, "%s:Output Fence passed - Number of Fences is %d\n", + __func__, f->num_fences); + + if (f->num_fences == 0) + goto free_exit; + + rc = inst->core->synx_ftbl->cvp_import_synx(inst, f, + (u32*)fences); + + if (rc) + goto free_exit; + + memcpy(f->pkt, cmd_hdr, cmd_hdr->size); + f->pkt->client_data.kdata |= FENCE_BIT; + + mutex_lock(&q->lock); + list_add_tail(&f->list, &inst->fence_cmd_queue.wait_list); + mutex_unlock(&q->lock); + + wake_up(&inst->fence_cmd_queue.wq); + + return f->num_fences; + +free_exit: + cvp_free_fence_data(f); +exit: +#endif /* CVP_CONFIG_SYNX_V2 */ + return rc; +} + + +static int cvp_enqueue_pkt(struct msm_cvp_inst* inst, + struct eva_kmd_hfi_packet *in_pkt, + unsigned int in_offset, + unsigned int in_buf_num) +{ + struct cvp_hfi_device *hdev; + struct cvp_hfi_cmd_session_hdr *cmd_hdr; + int pkt_type, rc = 0; + enum buf_map_type map_type; + + hdev = inst->core->device; + + pkt_type = in_pkt->pkt_data[1]; + map_type = cvp_find_map_type(pkt_type); + + cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; + /* The kdata will be overriden by transaction ID if the cmd has buf */ + cmd_hdr->client_data.kdata = 0; + + if (map_type == MAP_PERSIST) + rc = msm_cvp_map_user_persist(inst, in_pkt, in_offset, in_buf_num); + else if (map_type == UNMAP_PERSIST) + rc = msm_cvp_mark_user_persist(inst, in_pkt, in_offset, in_buf_num); + else + rc = msm_cvp_map_frame(inst, in_pkt, in_offset, in_buf_num); + + if (cvp_populate_fences(in_pkt, in_offset, in_buf_num, inst) == 0) { + rc = call_hfi_op(hdev, session_send, (void*)inst->session, + in_pkt); + if (rc) { + dprintk(CVP_ERR,"%s: Failed in call_hfi_op %d, %x\n", + __func__, in_pkt->pkt_data[0], + in_pkt->pkt_data[1]); + if (map_type == MAP_FRAME) + msm_cvp_unmap_frame(inst, + cmd_hdr->client_data.kdata); + } + goto exit; + } else { + dprintk(CVP_SYNX, "Going fenced path\n"); + goto exit; + } + +exit: + return rc; +} + static inline int div_by_1dot5(unsigned int a) { unsigned long i = a << 1; @@ -1615,7 +1772,7 @@ int cvp_clean_session_queues(struct msm_cvp_inst *inst) mutex_lock(&q->lock); if (q->state == QUEUE_START) { mutex_unlock(&q->lock); - cvp_clean_fence_queue(inst, SYNX_STATE_SIGNALED_ERROR); + cvp_clean_fence_queue(inst, SYNX_STATE_SIGNALED_CANCEL); } else { dprintk(CVP_WARN, "Incorrect fence cmd queue state %d\n", q->state); diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 0ac73dada1..a4e1e211e1 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1540,6 +1540,7 @@ int msm_cvp_map_frame(struct msm_cvp_inst *inst, if (!offset || !buf_num) return 0; + cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; ktid = atomic64_inc_return(&inst->core->kernel_trans_id); ktid &= (FENCE_BIT - 1); diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index 3b83488829..069e649083 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -12,6 +12,7 @@ #include #include #include +#include "cvp_comm_def.h" #define MAX_FRAME_BUFFER_NUMS 30 #define MAX_DMABUF_NUMS 64 @@ -108,6 +109,22 @@ static inline void DEINIT_DMAMAP_CACHE(struct cvp_dmamap_cache *cache) cache->nr = 0; } +#define INPUT_FENCE_BITMASK 0x1 +#define OUTPUT_FENCE_BITMASK 0x2 + +#ifdef CVP_CONFIG_SYNX_V2 +struct cvp_buf_type { + s32 fd; + u32 size; + u32 offset; + u32 flags; + u32 reserved1; + u32 reserved2; + u32 fence_type; + u32 input_handle; + u32 output_handle; +}; +#else struct cvp_buf_type { s32 fd; u32 size; @@ -121,6 +138,7 @@ struct cvp_buf_type { }; }; }; +#endif enum buffer_owner { DRIVER, diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index e88015e7b6..9da81cb07e 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -36,6 +36,7 @@ bool msm_cvp_mmrm_enabled = !true; #endif bool msm_cvp_dcvs_disable = !true; int msm_cvp_minidump_enable = !1; +bool cvp_kernel_fence_enabled = true; #define MAX_DBG_BUF_SIZE 4096 @@ -257,6 +258,7 @@ struct dentry *msm_cvp_debugfs_init_drv(void) &msm_cvp_minidump_enable); debugfs_create_bool("fw_coverage", 0644, dir, &msm_cvp_fw_coverage); debugfs_create_bool("auto_pil", 0644, dir, &msm_cvp_auto_pil); + debugfs_create_bool("kernel_fence", 0644, dir, &cvp_kernel_fence_enabled); debugfs_create_bool("disable_thermal_mitigation", 0644, dir, &msm_cvp_thermal_mitigation_disabled); debugfs_create_bool("enable_cacheop", 0644, dir, diff --git a/msm/eva/msm_cvp_debug.h b/msm/eva/msm_cvp_debug.h index 3ff7fccaed..b5e427088b 100644 --- a/msm/eva/msm_cvp_debug.h +++ b/msm/eva/msm_cvp_debug.h @@ -68,6 +68,7 @@ extern bool msm_cvp_dsp_disable; extern bool msm_cvp_mmrm_enabled; extern bool msm_cvp_dcvs_disable; extern int msm_cvp_minidump_enable; +extern bool cvp_kernel_fence_enabled; #define dprintk(__level, __fmt, arg...) \ do { \ diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index 40f05b5878..a99a1281ec 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -211,7 +211,7 @@ enum msm_cvp_modes { }; #define MAX_NUM_MSGS_PER_SESSION 128 -#define CVP_MAX_WAIT_TIME 2000 +#define CVP_MAX_WAIT_TIME 10000 struct cvp_session_msg { struct list_head node; @@ -417,7 +417,7 @@ struct msm_cvp_inst { u32 error_code; /* prev_error_code saves value of error_code before it's cleared */ u32 prev_error_code; - struct synx_session synx_session_id; + struct synx_session *synx_session_id; struct cvp_fence_queue fence_cmd_queue; char proc_name[TASK_COMM_LEN]; }; diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index e86936f1d8..8ebae0bcfd 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -141,6 +141,38 @@ static int msm_cvp_load_ipcc_regs(struct msm_cvp_platform_resources *res) return ret; } +static int msm_cvp_load_regspace_mapping(struct msm_cvp_platform_resources *res) +{ + int ret = 0; + unsigned int ipclite_mapping_config[3]; + unsigned int hwmutex_mapping_config[3]; + struct platform_device *pdev = res->pdev; + + ret = of_property_read_u32_array(pdev->dev.of_node, "ipclite_mappings", + ipclite_mapping_config, 3); + if (ret) { + dprintk(CVP_ERR, "Failed to read ipclite reg: %d\n", ret); + return ret; + } + res->ipclite_iova = ipclite_mapping_config[0]; + res->ipclite_size = ipclite_mapping_config[1]; + res->ipclite_phyaddr = ipclite_mapping_config[2]; + + ret = of_property_read_u32_array(pdev->dev.of_node, "hwmutex_mappings", + hwmutex_mapping_config, 3); + if (ret) { + dprintk(CVP_ERR, "Failed to read hwmutex reg: %d\n", ret); + return ret; + } + res->hwmutex_iova = hwmutex_mapping_config[0]; + res->hwmutex_size = hwmutex_mapping_config[1]; + res->hwmutex_phyaddr = hwmutex_mapping_config[2]; + dprintk(CVP_CORE, "ipclite %#x %#x %#x hwmutex %#x %#x %#x\n", + res->ipclite_iova, res->ipclite_phyaddr, res->ipclite_size, + res->hwmutex_iova, res->hwmutex_phyaddr, res->hwmutex_size); + return ret; +} + static int msm_cvp_load_gcc_regs(struct msm_cvp_platform_resources *res) { int ret = 0; @@ -859,6 +891,10 @@ int cvp_read_platform_resources_from_dt( if (rc) dprintk(CVP_ERR, "Failed to load IPCC regs: %d\n", rc); + rc = msm_cvp_load_regspace_mapping(res); + if (rc) + dprintk(CVP_ERR, "Failed to load reg space mapping: %d\n", rc); + rc = msm_cvp_load_gcc_regs(res); rc = msm_cvp_load_regulator_table(res); diff --git a/msm/eva/msm_cvp_resources.h b/msm/eva/msm_cvp_resources.h index a087349b40..926be0124b 100644 --- a/msm/eva/msm_cvp_resources.h +++ b/msm/eva/msm_cvp_resources.h @@ -156,6 +156,12 @@ struct msm_cvp_platform_resources { uint32_t register_size; uint32_t ipcc_reg_size; uint32_t gcc_reg_size; + phys_addr_t ipclite_iova; + phys_addr_t ipclite_phyaddr; + uint32_t ipclite_size; + phys_addr_t hwmutex_iova; + phys_addr_t hwmutex_phyaddr; + uint32_t hwmutex_size; uint32_t irq; uint32_t sku_version; struct allowed_clock_rates_table *allowed_clks_tbl; diff --git a/msm/eva/msm_cvp_synx.c b/msm/eva/msm_cvp_synx.c index 5801fda7b1..74b619f8d1 100644 --- a/msm/eva/msm_cvp_synx.c +++ b/msm/eva/msm_cvp_synx.c @@ -8,14 +8,21 @@ #include "msm_cvp_debug.h" #include "msm_cvp_core.h" #include "msm_cvp_dsp.h" +#include "cvp_comm_def.h" #ifdef CVP_SYNX_ENABLED -static int cvp_sess_init_synx_v1(struct msm_cvp_inst *inst) + +#ifdef CVP_CONFIG_SYNX_V2 + +static int cvp_sess_init_synx_v2(struct msm_cvp_inst *inst) { - struct synx_initialization_params params; + + struct synx_initialization_params params = { 0 }; params.name = "cvp-kernel-client"; - if (synx_initialize(&inst->synx_session_id, ¶ms)) { + params.id = SYNX_CLIENT_EVA_CTX0; + inst->synx_session_id = synx_initialize(¶ms); + if (IS_ERR_OR_NULL(&inst->synx_session_id)) { dprintk(CVP_ERR, "%s synx_initialize failed\n", __func__); return -EFAULT; } @@ -23,7 +30,272 @@ static int cvp_sess_init_synx_v1(struct msm_cvp_inst *inst) return 0; } -static int cvp_sess_deinit_synx(struct msm_cvp_inst *inst) +static int cvp_sess_deinit_synx_v2(struct msm_cvp_inst *inst) +{ + if (!inst) { + dprintk(CVP_ERR, "Used invalid sess in deinit_synx\n"); + return -EINVAL; + } + synx_uninitialize(inst->synx_session_id); + return 0; +} + +static void cvp_dump_fence_queue_v2(struct msm_cvp_inst *inst) +{ + struct cvp_fence_queue *q; + struct cvp_fence_command *f; + struct synx_session *ssid; + int i; + + q = &inst->fence_cmd_queue; + ssid = inst->synx_session_id; + mutex_lock(&q->lock); + dprintk(CVP_WARN, "inst %x fence q mode %d, ssid %pK\n", + hash32_ptr(inst->session), q->mode, ssid); + + dprintk(CVP_WARN, "fence cmdq wait list:\n"); + list_for_each_entry(f, &q->wait_list, list) { + dprintk(CVP_WARN, "frame pkt type 0x%x\n", f->pkt->packet_type); + for (i = 0; i < f->output_index; i++) + dprintk(CVP_WARN, "idx %d client hdl %d, state %d\n", + i, f->synx[i], + synx_get_status(ssid, f->synx[i])); + + } + + dprintk(CVP_WARN, "fence cmdq schedule list:\n"); + list_for_each_entry(f, &q->sched_list, list) { + dprintk(CVP_WARN, "frame pkt type 0x%x\n", f->pkt->packet_type); + for (i = 0; i < f->output_index; i++) + dprintk(CVP_WARN, "idx %d client hdl %d, state %d\n", + i, f->synx[i], + synx_get_status(ssid, f->synx[i])); + + } + mutex_unlock(&q->lock); +} + +static int cvp_import_synx_v2(struct msm_cvp_inst *inst, + struct cvp_fence_command *fc, + u32 *fence) +{ + int rc = 0, rr = 0; + int i; + struct eva_kmd_fence *fs; + struct synx_import_params params = {0}; + u32 h_synx; + struct synx_session *ssid; + + fs = (struct eva_kmd_fence *)fence; + ssid = inst->synx_session_id; + + for (i = 0; i < fc->num_fences; ++i) { + h_synx = fs[i].h_synx; + + if (h_synx) { + params.type = SYNX_IMPORT_INDV_PARAMS; + params.indv.fence = &h_synx; + params.indv.flags = SYNX_IMPORT_SYNX_FENCE + | SYNX_IMPORT_LOCAL_FENCE; + params.indv.new_h_synx = &fc->synx[i]; + + rc = synx_import(ssid, ¶ms); + if (rc) { + dprintk(CVP_ERR, + "%s: %u synx_import failed\n", + __func__, h_synx); + rr = rc; + } + } + } + + return rr; +} + +static int cvp_release_synx_v2(struct msm_cvp_inst *inst, + struct cvp_fence_command *fc) +{ + int rc = 0; + int i; + u32 h_synx; + struct synx_session *ssid; + + ssid = inst->synx_session_id; + for (i = 0; i < fc->num_fences; ++i) { + h_synx = fc->synx[i]; + if (h_synx) { + rc = synx_release(ssid, h_synx); + if (rc) + dprintk(CVP_ERR, + "%s: synx_release %d, %d failed\n", + __func__, h_synx, i); + } + } + return rc; +} + +static int cvp_cancel_synx_impl(struct msm_cvp_inst *inst, + enum cvp_synx_type type, + struct cvp_fence_command *fc, + int synx_state) +{ + int rc = 0; + int i; + u32 h_synx; + struct synx_session *ssid; + int start = 0, end = 0; + + ssid = inst->synx_session_id; + + if (type == CVP_INPUT_SYNX) { + start = 0; + end = fc->output_index; + } else if (type == CVP_OUTPUT_SYNX) { + start = fc->output_index; + end = fc->num_fences; + } else { + dprintk(CVP_ERR, "%s Incorrect synx type\n", __func__); + return -EINVAL; + } + + for (i = start; i < end; ++i) { + h_synx = fc->synx[i]; + if (h_synx) { + rc = synx_signal(ssid, h_synx, synx_state); + dprintk(CVP_SYNX, "Cancel synx %d session %llx\n", + h_synx, inst); + if (rc) + dprintk(CVP_ERR, + "%s: synx_signal %d %d %d failed\n", + __func__, h_synx, i, synx_state); + } + } + + return rc; + + +} + +static int cvp_cancel_synx_v2(struct msm_cvp_inst *inst, enum cvp_synx_type type, + struct cvp_fence_command *fc, int synx_state) +{ + return cvp_cancel_synx_impl(inst, type, fc, synx_state); +} + +static int cvp_wait_synx(struct synx_session *ssid, u32 *synx, u32 num_synx, + u32 *synx_state) +{ + int i = 0, rc = 0; + unsigned long timeout_ms = 2000; + u32 h_synx; + + while (i < num_synx) { + h_synx = synx[i]; + if (h_synx) { + rc = synx_wait(ssid, h_synx, timeout_ms); + if (rc) { + *synx_state = synx_get_status(ssid, h_synx); + if(*synx_state == SYNX_STATE_SIGNALED_SUCCESS) + { + dprintk(CVP_DBG, "%s: SYNX SIGNAl STATE SUCCESS \n", __func__); + rc=0; + i++; + continue; + } + else if (*synx_state == SYNX_STATE_SIGNALED_CANCEL) { + dprintk(CVP_SYNX, + "%s: synx_wait %d cancel %d state %d\n", + current->comm, i, rc, *synx_state); + } else { + dprintk(CVP_ERR, + "%s: synx_wait %d failed %d state %d\n", + current->comm, i, rc, *synx_state); + *synx_state = SYNX_STATE_SIGNALED_CANCEL; + } + return rc; + } else { + rc = 0; /* SYNX_STATE_SIGNALED_SUCCESS = 2 */ + } + + dprintk(CVP_SYNX, "Wait synx %u returned succes\n", + h_synx); + } + ++i; + } + return rc; +} + +static int cvp_signal_synx(struct synx_session *ssid, u32 *synx, u32 num_synx, + u32 synx_state) +{ + int i = 0, rc = 0; + u32 h_synx; + + while (i < num_synx) { + h_synx = synx[i]; + if (h_synx) { + rc = synx_signal(ssid, h_synx, synx_state); + if (rc) { + dprintk(CVP_ERR, + "%s: synx_signal %u %d failed\n", + current->comm, h_synx, i); + synx_state = SYNX_STATE_SIGNALED_CANCEL; + } + dprintk(CVP_SYNX, "Signaled synx %u state %d\n", + h_synx, synx_state); + } + ++i; + } + return rc; +} + +static int cvp_synx_ops_v2(struct msm_cvp_inst *inst, enum cvp_synx_type type, + struct cvp_fence_command *fc, u32 *synx_state) +{ + struct synx_session *ssid; + + ssid = inst->synx_session_id; + + if (type == CVP_INPUT_SYNX) { + return cvp_wait_synx(ssid, fc->synx, fc->output_index, + synx_state); + } else if (type == CVP_OUTPUT_SYNX) { + return cvp_signal_synx(ssid, &fc->synx[fc->output_index], + (fc->num_fences - fc->output_index), + *synx_state); + } else { + dprintk(CVP_ERR, "%s Incorrect SYNX type\n", __func__); + return -EINVAL; + } +} + +static struct msm_cvp_synx_ops cvp_synx = { + .cvp_sess_init_synx = cvp_sess_init_synx_v2, + .cvp_sess_deinit_synx = cvp_sess_deinit_synx_v2, + .cvp_release_synx = cvp_release_synx_v2, + .cvp_import_synx = cvp_import_synx_v2, + .cvp_synx_ops = cvp_synx_ops_v2, + .cvp_cancel_synx = cvp_cancel_synx_v2, + .cvp_dump_fence_queue = cvp_dump_fence_queue_v2, +}; + + +#else +static int cvp_sess_init_synx_v1(struct msm_cvp_inst *inst) +{ + struct synx_initialization_params params; + + params.name = "cvp-kernel-client"; + if (synx_initialize(&inst->synx_session_id, ¶ms)) { + + dprintk(CVP_ERR, "%s synx_initialize failed\n", __func__); + return -EFAULT; + } + + return 0; +} + +static int cvp_sess_deinit_synx_v1(struct msm_cvp_inst *inst) { if (!inst) { dprintk(CVP_ERR, "Used invalid sess in deinit_synx\n"); @@ -53,7 +325,6 @@ static void cvp_dump_fence_queue_v1(struct msm_cvp_inst *inst) dprintk(CVP_WARN, "idx %d client hdl %d, state %d\n", i, f->synx[i], synx_get_status(ssid, f->synx[i])); - } dprintk(CVP_WARN, "fence cmdq schedule list:\n"); @@ -63,7 +334,6 @@ static void cvp_dump_fence_queue_v1(struct msm_cvp_inst *inst) dprintk(CVP_WARN, "idx %d client hdl %d, state %d\n", i, f->synx[i], synx_get_status(ssid, f->synx[i])); - } mutex_unlock(&q->lock); } @@ -74,7 +344,7 @@ static int cvp_import_synx_v1(struct msm_cvp_inst *inst, { int rc = 0, rr = 0; int i; - struct cvp_fence_type *fs; + struct eva_kmd_fence *fs; struct synx_import_params params; s32 h_synx; struct synx_session ssid; @@ -84,7 +354,7 @@ static int cvp_import_synx_v1(struct msm_cvp_inst *inst, return -EINVAL; } - fs = (struct cvp_fence_type *)fence; + fs = (struct eva_kmd_fence *)fence; ssid = inst->synx_session_id; for (i = 0; i < fc->num_fences; ++i) { @@ -177,7 +447,7 @@ static int cvp_cancel_synx_impl(struct msm_cvp_inst *inst, } -static int cvp_cancel_synx(struct msm_cvp_inst *inst, enum cvp_synx_type type, +static int cvp_cancel_synx_v1(struct msm_cvp_inst *inst, enum cvp_synx_type type, struct cvp_fence_command *fc, int synx_state) { if (fc->signature != 0xFEEDFACE) { @@ -268,62 +538,76 @@ static int cvp_synx_ops_v1(struct msm_cvp_inst *inst, enum cvp_synx_type type, return -EINVAL; } } + +static struct msm_cvp_synx_ops cvp_synx = { + .cvp_sess_init_synx = cvp_sess_init_synx_v1, + .cvp_sess_deinit_synx = cvp_sess_deinit_synx_v1, + .cvp_release_synx = cvp_release_synx_v1, + .cvp_import_synx = cvp_import_synx_v1, + .cvp_synx_ops = cvp_synx_ops_v1, + .cvp_cancel_synx = cvp_cancel_synx_v1, + .cvp_dump_fence_queue = cvp_dump_fence_queue_v1, +}; + +#endif /* End of CVP_CONFIG_SYNX_V2 */ #else -static int cvp_sess_init_synx_v1(struct msm_cvp_inst *inst) +static int cvp_sess_init_synx_stub(struct msm_cvp_inst *inst) { return 0; } -static int cvp_sess_deinit_synx(struct msm_cvp_inst *inst) +static int cvp_sess_deinit_synx_stub(struct msm_cvp_inst *inst) { return 0; } -static int cvp_release_synx_v1(struct msm_cvp_inst *inst, +static int cvp_release_synx_stub(struct msm_cvp_inst *inst, struct cvp_fence_command *fc) { return 0; } -static int cvp_import_synx_v1(struct msm_cvp_inst *inst, +static int cvp_import_synx_stub(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, u32 *fence) { return 0; } -static int cvp_synx_ops_v1(struct msm_cvp_inst *inst, enum cvp_synx_type type, +static int cvp_synx_ops_stub(struct msm_cvp_inst *inst, enum cvp_synx_type type, struct cvp_fence_command *fc, u32 *synx_state) { return 0; } -static int cvp_cancel_synx(struct msm_cvp_inst *inst, enum cvp_synx_type type, +static int cvp_cancel_synx_stub(struct msm_cvp_inst *inst, enum cvp_synx_type type, struct cvp_fence_command *fc, int synx_state) { return 0; } -static void cvp_dump_fence_queue_v1(struct msm_cvp_inst *inst) +static void cvp_dump_fence_queue_stub(struct msm_cvp_inst *inst) { } -#endif -struct msm_cvp_synx_ops cvp_synx_v1 = { - .cvp_sess_init_synx = cvp_sess_init_synx_v1, - .cvp_sess_deinit_synx = cvp_sess_deinit_synx, - .cvp_release_synx = cvp_release_synx_v1, - .cvp_import_synx = cvp_import_synx_v1, - .cvp_synx_ops = cvp_synx_ops_v1, - .cvp_cancel_synx = cvp_cancel_synx, - .cvp_dump_fence_queue = cvp_dump_fence_queue_v1, +static struct msm_cvp_synx_ops cvp_synx = { + .cvp_sess_init_synx = cvp_sess_init_synx_stub, + .cvp_sess_deinit_synx = cvp_sess_deinit_synx_stub, + .cvp_release_synx = cvp_release_synx_stub, + .cvp_import_synx = cvp_import_synx_stub, + .cvp_synx_ops = cvp_synx_ops_stub, + .cvp_cancel_synx = cvp_cancel_synx_stub, + .cvp_dump_fence_queue = cvp_dump_fence_queue_stub, }; + +#endif /* End of CVP_SYNX_ENABLED */ + void cvp_synx_ftbl_init(struct msm_cvp_core *core) { if (!core) return; /* Synx API version check below if needed */ - core->synx_ftbl = &cvp_synx_v1; + core->synx_ftbl = &cvp_synx; } diff --git a/msm/eva/msm_cvp_synx.h b/msm/eva/msm_cvp_synx.h index 1190c06784..d4437dccb4 100644 --- a/msm/eva/msm_cvp_synx.h +++ b/msm/eva/msm_cvp_synx.h @@ -3,7 +3,7 @@ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */ -#ifndef _MSM_CVP_SYNX_H_ +//#ifndef _MSM_CVP_SYNX_H_ #define _MSM_CVP_SYNX_H_ #include @@ -32,11 +32,6 @@ struct cvp_fence_queue { struct list_head sched_list; }; -struct cvp_fence_type { - s32 h_synx; - u32 secure_key; -}; - struct cvp_fence_command { struct list_head list; u64 frame_id; @@ -76,4 +71,4 @@ struct msm_cvp_synx_ops { }; void cvp_synx_ftbl_init(struct msm_cvp_core *core); -#endif +//#endif From 163d88795c0db34b6c2cf6708848e5981a31b8e3 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 19 Oct 2022 15:04:49 -0700 Subject: [PATCH 139/317] msm: eva: Add core power on/off seq change For Lanai Change-Id: I06572cd9923d4b8c1565638006f01cb09af90bb5 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 44 ++++++++++++++++++++++++++++++++++++++++++-- msm/eva/cvp_hfi_io.h | 7 +++++++ 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 12ae387c18..cd2a103aff 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -3900,6 +3900,14 @@ static int __power_on_core(struct iris_hfi_device *device) return rc; } +#ifdef CONFIG_EVA_PINEAPPLE + __write_register(device, CVP_AON_WRAPPER_CVP_NOC_ARCG_CONTROL, 0); + __write_register(device, CVP_NOC_RCGCONTROLLER_HYSTERESIS_LOW, 0x2f); + __write_register(device, CVP_NOC_RCG_VNOC_NOC_CLK_FORCECLOCKON_LOW, 1); + __write_register(device, CVP_NOC_RCGCONTROLLER_MAINCTL_LOW, 1); + usleep_range(50, 100); + __write_register(device, CVP_NOC_RCG_VNOC_NOC_CLK_FORCECLOCKON_LOW, 0); +#endif dprintk(CVP_PWR, "EVA core powered on\n"); return 0; } @@ -4053,6 +4061,7 @@ static int __power_off_controller(struct iris_hfi_device *device) __write_register(device, CVP_CPU_CS_X2RPMh, 0x3); /* HPG 6.2.2 Step 2, noc to low power */ +#ifndef CONFIG_EVA_PINEAPPLE __write_register(device, CVP_AON_WRAPPER_CVP_NOC_LPI_CONTROL, 0x1); while (!reg_status && count < max_count) { lpi_status = @@ -4078,6 +4087,7 @@ static int __power_off_controller(struct iris_hfi_device *device) __print_sidebandmanager_regs(device); } +#endif /* New addition to put CPU/Tensilica to low power */ reg_status = 0; @@ -4157,8 +4167,8 @@ static int __power_off_controller(struct iris_hfi_device *device) static int __power_off_core(struct iris_hfi_device *device) { - u32 config, value = 0, count = 0, warn_flag = 0; - const u32 max_count = 10; + u32 reg_status = 0, lpi_status, config, value = 0, count = 0; + u32 warn_flag = 0, max_count = 10; value = __read_register(device, CVP_CC_MVS1_GDSCR); if (!(value & 0x80000000)) { @@ -4211,6 +4221,7 @@ static int __power_off_core(struct iris_hfi_device *device) warn_flag = 1; } +#ifndef CONFIG_EVA_PINEAPPLE /* Apply partial reset on MSF interface and wait for ACK */ __write_register(device, CVP_NOC_RESET_REQ, 0x7); count = 0; @@ -4244,6 +4255,35 @@ static int __power_off_core(struct iris_hfi_device *device) dprintk(CVP_WARN, "Core NoC reset de-assert failed\n"); warn_flag = 1; } +#else + count = 0; + max_count = 1000; + __write_register(device, CVP_AON_WRAPPER_CVP_NOC_LPI_CONTROL, 0x1); + while (!reg_status && count < max_count) { + lpi_status = + __read_register(device, + CVP_AON_WRAPPER_CVP_NOC_LPI_STATUS); + reg_status = lpi_status & BIT(0); + /* Wait for Core noc lpi status to be set */ + usleep_range(50, 100); + count++; + } + dprintk(CVP_PWR, + "Core Noc: lpi_status %x noc_status %x (count %d)\n", + lpi_status, reg_status, count); + if (count == max_count) { + u32 pc_ready, wfi_status; + + wfi_status = __read_register(device, CVP_WRAPPER_CPU_STATUS); + pc_ready = __read_register(device, CVP_CTRL_STATUS); + + dprintk(CVP_WARN, + "Core NOC not in qaccept status %x %x %x %x\n", + reg_status, lpi_status, wfi_status, pc_ready); + + __print_sidebandmanager_regs(device); + } +#endif if (warn_flag) __print_sidebandmanager_regs(device); diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index 6e3c39fb3d..10337d27c1 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -228,6 +228,8 @@ (CVP_NOC_CORE_BASE_OFFS + 0x1238) #define CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS \ (CVP_NOC_CORE_BASE_OFFS + 0x123C) +#define CVP_NOC_RCG_VNOC_NOC_CLK_FORCECLOCKON_LOW \ + (CVP_NOC_CORE_BASE_OFFS + 0x2018) #define CVP_NOC_PRIORITYLUT_LOW \ (CVP_NOC_CORE_BASE_OFFS + 0x3030) #define CVP_NOC_PRIORITYLUT_HIGH \ @@ -238,6 +240,10 @@ (CVP_NOC_CORE_BASE_OFFS + 0x3040) #define CVP_NOC_SAFELUT_LOW \ (CVP_NOC_CORE_BASE_OFFS + 0x3048) +#define CVP_NOC_RCGCONTROLLER_MAINCTL_LOW \ + (CVP_NOC_CORE_BASE_OFFS + 0xC008) +#define CVP_NOC_RCGCONTROLLER_HYSTERESIS_LOW \ + (CVP_NOC_CORE_BASE_OFFS + 0xC010) #define CVP_NOC_RESET_REQ \ (CVP_NOC_CORE_BASE_OFFS + 0xf000) #define CVP_NOC_RESET_ACK \ @@ -246,6 +252,7 @@ #define CVP_AON_WRAPPER_CVP_NOC_LPI_CONTROL (CVP_AON_BASE_OFFS + 0x8) #define CVP_AON_WRAPPER_CVP_NOC_LPI_STATUS (CVP_AON_BASE_OFFS + 0xC) +#define CVP_AON_WRAPPER_CVP_NOC_ARCG_CONTROL (CVP_AON_BASE_OFFS + 0x14) #define CVP_CC_BASE_OFFS 0x000F8000 #define CVP_CC_MVS1C_GDSCR (CVP_CC_BASE_OFFS + 0x78) From abe2519bd896f8ca1cd09bab335856b24cb6ab6d Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 17 Oct 2022 09:00:05 -0700 Subject: [PATCH 140/317] msm: eva: Add EVA4.0 blocks for power voting VADL, TOF, RGE, XRA and LSR added. Change-Id: I5099b72bb38199d493a710c716fc528ab2cc0e7c Signed-off-by: George Shen --- include/uapi/eva/media/msm_eva_private.h | 21 + msm/Kbuild | 1 + msm/Makefile | 3 +- msm/eva/cvp_hfi_helper.h | 9 +- msm/eva/cvp_power.c | 539 ++++++++++++++++++++ msm/eva/cvp_power.h | 27 + msm/eva/msm_cvp.c | 618 ++++------------------- msm/eva/msm_cvp_dsp.c | 16 +- msm/eva/msm_cvp_internal.h | 22 +- 9 files changed, 695 insertions(+), 561 deletions(-) create mode 100644 msm/eva/cvp_power.c create mode 100644 msm/eva/cvp_power.h diff --git a/include/uapi/eva/media/msm_eva_private.h b/include/uapi/eva/media/msm_eva_private.h index 2e61a12664..cf4745d65c 100644 --- a/include/uapi/eva/media/msm_eva_private.h +++ b/include/uapi/eva/media/msm_eva_private.h @@ -205,6 +205,27 @@ struct eva_kmd_hfi_packet { #define EVA_KMD_PROP_PWR_FPS_OD 0x20 #define EVA_KMD_PROP_PWR_FPS_ICA 0x21 +#define EVA_KMD_PROP_PWR_VADL 0x22 +#define EVA_KMD_PROP_PWR_VADL_OP 0x23 +#define EVA_KMD_PROP_PWR_FPS_VADL 0x24 + +#define EVA_KMD_PROP_PWR_TOF 0x25 +#define EVA_KMD_PROP_PWR_TOF_OP 0x26 +#define EVA_KMD_PROP_PWR_FPS_TOF 0x27 + +#define EVA_KMD_PROP_PWR_RGE 0x28 +#define EVA_KMD_PROP_PWR_RGE_OP 0x29 +#define EVA_KMD_PROP_PWR_FPS_RGE 0x2A + +#define EVA_KMD_PROP_PWR_XRA 0x2B +#define EVA_KMD_PROP_PWR_XRA_OP 0x2C +#define EVA_KMD_PROP_PWR_FPS_XRA 0x2D + +#define EVA_KMD_PROP_PWR_LSR 0x2E +#define EVA_KMD_PROP_PWR_LSR_OP 0x2F +#define EVA_KMD_PROP_PWR_FPS_LSR 0x30 + + #define MAX_KMD_PROP_NUM_PER_PACKET 8 #define MAX_KMD_PROP_TYPE (EVA_KMD_PROP_PWR_FPS_ICA + 1) diff --git a/msm/Kbuild b/msm/Kbuild index d11b45c343..62f4820beb 100644 --- a/msm/Kbuild +++ b/msm/Kbuild @@ -60,6 +60,7 @@ msm-eva-objs := eva/cvp.o \ eva/msm_cvp_buf.o \ eva/msm_cvp_synx.o \ eva/cvp_fw_load.o \ + eva/cvp_power.o \ eva/vm/cvp_vm_main.o \ eva/vm/cvp_vm_msgq.o \ eva/vm/cvp_vm_resource.o diff --git a/msm/Makefile b/msm/Makefile index 620090032e..88a6c2649a 100644 --- a/msm/Makefile +++ b/msm/Makefile @@ -20,7 +20,8 @@ msm-eva-objs := eva/cvp.o \ eva/msm_cvp_dsp.o \ eva/msm_cvp_buf.o \ eva/msm_cvp_synx.o \ - eva/cvp_fw_load.o + eva/cvp_fw_load.o \ + eva/cvp_power.o obj-$(CONFIG_MSM_EVA) := msm-eva.o diff --git a/msm/eva/cvp_hfi_helper.h b/msm/eva/cvp_hfi_helper.h index 33b2ad284b..a66782d4d7 100644 --- a/msm/eva/cvp_hfi_helper.h +++ b/msm/eva/cvp_hfi_helper.h @@ -378,13 +378,18 @@ struct cvp_hfi_dumpmsg_session_hdr { } __packed; #define HFI_MAX_HW_ACTIVATIONS_PER_FRAME (6) -#define HFI_MAX_HW_THREADS (4) enum hfi_hw_thread { HFI_HW_FDU, HFI_HW_MPU, HFI_HW_OD, - HFI_HW_ICA + HFI_HW_ICA, + HFI_HW_VADL, + HFI_HW_TOF, + HFI_HW_RGE, + HFI_HW_XRA, + HFI_HW_LSR, + HFI_MAX_HW_THREADS }; struct cvp_hfi_msg_session_hdr_ext { diff --git a/msm/eva/cvp_power.c b/msm/eva/cvp_power.c new file mode 100644 index 0000000000..7e39db27d2 --- /dev/null +++ b/msm/eva/cvp_power.c @@ -0,0 +1,539 @@ + +/* SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + */ + +#include "msm_cvp.h" +#include "cvp_power.h" + +static inline int find_max(unsigned long *array, unsigned int num) +{ + int i, max = 0; + + for (i = 0; i < num; i++) + max = array[i] > max ? array[i] : max; + + return max; +} + +static bool is_subblock_profile_existed(struct msm_cvp_inst *inst) +{ + return (inst->prop.cycles[HFI_HW_OD] || + inst->prop.cycles[HFI_HW_MPU] || + inst->prop.cycles[HFI_HW_FDU] || + inst->prop.cycles[HFI_HW_ICA] || + inst->prop.cycles[HFI_HW_VADL] || + inst->prop.cycles[HFI_HW_TOF] || + inst->prop.cycles[HFI_HW_RGE] || + inst->prop.cycles[HFI_HW_XRA] || + inst->prop.cycles[HFI_HW_LSR]); +} + +static void aggregate_power_update(struct msm_cvp_core *core, + struct cvp_power_level *nrt_pwr, + struct cvp_power_level *rt_pwr, + unsigned int max_clk_rate) +{ + struct msm_cvp_inst *inst; + int i, j; + unsigned long blocks_sum[2][HFI_MAX_HW_THREADS] = {0}; + unsigned long fw_sum[2] = {0}, max_cycle[2] = {0}, op_max_cycle[2] = {0}; + unsigned long op_blocks_max[2][HFI_MAX_HW_THREADS] = {0}; + unsigned long op_fw_max[2] = {0}, bw_sum[2] = {0}, op_bw_max[2] = {0}; + + for (j = 0; j < HFI_MAX_HW_THREADS; j++) + core->dyn_clk.sum_fps[j] = 0; + + list_for_each_entry(inst, &core->instances, list) { + if (inst->state == MSM_CVP_CORE_INVALID || + inst->state == MSM_CVP_CORE_UNINIT || + !is_subblock_profile_existed(inst)) + continue; + if (inst->prop.priority <= CVP_RT_PRIO_THRESHOLD) { + /* Non-realtime session use index 0 */ + i = 0; + } else { + i = 1; + } + dprintk(CVP_PROF, "pwrUpdate fdu od mpu ica vadl tof rge xra lsr\n"); + for (j = 0; j < HFI_MAX_HW_THREADS; j++) + dprintk(CVP_PROF, "%u ", inst->prop.cycles[j]); + dprintk(CVP_PROF, "\n"); + + dprintk(CVP_PROF, "pwrUpdate fdu_o od_o ica_o mpu_o vadl_o tof_o rge_o xra_o lsr_o\n"); + for (j = 0; j < HFI_MAX_HW_THREADS; j++) + dprintk(CVP_PROF, "%u ", inst->prop.op_cycles[j]); + dprintk(CVP_PROF, "\n"); + + dprintk(CVP_PROF, " fw %u fw_o %u\n", inst->prop.fw_cycles, inst->prop.fw_op_cycles); + + for (j = 0; j < HFI_MAX_HW_THREADS; j++) + blocks_sum[i][j] += inst->prop.cycles[j]; + + fw_sum[i] += inst->prop.fw_cycles; + + for (j = 0; j < HFI_MAX_HW_THREADS; j++) + op_blocks_max[i][j] = + (op_blocks_max[i][j] >= inst->prop.op_cycles[j]) ? + op_blocks_max[i][j] : inst->prop.op_cycles[j]; + + op_fw_max[i] = + (op_fw_max[i] >= inst->prop.fw_op_cycles) ? + op_fw_max[i] : inst->prop.fw_op_cycles; + + bw_sum[i] += inst->prop.ddr_bw; + + op_bw_max[i] = + (op_bw_max[i] >= inst->prop.ddr_op_bw) ? + op_bw_max[i] : inst->prop.ddr_op_bw; + + dprintk(CVP_PWR, "%s:%d - fps fdu mpu od ica vadl tof rge xra lsf\n", + __func__, __LINE__); + + for (j = 0; j < HFI_MAX_HW_THREADS; j++) { + dprintk(CVP_PWR, " %d ", inst->prop.fps[j]); + core->dyn_clk.sum_fps[j] += inst->prop.fps[j]; + } + dprintk(CVP_PWR, "\n"); + + dprintk(CVP_PWR, "%s:%d - sum_fps fdu mpu od ica vadl tof rge xra lsf\n", + __func__, __LINE__); + for (j = 0; j < HFI_MAX_HW_THREADS; j++) + dprintk(CVP_PWR, " %d ", core->dyn_clk.sum_fps[j]); + dprintk(CVP_PWR, "\n"); + } + + for (i = 0; i < 2; i++) { + max_cycle[i] = find_max(&blocks_sum[i][0], HFI_MAX_HW_THREADS); + op_max_cycle[i] = find_max(&op_blocks_max[i][0], HFI_MAX_HW_THREADS); + + op_max_cycle[i] = + (op_max_cycle[i] > max_clk_rate) ? + max_clk_rate : op_max_cycle[i]; + bw_sum[i] = (bw_sum[i] >= op_bw_max[i]) ? + bw_sum[i] : op_bw_max[i]; + } + + nrt_pwr->core_sum += max_cycle[0]; + nrt_pwr->op_core_sum = (nrt_pwr->op_core_sum >= op_max_cycle[0]) ? + nrt_pwr->op_core_sum : op_max_cycle[0]; + nrt_pwr->bw_sum += bw_sum[0]; + rt_pwr->core_sum += max_cycle[1]; + rt_pwr->op_core_sum = (rt_pwr->op_core_sum >= op_max_cycle[1]) ? + rt_pwr->op_core_sum : op_max_cycle[1]; + rt_pwr->bw_sum += bw_sum[1]; +} + +/** + * adjust_bw_freqs(): calculate CVP clock freq and bw required to sustain + * required use case. + * Bandwidth vote will be best-effort, not returning error if the request + * b/w exceeds max limit. + * Clock vote from non-realtime sessions will be best effort, not returning + * error if the aggreated session clock request exceeds max limit. + * Clock vote from realtime session will be hard request. If aggregated + * session clock request exceeds max limit, the function will return + * error. + * + * Ensure caller acquires clk_lock! + */ +static int adjust_bw_freqs(void) +{ + struct msm_cvp_core *core; + struct iris_hfi_device *hdev; + struct bus_info *bus; + struct clock_set *clocks; + struct clock_info *cl; + struct allowed_clock_rates_table *tbl = NULL; + unsigned int tbl_size; + unsigned int cvp_min_rate, cvp_max_rate, max_bw, min_bw; + struct cvp_power_level rt_pwr = {0}, nrt_pwr = {0}; + unsigned long tmp, core_sum, op_core_sum, bw_sum; + int i, rc = 0; + unsigned long ctrl_freq; + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + + hdev = core->device->hfi_device_data; + clocks = &core->resources.clock_set; + cl = &clocks->clock_tbl[clocks->count - 1]; + tbl = core->resources.allowed_clks_tbl; + tbl_size = core->resources.allowed_clks_tbl_size; + cvp_min_rate = tbl[0].clock_rate; + cvp_max_rate = tbl[tbl_size - 1].clock_rate; + bus = &core->resources.bus_set.bus_tbl[1]; + max_bw = bus->range[1]; + min_bw = max_bw/10; + + aggregate_power_update(core, &nrt_pwr, &rt_pwr, cvp_max_rate); + dprintk(CVP_PROF, "PwrUpdate nrt %u %u rt %u %u\n", + nrt_pwr.core_sum, nrt_pwr.op_core_sum, + rt_pwr.core_sum, rt_pwr.op_core_sum); + + if (rt_pwr.core_sum > cvp_max_rate) { + dprintk(CVP_WARN, "%s clk vote out of range %lld\n", + __func__, rt_pwr.core_sum); + return -ENOTSUPP; + } + + core_sum = rt_pwr.core_sum + nrt_pwr.core_sum; + op_core_sum = (rt_pwr.op_core_sum >= nrt_pwr.op_core_sum) ? + rt_pwr.op_core_sum : nrt_pwr.op_core_sum; + + core_sum = (core_sum >= op_core_sum) ? + core_sum : op_core_sum; + + if (core_sum > cvp_max_rate) { + core_sum = cvp_max_rate; + } else if (core_sum <= cvp_min_rate) { + core_sum = cvp_min_rate; + } else { + for (i = 1; i < tbl_size; i++) + if (core_sum <= tbl[i].clock_rate) + break; + core_sum = tbl[i].clock_rate; + } + + bw_sum = rt_pwr.bw_sum + nrt_pwr.bw_sum; + bw_sum = bw_sum >> 10; + bw_sum = (bw_sum > max_bw) ? max_bw : bw_sum; + bw_sum = (bw_sum < min_bw) ? min_bw : bw_sum; + + dprintk(CVP_PROF, "%s %lld %lld\n", __func__, + core_sum, bw_sum); + if (!cl->has_scaling) { + dprintk(CVP_ERR, "Cannot scale CVP clock\n"); + return -EINVAL; + } + + tmp = core->curr_freq; + core->curr_freq = core_sum; + core->orig_core_sum = core_sum; + rc = msm_cvp_set_clocks(core); + if (rc) { + dprintk(CVP_ERR, + "Failed to set clock rate %u %s: %d %s\n", + core_sum, cl->name, rc, __func__); + core->curr_freq = tmp; + return rc; + } + + ctrl_freq = (core->curr_freq*3)>>1; + core->dyn_clk.conf_freq = core->curr_freq; + for (i = 0; i < HFI_MAX_HW_THREADS; ++i) { + core->dyn_clk.hi_ctrl_lim[i] = core->dyn_clk.sum_fps[i] ? + ctrl_freq/core->dyn_clk.sum_fps[i] : 0; + core->dyn_clk.lo_ctrl_lim[i] = + core->dyn_clk.hi_ctrl_lim[i]; + } + + hdev->clk_freq = core->curr_freq; + rc = msm_cvp_set_bw(bus, bw_sum); + + return rc; +} + +int msm_cvp_update_power(struct msm_cvp_inst *inst) +{ + int rc = 0; + struct msm_cvp_core *core; + struct msm_cvp_inst *s; + + if (!inst) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + s = cvp_get_inst_validate(inst->core, inst); + if (!s) + return -ECONNRESET; + + core = inst->core; + + mutex_lock(&core->clk_lock); + rc = adjust_bw_freqs(); + mutex_unlock(&core->clk_lock); + cvp_put_inst(s); + + return rc; +} + + +static int cvp_readjust_clock(struct msm_cvp_core *core, + u32 avg_cycles, enum hfi_hw_thread i) +{ + int rc = 0; + struct allowed_clock_rates_table *tbl = NULL; + unsigned int tbl_size = 0; + unsigned int cvp_min_rate = 0, cvp_max_rate = 0; + unsigned long tmp = core->curr_freq; + unsigned long lo_freq = 0; + u32 j; + + tbl = core->resources.allowed_clks_tbl; + tbl_size = core->resources.allowed_clks_tbl_size; + cvp_min_rate = tbl[0].clock_rate; + cvp_max_rate = tbl[tbl_size - 1].clock_rate; + + if (!((avg_cycles > core->dyn_clk.hi_ctrl_lim[i] && + core->curr_freq != cvp_max_rate) || + (avg_cycles <= core->dyn_clk.lo_ctrl_lim[i] && + core->curr_freq != cvp_min_rate))) { + return rc; + } + + core->curr_freq = ((avg_cycles * core->dyn_clk.sum_fps[i]) << 1)/3; + dprintk(CVP_PWR, + "%s - cycles tot %u, avg %u. sum_fps %u, cur_freq %u\n", + __func__, + core->dyn_clk.cycle[i].total, + avg_cycles, + core->dyn_clk.sum_fps[i], + core->curr_freq); + + if (core->curr_freq > cvp_max_rate) { + core->curr_freq = cvp_max_rate; + lo_freq = (tbl_size > 1) ? + tbl[tbl_size - 2].clock_rate : + cvp_min_rate; + } else if (core->curr_freq <= cvp_min_rate) { + core->curr_freq = cvp_min_rate; + lo_freq = cvp_min_rate; + } else { + for (j = 1; j < tbl_size; j++) + if (core->curr_freq <= tbl[j].clock_rate) + break; + core->curr_freq = tbl[j].clock_rate; + lo_freq = tbl[j-1].clock_rate; + } + + if (core->orig_core_sum > core->curr_freq) { + dprintk(CVP_PWR, + "%s - %d - Cancel readjust, core %u, freq %u\n", + __func__, i, core->orig_core_sum, core->curr_freq); + core->curr_freq = tmp; + return rc; + } + + dprintk(CVP_PWR, + "%s:%d - %d - Readjust to %u\n", + __func__, __LINE__, i, core->curr_freq); + rc = msm_cvp_set_clocks(core); + if (rc) { + dprintk(CVP_ERR, + "Failed to set clock rate %u: %d %s\n", + core->curr_freq, rc, __func__); + core->curr_freq = tmp; + } else { + lo_freq = (lo_freq < core->dyn_clk.conf_freq) ? + core->dyn_clk.conf_freq : lo_freq; + core->dyn_clk.hi_ctrl_lim[i] = core->dyn_clk.sum_fps[i] ? + ((core->curr_freq*3)>>1)/core->dyn_clk.sum_fps[i] : 0; + core->dyn_clk.lo_ctrl_lim[i] = + core->dyn_clk.sum_fps[i] ? + ((lo_freq*3)>>1)/core->dyn_clk.sum_fps[i] : 0; + + dprintk(CVP_PWR, + "%s - Readjust clk to %u. New lim [%d] hi %u lo %u\n", + __func__, core->curr_freq, i, + core->dyn_clk.hi_ctrl_lim[i], + core->dyn_clk.lo_ctrl_lim[i]); + } + + return rc; +} + +int cvp_check_clock(struct msm_cvp_inst *inst, + struct cvp_hfi_msg_session_hdr_ext *hdr) +{ + int rc = 0; + u32 i, j; + u32 hw_cycles[HFI_MAX_HW_THREADS] = {0}; + u32 fw_cycles = 0; + struct msm_cvp_core *core = inst->core; + + for (i = 0; i < HFI_MAX_HW_ACTIVATIONS_PER_FRAME; ++i) + fw_cycles += hdr->fw_cycles[i]; + + for (i = 0; i < HFI_MAX_HW_THREADS; ++i) + for (j = 0; j < HFI_MAX_HW_ACTIVATIONS_PER_FRAME; ++j) + hw_cycles[i] += hdr->hw_cycles[i][j]; + + dprintk(CVP_PWR, "%s - cycles fw %u. FDU %d MPU %d ODU %d ICA %d\n", + __func__, fw_cycles, hw_cycles[0], + hw_cycles[1], hw_cycles[2], hw_cycles[3]); + + mutex_lock(&core->clk_lock); + for (i = 0; i < HFI_MAX_HW_THREADS; ++i) { + dprintk(CVP_PWR, "%s - %d: hw_cycles %u, tens_thresh %u\n", + __func__, i, hw_cycles[i], + core->dyn_clk.hi_ctrl_lim[i]); + if (core->dyn_clk.hi_ctrl_lim[i]) { + if (core->dyn_clk.cycle[i].size < CVP_CYCLE_STAT_SIZE) + core->dyn_clk.cycle[i].size++; + else + core->dyn_clk.cycle[i].total -= + core->dyn_clk.cycle[i].busy[ + core->dyn_clk.cycle[i].idx]; + if (hw_cycles[i]) { + core->dyn_clk.cycle[i].busy[ + core->dyn_clk.cycle[i].idx] + = hw_cycles[i] + fw_cycles; + core->dyn_clk.cycle[i].total + += hw_cycles[i] + fw_cycles; + dprintk(CVP_PWR, + "%s: busy (hw + fw) cycles = %u\n", + __func__, + core->dyn_clk.cycle[i].busy[ + core->dyn_clk.cycle[i].idx]); + dprintk(CVP_PWR, "total cycles %u\n", + core->dyn_clk.cycle[i].total); + } else { + core->dyn_clk.cycle[i].busy[ + core->dyn_clk.cycle[i].idx] = + hdr->busy_cycles; + core->dyn_clk.cycle[i].total += + hdr->busy_cycles; + dprintk(CVP_PWR, + "%s - busy cycles = %u total %u\n", + __func__, + core->dyn_clk.cycle[i].busy[ + core->dyn_clk.cycle[i].idx], + core->dyn_clk.cycle[i].total); + } + + core->dyn_clk.cycle[i].idx = + (core->dyn_clk.cycle[i].idx == + CVP_CYCLE_STAT_SIZE-1) ? + 0 : core->dyn_clk.cycle[i].idx+1; + + dprintk(CVP_PWR, "%s - %d: size %u, tens_thresh %u\n", + __func__, i, core->dyn_clk.cycle[i].size, + core->dyn_clk.hi_ctrl_lim[i]); + if (core->dyn_clk.cycle[i].size == CVP_CYCLE_STAT_SIZE + && core->dyn_clk.hi_ctrl_lim[i] != 0) { + u32 avg_cycles = + core->dyn_clk.cycle[i].total>>3; + + rc = cvp_readjust_clock(core, + avg_cycles, + i); + } + } + } + mutex_unlock(&core->clk_lock); + + return rc; +} + +unsigned int msm_cvp_get_hw_aggregate_cycles(enum hfi_hw_thread hwblk) +{ + struct msm_cvp_core *core; + struct msm_cvp_inst *inst; + unsigned long cycles_sum = 0; + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + + if (!core) { + dprintk(CVP_ERR, "%s: invalid core\n", __func__); + return -EINVAL; + } + + mutex_lock(&core->clk_lock); + list_for_each_entry(inst, &core->instances, list) { + if (inst->state == MSM_CVP_CORE_INVALID || + inst->state == MSM_CVP_CORE_UNINIT || + !is_subblock_profile_existed(inst)) + continue; + switch (hwblk) { + case HFI_HW_FDU: + { + cycles_sum += inst->prop.cycles[HFI_HW_FDU]; + break; + } + case HFI_HW_ICA: + { + cycles_sum += inst->prop.cycles[HFI_HW_ICA]; + break; + } + case HFI_HW_MPU: + { + cycles_sum += inst->prop.cycles[HFI_HW_MPU]; + break; + } + case HFI_HW_OD: + { + cycles_sum += inst->prop.cycles[HFI_HW_OD]; + break; + } + case HFI_HW_VADL: + { + cycles_sum += inst->prop.cycles[HFI_HW_VADL]; + break; + } + case HFI_HW_TOF: + { + cycles_sum += inst->prop.cycles[HFI_HW_TOF]; + break; + } + case HFI_HW_RGE: + { + cycles_sum += inst->prop.cycles[HFI_HW_RGE]; + break; + } + case HFI_HW_XRA: + { + cycles_sum += inst->prop.cycles[HFI_HW_XRA]; + break; + } + case HFI_HW_LSR: + { + cycles_sum += inst->prop.cycles[HFI_HW_LSR]; + break; + } + default: + dprintk(CVP_ERR, "unrecognized hw block %d\n", + hwblk); + break; + } + } + mutex_unlock(&core->clk_lock); + cycles_sum = cycles_sum&0xFFFFFFFF; + return (unsigned int)cycles_sum; +} + +bool check_clock_required(struct msm_cvp_inst *inst, + struct eva_kmd_hfi_packet *hdr) +{ + struct cvp_hfi_msg_session_hdr_ext *ehdr = + (struct cvp_hfi_msg_session_hdr_ext *)hdr; + bool clock_check = false; + + if (!msm_cvp_dcvs_disable && + ehdr->packet_type == HFI_MSG_SESSION_CVP_FD) { + if (ehdr->size == sizeof(struct cvp_hfi_msg_session_hdr_ext) + + sizeof(struct cvp_hfi_buf_type)) { + struct msm_cvp_core *core = inst->core; + + dprintk(CVP_PWR, "busy cycle %d, total %d\n", + ehdr->busy_cycles, ehdr->total_cycles); + + if (core->dyn_clk.sum_fps[HFI_HW_FDU] || + core->dyn_clk.sum_fps[HFI_HW_MPU] || + core->dyn_clk.sum_fps[HFI_HW_OD] || + core->dyn_clk.sum_fps[HFI_HW_ICA]) { + clock_check = true; + } + } else { + dprintk(CVP_WARN, "dcvs is disabled, %d != %d + %d\n", + ehdr->size, sizeof(struct cvp_hfi_msg_session_hdr_ext), + sizeof(struct cvp_hfi_buf_type)); + } + } + + return clock_check; +} + + diff --git a/msm/eva/cvp_power.h b/msm/eva/cvp_power.h new file mode 100644 index 0000000000..ec438e2523 --- /dev/null +++ b/msm/eva/cvp_power.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#ifndef _CVP_POWER_H_ +#define _CVP_POWER_H_ + +#include "msm_cvp_internal.h" +#include "msm_cvp_common.h" +#include "msm_cvp_clocks.h" +#include "msm_cvp_debug.h" +#include "msm_cvp_dsp.h" + +struct cvp_power_level { + unsigned long core_sum; + unsigned long op_core_sum; + unsigned long bw_sum; +}; + +int msm_cvp_update_power(struct msm_cvp_inst *inst); +unsigned int msm_cvp_get_hw_aggregate_cycles(enum hfi_hw_thread hwblk); +int cvp_check_clock(struct msm_cvp_inst *inst, + struct cvp_hfi_msg_session_hdr_ext *hdr); +bool check_clock_required(struct msm_cvp_inst *inst, + struct eva_kmd_hfi_packet *hdr); +#endif diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 22de79f817..7273510b4c 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -8,21 +8,13 @@ #include "cvp_core_hfi.h" #include "msm_cvp_buf.h" #include "cvp_comm_def.h" - -struct cvp_power_level { - unsigned long core_sum; - unsigned long op_core_sum; - unsigned long bw_sum; -}; +#include "cvp_power.h" static int cvp_enqueue_pkt(struct msm_cvp_inst* inst, struct eva_kmd_hfi_packet *in_pkt, unsigned int in_offset, unsigned int in_buf_num); -static int cvp_check_clock(struct msm_cvp_inst *inst, - struct cvp_hfi_msg_session_hdr_ext *hdr); - int msm_cvp_get_session_info(struct msm_cvp_inst *inst, u32 *session) { int rc = 0; @@ -133,38 +125,6 @@ exit: return rc; } -static bool check_clock_required(struct msm_cvp_inst *inst, - struct eva_kmd_hfi_packet *hdr) -{ - struct cvp_hfi_msg_session_hdr_ext *ehdr = - (struct cvp_hfi_msg_session_hdr_ext *)hdr; - bool clock_check = false; - - if (!msm_cvp_dcvs_disable && - ehdr->packet_type == HFI_MSG_SESSION_CVP_FD) { - if (ehdr->size == sizeof(struct cvp_hfi_msg_session_hdr_ext) - + sizeof(struct cvp_hfi_buf_type)) { - struct msm_cvp_core *core = inst->core; - - dprintk(CVP_PWR, "busy cycle %d, total %d\n", - ehdr->busy_cycles, ehdr->total_cycles); - - if (core->dyn_clk.sum_fps[HFI_HW_FDU] || - core->dyn_clk.sum_fps[HFI_HW_MPU] || - core->dyn_clk.sum_fps[HFI_HW_OD] || - core->dyn_clk.sum_fps[HFI_HW_ICA]) { - clock_check = true; - } - } else { - dprintk(CVP_WARN, "dcvs is disabled, %d != %d + %d\n", - ehdr->size, sizeof(struct cvp_hfi_msg_session_hdr_ext), - sizeof(struct cvp_hfi_buf_type)); - } - } - - return clock_check; -} - static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst, struct eva_kmd_hfi_packet *out_pkt) { @@ -308,173 +268,6 @@ static bool cvp_fence_wait(struct cvp_fence_queue *q, return true; } -static int cvp_readjust_clock(struct msm_cvp_core *core, - u32 avg_cycles, enum hfi_hw_thread i) -{ - int rc = 0; - struct allowed_clock_rates_table *tbl = NULL; - unsigned int tbl_size = 0; - unsigned int cvp_min_rate = 0, cvp_max_rate = 0; - unsigned long tmp = core->curr_freq; - unsigned long lo_freq = 0; - u32 j; - - tbl = core->resources.allowed_clks_tbl; - tbl_size = core->resources.allowed_clks_tbl_size; - cvp_min_rate = tbl[0].clock_rate; - cvp_max_rate = tbl[tbl_size - 1].clock_rate; - - if (!((avg_cycles > core->dyn_clk.hi_ctrl_lim[i] && - core->curr_freq != cvp_max_rate) || - (avg_cycles <= core->dyn_clk.lo_ctrl_lim[i] && - core->curr_freq != cvp_min_rate))) { - return rc; - } - - core->curr_freq = ((avg_cycles * core->dyn_clk.sum_fps[i]) << 1)/3; - dprintk(CVP_PWR, - "%s - cycles tot %u, avg %u. sum_fps %u, cur_freq %u\n", - __func__, - core->dyn_clk.cycle[i].total, - avg_cycles, - core->dyn_clk.sum_fps[i], - core->curr_freq); - - if (core->curr_freq > cvp_max_rate) { - core->curr_freq = cvp_max_rate; - lo_freq = (tbl_size > 1) ? - tbl[tbl_size - 2].clock_rate : - cvp_min_rate; - } else if (core->curr_freq <= cvp_min_rate) { - core->curr_freq = cvp_min_rate; - lo_freq = cvp_min_rate; - } else { - for (j = 1; j < tbl_size; j++) - if (core->curr_freq <= tbl[j].clock_rate) - break; - core->curr_freq = tbl[j].clock_rate; - lo_freq = tbl[j-1].clock_rate; - } - - if (core->orig_core_sum > core->curr_freq) { - dprintk(CVP_PWR, - "%s - %d - Cancel readjust, core %u, freq %u\n", - __func__, i, core->orig_core_sum, core->curr_freq); - core->curr_freq = tmp; - return rc; - } - - dprintk(CVP_PWR, - "%s:%d - %d - Readjust to %u\n", - __func__, __LINE__, i, core->curr_freq); - rc = msm_cvp_set_clocks(core); - if (rc) { - dprintk(CVP_ERR, - "Failed to set clock rate %u: %d %s\n", - core->curr_freq, rc, __func__); - core->curr_freq = tmp; - } else { - lo_freq = (lo_freq < core->dyn_clk.conf_freq) ? - core->dyn_clk.conf_freq : lo_freq; - core->dyn_clk.hi_ctrl_lim[i] = core->dyn_clk.sum_fps[i] ? - ((core->curr_freq*3)>>1)/core->dyn_clk.sum_fps[i] : 0; - core->dyn_clk.lo_ctrl_lim[i] = - core->dyn_clk.sum_fps[i] ? - ((lo_freq*3)>>1)/core->dyn_clk.sum_fps[i] : 0; - - dprintk(CVP_PWR, - "%s - Readjust clk to %u. New lim [%d] hi %u lo %u\n", - __func__, core->curr_freq, i, - core->dyn_clk.hi_ctrl_lim[i], - core->dyn_clk.lo_ctrl_lim[i]); - } - - return rc; -} - -static int cvp_check_clock(struct msm_cvp_inst *inst, - struct cvp_hfi_msg_session_hdr_ext *hdr) -{ - int rc = 0; - u32 i, j; - u32 hw_cycles[HFI_MAX_HW_THREADS] = {0}; - u32 fw_cycles = 0; - struct msm_cvp_core *core = inst->core; - - for (i = 0; i < HFI_MAX_HW_ACTIVATIONS_PER_FRAME; ++i) - fw_cycles += hdr->fw_cycles[i]; - - for (i = 0; i < HFI_MAX_HW_THREADS; ++i) - for (j = 0; j < HFI_MAX_HW_ACTIVATIONS_PER_FRAME; ++j) - hw_cycles[i] += hdr->hw_cycles[i][j]; - - dprintk(CVP_PWR, "%s - cycles fw %u. FDU %d MPU %d ODU %d ICA %d\n", - __func__, fw_cycles, hw_cycles[0], - hw_cycles[1], hw_cycles[2], hw_cycles[3]); - - mutex_lock(&core->clk_lock); - for (i = 0; i < HFI_MAX_HW_THREADS; ++i) { - dprintk(CVP_PWR, "%s - %d: hw_cycles %u, tens_thresh %u\n", - __func__, i, hw_cycles[i], - core->dyn_clk.hi_ctrl_lim[i]); - if (core->dyn_clk.hi_ctrl_lim[i]) { - if (core->dyn_clk.cycle[i].size < CVP_CYCLE_STAT_SIZE) - core->dyn_clk.cycle[i].size++; - else - core->dyn_clk.cycle[i].total -= - core->dyn_clk.cycle[i].busy[ - core->dyn_clk.cycle[i].idx]; - if (hw_cycles[i]) { - core->dyn_clk.cycle[i].busy[ - core->dyn_clk.cycle[i].idx] - = hw_cycles[i] + fw_cycles; - core->dyn_clk.cycle[i].total - += hw_cycles[i] + fw_cycles; - dprintk(CVP_PWR, - "%s: busy (hw + fw) cycles = %u\n", - __func__, - core->dyn_clk.cycle[i].busy[ - core->dyn_clk.cycle[i].idx]); - dprintk(CVP_PWR, "total cycles %u\n", - core->dyn_clk.cycle[i].total); - } else { - core->dyn_clk.cycle[i].busy[ - core->dyn_clk.cycle[i].idx] = - hdr->busy_cycles; - core->dyn_clk.cycle[i].total += - hdr->busy_cycles; - dprintk(CVP_PWR, - "%s - busy cycles = %u total %u\n", - __func__, - core->dyn_clk.cycle[i].busy[ - core->dyn_clk.cycle[i].idx], - core->dyn_clk.cycle[i].total); - } - - core->dyn_clk.cycle[i].idx = - (core->dyn_clk.cycle[i].idx == - CVP_CYCLE_STAT_SIZE-1) ? - 0 : core->dyn_clk.cycle[i].idx+1; - - dprintk(CVP_PWR, "%s - %d: size %u, tens_thresh %u\n", - __func__, i, core->dyn_clk.cycle[i].size, - core->dyn_clk.hi_ctrl_lim[i]); - if (core->dyn_clk.cycle[i].size == CVP_CYCLE_STAT_SIZE - && core->dyn_clk.hi_ctrl_lim[i] != 0) { - u32 avg_cycles = - core->dyn_clk.cycle[i].total>>3; - - rc = cvp_readjust_clock(core, - avg_cycles, - i); - } - } - } - mutex_unlock(&core->clk_lock); - - return rc; -} - static int cvp_fence_proc(struct msm_cvp_inst *inst, struct cvp_fence_command *fc, struct cvp_hfi_cmd_session_hdr *pkt) @@ -930,265 +723,6 @@ static inline int div_by_1dot5(unsigned int a) return (unsigned int) i/3; } -static inline int max_3(unsigned int a, unsigned int b, unsigned int c) -{ - return (a >= b) ? ((a >= c) ? a : c) : ((b >= c) ? b : c); -} - -static bool is_subblock_profile_existed(struct msm_cvp_inst *inst) -{ - return (inst->prop.od_cycles || - inst->prop.mpu_cycles || - inst->prop.fdu_cycles || - inst->prop.ica_cycles); -} - -static void aggregate_power_update(struct msm_cvp_core *core, - struct cvp_power_level *nrt_pwr, - struct cvp_power_level *rt_pwr, - unsigned int max_clk_rate) -{ - struct msm_cvp_inst *inst; - int i; - unsigned long fdu_sum[2] = {0}, od_sum[2] = {0}, mpu_sum[2] = {0}; - unsigned long ica_sum[2] = {0}, fw_sum[2] = {0}; - unsigned long op_fdu_max[2] = {0}, op_od_max[2] = {0}; - unsigned long op_mpu_max[2] = {0}, op_ica_max[2] = {0}; - unsigned long op_fw_max[2] = {0}, bw_sum[2] = {0}, op_bw_max[2] = {0}; - core->dyn_clk.sum_fps[HFI_HW_FDU] = 0; - core->dyn_clk.sum_fps[HFI_HW_MPU] = 0; - core->dyn_clk.sum_fps[HFI_HW_OD] = 0; - core->dyn_clk.sum_fps[HFI_HW_ICA] = 0; - - list_for_each_entry(inst, &core->instances, list) { - if (inst->state == MSM_CVP_CORE_INVALID || - inst->state == MSM_CVP_CORE_UNINIT || - !is_subblock_profile_existed(inst)) - continue; - if (inst->prop.priority <= CVP_RT_PRIO_THRESHOLD) { - /* Non-realtime session use index 0 */ - i = 0; - } else { - i = 1; - } - dprintk(CVP_PROF, "pwrUpdate fdu %u od %u mpu %u ica %u\n", - inst->prop.fdu_cycles, - inst->prop.od_cycles, - inst->prop.mpu_cycles, - inst->prop.ica_cycles); - - dprintk(CVP_PROF, "pwrUpdate fw %u fdu_o %u od_o %u mpu_o %u\n", - inst->prop.fw_cycles, - inst->prop.fdu_op_cycles, - inst->prop.od_op_cycles, - inst->prop.mpu_op_cycles); - - dprintk(CVP_PROF, "pwrUpdate ica_o %u fw_o %u bw %u bw_o %u\n", - inst->prop.ica_op_cycles, - inst->prop.fw_op_cycles, - inst->prop.ddr_bw, - inst->prop.ddr_op_bw); - - fdu_sum[i] += inst->prop.fdu_cycles; - od_sum[i] += inst->prop.od_cycles; - mpu_sum[i] += inst->prop.mpu_cycles; - ica_sum[i] += inst->prop.ica_cycles; - fw_sum[i] += inst->prop.fw_cycles; - op_fdu_max[i] = - (op_fdu_max[i] >= inst->prop.fdu_op_cycles) ? - op_fdu_max[i] : inst->prop.fdu_op_cycles; - op_od_max[i] = - (op_od_max[i] >= inst->prop.od_op_cycles) ? - op_od_max[i] : inst->prop.od_op_cycles; - op_mpu_max[i] = - (op_mpu_max[i] >= inst->prop.mpu_op_cycles) ? - op_mpu_max[i] : inst->prop.mpu_op_cycles; - op_ica_max[i] = - (op_ica_max[i] >= inst->prop.ica_op_cycles) ? - op_ica_max[i] : inst->prop.ica_op_cycles; - op_fw_max[i] = - (op_fw_max[i] >= inst->prop.fw_op_cycles) ? - op_fw_max[i] : inst->prop.fw_op_cycles; - bw_sum[i] += inst->prop.ddr_bw; - op_bw_max[i] = - (op_bw_max[i] >= inst->prop.ddr_op_bw) ? - op_bw_max[i] : inst->prop.ddr_op_bw; - - dprintk(CVP_PWR, "%s:%d - fps fdu %d mpu %d od %d ica %d\n", - __func__, __LINE__, - inst->prop.fps[HFI_HW_FDU], inst->prop.fps[HFI_HW_MPU], - inst->prop.fps[HFI_HW_OD], inst->prop.fps[HFI_HW_ICA]); - core->dyn_clk.sum_fps[HFI_HW_FDU] += inst->prop.fps[HFI_HW_FDU]; - core->dyn_clk.sum_fps[HFI_HW_MPU] += inst->prop.fps[HFI_HW_MPU]; - core->dyn_clk.sum_fps[HFI_HW_OD] += inst->prop.fps[HFI_HW_OD]; - core->dyn_clk.sum_fps[HFI_HW_ICA] += inst->prop.fps[HFI_HW_ICA]; - dprintk(CVP_PWR, "%s:%d - sum_fps fdu %d mpu %d od %d ica %d\n", - __func__, __LINE__, - core->dyn_clk.sum_fps[HFI_HW_FDU], - core->dyn_clk.sum_fps[HFI_HW_MPU], - core->dyn_clk.sum_fps[HFI_HW_OD], - core->dyn_clk.sum_fps[HFI_HW_ICA]); - } - - for (i = 0; i < 2; i++) { - fdu_sum[i] = max_3(fdu_sum[i], od_sum[i], mpu_sum[i]); - fdu_sum[i] = max_3(fdu_sum[i], ica_sum[i], fw_sum[i]); - - op_fdu_max[i] = max_3(op_fdu_max[i], op_od_max[i], - op_mpu_max[i]); - op_fdu_max[i] = max_3(op_fdu_max[i], - op_ica_max[i], op_fw_max[i]); - op_fdu_max[i] = - (op_fdu_max[i] > max_clk_rate) ? - max_clk_rate : op_fdu_max[i]; - bw_sum[i] = (bw_sum[i] >= op_bw_max[i]) ? - bw_sum[i] : op_bw_max[i]; - } - - nrt_pwr->core_sum += fdu_sum[0]; - nrt_pwr->op_core_sum = (nrt_pwr->op_core_sum >= op_fdu_max[0]) ? - nrt_pwr->op_core_sum : op_fdu_max[0]; - nrt_pwr->bw_sum += bw_sum[0]; - rt_pwr->core_sum += fdu_sum[1]; - rt_pwr->op_core_sum = (rt_pwr->op_core_sum >= op_fdu_max[1]) ? - rt_pwr->op_core_sum : op_fdu_max[1]; - rt_pwr->bw_sum += bw_sum[1]; -} - -/** - * adjust_bw_freqs(): calculate CVP clock freq and bw required to sustain - * required use case. - * Bandwidth vote will be best-effort, not returning error if the request - * b/w exceeds max limit. - * Clock vote from non-realtime sessions will be best effort, not returning - * error if the aggreated session clock request exceeds max limit. - * Clock vote from realtime session will be hard request. If aggregated - * session clock request exceeds max limit, the function will return - * error. - * - * Ensure caller acquires clk_lock! - */ -static int adjust_bw_freqs(void) -{ - struct msm_cvp_core *core; - struct iris_hfi_device *hdev; - struct bus_info *bus; - struct clock_set *clocks; - struct clock_info *cl; - struct allowed_clock_rates_table *tbl = NULL; - unsigned int tbl_size; - unsigned int cvp_min_rate, cvp_max_rate, max_bw, min_bw; - struct cvp_power_level rt_pwr = {0}, nrt_pwr = {0}; - unsigned long tmp, core_sum, op_core_sum, bw_sum; - int i, rc = 0; - unsigned long ctrl_freq; - - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); - - hdev = core->device->hfi_device_data; - clocks = &core->resources.clock_set; - cl = &clocks->clock_tbl[clocks->count - 1]; - tbl = core->resources.allowed_clks_tbl; - tbl_size = core->resources.allowed_clks_tbl_size; - cvp_min_rate = tbl[0].clock_rate; - cvp_max_rate = tbl[tbl_size - 1].clock_rate; - bus = &core->resources.bus_set.bus_tbl[1]; - max_bw = bus->range[1]; - min_bw = max_bw/10; - - aggregate_power_update(core, &nrt_pwr, &rt_pwr, cvp_max_rate); - dprintk(CVP_PROF, "PwrUpdate nrt %u %u rt %u %u\n", - nrt_pwr.core_sum, nrt_pwr.op_core_sum, - rt_pwr.core_sum, rt_pwr.op_core_sum); - - if (rt_pwr.core_sum > cvp_max_rate) { - dprintk(CVP_WARN, "%s clk vote out of range %lld\n", - __func__, rt_pwr.core_sum); - return -ENOTSUPP; - } - - core_sum = rt_pwr.core_sum + nrt_pwr.core_sum; - op_core_sum = (rt_pwr.op_core_sum >= nrt_pwr.op_core_sum) ? - rt_pwr.op_core_sum : nrt_pwr.op_core_sum; - - core_sum = (core_sum >= op_core_sum) ? - core_sum : op_core_sum; - - if (core_sum > cvp_max_rate) { - core_sum = cvp_max_rate; - } else if (core_sum <= cvp_min_rate) { - core_sum = cvp_min_rate; - } else { - for (i = 1; i < tbl_size; i++) - if (core_sum <= tbl[i].clock_rate) - break; - core_sum = tbl[i].clock_rate; - } - - bw_sum = rt_pwr.bw_sum + nrt_pwr.bw_sum; - bw_sum = bw_sum >> 10; - bw_sum = (bw_sum > max_bw) ? max_bw : bw_sum; - bw_sum = (bw_sum < min_bw) ? min_bw : bw_sum; - - dprintk(CVP_PROF, "%s %lld %lld\n", __func__, - core_sum, bw_sum); - if (!cl->has_scaling) { - dprintk(CVP_ERR, "Cannot scale CVP clock\n"); - return -EINVAL; - } - - tmp = core->curr_freq; - core->curr_freq = core_sum; - core->orig_core_sum = core_sum; - rc = msm_cvp_set_clocks(core); - if (rc) { - dprintk(CVP_ERR, - "Failed to set clock rate %u %s: %d %s\n", - core_sum, cl->name, rc, __func__); - core->curr_freq = tmp; - return rc; - } - - ctrl_freq = (core->curr_freq*3)>>1; - core->dyn_clk.conf_freq = core->curr_freq; - for (i = 0; i < HFI_MAX_HW_THREADS; ++i) { - core->dyn_clk.hi_ctrl_lim[i] = core->dyn_clk.sum_fps[i] ? - ctrl_freq/core->dyn_clk.sum_fps[i] : 0; - core->dyn_clk.lo_ctrl_lim[i] = - core->dyn_clk.hi_ctrl_lim[i]; - } - - hdev->clk_freq = core->curr_freq; - rc = msm_cvp_set_bw(bus, bw_sum); - - return rc; -} - -int msm_cvp_update_power(struct msm_cvp_inst *inst) -{ - int rc = 0; - struct msm_cvp_core *core; - struct msm_cvp_inst *s; - - if (!inst) { - dprintk(CVP_ERR, "%s: invalid params\n", __func__); - return -EINVAL; - } - - s = cvp_get_inst_validate(inst->core, inst); - if (!s) - return -ECONNRESET; - - core = inst->core; - - mutex_lock(&core->clk_lock); - rc = adjust_bw_freqs(); - mutex_unlock(&core->clk_lock); - cvp_put_inst(s); - - return rc; -} - int msm_cvp_session_delete(struct msm_cvp_inst *inst) { return 0; @@ -1437,57 +971,6 @@ static int msm_cvp_session_ctrl(struct msm_cvp_inst *inst, return rc; } -static unsigned int msm_cvp_get_hw_aggregate_cycles(enum hw_block hwblk) -{ - struct msm_cvp_core *core; - struct msm_cvp_inst *inst; - unsigned long cycles_sum = 0; - - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); - - if (!core) { - dprintk(CVP_ERR, "%s: invalid core\n", __func__); - return -EINVAL; - } - - mutex_lock(&core->clk_lock); - list_for_each_entry(inst, &core->instances, list) { - if (inst->state == MSM_CVP_CORE_INVALID || - inst->state == MSM_CVP_CORE_UNINIT || - !is_subblock_profile_existed(inst)) - continue; - switch (hwblk) { - case CVP_FDU: - { - cycles_sum += inst->prop.fdu_cycles; - break; - } - case CVP_ICA: - { - cycles_sum += inst->prop.ica_cycles; - break; - } - case CVP_MPU: - { - cycles_sum += inst->prop.mpu_cycles; - break; - } - case CVP_OD: - { - cycles_sum += inst->prop.od_cycles; - break; - } - default: - dprintk(CVP_ERR, "unrecognized hw block %d\n", - hwblk); - break; - } - } - mutex_unlock(&core->clk_lock); - cycles_sum = cycles_sum&0xFFFFFFFF; - return (unsigned int)cycles_sum; -} - static int msm_cvp_get_sysprop(struct msm_cvp_inst *inst, struct eva_kmd_arg *arg) { @@ -1535,25 +1018,55 @@ static int msm_cvp_get_sysprop(struct msm_cvp_inst *inst, case EVA_KMD_PROP_PWR_FDU: { props->prop_data[i].data = - msm_cvp_get_hw_aggregate_cycles(CVP_FDU); + msm_cvp_get_hw_aggregate_cycles(HFI_HW_FDU); break; } case EVA_KMD_PROP_PWR_ICA: { props->prop_data[i].data = - msm_cvp_get_hw_aggregate_cycles(CVP_ICA); + msm_cvp_get_hw_aggregate_cycles(HFI_HW_ICA); break; } case EVA_KMD_PROP_PWR_OD: { props->prop_data[i].data = - msm_cvp_get_hw_aggregate_cycles(CVP_OD); + msm_cvp_get_hw_aggregate_cycles(HFI_HW_OD); break; } case EVA_KMD_PROP_PWR_MPU: { props->prop_data[i].data = - msm_cvp_get_hw_aggregate_cycles(CVP_MPU); + msm_cvp_get_hw_aggregate_cycles(HFI_HW_MPU); + break; + } + case EVA_KMD_PROP_PWR_VADL: + { + props->prop_data[i].data = + msm_cvp_get_hw_aggregate_cycles(HFI_HW_VADL); + break; + } + case EVA_KMD_PROP_PWR_TOF: + { + props->prop_data[i].data = + msm_cvp_get_hw_aggregate_cycles(HFI_HW_TOF); + break; + } + case EVA_KMD_PROP_PWR_RGE: + { + props->prop_data[i].data = + msm_cvp_get_hw_aggregate_cycles(HFI_HW_RGE); + break; + } + case EVA_KMD_PROP_PWR_XRA: + { + props->prop_data[i].data = + msm_cvp_get_hw_aggregate_cycles(HFI_HW_XRA); + break; + } + case EVA_KMD_PROP_PWR_LSR: + { + props->prop_data[i].data = + msm_cvp_get_hw_aggregate_cycles(HFI_HW_LSR); break; } default: @@ -1605,17 +1118,32 @@ static int msm_cvp_set_sysprop(struct msm_cvp_inst *inst, session_prop->dsp_mask = prop_array[i].data; break; case EVA_KMD_PROP_PWR_FDU: - session_prop->fdu_cycles = prop_array[i].data; + session_prop->cycles[HFI_HW_FDU] = prop_array[i].data; break; case EVA_KMD_PROP_PWR_ICA: - session_prop->ica_cycles = + session_prop->cycles[HFI_HW_ICA] = div_by_1dot5(prop_array[i].data); break; case EVA_KMD_PROP_PWR_OD: - session_prop->od_cycles = prop_array[i].data; + session_prop->cycles[HFI_HW_OD] = prop_array[i].data; break; case EVA_KMD_PROP_PWR_MPU: - session_prop->mpu_cycles = prop_array[i].data; + session_prop->cycles[HFI_HW_MPU] = prop_array[i].data; + break; + case EVA_KMD_PROP_PWR_VADL: + session_prop->cycles[HFI_HW_VADL] = prop_array[i].data; + break; + case EVA_KMD_PROP_PWR_TOF: + session_prop->cycles[HFI_HW_TOF] = prop_array[i].data; + break; + case EVA_KMD_PROP_PWR_RGE: + session_prop->cycles[HFI_HW_RGE] = prop_array[i].data; + break; + case EVA_KMD_PROP_PWR_XRA: + session_prop->cycles[HFI_HW_XRA] = prop_array[i].data; + break; + case EVA_KMD_PROP_PWR_LSR: + session_prop->cycles[HFI_HW_LSR] = prop_array[i].data; break; case EVA_KMD_PROP_PWR_FW: session_prop->fw_cycles = @@ -1628,17 +1156,32 @@ static int msm_cvp_set_sysprop(struct msm_cvp_inst *inst, session_prop->ddr_cache = prop_array[i].data; break; case EVA_KMD_PROP_PWR_FDU_OP: - session_prop->fdu_op_cycles = prop_array[i].data; + session_prop->op_cycles[HFI_HW_FDU] = prop_array[i].data; break; case EVA_KMD_PROP_PWR_ICA_OP: - session_prop->ica_op_cycles = + session_prop->op_cycles[HFI_HW_ICA] = div_by_1dot5(prop_array[i].data); break; case EVA_KMD_PROP_PWR_OD_OP: - session_prop->od_op_cycles = prop_array[i].data; + session_prop->op_cycles[HFI_HW_OD] = prop_array[i].data; break; case EVA_KMD_PROP_PWR_MPU_OP: - session_prop->mpu_op_cycles = prop_array[i].data; + session_prop->op_cycles[HFI_HW_MPU] = prop_array[i].data; + break; + case EVA_KMD_PROP_PWR_VADL_OP: + session_prop->op_cycles[HFI_HW_VADL] = prop_array[i].data; + break; + case EVA_KMD_PROP_PWR_TOF_OP: + session_prop->op_cycles[HFI_HW_TOF] = prop_array[i].data; + break; + case EVA_KMD_PROP_PWR_RGE_OP: + session_prop->op_cycles[HFI_HW_RGE] = prop_array[i].data; + break; + case EVA_KMD_PROP_PWR_XRA_OP: + session_prop->op_cycles[HFI_HW_XRA] = prop_array[i].data; + break; + case EVA_KMD_PROP_PWR_LSR_OP: + session_prop->op_cycles[HFI_HW_LSR] = prop_array[i].data; break; case EVA_KMD_PROP_PWR_FW_OP: session_prop->fw_op_cycles = @@ -1662,6 +1205,21 @@ static int msm_cvp_set_sysprop(struct msm_cvp_inst *inst, case EVA_KMD_PROP_PWR_FPS_ICA: session_prop->fps[HFI_HW_ICA] = prop_array[i].data; break; + case EVA_KMD_PROP_PWR_FPS_VADL: + session_prop->fps[HFI_HW_VADL] = prop_array[i].data; + break; + case EVA_KMD_PROP_PWR_FPS_TOF: + session_prop->fps[HFI_HW_TOF] = prop_array[i].data; + break; + case EVA_KMD_PROP_PWR_FPS_RGE: + session_prop->fps[HFI_HW_RGE] = prop_array[i].data; + break; + case EVA_KMD_PROP_PWR_FPS_XRA: + session_prop->fps[HFI_HW_XRA] = prop_array[i].data; + break; + case EVA_KMD_PROP_PWR_FPS_LSR: + session_prop->fps[HFI_HW_LSR] = prop_array[i].data; + break; case EVA_KMD_PROP_SESSION_DUMPOFFSET: session_prop->dump_offset = prop_array[i].data; break; diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index b28efb0b43..ac6974a4d5 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1627,17 +1627,17 @@ static void __dsp_cvp_power_req(struct cvp_dsp_cmd_msg *cmd) print_power(&dsp2cpu_cmd->power_req); - inst->prop.fdu_cycles = dsp2cpu_cmd->power_req.clock_fdu; - inst->prop.ica_cycles = dsp2cpu_cmd->power_req.clock_ica; - inst->prop.od_cycles = dsp2cpu_cmd->power_req.clock_od; - inst->prop.mpu_cycles = dsp2cpu_cmd->power_req.clock_mpu; + inst->prop.cycles[HFI_HW_FDU] = dsp2cpu_cmd->power_req.clock_fdu; + inst->prop.cycles[HFI_HW_ICA] = dsp2cpu_cmd->power_req.clock_ica; + inst->prop.cycles[HFI_HW_OD] = dsp2cpu_cmd->power_req.clock_od; + inst->prop.cycles[HFI_HW_MPU] = dsp2cpu_cmd->power_req.clock_mpu; inst->prop.fw_cycles = dsp2cpu_cmd->power_req.clock_fw; inst->prop.ddr_bw = dsp2cpu_cmd->power_req.bw_ddr; inst->prop.ddr_cache = dsp2cpu_cmd->power_req.bw_sys_cache; - inst->prop.fdu_op_cycles = dsp2cpu_cmd->power_req.op_clock_fdu; - inst->prop.ica_op_cycles = dsp2cpu_cmd->power_req.op_clock_ica; - inst->prop.od_op_cycles = dsp2cpu_cmd->power_req.op_clock_od; - inst->prop.mpu_op_cycles = dsp2cpu_cmd->power_req.op_clock_mpu; + inst->prop.op_cycles[HFI_HW_FDU] = dsp2cpu_cmd->power_req.op_clock_fdu; + inst->prop.op_cycles[HFI_HW_ICA] = dsp2cpu_cmd->power_req.op_clock_ica; + inst->prop.op_cycles[HFI_HW_OD] = dsp2cpu_cmd->power_req.op_clock_od; + inst->prop.op_cycles[HFI_HW_MPU] = dsp2cpu_cmd->power_req.op_clock_mpu; inst->prop.fw_op_cycles = dsp2cpu_cmd->power_req.op_clock_fw; inst->prop.ddr_op_bw = dsp2cpu_cmd->power_req.op_bw_ddr; inst->prop.ddr_op_cache = dsp2cpu_cmd->power_req.op_bw_sys_cache; diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index a99a1281ec..6c2c87e58e 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -55,18 +55,6 @@ enum cvp_core_state { CVP_CORE_INIT_DONE, }; -/* - * Do not change the enum values unless - * you know what you are doing - */ - -enum hw_block { - CVP_FDU = 0x0001, - CVP_ICA, - CVP_MPU, - CVP_OD -}; - enum instance_state { MSM_CVP_CORE_UNINIT_DONE = 0x0001, MSM_CVP_CORE_INIT, @@ -249,15 +237,9 @@ struct cvp_session_prop { u32 is_secure; u32 dsp_mask; u32 fthread_nr; - u32 fdu_cycles; - u32 od_cycles; - u32 mpu_cycles; - u32 ica_cycles; + u32 cycles[HFI_MAX_HW_THREADS]; u32 fw_cycles; - u32 fdu_op_cycles; - u32 od_op_cycles; - u32 mpu_op_cycles; - u32 ica_op_cycles; + u32 op_cycles[HFI_MAX_HW_THREADS]; u32 fw_op_cycles; u32 ddr_bw; u32 ddr_op_bw; From 1aed484f01a71c54dfbb422534db2c10199b1a04 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 19 Oct 2022 20:03:49 -0700 Subject: [PATCH 141/317] msm: eva: enabling support for data path bringup. Add checksum support per packet type, configurable. Add debug hook to print SID setting registers at SMMU fault. Enable Auto-PIL. Enable DSP interface. Change-Id: Ie1fd2c584681b751836854667981a3c10beb56d4 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 38 +++++++++++++++++++++++++++++++++++++ msm/eva/cvp_hfi_api.h | 2 ++ msm/eva/cvp_smem.c | 37 ++++++++++++++++++++++++++++++++++-- msm/eva/msm_cvp_buf.c | 2 +- msm/eva/msm_cvp_debug.c | 2 +- msm/eva/msm_cvp_platform.c | 2 +- msm/eva/msm_cvp_res_parse.c | 4 +++- 7 files changed, 81 insertions(+), 6 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index cd2a103aff..2c400eef3e 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -2298,6 +2298,43 @@ static int iris_hfi_session_clean(void *session) return 0; } +static int iris_debug_hook(void *device) +{ + struct iris_hfi_device *dev = device; + u32 val; + + if (!device) { + dprintk(CVP_ERR, "%s Invalid device\n", __func__); + return -ENODEV; + } +#define CVP0_CVP_SS_FDU_SECURE_ENABLE 0x90 +#define CVP0_CVP_SS_MPU_SECURE_ENABLE 0x94 +#define CVP0_CVP_SS_ARP_THREAD_0_SECURE_ENABLE 0xA0 +#define CVP0_CVP_SS_ARP_THREAD_1_SECURE_ENABLE 0xA4 +#define CVP0_CVP_SS_ARP_THREAD_2_SECURE_ENABLE 0xA8 +#define CVP0_CVP_SS_ARP_THREAD_3_SECURE_ENABLE 0xAC + + val = __read_register(dev, CVP0_CVP_SS_FDU_SECURE_ENABLE); + dprintk(CVP_ERR, "FDU_SECURE_ENABLE %#x\n", val); + + val = __read_register(dev, CVP0_CVP_SS_MPU_SECURE_ENABLE); + dprintk(CVP_ERR, "MPU_SECURE_ENABLE %#x\n", val); + + val = __read_register(dev, CVP0_CVP_SS_ARP_THREAD_0_SECURE_ENABLE); + dprintk(CVP_ERR, "ARP_THREAD_0_SECURE_ENABLE %#x\n", val); + + val = __read_register(dev, CVP0_CVP_SS_ARP_THREAD_1_SECURE_ENABLE); + dprintk(CVP_ERR, "ARP_THREAD_1_SECURE_ENABLE %#x\n", val); + + val = __read_register(dev, CVP0_CVP_SS_ARP_THREAD_2_SECURE_ENABLE); + dprintk(CVP_ERR, "ARP_THREAD_2_SECURE_ENABLE %#x\n", val); + + val = __read_register(dev, CVP0_CVP_SS_ARP_THREAD_3_SECURE_ENABLE); + dprintk(CVP_ERR, "ARP_THREAD_3_SECURE_ENABLE %#x\n", val); + + return 0; +} + static int iris_hfi_session_init(void *device, void *session_id, void **new_session) { @@ -4870,6 +4907,7 @@ static void iris_init_hfi_callbacks(struct cvp_hfi_device *hdev) hdev->noc_error_info = iris_hfi_noc_error_info; hdev->validate_session = iris_hfi_validate_session; hdev->pm_qos_update = iris_pm_qos_update; + hdev->debug_hook = iris_debug_hook; } int cvp_iris_hfi_initialize(struct cvp_hfi_device *hdev, u32 device_id, diff --git a/msm/eva/cvp_hfi_api.h b/msm/eva/cvp_hfi_api.h index e3dea9a61d..705db12cca 100644 --- a/msm/eva/cvp_hfi_api.h +++ b/msm/eva/cvp_hfi_api.h @@ -241,6 +241,7 @@ struct msm_cvp_hfi_defs { unsigned int size; unsigned int type; bool is_config_pkt; + bool checksum_enabled; enum hal_command_response resp; char name[PKT_NAME_LEN]; }; @@ -270,6 +271,7 @@ struct cvp_hfi_device { int (*noc_error_info)(void *dev); int (*validate_session)(void *sess, const char *func); int (*pm_qos_update)(void *device); + int (*debug_hook)(void *device); }; typedef void (*hfi_cmd_response_callback) (enum hal_command_response cmd, diff --git a/msm/eva/cvp_smem.c b/msm/eva/cvp_smem.c index d7f90009f3..2eb0c89a7b 100644 --- a/msm/eva/cvp_smem.c +++ b/msm/eva/cvp_smem.c @@ -211,7 +211,7 @@ int msm_cvp_map_smem(struct msm_cvp_inst *inst, int i, rc = 0; dma_addr_t iova = 0; - u32 temp = 0; + u32 temp = 0, checksum = 0; u32 align = SZ_4K; struct dma_buf *dma_buf; bool is_config_pkt = false; @@ -262,6 +262,20 @@ int msm_cvp_map_smem(struct msm_cvp_inst *inst, /* User persist buffer has no feature config info */ is_config_pkt = cvp_hfi_defs[i].is_config_pkt; + if (i > 0 && cvp_hfi_defs[i].checksum_enabled) { + dma_buf_begin_cpu_access(dma_buf, DMA_BIDIRECTIONAL); + smem->kvaddr = __cvp_dma_buf_vmap(dma_buf); + if (!smem->kvaddr) { + dprintk(CVP_WARN, "%s Fail map into kernel\n", + __func__); + dma_buf_end_cpu_access(dma_buf, DMA_BIDIRECTIONAL); + } else { + for (i = 0; i < 256; i++) + checksum += *(u32 *)(smem->kvaddr + i*sizeof(u32)); + dprintk(CVP_MEM, "Map checksum %#x fd=%d\n", + checksum, smem->fd); + } + } print_smem(CVP_MEM, str, inst, smem); atomic_inc(&inst->smem_count); goto success; @@ -277,7 +291,9 @@ int msm_cvp_unmap_smem(struct msm_cvp_inst *inst, struct msm_cvp_smem *smem, const char *str) { - int rc = 0; + int i, rc = 0; + u32 checksum = 0; + struct dma_buf *dma_buf; if (!smem) { dprintk(CVP_ERR, "%s: Invalid params: %pK\n", __func__, smem); @@ -286,6 +302,23 @@ int msm_cvp_unmap_smem(struct msm_cvp_inst *inst, } print_smem(CVP_MEM, str, inst, smem); + dma_buf = smem->dma_buf; + i = get_pkt_index_from_type(smem->pkt_type); + if (i > 0 && cvp_hfi_defs[i].checksum_enabled) { + if (!smem->kvaddr) { + dprintk(CVP_WARN, "%s DS buf Fail map into kernel\n", + __func__); + dma_buf_end_cpu_access(dma_buf, DMA_BIDIRECTIONAL); + } else { + for (i = 0; i < 256; i++) + checksum += *(u32 *)(smem->kvaddr + i*sizeof(u32)); + dprintk(CVP_MEM, "Unmap checksum %#x fd=%d\n", + checksum, smem->fd); + __cvp_dma_buf_vunmap(dma_buf, smem->kvaddr); + smem->kvaddr = 0; + dma_buf_end_cpu_access(dma_buf, DMA_BIDIRECTIONAL); + } + } rc = msm_dma_put_device_address(smem->flags, &smem->mapping_info); if (rc) { dprintk(CVP_ERR, "Failed to put device address: %d\n", rc); diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index a4e1e211e1..9d22df2191 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1794,7 +1794,7 @@ struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, /* PERSIST buffer requires secure mapping * Disable and wait for hyp_assign available */ - smem_flags |= SMEM_SECURE | SMEM_NON_PIXEL; + smem_flags |= SMEM_SECURE | SMEM_NON_PIXEL; buf = cvp_kmem_cache_zalloc(&cvp_driver->buf_cache, GFP_KERNEL); if (!buf) { diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 9da81cb07e..e2f7c4481e 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -22,7 +22,7 @@ int msm_cvp_fw_debug = 0x18; int msm_cvp_fw_debug_mode = 1; int msm_cvp_fw_low_power_mode = 0; /*disable during initial stage*/ bool msm_cvp_fw_coverage = !true; -bool msm_cvp_auto_pil = !true; /*disable during initial stage*/ +bool msm_cvp_auto_pil = true; bool msm_cvp_cacheop_enabled = true; bool msm_cvp_thermal_mitigation_disabled = !true; bool msm_cvp_cacheop_disabled = !true; diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index ae44e53d0f..3d2c88056f 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -247,7 +247,7 @@ static struct msm_cvp_common_data sm8650_common_data[] = { }, { .key = "qcom,dsp-enabled", - .value = 0, /* Disable during initial stage for Rumi 48 bringup */ + .value = 1, } }; diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index 8ebae0bcfd..776b0b315f 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -1019,8 +1019,10 @@ int msm_cvp_smmu_fault_handler(struct iommu_domain *domain, msm_cvp_print_inst_bufs(inst, log); } hdev = core->device->hfi_device_data; - if (hdev) + if (hdev) { hdev->error = CVP_ERR_NOC_ERROR; + call_hfi_op(core->device, debug_hook, hdev); + } mutex_unlock(&core->lock); /* * Return -EINVAL to elicit the default behaviour of smmu driver. From 7b624f7924ff31d11e3d3a00030495af52c59a4a Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 28 Oct 2022 11:17:24 -0700 Subject: [PATCH 142/317] msm: eva: Use dummy CB to map secure camera buf Per SMMU driver team recommendation. The "mapped" result will be the virtual addresss of S2 VM_SECURE_CAMERA page tables. Change-Id: Ide5a330e208e503182e4aa46a8fa2ba093202ced Signed-off-by: George Shen --- msm/eva/cvp_smem.c | 10 ++++------ msm/eva/msm_cvp_res_parse.c | 4 ++++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/msm/eva/cvp_smem.c b/msm/eva/cvp_smem.c index 2eb0c89a7b..3b36fef91d 100644 --- a/msm/eva/cvp_smem.c +++ b/msm/eva/cvp_smem.c @@ -114,11 +114,7 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, u32 align, } if (table->sgl) { - if (flags & SMEM_CAMERA) { - *iova = sg_phys(table->sgl); - } else { - *iova = table->sgl->dma_address; - } + *iova = table->sgl->dma_address; } else { dprintk(CVP_ERR, "sgl is NULL\n"); rc = -ENOMEM; @@ -538,6 +534,7 @@ struct context_bank_info *msm_cvp_smem_get_context_bank( char *non_secure_cb = "cvp_hlos"; char *secure_nonpixel_cb = "cvp_sec_nonpixel"; char *secure_pixel_cb = "cvp_sec_pixel"; + char *dummy_cb = "cvp_dummy"; bool is_secure = (flags & SMEM_SECURE) ? true : false; if (flags & SMEM_PIXEL) @@ -545,7 +542,8 @@ struct context_bank_info *msm_cvp_smem_get_context_bank( else if (flags & SMEM_NON_PIXEL) search_str = secure_nonpixel_cb; else if (flags & SMEM_CAMERA) - search_str = secure_pixel_cb; + /* Secure Camera pixel buffer */ + search_str = dummy_cb; else search_str = non_secure_cb; diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index 776b0b315f..99364010df 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -1063,6 +1063,9 @@ static int msm_cvp_populate_context_bank(struct device *dev, } dprintk(CVP_CORE, "%s: context bank has name %s\n", __func__, cb->name); + if (!strcmp(cb->name, "cvp_dummy")) + goto success_setup_cb; + rc = of_property_read_u32_array(np, "qcom,iommu-dma-addr-pool", (u32 *)&cb->addr_range, 2); if (rc) { @@ -1088,6 +1091,7 @@ static int msm_cvp_populate_context_bank(struct device *dev, cb->name, cb->addr_range.start, cb->addr_range.size, cb->buffer_type); +success_setup_cb: cb->domain = iommu_get_domain_for_dev(dev); if (IS_ERR_OR_NULL(cb->domain)) { dprintk(CVP_ERR, "Create domain failed\n"); From c96b96ee2d6ad94487d92bb6859c777281fd443b Mon Sep 17 00:00:00 2001 From: Aniruddh Sharma Date: Tue, 14 Jun 2022 22:54:00 +0530 Subject: [PATCH 143/317] msm: eva: Correction in the buffer validity check Offset of kmd_arg is expected to be in words (As we are feeding the offset in word size from UMD lib). Whereas the validity check function treats it as bytes which is wrong. This might lead to crash if lager offset is feed from UMD via ioctl call. Change-Id: I7de76cea5abe9a34d4194d041af7a3af7550d86d Signed-off-by: Aniruddh Sharma --- msm/eva/msm_cvp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp.h b/msm/eva/msm_cvp.h index 79ecf7434e..d64f91ab22 100644 --- a/msm/eva/msm_cvp.h +++ b/msm/eva/msm_cvp.h @@ -22,7 +22,7 @@ static inline bool is_buf_param_valid(u32 buf_num, u32 offset) if (buf_num > max_buf_num) return false; - if ((offset + buf_num * sizeof(struct cvp_buf_type)) > + if ((offset * sizeof(u32) + buf_num * sizeof(struct cvp_buf_type)) > sizeof(struct eva_kmd_hfi_packet)) return false; From 1002a6ed6a18130a6313a940222cea43fce1adb7 Mon Sep 17 00:00:00 2001 From: VIVEK VARDHAN JOSHI Date: Fri, 28 Oct 2022 19:54:18 +0530 Subject: [PATCH 144/317] EVA-kernel:Added DME mode HFI command to eva kernel Change-Id: I0d9d4ceac9cc5ffd2198570b383c15e47dab1b6f --- msm/eva/cvp_hfi.h | 7 +++++++ msm/eva/msm_cvp_platform.c | 17 +++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/msm/eva/cvp_hfi.h b/msm/eva/cvp_hfi.h index 390eb3989b..1e47b83b17 100644 --- a/msm/eva/cvp_hfi.h +++ b/msm/eva/cvp_hfi.h @@ -71,6 +71,11 @@ #define HFI_CMD_SESSION_CVP_DME_FRAME\ (HFI_CMD_SESSION_CVP_START + 0x03A) +#define HFI_CMD_SESSION_EVA_DME_ONLY_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x040) +#define HFI_CMD_SESSION_EVA_DME_ONLY_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x041) + #define HFI_CMD_SESSION_CVP_CV_TME_CONFIG\ (HFI_CMD_SESSION_CVP_START + 0x047) #define HFI_CMD_SESSION_CVP_CV_TME_FRAME\ @@ -210,6 +215,8 @@ #define HFI_MSG_SESSION_CVP_DME\ (HFI_MSG_SESSION_CVP_START + 0x023) +#define HFI_MSG_SESSION_EVA_DME_ONLY\ + (HFI_MSG_SESSION_CVP_START + 0x050) #define HFI_MSG_SESSION_CVP_OPERATION_CONFIG (HFI_MSG_SESSION_CVP_START + 0x030) #define HFI_MSG_SESSION_CVP_SET_PERSIST_BUFFERS\ diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 3d2c88056f..101de95d04 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -800,6 +800,23 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { .resp = HAL_NO_RESP, .name = "SYNX_TEST", }, + [HFI_CMD_SESSION_EVA_DME_ONLY_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_EVA_DME_ONLY_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "DME_CONFIG", + }, + [HFI_CMD_SESSION_EVA_DME_ONLY_FRAME - HFI_CMD_SESSION_CVP_START] = + { + .size = 0xFFFFFFFF, + .type = HFI_CMD_SESSION_EVA_DME_ONLY_FRAME, + .is_config_pkt = false, + .resp = HAL_NO_RESP, + .name = "DME_FRAME", + }, + }; int get_pkt_index(struct cvp_hal_session_cmd_pkt *hdr) From e8a2fe9b880cb2c1685433717cf343e8ea55edb2 Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 4 Nov 2022 12:47:51 -0700 Subject: [PATCH 145/317] msm: eva: Make synx packet config pkt Make kernel fencing works. Change-Id: Ib524c9ace64be89d05a516bf6ccbac64b133b219 Signed-off-by: George Shen --- msm/eva/msm_cvp.c | 15 +++++++++++---- msm/eva/msm_cvp_platform.c | 2 +- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 7273510b4c..a113488328 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -577,8 +577,7 @@ static int cvp_populate_fences( struct eva_kmd_hfi_packet *in_pkt, enum op_mode mode; struct cvp_buf_type *buf; - int rc; - rc = 0; + int rc = 0; q = &inst->fence_cmd_queue; @@ -592,6 +591,9 @@ static int cvp_populate_fences( struct eva_kmd_hfi_packet *in_pkt, goto exit; } + if (!cvp_kernel_fence_enabled) + goto exit; + cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; rc = cvp_alloc_fence_data((&f), cmd_hdr->size); if (rc) @@ -695,7 +697,11 @@ static int cvp_enqueue_pkt(struct msm_cvp_inst* inst, else rc = msm_cvp_map_frame(inst, in_pkt, in_offset, in_buf_num); - if (cvp_populate_fences(in_pkt, in_offset, in_buf_num, inst) == 0) { + if (rc) + return rc; + + rc = cvp_populate_fences(in_pkt, in_offset, in_buf_num, inst); + if (rc == 0) { rc = call_hfi_op(hdev, session_send, (void*)inst->session, in_pkt); if (rc) { @@ -708,7 +714,8 @@ static int cvp_enqueue_pkt(struct msm_cvp_inst* inst, } goto exit; } else { - dprintk(CVP_SYNX, "Going fenced path\n"); + if (rc > 0) + dprintk(CVP_SYNX, "Going fenced path\n"); goto exit; } diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 101de95d04..c89b69ce70 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -796,7 +796,7 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { { .size = 0xFFFFFFFF, .type = HFI_CMD_SESSION_CVP_SYNX, - .is_config_pkt = false, + .is_config_pkt = true, .resp = HAL_NO_RESP, .name = "SYNX_TEST", }, From c7a2d986df2da9d4a1ef14d993acf4a81666b5f7 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 7 Nov 2022 09:50:22 -0800 Subject: [PATCH 146/317] msm: eva: Fix dprintk compilation errors Shown in recent Lanai releases Change-Id: Ia85a57756a35f14d4426ea5ea10cd5374188a9d4 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 2 +- msm/eva/msm_cvp.c | 2 +- msm/eva/msm_cvp_common.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 2c400eef3e..3504761448 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -3628,7 +3628,7 @@ static int __enable_regulator(struct iris_hfi_device *device, return 0; } - dprintk(CVP_ERR, "regulator %s not found\n"); + dprintk(CVP_ERR, "regulator %s not found\n", name); return -EINVAL; } diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index a113488328..52eb2912b7 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -510,7 +510,7 @@ static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst, if (is_config_pkt) pr_info(CVP_DBG_TAG "inst %pK config %s\n", - inst, cvp_hfi_defs[idx].name); + "pkt", inst, cvp_hfi_defs[idx].name); rc = msm_cvp_map_frame(inst, (struct eva_kmd_hfi_packet *)pkt, offset, buf_num); diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index e0e76dc7bb..4d097ed56e 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -24,7 +24,7 @@ static void handle_session_error(enum hal_command_response cmd, void *data); static void msm_cvp_comm_generate_session_error(struct msm_cvp_inst *inst) { - dprintk(CVP_WARN, "%s function is deprecated\n"); + dprintk(CVP_WARN, "%s function is deprecated\n", __func__); } static void dump_hfi_queue(struct iris_hfi_device *device) From 816d381554a69f1c996cdd65bb0f759b057768a4 Mon Sep 17 00:00:00 2001 From: Ronald Karyodisa Date: Tue, 8 Nov 2022 09:29:44 -0800 Subject: [PATCH 147/317] msm: eva: Fix dprintk compilation errors Change-Id: Idc30f3b510ada403548f27df6dcb19793966e5f0 --- msm/eva/msm_cvp_buf.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 9d22df2191..84503caad0 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -98,7 +98,7 @@ static void print_internal_buffer(u32 tag, const char *str, } else { dprintk(tag, "%s: %x : idx %2d fd %d off %d size %d iova %#x", - str, hash32_ptr(inst->session), cbuf->fd, + str, hash32_ptr(inst->session), cbuf->index, cbuf->fd, cbuf->offset, cbuf->size, cbuf->smem->device_addr); } } @@ -108,7 +108,8 @@ void print_cvp_buffer(u32 tag, const char *str, struct msm_cvp_inst *inst, { if (!inst || !cbuf) dprintk(CVP_ERR, - "%s Invalid params inst %pK, cbuf %pK\n", inst, cbuf); + "%s Invalid params inst %pK, cbuf %pK\n", + str, inst, cbuf); print_smem(tag, str, inst, cbuf->smem); } @@ -690,7 +691,7 @@ static void _wncc_print_cvpwnccbufs_table(struct msm_cvp_inst* inst) return; } - dprintk(CVP_DBG, "%s: wncc buffer table:"); + dprintk(CVP_DBG, "%s: wncc buffer table:", __func__); for (i = 0; i < EVA_KMD_WNCC_MAX_SRC_BUFS && entries < inst->cvpwnccbufs_num; i++) { if (inst->cvpwnccbufs_table[i].iova != 0) { From d052ed9da6f77f9ccd571f04ab8cbeec1716ad19 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 10 Nov 2022 10:01:20 -0800 Subject: [PATCH 148/317] msm: eva: print kdata in MSG For presilicon debugging Change-Id: I4fc82e1a14d8f623f237c30e3ab63877ddfb97f5 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 3504761448..822235aa1c 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -2985,13 +2985,14 @@ static void print_msg_hdr(void *hdr) { struct cvp_hfi_msg_session_hdr *new_hdr = (struct cvp_hfi_msg_session_hdr *)hdr; - dprintk(CVP_HFI, "HFI MSG received: %x %x %x %x %x %x %x\n", + dprintk(CVP_HFI, "HFI MSG received: %x %x %x %x %x %x %x %#llx\n", new_hdr->size, new_hdr->packet_type, new_hdr->session_id, new_hdr->client_data.transaction_id, new_hdr->client_data.data1, new_hdr->client_data.data2, - new_hdr->error_type); + new_hdr->error_type, + new_hdr->client_data.kdata); } static int __response_handler(struct iris_hfi_device *device) From b92ce5157043bfc1cf56ba0573f3b6911d66e2ee Mon Sep 17 00:00:00 2001 From: Yu SI Date: Thu, 27 Oct 2022 17:31:33 -0700 Subject: [PATCH 149/317] msm: eva: add support for Synx fastRpc ko dependency --added support for Synx ko dependency --enable Synx compilation flag --added MODULE_SOFTDEP on synx-driver --similar updates applied for fastRPC --use KBUILD_REQUIRED_KOS instead of KBUILD_EXTRA_SYMBOLS --last patch disable synx temporarily Change-Id: Ib4fe2fd6b16e200f924f0105ece4363bc8c882e6 Signed-off-by: Yu SI --- Android.mk | 23 +++++++++++++++++++++-- msm/Kbuild | 1 + msm/eva/cvp.c | 2 ++ msm/eva/cvp_comm_def.h | 2 ++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/Android.mk b/Android.mk index 58cd734031..a02ff77dee 100644 --- a/Android.mk +++ b/Android.mk @@ -15,10 +15,29 @@ LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT) LOCAL_ADDITIONAL_DEPENDENCY := synx-driver.ko # export to kbuild -KBUILD_OPTIONS += KBUILD_EXTRA_SYMBOLS=$(shell pwd)/$(call intermediates-dir-for,DLKM,mmrm-module-symvers)/Module.symvers - +# Setup mmrm dependency LOCAL_REQUIRED_MODULES := mmrm-module-symvers LOCAL_ADDITIONAL_DEPENDENCIES := $(call intermediates-dir-for,DLKM,mmrm-module-symvers)/Module.symvers +KBUILD_REQUIRED_KOS += msm-mmrm.ko + +# Setup SynX dependency +CONFIG_SYNX := n +#ifdef CONFIG_SYNX +ifeq ($(CONFIG_SYNX), y) +$(warning Compiling SynX) +LOCAL_REQUIRED_MODULES += synx-driver-symvers +LOCAL_ADDITIONAL_DEPENDENCIES += $(call intermediates-dir-for,DLKM,synx-driver-symvers)/synx-driver-symvers +KBUILD_REQUIRED_KOS += synx-driver.ko +endif + +# Setup fastRPC dependency +CONFIG_FASTRPC := y +ifeq ($(CONFIG_FASTRPC), y) +$(warning Compiling FastRPC) +LOCAL_REQUIRED_MODULES += dsp-module-symvers +LOCAL_ADDITIONAL_DEPENDENCIES += $(call intermediates-dir-for,DLKM,dsp-module-symvers)/Module.symvers +KBUILD_REQUIRED_KOS += frpc-adsprpc.ko +endif # print out variables $(info KBUILD_OPTIONS = $(KBUILD_OPTIONS)) diff --git a/msm/Kbuild b/msm/Kbuild index 62f4820beb..accd759e7e 100644 --- a/msm/Kbuild +++ b/msm/Kbuild @@ -33,6 +33,7 @@ $(info within KBUILD file CONFIG_ARCH_PINEAPPLE = $(CONFIG_ARCH_PINEAPPLE)) KBUILD_CPPFLAGS += -DCONFIG_EVA_PINEAPPLE=1 -DCVP_CONFIG_SYNX_V2=1 ccflags-y += -DCONFIG_EVA_PINEAPPLE=1 -DCVP_CONFIG_SYNX_V2=1 ccflags-y += -I$(EVA_ROOT)/../synx-kernel/msm/synx/ \ + -I$(EVA_ROOT)/../dsp-kernel/include/ \ -I$(EVA_ROOT)/../synx-kernel/include/uapi/synx/media/ endif diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index 06a39aec08..aef273fb8e 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -649,5 +649,7 @@ module_init(msm_cvp_init); module_exit(msm_cvp_exit); MODULE_SOFTDEP("pre: msm-mmrm"); +MODULE_SOFTDEP("pre: synx-driver"); +MODULE_SOFTDEP("pre: frpc-adsprpc"); MODULE_LICENSE("GPL v2"); MODULE_IMPORT_NS(DMA_BUF); diff --git a/msm/eva/cvp_comm_def.h b/msm/eva/cvp_comm_def.h index a798a1b65e..5cb741f19d 100644 --- a/msm/eva/cvp_comm_def.h +++ b/msm/eva/cvp_comm_def.h @@ -37,6 +37,8 @@ enum queue_state { #ifdef CONFIG_EVA_PINEAPPLE #define CVP_MMRM_ENABLED 1 #define CVP_CONFIG_SYNX_V2 1 +/* #define CVP_SYNX_ENABLED 1 */ /* temp disable til Synx ready*/ +#define CVP_FASTRPC_ENABLED 1 #endif /* End of CONFIG_EVA_PINEAPPLE */ From 75bac2914597c9dc318fbf2861b4dc184ccebbc8 Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 15 Nov 2022 10:06:14 -0800 Subject: [PATCH 150/317] msm: eva: port eva-kernel.lnx.2.0 changes Change-Id: I3121f71a11c8a48081309ad46c04bedc6b6a3ca1 Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 7 +++---- msm/eva/msm_cvp_dsp.c | 7 +++++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 84503caad0..0d824e2d74 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -106,10 +106,12 @@ static void print_internal_buffer(u32 tag, const char *str, void print_cvp_buffer(u32 tag, const char *str, struct msm_cvp_inst *inst, struct cvp_internal_buf *cbuf) { - if (!inst || !cbuf) + if (!inst || !cbuf) { dprintk(CVP_ERR, "%s Invalid params inst %pK, cbuf %pK\n", str, inst, cbuf); + return; + } print_smem(tag, str, inst, cbuf->smem); } @@ -1272,9 +1274,6 @@ static struct msm_cvp_smem *msm_cvp_session_get_smem(struct msm_cvp_inst *inst, goto exit2; } - if (smem->fd != buf->fd) - dprintk(CVP_ERR, "%s Failed fd check\n", __func__); - return smem; exit2: diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index ac6974a4d5..242642db32 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -366,6 +366,11 @@ static struct cvp_dsp_fastrpc_driver_entry *pop_frpc_node(void) search_again: ptr = &me->fastrpc_driver_list.list; + if (!ptr) { + frpc_node = NULL; + goto exit; + } + mutex_lock(&me->fastrpc_driver_list.lock); list_for_each_safe(ptr, next, &me->fastrpc_driver_list.list) { frpc_node = list_entry(ptr, @@ -563,6 +568,8 @@ static void cvp_remove_dsp_sessions(void) while ((frpc_node = pop_frpc_node())) { s = &frpc_node->dsp_sessions.list; + if (!s) + return; list_for_each_safe(s, next_s, &frpc_node->dsp_sessions.list) { inst = list_entry(s, struct msm_cvp_inst, From 1fb08bdc09da3011925de9928b156705101152ba Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 15 Nov 2022 09:45:45 -0800 Subject: [PATCH 151/317] msm: eva: add RGE, VADL ITOF CB setting print Dumps registers to debug FW issue in setting CBs for CDM buffers. Change-Id: I287f18455f2a6b2f7cebd520c73a0de84030a8e6 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 70 +++++++++++++++++++++++++++++++++++++++++++++- msm/eva/cvp_smem.c | 2 ++ 2 files changed, 71 insertions(+), 1 deletion(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 822235aa1c..5632809838 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -2307,13 +2307,13 @@ static int iris_debug_hook(void *device) dprintk(CVP_ERR, "%s Invalid device\n", __func__); return -ENODEV; } + /******* FDU & MPU *****/ #define CVP0_CVP_SS_FDU_SECURE_ENABLE 0x90 #define CVP0_CVP_SS_MPU_SECURE_ENABLE 0x94 #define CVP0_CVP_SS_ARP_THREAD_0_SECURE_ENABLE 0xA0 #define CVP0_CVP_SS_ARP_THREAD_1_SECURE_ENABLE 0xA4 #define CVP0_CVP_SS_ARP_THREAD_2_SECURE_ENABLE 0xA8 #define CVP0_CVP_SS_ARP_THREAD_3_SECURE_ENABLE 0xAC - val = __read_register(dev, CVP0_CVP_SS_FDU_SECURE_ENABLE); dprintk(CVP_ERR, "FDU_SECURE_ENABLE %#x\n", val); @@ -2332,6 +2332,74 @@ static int iris_debug_hook(void *device) val = __read_register(dev, CVP0_CVP_SS_ARP_THREAD_3_SECURE_ENABLE); dprintk(CVP_ERR, "ARP_THREAD_3_SECURE_ENABLE %#x\n", val); + + /***** GCE ******* + * Bit 0 of below register is CDM secure enable for GCE + * CDM buffer will be in CB4 if set + */ +#define CVP_GCE_GCE_SS_CP_CTL 0x51100 + /* STATUS bit0 && CFG bit 4 of below register set, + * expect pixel buffers in CB3, + * otherwise in CB0 + * CFG bit 9:8 b01 -> LMC input in CB3 + * CFG bit 9:8 b10 -> LMC input in CB4 + */ +#define CVP_GCE0_CP_STATUS 0x51080 +#define CVP_GCE0_BIU_RD_INPUT_IF_SECURITY_CFG 0x52020 + + val = __read_register(dev, CVP_GCE_GCE_SS_CP_CTL); + dprintk(CVP_ERR, "CVP_GCE_GCE_SS_CP_CTL %#x\n", val); + val = __read_register(dev, CVP_GCE0_CP_STATUS); + dprintk(CVP_ERR, "CVP_GCE0_CP_STATUS %#x\n", val); + val = __read_register(dev, CVP_GCE0_BIU_RD_INPUT_IF_SECURITY_CFG); + dprintk(CVP_ERR, "CVP_GCE0_BIU_RD_INPUT_IF_SECURITY_CFG %#x\n", val); + /***** RGE ***** + * Bit 0 of below regiser is CDM secure enable for RGE + * CDM buffer to be in CB4 i fset + */ +#define CVP_RGE0_TOPRGE_CP_CTL 0x31010 + /* CFG bit 4 && IN bit 0: + * if both are set, expect CB3 or CB4 depending on IN 6:4 field + * either is clear, expect CB0 + */ +#define CVP_RGE0_BUS_RD_INPUT_IF_SECURITY_CFG 0x32020 +#define CVP_RGE0_TOPSPARE_IN 0x311F4 + + val = __read_register(dev, CVP_RGE0_TOPRGE_CP_CTL); + dprintk(CVP_ERR, "CVP_RGE0_TOPRGE_CP_CTL %#x\n", val); + val = __read_register(dev, CVP_RGE0_BUS_RD_INPUT_IF_SECURITY_CFG); + dprintk(CVP_ERR, "CVP_RGE0_BUS_RD_INPUT_IF_SECURITY_CFG %#x\n", val); + val = __read_register(dev, CVP_RGE0_TOPSPARE_IN); + dprintk(CVP_ERR, "CVP_RGE0_TOPSPARE_IN %#x\n", val); + /****** VADL ****** + * Bit 0 of below register is CDM secure enable for VADL + * CDM buffer will bei in CB4 if set + */ +#define CVP_VADL0_VADL_SS_CP_CTL 0x21010 + /* Below registers are used the same way as RGE */ +#define CVP_VADL0_BUS_RD_INPUT_IF_SECURITY_CFG 0x22020 +#define CVP_VADL0_SPARE_IN 0x211F4 + + val = __read_register(dev, CVP_VADL0_VADL_SS_CP_CTL); + dprintk(CVP_ERR, "CVP_VADL0_VADL_SS_CP_CTL %#x\n", val); + val = __read_register(dev, CVP_VADL0_BUS_RD_INPUT_IF_SECURITY_CFG); + dprintk(CVP_ERR, "CVP_VADL0_BUS_RD_INPUT_IF_SECURITY_CFG %#x\n", val); + val = __read_register(dev, CVP_VADL0_SPARE_IN); + dprintk(CVP_ERR, "CVP_VADL0_SPARE_IN %#x\n", val); + /****** ITOF ***** + * Below registers are used the same way as RGE + */ +#define CVP_ITOF0_TOF_SS_CP_CTL 0x41010 +#define CVP_ITOF0_BUS_RD_INPUT_IF_SECURITY_CFG 0x42020 +#define CVP_ITOF0_TOF_SS_SPARE_IN 0x411F4 + + val = __read_register(dev, CVP_ITOF0_TOF_SS_CP_CTL); + dprintk(CVP_ERR, "CVP_ITOF0_TOF_SS_CP_CTL %#x\n", val); + val = __read_register(dev, CVP_ITOF0_BUS_RD_INPUT_IF_SECURITY_CFG); + dprintk(CVP_ERR, "CVP_ITOF0_BUS_RD_INPUT_IF_SECURITY_CFG %#x\n", val); + val = __read_register(dev, CVP_ITOF0_TOF_SS_SPARE_IN); + dprintk(CVP_ERR, "CVP_ITOF0_TOF_SS_SPARE_IN %#x\n", val); + return 0; } diff --git a/msm/eva/cvp_smem.c b/msm/eva/cvp_smem.c index 3b36fef91d..2e1f09bd6b 100644 --- a/msm/eva/cvp_smem.c +++ b/msm/eva/cvp_smem.c @@ -234,6 +234,8 @@ int msm_cvp_map_smem(struct msm_cvp_inst *inst, smem->flags |= (SMEM_SECURE | SMEM_NON_PIXEL); else if (vmid_list[temp] == VMID_CP_CAMERA) smem->flags |= (SMEM_SECURE | SMEM_CAMERA); + dprintk(CVP_MEM, "inst %pK VM idx %d VM_ID %d fd %d pkt_type %#x\n", + inst, temp, vmid_list[temp], smem->fd, smem->pkt_type); } rc = msm_dma_get_device_address(dma_buf, align, &iova, smem->flags, From 4be6d0c36bc6455847594367a47e9a1d732e5a34 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 21 Nov 2022 11:41:19 -0800 Subject: [PATCH 152/317] msm: eva: Reset IOVA in invalid buf entry Set 0 as IOVA and SIZE of the invalid buffer entry in HFI packet. Change-Id: I1ea90d2188a0dd6047fd24a44e16b9a40fc4d8dc Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 0d824e2d74..848a7a0302 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1558,8 +1558,11 @@ int msm_cvp_map_frame(struct msm_cvp_inst *inst, buf = (struct cvp_buf_type *)&in_pkt->pkt_data[offset]; offset += sizeof(*buf) >> 2; - if (buf->fd < 0 || !buf->size) + if (buf->fd < 0 || !buf->size) { + buf->fd = 0; + buf->size = 0; continue; + } iova = msm_cvp_map_frame_buf(inst, buf, frame, cmd_hdr->packet_type, i); if (!iova) { From 867c0cc2b43a35a2b5795b4177f5ec75f61234ae Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 22 Nov 2022 09:47:08 -0800 Subject: [PATCH 153/317] msm: eva: Print more hfi queue info To help EVA timeout debugging. Change-Id: I431a4b9b0088c4e1b2a93adacd75457ca7caf6da Signed-off-by: George Shen --- msm/eva/msm_cvp_common.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 4d097ed56e..3739bc6cc2 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -50,15 +50,18 @@ static void dump_hfi_queue(struct iris_hfi_device *device) dprintk(CVP_ERR, "HFI queue not init, fail to dump\n"); return; } - dprintk(CVP_ERR, "queue details: %d %d\n", - queue->qhdr_read_idx, queue->qhdr_write_idx); + dprintk(CVP_ERR, "queue details: r:w %d:%d r:t %d %d\n", + queue->qhdr_read_idx, queue->qhdr_write_idx, + queue->qhdr_rx_req, queue->qhdr_tx_req); if (queue->qhdr_read_idx != queue->qhdr_write_idx) { read_idx = queue->qhdr_read_idx; read_ptr = (u32 *)((qinfo->q_array.align_virtual_addr) + (read_idx << 2)); - dprintk(CVP_ERR, "queue payload: %x %x %x %x\n", - read_ptr[0], read_ptr[1], - read_ptr[2], read_ptr[3]); + dprintk(CVP_ERR, + "queue payload: %x %x %x %x %x %x %x %x\n", + read_ptr[0], read_ptr[1], read_ptr[2], + read_ptr[3], read_ptr[4], read_ptr[5], + read_ptr[6], read_ptr[7]); } } From 900e40a17f1664c6ca7442c4a1e2f343b7cb7ae5 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Tue, 15 Nov 2022 23:13:45 -0800 Subject: [PATCH 154/317] msm: eva: enable Synx dependency enable synx dependency Change-Id: Iaf60e8478df52f65a5ae401e038d1692f5a37939 Signed-off-by: Yu SI --- Android.mk | 2 +- msm/eva/cvp_comm_def.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Android.mk b/Android.mk index a02ff77dee..214ee88bff 100644 --- a/Android.mk +++ b/Android.mk @@ -21,7 +21,7 @@ LOCAL_ADDITIONAL_DEPENDENCIES := $(call intermediates-dir-for,DLKM,mmrm-module-s KBUILD_REQUIRED_KOS += msm-mmrm.ko # Setup SynX dependency -CONFIG_SYNX := n +CONFIG_SYNX := y #ifdef CONFIG_SYNX ifeq ($(CONFIG_SYNX), y) $(warning Compiling SynX) diff --git a/msm/eva/cvp_comm_def.h b/msm/eva/cvp_comm_def.h index 5cb741f19d..a922f2d2c4 100644 --- a/msm/eva/cvp_comm_def.h +++ b/msm/eva/cvp_comm_def.h @@ -37,7 +37,7 @@ enum queue_state { #ifdef CONFIG_EVA_PINEAPPLE #define CVP_MMRM_ENABLED 1 #define CVP_CONFIG_SYNX_V2 1 -/* #define CVP_SYNX_ENABLED 1 */ /* temp disable til Synx ready*/ +#define CVP_SYNX_ENABLED 1 #define CVP_FASTRPC_ENABLED 1 #endif /* End of CONFIG_EVA_PINEAPPLE */ From 991c1ebc43212ac3c1bbb44f7c66f2751aec8c43 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 1 Dec 2022 22:16:58 -0800 Subject: [PATCH 155/317] msm: eva: handle SoC fencing returning MSG Needs to unmap frame buffer and avoid enqueue the MSG in session queue. In SoC fencing cases, session queue will not be drained by UMD. It can lead to session stop error. Change-Id: I980689ae16286712df704f94385ca0ccfc64488a Signed-off-by: George Shen --- msm/eva/msm_cvp.c | 25 +++++++++++++++++++++---- msm/eva/msm_cvp_synx.c | 3 +++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 52eb2912b7..5642f10c8d 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -591,9 +591,6 @@ static int cvp_populate_fences( struct eva_kmd_hfi_packet *in_pkt, goto exit; } - if (!cvp_kernel_fence_enabled) - goto exit; - cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; rc = cvp_alloc_fence_data((&f), cmd_hdr->size); if (rc) @@ -603,9 +600,28 @@ static int cvp_populate_fences( struct eva_kmd_hfi_packet *in_pkt, f->mode = OP_NORMAL; f->signature = 0xFEEDFACE; f->num_fences = 0; + f->output_index = 0; + buf_offset = offset; + + if (!cvp_kernel_fence_enabled) { + for (i = 0; i < num; i++) { + buf = (struct cvp_buf_type *)&in_pkt->pkt_data[buf_offset]; + buf_offset += sizeof(*buf) >> 2; + + if (buf->input_handle || buf->output_handle) { + f->num_fences++; + if (buf->input_handle) + f->output_index++; + } + } + f->signature = 0xB0BABABE; + if (f->num_fences) + goto fence_cmd_queue; + + goto free_exit; + } /* First pass to find INPUT synx handles */ - buf_offset = offset; for (i = 0; i < num; i++) { buf = (struct cvp_buf_type *)&in_pkt->pkt_data[buf_offset]; buf_offset += sizeof(*buf) >> 2; @@ -652,6 +668,7 @@ static int cvp_populate_fences( struct eva_kmd_hfi_packet *in_pkt, if (rc) goto free_exit; +fence_cmd_queue: memcpy(f->pkt, cmd_hdr, cmd_hdr->size); f->pkt->client_data.kdata |= FENCE_BIT; diff --git a/msm/eva/msm_cvp_synx.c b/msm/eva/msm_cvp_synx.c index 74b619f8d1..b2d38dca65 100644 --- a/msm/eva/msm_cvp_synx.c +++ b/msm/eva/msm_cvp_synx.c @@ -254,6 +254,9 @@ static int cvp_synx_ops_v2(struct msm_cvp_inst *inst, enum cvp_synx_type type, { struct synx_session *ssid; + if (fc->signature == 0xB0BABABE) + return 0; + ssid = inst->synx_session_id; if (type == CVP_INPUT_SYNX) { From f2e6be65e43ca837daa97145b6bec84d1e2a5326 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 5 Dec 2022 13:22:44 -0800 Subject: [PATCH 156/317] msm: eva: Move cvp_buf_type to UAPI Ensure consistent buffer type use between UMD and KMD. Change-Id: I77d619420d584e3c29babc8ddc5e80232f901009 Signed-off-by: George Shen --- include/uapi/eva/media/msm_eva_private.h | 27 +++++++++++++++++++++++ msm/eva/msm_cvp_buf.h | 28 ------------------------ 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/include/uapi/eva/media/msm_eva_private.h b/include/uapi/eva/media/msm_eva_private.h index cf4745d65c..16ff740db7 100644 --- a/include/uapi/eva/media/msm_eva_private.h +++ b/include/uapi/eva/media/msm_eva_private.h @@ -119,6 +119,33 @@ struct eva_kmd_client_data { __u32 client_data1; __u32 client_data2; }; +#ifdef CVP_CONFIG_SYNX_V2 +struct cvp_buf_type { + __s32 fd; + __u32 size; + __u32 offset; + __u32 flags; + __u32 reserved1; + __u32 reserved2; + __u32 fence_type; + __u32 input_handle; + __u32 output_handle; +}; +#else +struct cvp_buf_type { + __s32 fd; + __u32 size; + __u32 offset; + __u32 flags; + union { + struct dma_buf *dbuf; + struct { + __u32 reserved1; + __u32 reserved2; + }; + }; +}; +#endif /** * Structures and macros for Out-of-Band (OOB) buffer diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index 069e649083..e73e455fd8 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -112,34 +112,6 @@ static inline void DEINIT_DMAMAP_CACHE(struct cvp_dmamap_cache *cache) #define INPUT_FENCE_BITMASK 0x1 #define OUTPUT_FENCE_BITMASK 0x2 -#ifdef CVP_CONFIG_SYNX_V2 -struct cvp_buf_type { - s32 fd; - u32 size; - u32 offset; - u32 flags; - u32 reserved1; - u32 reserved2; - u32 fence_type; - u32 input_handle; - u32 output_handle; -}; -#else -struct cvp_buf_type { - s32 fd; - u32 size; - u32 offset; - u32 flags; - union { - struct dma_buf *dbuf; - struct { - u32 reserved1; - u32 reserved2; - }; - }; -}; -#endif - enum buffer_owner { DRIVER, FIRMWARE, From 94711ec8b3801065c65981d0b58214ef539dc3cf Mon Sep 17 00:00:00 2001 From: Sabharsh Sidhu Date: Fri, 2 Dec 2022 23:35:38 -0800 Subject: [PATCH 157/317] msm: eva: Update WarpNCC offset macro Change-Id: I380b1ea1afbf8699dd27dfea7f68b0b905a20e49 Signed-off-by: Sabharsh Sidhu --- include/uapi/eva/media/msm_eva_private.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/uapi/eva/media/msm_eva_private.h b/include/uapi/eva/media/msm_eva_private.h index 16ff740db7..d54280cd6c 100644 --- a/include/uapi/eva/media/msm_eva_private.h +++ b/include/uapi/eva/media/msm_eva_private.h @@ -156,7 +156,7 @@ struct cvp_buf_type { #define EVA_KMD_WNCC_MAX_ADDRESSES 4095 #define EVA_KMD_WNCC_MAX_SRC_BUFS 2400 #define EVA_KMD_WNCC_SRC_BUF_ID_OFFSET 1 -#define EVA_KMD_WNCC_HFI_METADATA_BUFS_OFFSET 44 +#define EVA_KMD_WNCC_HFI_METADATA_BUFS_OFFSET (14 + sizeof(struct cvp_buf_type) / sizeof(__u32) * 5) struct eva_kmd_wncc_metadata { __u64 loc_x_dec : 12; From 2dbd8c396e68a40f4998a52803e5331c6732b67c Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 8 Dec 2022 11:40:12 -0800 Subject: [PATCH 158/317] msm: eva: Support Lanai new HFI cvp_buf_type Keep ERR/WARN/FW logging only. Change-Id: I910dd109fa6d16f093848e7c3c3a03c1568f87e6 Signed-off-by: George Shen --- include/uapi/eva/media/msm_eva_private.h | 16 ---------------- msm/eva/msm_cvp_debug.c | 2 +- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/include/uapi/eva/media/msm_eva_private.h b/include/uapi/eva/media/msm_eva_private.h index d54280cd6c..b64622de3f 100644 --- a/include/uapi/eva/media/msm_eva_private.h +++ b/include/uapi/eva/media/msm_eva_private.h @@ -119,7 +119,6 @@ struct eva_kmd_client_data { __u32 client_data1; __u32 client_data2; }; -#ifdef CVP_CONFIG_SYNX_V2 struct cvp_buf_type { __s32 fd; __u32 size; @@ -131,21 +130,6 @@ struct cvp_buf_type { __u32 input_handle; __u32 output_handle; }; -#else -struct cvp_buf_type { - __s32 fd; - __u32 size; - __u32 offset; - __u32 flags; - union { - struct dma_buf *dbuf; - struct { - __u32 reserved1; - __u32 reserved2; - }; - }; -}; -#endif /** * Structures and macros for Out-of-Band (OOB) buffer diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index e2f7c4481e..f8d7355180 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -12,7 +12,7 @@ #define CREATE_TRACE_POINTS #define MAX_SSR_STRING_LEN 10 -int msm_cvp_debug = CVP_ERR | CVP_WARN | CVP_FW | CVP_DBG; +int msm_cvp_debug = CVP_ERR | CVP_WARN | CVP_FW; EXPORT_SYMBOL(msm_cvp_debug); int msm_cvp_debug_out = CVP_OUT_PRINTK; From 3a972b2c7ebb05e6fe094cdf21a19e1d04db4575 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 12 Dec 2022 19:32:50 -0800 Subject: [PATCH 159/317] msm: eva: Update RGE packet type Type changed in recent FW. Change-Id: I6adb21e16d444b231b40db6bca925be1b84a8cb6 Signed-off-by: George Shen --- msm/eva/cvp_hfi.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/msm/eva/cvp_hfi.h b/msm/eva/cvp_hfi.h index 1e47b83b17..85d7bf809a 100644 --- a/msm/eva/cvp_hfi.h +++ b/msm/eva/cvp_hfi.h @@ -161,10 +161,6 @@ (HFI_CMD_SESSION_CVP_START + 0x072) #define HFI_CMD_SESSION_CVP_SET_SNAPSHOT_MODE\ (HFI_CMD_SESSION_CVP_START + 0x073) -#define HFI_CMD_SESSION_CVP_RGE_FRAME\ - (HFI_CMD_SESSION_CVP_START + 0x076) -#define HFI_CMD_SESSION_CVP_RGE_CONFIG\ - (HFI_CMD_SESSION_CVP_START + 0x077) #define HFI_CMD_SESSION_EVA_ITOF_FRAME\ (HFI_CMD_SESSION_CVP_START + 0x078) #define HFI_CMD_SESSION_EVA_ITOF_CONFIG\ @@ -173,6 +169,10 @@ (HFI_CMD_SESSION_CVP_START + 0x07C) #define HFI_CMD_SESSION_EVA_DLFD_CONFIG\ (HFI_CMD_SESSION_CVP_START + 0x07D) +#define HFI_CMD_SESSION_CVP_RGE_FRAME\ + (HFI_CMD_SESSION_CVP_START + 0x07E) +#define HFI_CMD_SESSION_CVP_RGE_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x07F) #define HFI_CMD_SESSION_EVA_DLFL_FRAME\ (HFI_CMD_SESSION_CVP_START + 0x080) #define HFI_CMD_SESSION_EVA_DLFL_CONFIG\ From e4a19ce6d49906610890bf2ea813b46e74cf884b Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 14 Dec 2022 13:54:59 -0800 Subject: [PATCH 160/317] msm: eva: Avoid accessing SID control reg It currently causes SoC NoC error in case of SMMU fault. Change-Id: I64f08f38171a8944cf1d0018b75981e4b5084633 Signed-off-by: George Shen --- msm/eva/msm_cvp_res_parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index 99364010df..1d9dc7ad91 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -1021,7 +1021,7 @@ int msm_cvp_smmu_fault_handler(struct iommu_domain *domain, hdev = core->device->hfi_device_data; if (hdev) { hdev->error = CVP_ERR_NOC_ERROR; - call_hfi_op(core->device, debug_hook, hdev); + /* call_hfi_op(core->device, debug_hook, hdev); */ } mutex_unlock(&core->lock); /* From d9410c76536d1ead7d3878706ca0976eab148f42 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Mon, 5 Dec 2022 23:00:32 -0800 Subject: [PATCH 161/317] msm: eva: power on off sequence update update according to HPG --added utility to asser & de-assert clk individually by name --added xo clk reset and vote for sleep_clk --defined more CVP_AON_WRAPPER_XXX regs in IO header --updated power off controller sequence --updated power on controller sequence Debug, to move later --clk_set_flags for mvs1c cbcr for retain_periph retain_mem Change-Id: Ia0872270412119e4dc6c3e2b12b59862adeea0c5 Signed-off-by: Yu SI Signed-off-by: George Shen --- msm/eva/cvp_core_hfi.h | 9 ++ msm/eva/cvp_hfi.c | 236 ++++++++++++++++++++++++++++++++++--- msm/eva/cvp_hfi_io.h | 3 + msm/eva/msm_cvp_platform.c | 2 +- 4 files changed, 234 insertions(+), 16 deletions(-) diff --git a/msm/eva/cvp_core_hfi.h b/msm/eva/cvp_core_hfi.h index ed7e04f09f..b00cd4bd81 100644 --- a/msm/eva/cvp_core_hfi.h +++ b/msm/eva/cvp_core_hfi.h @@ -175,6 +175,13 @@ struct cvp_iface_q_info { iris_hfi_for_each_thing_reverse_continue(__device, __rinfo, \ clock, __from) +/* reset set helpers */ +#define iris_hfi_for_each_reset_clock(__device, __resetinfo) \ + iris_hfi_for_each_thing(__device, __resetinfo, reset) + +#define iris_hfi_for_each_reset_clock_reverse(__device, __resetinfo) \ + iris_hfi_for_each_thing_reverse(__device, __resetinfo, reset) + /* Bus set helpers */ #define iris_hfi_for_each_bus(__device, __binfo) \ iris_hfi_for_each_thing(__device, __binfo, bus) @@ -224,6 +231,8 @@ struct iris_hfi_vpu_ops { int (*reset_ahb2axi_bridge)(struct iris_hfi_device *device); void (*power_off)(struct iris_hfi_device *device); void (*noc_error_info)(struct iris_hfi_device *device); + int (*reset_control_assert_name)(struct iris_hfi_device *device, const char *name); + int (*reset_control_deassert_name)(struct iris_hfi_device *device, const char *name); }; struct iris_hfi_device { diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 5632809838..a64e02426a 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -33,6 +33,9 @@ #include "vm/cvp_vm.h" #include "cvp_dump.h" +// ysi - added for debug +#include + #define REG_ADDR_OFFSET_BITMASK 0x000FFFFF #define QDSS_IOVA_START 0x80001000 #define MIN_PAYLOAD_SIZE 3 @@ -103,6 +106,9 @@ static int __power_off_controller(struct iris_hfi_device *device); static int __hwfence_regs_map(struct iris_hfi_device *device); static int __hwfence_regs_unmap(struct iris_hfi_device *device); +static int __reset_control_assert_name(struct iris_hfi_device *device, const char *name); +static int __reset_control_deassert_name(struct iris_hfi_device *device, const char *name); + static struct iris_hfi_vpu_ops iris2_ops = { .interrupt_init = interrupt_init_iris2, .setup_dsp_uc_memmap = setup_dsp_uc_memmap_vpu5, @@ -110,6 +116,8 @@ static struct iris_hfi_vpu_ops iris2_ops = { .reset_ahb2axi_bridge = reset_ahb2axi_bridge, .power_off = power_off_iris2, .noc_error_info = __noc_error_info_iris2, + .reset_control_assert_name = __reset_control_assert_name, + .reset_control_deassert_name = __reset_control_deassert_name, }; /** @@ -1001,7 +1009,7 @@ static inline void check_tensilica_in_reset(struct iris_hfi_device *device) static inline int __boot_firmware(struct iris_hfi_device *device) { int rc = 0, loop = 10; - u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 1000; + u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 500; u32 reg_gdsc; /* @@ -1013,6 +1021,9 @@ static inline int __boot_firmware(struct iris_hfi_device *device) if (__enable_hw_power_collapse(device)) dprintk(CVP_ERR, "Failed to enabled inter-frame PC\n"); + if (!msm_cvp_fw_low_power_mode) + goto skip_core_power_check; + while (loop) { reg_gdsc = __read_register(device, CVP_CC_MVS1_GDSCR); if (reg_gdsc & 0x80000000) { @@ -1026,6 +1037,7 @@ static inline int __boot_firmware(struct iris_hfi_device *device) if (!loop) dprintk(CVP_ERR, "fail to power off CORE during resume\n"); +skip_core_power_check: ctrl_init_val = BIT(0); __write_register(device, CVP_CTRL_INIT, ctrl_init_val); while (!ctrl_status && count < max_tries) { @@ -1037,7 +1049,7 @@ static inline int __boot_firmware(struct iris_hfi_device *device) } /* Reduce to 500, 1000 on silicon */ - usleep_range(50000, 100000); + usleep_range(500, 1000); count++; } @@ -3393,6 +3405,69 @@ failed_to_reset: return rc; } + +static int __reset_control_assert_name(struct iris_hfi_device *device, + const char *name) +{ + struct reset_info *rcinfo = NULL; + int rc = 0; + bool found = false; + + iris_hfi_for_each_reset_clock(device, rcinfo) { + if (strcmp(rcinfo->name, name)) + continue; + + found = true; + rc = reset_control_assert(rcinfo->rst); + if (rc) + dprintk(CVP_ERR, + "%s: failed to assert reset control (%s), rc = %d\n", + __func__, rcinfo->name, rc); + else + dprintk(CVP_PWR, "%s: assert reset control (%s)\n", + __func__, rcinfo->name); + break; + } + if (!found) { + dprintk(CVP_PWR, "%s: reset control (%s) not found\n", + __func__, name); + rc = -EINVAL; + } + + return rc; +} + +static int __reset_control_deassert_name(struct iris_hfi_device *device, + const char *name) +{ + struct reset_info *rcinfo = NULL; + int rc = 0; + bool found = false; + + iris_hfi_for_each_reset_clock(device, rcinfo) { + if (strcmp(rcinfo->name, name)) + continue; + found = true; + rc = reset_control_deassert(rcinfo->rst); + if (rc) + dprintk(CVP_ERR, + "%s: deassert reset control for (%s) failed, rc %d\n", + __func__, rcinfo->name, rc); + else + dprintk(CVP_PWR, "%s: deassert reset control (%s)\n", + __func__, rcinfo->name); + break; + } + if (!found) { + dprintk(CVP_PWR, "%s: reset control (%s) not found\n", + __func__, name); + rc = -EINVAL; + } + + return rc; +} + + static void __deinit_bus(struct iris_hfi_device *device) { struct bus_info *bus = NULL; @@ -3947,18 +4022,53 @@ static int __power_on_controller(struct iris_hfi_device *device) { int rc = 0; + struct clock_info *cl = NULL; + rc = __enable_regulator(device, "cvp"); if (rc) { dprintk(CVP_ERR, "Failed to enable ctrler: %d\n", rc); return rc; } - rc = call_iris_op(device, reset_ahb2axi_bridge, device); + rc = msm_cvp_prepare_enable_clk(device, "sleep_clk"); if (rc) { - dprintk(CVP_ERR, "Failed to reset ahb2axi: %d\n", rc); + dprintk(CVP_ERR, "Failed to enable sleep clk: %d\n", rc); goto fail_reset_clks; } + rc = call_iris_op(device, reset_control_assert_name, device, "cvp_axi_reset"); + if (rc) { + dprintk(CVP_ERR, "%s: assert cvp_axi_reset failed\n", __func__); + } + else { + dprintk(CVP_PWR, "%s: ysi-debug assert cvp_axi_reset succeed\n", __func__); + } + + rc = call_iris_op(device, reset_control_assert_name, device, "cvp_core_reset"); + if (rc) { + dprintk(CVP_ERR, "%s: assert cvp_core_reset failed\n", __func__); + } + else { + dprintk(CVP_PWR, "%s: ysi-debug assert cvp_core_reset succeed\n", __func__); + } + /* wait for deassert */ + usleep_range(1000, 1050); + + rc = call_iris_op(device, reset_control_deassert_name, device, "cvp_axi_reset"); + if (rc) { + dprintk(CVP_ERR, "%s: de-assert cvp_axi_reset failed\n", __func__); + } + else { + dprintk(CVP_PWR, "%s: ysi-debug de-assert cvp_axi_reset succeed\n", __func__); + } + rc = call_iris_op(device, reset_control_deassert_name, device, "cvp_core_reset"); + if (rc) { + dprintk(CVP_ERR, "%s: de-assert cvp_core_reset failed\n", __func__); + } + else { + dprintk(CVP_PWR, "%s: ysi-debug de-assert cvp_core_reset succeed\n", __func__); + } + rc = msm_cvp_prepare_enable_clk(device, "gcc_video_axi1"); if (rc) { dprintk(CVP_ERR, "Failed to enable axi1 clk: %d\n", rc); @@ -3971,6 +4081,14 @@ static int __power_on_controller(struct iris_hfi_device *device) goto fail_enable_clk; } + iris_hfi_for_each_clock(device, cl) { + if (strcmp(cl->name, "cvp_clk")) { + qcom_clk_set_flags(cl->clk, CLKFLAG_RETAIN_PERIPH); + qcom_clk_set_flags(cl->clk, CLKFLAG_RETAIN_MEM); + break; + } + } + dprintk(CVP_PWR, "EVA controller powered on\n"); return 0; @@ -4006,14 +4124,14 @@ static int __power_on_core(struct iris_hfi_device *device) return rc; } -#ifdef CONFIG_EVA_PINEAPPLE +/*#ifdef CONFIG_EVA_PINEAPPLE __write_register(device, CVP_AON_WRAPPER_CVP_NOC_ARCG_CONTROL, 0); __write_register(device, CVP_NOC_RCGCONTROLLER_HYSTERESIS_LOW, 0x2f); __write_register(device, CVP_NOC_RCG_VNOC_NOC_CLK_FORCECLOCKON_LOW, 1); __write_register(device, CVP_NOC_RCGCONTROLLER_MAINCTL_LOW, 1); usleep_range(50, 100); __write_register(device, CVP_NOC_RCG_VNOC_NOC_CLK_FORCECLOCKON_LOW, 0); -#endif +#endif*/ dprintk(CVP_PWR, "EVA core powered on\n"); return 0; } @@ -4163,6 +4281,8 @@ static int __power_off_controller(struct iris_hfi_device *device) u32 sbm_ln0_low; int rc; + u32 spare_val, spare_status; + /* HPG 6.2.2 Step 1 */ __write_register(device, CVP_CPU_CS_X2RPMh, 0x3); @@ -4247,27 +4367,111 @@ static int __power_off_controller(struct iris_hfi_device *device) "DBLP Release: lpi_status %x\n", lpi_status); } - /* PDXFIFO reset: addition for Kailua */ -#ifdef CONFIG_EVA_KALAMA + /* PDXFIFO reset: addition for Kailua / Lanai */ + __write_register(device, CVP_WRAPPER_AXI_CLOCK_CONFIG, 0x3); __write_register(device, CVP_WRAPPER_QNS4PDXFIFO_RESET, 0x1); __write_register(device, CVP_WRAPPER_QNS4PDXFIFO_RESET, 0x0); __write_register(device, CVP_WRAPPER_AXI_CLOCK_CONFIG, 0x0); -#endif + /* HPG 6.2.2 Step 5 */ msm_cvp_disable_unprepare_clk(device, "cvp_clk"); - /* HPG 6.2.2 Step 7 */ - msm_cvp_disable_unprepare_clk(device, "gcc_video_axi1"); + rc = call_iris_op(device, reset_control_assert_name, device, "cvp_axi_reset"); + if (rc) { + dprintk(CVP_ERR, "%s: assert cvp_axi_reset failed\n", __func__); + } + else { + dprintk(CVP_PWR, "%s: ysi-debug assert cvp_axi_reset succeed\n", __func__); + } - /* Added to avoid pending transaction after power off */ - rc = call_iris_op(device, reset_ahb2axi_bridge, device); - if (rc) - dprintk(CVP_ERR, "Off: Failed to reset ahb2axi: %d\n", rc); + rc = call_iris_op(device, reset_control_assert_name, device, "cvp_core_reset"); + if (rc) { + dprintk(CVP_ERR, "%s: assert cvp_core_reset failed\n", __func__); + } + else { + dprintk(CVP_PWR, "%s: ysi-debug assert cvp_core_reset succeed\n", __func__); + } + /* wait for deassert */ + usleep_range(1000, 1050); + + rc = call_iris_op(device, reset_control_deassert_name, device, "cvp_axi_reset"); + if (rc) { + dprintk(CVP_ERR, "%s: de-assert cvp_axi_reset failed\n", __func__); + } + else { + dprintk(CVP_PWR, "%s: ysi-debug de-assert cvp_axi_reset succeed\n", __func__); + } + rc = call_iris_op(device, reset_control_deassert_name, device, "cvp_core_reset"); + if (rc) { + dprintk(CVP_ERR, "%s: de-assert cvp_core_reset failed\n", __func__); + } + else { + dprintk(CVP_PWR, "%s: ysi-debug de-assert cvp_core_reset succeed\n", __func__); + } + + /* disable EVA NoC clock */ + __write_register(device, CVP_AON_WRAPPER_CVP_NOC_CORE_CLK_CONTROL, 0x1); + + /* enable EVA NoC reset */ + __write_register(device, CVP_AON_WRAPPER_CVP_NOC_CORE_SW_RESET, 0x1); + + + spare_status = 0x1; + while (spare_status != 0x0) { + spare_val = __read_register(device, CVP_AON_WRAPPER_SPARE); + dprintk(CVP_PWR, "%s: ysi-debug spare_val %x\n", __func__, spare_val); + spare_status = spare_val & 0x2; + dprintk(CVP_PWR, "%s: ysi-debug spare_status & 0x2 %x\n", __func__, spare_status); + usleep_range(50, 100); + } + __write_register(device, CVP_AON_WRAPPER_SPARE, 0x1); + rc = call_iris_op(device, reset_control_assert_name, device, "cvp_xo_reset"); + if (rc) { + dprintk(CVP_ERR, "%s: assert cvp_xo_reset failed\n", __func__); + } + else { + dprintk(CVP_PWR, "%s: ysi-debug assert cvp_xo_reset succeed\n", __func__); + } + + /* de-assert EVA_NoC reset */ + __write_register(device, CVP_AON_WRAPPER_CVP_NOC_CORE_SW_RESET, 0x0); + + /* de-assert EVA video_cc XO reset and enable video_cc XO clock after 80us */ + usleep_range(80, 100); + rc = call_iris_op(device, reset_control_deassert_name, device, "cvp_xo_reset"); + if (rc) { + dprintk(CVP_ERR, "%s: de-assert cvp_xo_reset failed\n", __func__); + } + else { + dprintk(CVP_PWR, "%s: ysi-debug de-assert cvp_xo_reset succeed\n", __func__); + } + + /* clear XO mask bit - this step was missing in previous sequence */ + __write_register(device, CVP_AON_WRAPPER_SPARE, 0x0); + + + /* enable EVA NoC clock */ + __write_register(device, CVP_AON_WRAPPER_CVP_NOC_CORE_CLK_CONTROL, 0x0); + + /* De-assert EVA_CTL Force Sleep Retention */ + + usleep_range(400, 500); /* HPG 6.2.2 Step 6 */ __disable_regulator(device, "cvp"); + /* HPG 6.2.2 Step 7 */ + rc = msm_cvp_disable_unprepare_clk(device, "gcc_video_axi1"); + if (rc) { + dprintk(CVP_ERR, "Failed to enable axi1 clk: %d\n", rc); + } + + rc = msm_cvp_disable_unprepare_clk(device, "sleep_clk"); + if (rc) { + dprintk(CVP_ERR, "Failed to disable sleep clk: %d\n", rc); + } + return 0; } @@ -4389,6 +4593,8 @@ static int __power_off_core(struct iris_hfi_device *device) __print_sidebandmanager_regs(device); } + + __write_register(device, CVP_AON_WRAPPER_CVP_NOC_LPI_CONTROL, 0x0); #endif if (warn_flag) diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index 10337d27c1..5ab6a9f8ac 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -253,6 +253,9 @@ #define CVP_AON_WRAPPER_CVP_NOC_LPI_CONTROL (CVP_AON_BASE_OFFS + 0x8) #define CVP_AON_WRAPPER_CVP_NOC_LPI_STATUS (CVP_AON_BASE_OFFS + 0xC) #define CVP_AON_WRAPPER_CVP_NOC_ARCG_CONTROL (CVP_AON_BASE_OFFS + 0x14) +#define CVP_AON_WRAPPER_CVP_NOC_CORE_CLK_CONTROL (CVP_AON_BASE_OFFS + 0x24) +#define CVP_AON_WRAPPER_CVP_NOC_CORE_SW_RESET (CVP_AON_BASE_OFFS + 0x1C) +#define CVP_AON_WRAPPER_SPARE (CVP_AON_BASE_OFFS + 0x28) #define CVP_CC_BASE_OFFS 0x000F8000 #define CVP_CC_MVS1C_GDSCR (CVP_CC_BASE_OFFS + 0x78) diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index c89b69ce70..4e131657ba 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -206,7 +206,7 @@ static struct msm_cvp_common_data sm8650_common_data[] = { }, { .key = "qcom,sw-power-collapse", - .value = 0, /* Disable during initial stage for Rumi 48 bringup */ + .value = 0, }, { .key = "qcom,domain-attr-non-fatal-faults", From b873ee6df9020da8b2931f4d24519ef201e34661 Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 3 Jan 2023 21:43:22 -0800 Subject: [PATCH 162/317] msm: eva: Support XO clock reset mutual exclusion Using existing clock reset APIs. Remove DSP debug level bitmask check. Change-Id: Iab6ff6309b2d56e678b468b2137834f8931071e9 Signed-off-by: George Shen --- msm/eva/cvp_core_hfi.h | 3 +- msm/eva/cvp_hfi.c | 265 +++++++++++++++++------------------- msm/eva/msm_cvp_debug.c | 6 - msm/eva/msm_cvp_dsp.h | 8 -- msm/eva/msm_cvp_res_parse.c | 2 +- msm/eva/msm_cvp_resources.h | 17 ++- 6 files changed, 137 insertions(+), 164 deletions(-) diff --git a/msm/eva/cvp_core_hfi.h b/msm/eva/cvp_core_hfi.h index b00cd4bd81..21f85ed00c 100644 --- a/msm/eva/cvp_core_hfi.h +++ b/msm/eva/cvp_core_hfi.h @@ -228,11 +228,12 @@ struct iris_hfi_vpu_ops { void (*interrupt_init)(struct iris_hfi_device *ptr); void (*setup_dsp_uc_memmap)(struct iris_hfi_device *device); void (*clock_config_on_enable)(struct iris_hfi_device *device); - int (*reset_ahb2axi_bridge)(struct iris_hfi_device *device); void (*power_off)(struct iris_hfi_device *device); void (*noc_error_info)(struct iris_hfi_device *device); int (*reset_control_assert_name)(struct iris_hfi_device *device, const char *name); int (*reset_control_deassert_name)(struct iris_hfi_device *device, const char *name); + int (*reset_control_acquire_name)(struct iris_hfi_device *device, const char *name); + int (*reset_control_release_name)(struct iris_hfi_device *device, const char *name); }; struct iris_hfi_device { diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index a64e02426a..0bc003e268 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -95,7 +95,6 @@ static int iris_hfi_noc_error_info(void *dev); static void interrupt_init_iris2(struct iris_hfi_device *device); static void setup_dsp_uc_memmap_vpu5(struct iris_hfi_device *device); static void clock_config_on_enable_vpu5(struct iris_hfi_device *device); -static int reset_ahb2axi_bridge(struct iris_hfi_device *device); static void power_off_iris2(struct iris_hfi_device *device); static int __set_ubwc_config(struct iris_hfi_device *device); @@ -108,16 +107,20 @@ static int __hwfence_regs_unmap(struct iris_hfi_device *device); static int __reset_control_assert_name(struct iris_hfi_device *device, const char *name); static int __reset_control_deassert_name(struct iris_hfi_device *device, const char *name); +static int __reset_control_acquire(struct iris_hfi_device *device, const char *name); +static int __reset_control_release(struct iris_hfi_device *device, const char *name); + static struct iris_hfi_vpu_ops iris2_ops = { .interrupt_init = interrupt_init_iris2, .setup_dsp_uc_memmap = setup_dsp_uc_memmap_vpu5, .clock_config_on_enable = clock_config_on_enable_vpu5, - .reset_ahb2axi_bridge = reset_ahb2axi_bridge, .power_off = power_off_iris2, .noc_error_info = __noc_error_info_iris2, .reset_control_assert_name = __reset_control_assert_name, .reset_control_deassert_name = __reset_control_deassert_name, + .reset_control_acquire_name = __reset_control_acquire, + .reset_control_release_name = __reset_control_release, }; /** @@ -3294,118 +3297,54 @@ irqreturn_t cvp_hfi_isr(int irq, void *dev) static int __handle_reset_clk(struct msm_cvp_platform_resources *res, int reset_index, enum reset_state state, - enum power_state pwr_state) + enum action_stage stage) { int rc = 0; struct reset_control *rst; - struct reset_info rst_info; + struct reset_info *rst_info; struct reset_set *rst_set = &res->reset_set; if (!rst_set->reset_tbl) return 0; - rst_info = rst_set->reset_tbl[reset_index]; - rst = rst_info.rst; - dprintk(CVP_PWR, "reset_clk: name %s reset_state %d rst %pK ps=%d\n", - rst_set->reset_tbl[reset_index].name, state, rst, pwr_state); + rst_info = &rst_set->reset_tbl[reset_index]; + rst = rst_info->rst; + dprintk(CVP_PWR, "reset_clk: name %s reset_state %d rst %pK stage=%d\n", + rst_set->reset_tbl[reset_index].name, state, rst, stage); - switch (state) { - case INIT: + if (state == INIT) { if (rst) goto skip_reset_init; - rst = devm_reset_control_get(&res->pdev->dev, + if (stage == CVP_ON_USE) { + rst = reset_control_get_exclusive_released(&res->pdev->dev, rst_set->reset_tbl[reset_index].name); - if (IS_ERR(rst)) + if (IS_ERR(rst)) { + rc = PTR_ERR(rst); + rst_info->state = RESET_INIT; + } + } else if (stage == CVP_ON_INIT) { + rst = devm_reset_control_get(&res->pdev->dev, + rst_set->reset_tbl[reset_index].name); + if (IS_ERR(rst)) rc = PTR_ERR(rst); + } else { + dprintk(CVP_ERR, "Invalid reset stage\n"); + return -EINVAL; + } rst_set->reset_tbl[reset_index].rst = rst; - break; - case ASSERT: - if (!rst) { - rc = PTR_ERR(rst); - goto failed_to_reset; - } - - if (pwr_state != CVP_POWER_IGNORED && - pwr_state != rst_info.required_state) - break; - - rc = reset_control_assert(rst); - break; - case DEASSERT: - if (!rst) { - rc = PTR_ERR(rst); - goto failed_to_reset; - } - - if (pwr_state != CVP_POWER_IGNORED && - pwr_state != rst_info.required_state) - break; - - rc = reset_control_deassert(rst); - break; - default: + } else { dprintk(CVP_ERR, "Invalid reset request\n"); - if (rc) - goto failed_to_reset; + rc = -EINVAL; } return 0; skip_reset_init: -failed_to_reset: return rc; } -static int reset_ahb2axi_bridge(struct iris_hfi_device *device) -{ - int rc, i; - enum power_state s; - - if (!device) { - dprintk(CVP_ERR, "NULL device\n"); - rc = -EINVAL; - goto failed_to_reset; - } - - if (device->power_enabled) - s = CVP_POWER_ON; - else - s = CVP_POWER_OFF; - -#ifdef CONFIG_EVA_WAIPIO - s = CVP_POWER_IGNORED; -#endif - - for (i = 0; i < device->res->reset_set.count; i++) { - rc = __handle_reset_clk(device->res, i, ASSERT, s); - if (rc) { - dprintk(CVP_ERR, - "failed to assert reset clocks\n"); - goto failed_to_reset; - } - } - - /* wait for deassert */ - usleep_range(1000, 1050); - - for (i = 0; i < device->res->reset_set.count; i++) { - rc = __handle_reset_clk(device->res, i, DEASSERT, s); - if (rc) { - dprintk(CVP_ERR, - "failed to deassert reset clocks\n"); - goto failed_to_reset; - } - } - - return 0; - -failed_to_reset: - return rc; -} - - static int __reset_control_assert_name(struct iris_hfi_device *device, const char *name) { @@ -3467,7 +3406,84 @@ static int __reset_control_deassert_name(struct iris_hfi_device *device, return rc; } +static int __reset_control_acquire(struct iris_hfi_device *device, + const char *name) +{ + struct reset_info *rcinfo = NULL; + int rc = 0; + bool found = false; + int max_retries = 10; + iris_hfi_for_each_reset_clock(device, rcinfo) { + if (strcmp(rcinfo->name, name)) + continue; + found = true; + if (rcinfo->state == RESET_ACQUIRED) + return rc; +acquire_again: + rc = reset_control_acquire(rcinfo->rst); + if (rc) { + if (rc == -EBUSY) { + usleep_range(500, 1000); + max_retries--; + if (max_retries) { + goto acquire_again; + } else { + dprintk(CVP_ERR, "%s failed acquire\n", + __func__); + rc = -EINVAL; + } + } else { + dprintk(CVP_ERR, + "%s: acquire failed (%s) rc %d\n", + __func__, rcinfo->name, rc); + rc = -EINVAL; + } + } else { + dprintk(CVP_PWR, "%s: reset acquire succeed (%s)\n", + __func__, rcinfo->name); + rcinfo->state = RESET_ACQUIRED; + } + break; + } + if (!found) { + dprintk(CVP_PWR, "%s: reset control (%s) not found\n", + __func__, name); + rc = -EINVAL; + } + + return rc; +} + +static int __reset_control_release(struct iris_hfi_device *device, + const char *name) +{ + struct reset_info *rcinfo = NULL; + int rc = 0; + bool found = false; + + iris_hfi_for_each_reset_clock(device, rcinfo) { + if (strcmp(rcinfo->name, name)) + continue; + found = true; + if (rcinfo->state != RESET_ACQUIRED) { + dprintk(CVP_WARN, "Double releasing reset clk?\n"); + return -EINVAL; + } + reset_control_release(rcinfo->rst); + dprintk(CVP_PWR, "%s: reset release succeed (%s)\n", + __func__, rcinfo->name); + rcinfo->state = RESET_RELEASED; + break; + } + if (!found) { + dprintk(CVP_PWR, "%s: reset control (%s) not found\n", + __func__, name); + rc = -EINVAL; + } + + return rc; +} static void __deinit_bus(struct iris_hfi_device *device) { struct bus_info *bus = NULL; @@ -4037,37 +4053,21 @@ static int __power_on_controller(struct iris_hfi_device *device) } rc = call_iris_op(device, reset_control_assert_name, device, "cvp_axi_reset"); - if (rc) { + if (rc) dprintk(CVP_ERR, "%s: assert cvp_axi_reset failed\n", __func__); - } - else { - dprintk(CVP_PWR, "%s: ysi-debug assert cvp_axi_reset succeed\n", __func__); - } rc = call_iris_op(device, reset_control_assert_name, device, "cvp_core_reset"); - if (rc) { + if (rc) dprintk(CVP_ERR, "%s: assert cvp_core_reset failed\n", __func__); - } - else { - dprintk(CVP_PWR, "%s: ysi-debug assert cvp_core_reset succeed\n", __func__); - } /* wait for deassert */ usleep_range(1000, 1050); rc = call_iris_op(device, reset_control_deassert_name, device, "cvp_axi_reset"); - if (rc) { + if (rc) dprintk(CVP_ERR, "%s: de-assert cvp_axi_reset failed\n", __func__); - } - else { - dprintk(CVP_PWR, "%s: ysi-debug de-assert cvp_axi_reset succeed\n", __func__); - } rc = call_iris_op(device, reset_control_deassert_name, device, "cvp_core_reset"); - if (rc) { + if (rc) dprintk(CVP_ERR, "%s: de-assert cvp_core_reset failed\n", __func__); - } - else { - dprintk(CVP_PWR, "%s: ysi-debug de-assert cvp_core_reset succeed\n", __func__); - } rc = msm_cvp_prepare_enable_clk(device, "gcc_video_axi1"); if (rc) { @@ -4378,37 +4378,22 @@ static int __power_off_controller(struct iris_hfi_device *device) msm_cvp_disable_unprepare_clk(device, "cvp_clk"); rc = call_iris_op(device, reset_control_assert_name, device, "cvp_axi_reset"); - if (rc) { + if (rc) dprintk(CVP_ERR, "%s: assert cvp_axi_reset failed\n", __func__); - } - else { - dprintk(CVP_PWR, "%s: ysi-debug assert cvp_axi_reset succeed\n", __func__); - } rc = call_iris_op(device, reset_control_assert_name, device, "cvp_core_reset"); - if (rc) { + if (rc) dprintk(CVP_ERR, "%s: assert cvp_core_reset failed\n", __func__); - } - else { - dprintk(CVP_PWR, "%s: ysi-debug assert cvp_core_reset succeed\n", __func__); - } /* wait for deassert */ usleep_range(1000, 1050); rc = call_iris_op(device, reset_control_deassert_name, device, "cvp_axi_reset"); - if (rc) { + if (rc) dprintk(CVP_ERR, "%s: de-assert cvp_axi_reset failed\n", __func__); - } - else { - dprintk(CVP_PWR, "%s: ysi-debug de-assert cvp_axi_reset succeed\n", __func__); - } + rc = call_iris_op(device, reset_control_deassert_name, device, "cvp_core_reset"); - if (rc) { + if (rc) dprintk(CVP_ERR, "%s: de-assert cvp_core_reset failed\n", __func__); - } - else { - dprintk(CVP_PWR, "%s: ysi-debug de-assert cvp_core_reset succeed\n", __func__); - } /* disable EVA NoC clock */ __write_register(device, CVP_AON_WRAPPER_CVP_NOC_CORE_CLK_CONTROL, 0x1); @@ -4416,23 +4401,21 @@ static int __power_off_controller(struct iris_hfi_device *device) /* enable EVA NoC reset */ __write_register(device, CVP_AON_WRAPPER_CVP_NOC_CORE_SW_RESET, 0x1); - + rc = call_iris_op(device, reset_control_acquire_name, device, "cvp_xo_reset"); + if (rc) { + dprintk(CVP_ERR, "FATAL ERROR, HPG step 17 to 20 will be bypassed\n"); + goto skip_xo_reset; + } spare_status = 0x1; while (spare_status != 0x0) { spare_val = __read_register(device, CVP_AON_WRAPPER_SPARE); - dprintk(CVP_PWR, "%s: ysi-debug spare_val %x\n", __func__, spare_val); spare_status = spare_val & 0x2; - dprintk(CVP_PWR, "%s: ysi-debug spare_status & 0x2 %x\n", __func__, spare_status); usleep_range(50, 100); } __write_register(device, CVP_AON_WRAPPER_SPARE, 0x1); rc = call_iris_op(device, reset_control_assert_name, device, "cvp_xo_reset"); - if (rc) { + if (rc) dprintk(CVP_ERR, "%s: assert cvp_xo_reset failed\n", __func__); - } - else { - dprintk(CVP_PWR, "%s: ysi-debug assert cvp_xo_reset succeed\n", __func__); - } /* de-assert EVA_NoC reset */ __write_register(device, CVP_AON_WRAPPER_CVP_NOC_CORE_SW_RESET, 0x0); @@ -4440,17 +4423,15 @@ static int __power_off_controller(struct iris_hfi_device *device) /* de-assert EVA video_cc XO reset and enable video_cc XO clock after 80us */ usleep_range(80, 100); rc = call_iris_op(device, reset_control_deassert_name, device, "cvp_xo_reset"); - if (rc) { + if (rc) dprintk(CVP_ERR, "%s: de-assert cvp_xo_reset failed\n", __func__); - } - else { - dprintk(CVP_PWR, "%s: ysi-debug de-assert cvp_xo_reset succeed\n", __func__); - } /* clear XO mask bit - this step was missing in previous sequence */ __write_register(device, CVP_AON_WRAPPER_SPARE, 0x0); + call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); +skip_xo_reset: /* enable EVA NoC clock */ __write_register(device, CVP_AON_WRAPPER_CVP_NOC_CORE_CLK_CONTROL, 0x0); diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index f8d7355180..8bf416327f 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -337,12 +337,6 @@ DEFINE_DEBUGFS_ATTRIBUTE(clk_rate_fops, _clk_rate_get, _clk_rate_set, "%llu\n"); static int _dsp_dbg_set(void *data, u64 val) { - - if (val == 0 || val >= (1 << (EVA_MEM_DEBUG_ON + 1))) { - dprintk(CVP_WARN, "DSP debug mask cannot be %llx\n", val); - return 0; - } - gfa_cv.debug_mask = (uint32_t)val; cvp_dsp_send_debug_mask(); diff --git a/msm/eva/msm_cvp_dsp.h b/msm/eva/msm_cvp_dsp.h index 5e0e07d494..0232a7ddc0 100644 --- a/msm/eva/msm_cvp_dsp.h +++ b/msm/eva/msm_cvp_dsp.h @@ -99,14 +99,6 @@ enum CVP_DSP_COMMAND { CVP_DSP_MAX_CMD = 21, }; -enum eva_dsp_debug_bits { - EVA_PORT_INFO_ON = 0, - EVA_PORT_DEBUG_ON = 1, - EVA_QDI_INFO_ON = 2, - EVA_QDI_DEBUG_ON = 3, - EVA_MEM_DEBUG_ON = 4 -}; - struct eva_power_req { uint32_t clock_fdu; uint32_t clock_ica; diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index 1d9dc7ad91..c78c09b95b 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -764,7 +764,7 @@ static int msm_cvp_load_reset_table( of_property_read_string_index(pdev->dev.of_node, "reset-names", c, &rc->name); - rc->required_state = pwr_stats[c]; + rc->required_stage = pwr_stats[c]; } return 0; diff --git a/msm/eva/msm_cvp_resources.h b/msm/eva/msm_cvp_resources.h index 926be0124b..451e66f3be 100644 --- a/msm/eva/msm_cvp_resources.h +++ b/msm/eva/msm_cvp_resources.h @@ -85,16 +85,21 @@ struct bus_set { u32 count; }; -enum power_state { - CVP_POWER_INIT, - CVP_POWER_ON, - CVP_POWER_OFF, - CVP_POWER_IGNORED, +enum action_stage { + CVP_ON_INIT, + CVP_ON_USE, + CVP_ON_INVALID, +}; +enum reset_clk_state { + RESET_INIT, + RESET_ACQUIRED, + RESET_RELEASED, }; struct reset_info { struct reset_control *rst; - enum power_state required_state; + enum action_stage required_stage; + enum reset_clk_state state; const char *name; }; From 803a412ea9ceaba570c22a8c971bee3fb7312877 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Wed, 4 Jan 2023 20:20:43 -0800 Subject: [PATCH 163/317] msm: eva: add AON mapping for FW added support to map AON reg range for FW updated clk_get return check Change-Id: I93732f840a6354558853d6c6644b569c53fa93db Signed-off-by: Yu SI --- msm/eva/cvp_hfi.c | 57 ++++++++++++++++++++++++++----------- msm/eva/msm_cvp_clocks.c | 7 +++-- msm/eva/msm_cvp_res_parse.c | 15 ++++++++++ msm/eva/msm_cvp_resources.h | 3 ++ 4 files changed, 63 insertions(+), 19 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 0bc003e268..c4f60fa1fe 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1928,27 +1928,44 @@ static int __hwfence_regs_map(struct iris_hfi_device *device) return -EINVAL; } - rc = iommu_map(cb->domain, device->res->ipclite_iova, + if (device->res->ipclite_phyaddr != 0) { + rc = iommu_map(cb->domain, device->res->ipclite_iova, device->res->ipclite_phyaddr, device->res->ipclite_size, IOMMU_READ | IOMMU_WRITE); - if (rc) { - dprintk(CVP_ERR, "map ipclite fail %d %#x %#x %#x\n", - rc, device->res->ipclite_iova, - device->res->ipclite_phyaddr, - device->res->ipclite_size); - return rc; + if (rc) { + dprintk(CVP_ERR, "map ipclite fail %d %#x %#x %#x\n", + rc, device->res->ipclite_iova, + device->res->ipclite_phyaddr, + device->res->ipclite_size); + return rc; + } } - rc = iommu_map(cb->domain, device->res->hwmutex_iova, + if (device->res->hwmutex_phyaddr != 0) { + rc = iommu_map(cb->domain, device->res->hwmutex_iova, device->res->hwmutex_phyaddr, device->res->hwmutex_size, IOMMU_MMIO | IOMMU_READ | IOMMU_WRITE); - if (rc) { - dprintk(CVP_ERR, "map hwmutex fail %d %#x %#x %#x\n", - rc, device->res->hwmutex_iova, - device->res->hwmutex_phyaddr, - device->res->hwmutex_size); - return rc; + if (rc) { + dprintk(CVP_ERR, "map hwmutex fail %d %#x %#x %#x\n", + rc, device->res->hwmutex_iova, + device->res->hwmutex_phyaddr, + device->res->hwmutex_size); + return rc; + } + } + if (device->res->aon_phyaddr != 0) { + rc = iommu_map(cb->domain, device->res->aon_iova, + device->res->aon_phyaddr, + device->res->aon_size, + IOMMU_READ | IOMMU_WRITE); + if (rc) { + dprintk(CVP_ERR, "map aon fail %d %#x %#x %#x\n", + rc, device->res->aon_iova, + device->res->aon_phyaddr, + device->res->aon_size); + return rc; + } } return rc; } @@ -1964,10 +1981,18 @@ static int __hwfence_regs_unmap(struct iris_hfi_device *device) return -EINVAL; } - iommu_unmap(cb->domain, device->res->ipclite_iova, + if (device->res->ipclite_iova != 0) { + iommu_unmap(cb->domain, device->res->ipclite_iova, device->res->ipclite_size); - iommu_unmap(cb->domain, device->res->hwmutex_iova, + } + if (device->res->hwmutex_iova != 0) { + iommu_unmap(cb->domain, device->res->hwmutex_iova, device->res->hwmutex_size); + } + if (device->res->aon_iova != 0) { + iommu_unmap(cb->domain, device->res->aon_iova, + device->res->aon_size); + } return rc; } diff --git a/msm/eva/msm_cvp_clocks.c b/msm/eva/msm_cvp_clocks.c index b61fd359a5..807ef2ff73 100644 --- a/msm/eva/msm_cvp_clocks.c +++ b/msm/eva/msm_cvp_clocks.c @@ -416,10 +416,11 @@ int msm_cvp_init_clocks(struct iris_hfi_device *device) iris_hfi_for_each_clock(device, cl) { if (!cl->clk) { cl->clk = clk_get(&device->res->pdev->dev, cl->name); - if (IS_ERR_OR_NULL(cl->clk)) { + if (IS_ERR(cl->clk)) { + rc = PTR_ERR(cl->clk); dprintk(CVP_ERR, - "Failed to get clock: %s\n", cl->name); - rc = PTR_ERR(cl->clk) ? : -EINVAL; + "Failed to get clock: %s, rc %d\n", + cl->name, rc); cl->clk = NULL; goto err_clk_get; } diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index c78c09b95b..7dd9fd45f3 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -146,6 +146,7 @@ static int msm_cvp_load_regspace_mapping(struct msm_cvp_platform_resources *res) int ret = 0; unsigned int ipclite_mapping_config[3]; unsigned int hwmutex_mapping_config[3]; + unsigned int aon_mapping_config[3]; struct platform_device *pdev = res->pdev; ret = of_property_read_u32_array(pdev->dev.of_node, "ipclite_mappings", @@ -170,6 +171,20 @@ static int msm_cvp_load_regspace_mapping(struct msm_cvp_platform_resources *res) dprintk(CVP_CORE, "ipclite %#x %#x %#x hwmutex %#x %#x %#x\n", res->ipclite_iova, res->ipclite_phyaddr, res->ipclite_size, res->hwmutex_iova, res->hwmutex_phyaddr, res->hwmutex_size); + + + ret = of_property_read_u32_array(pdev->dev.of_node, "aon_mappings", + aon_mapping_config, 3); + if (ret) { + dprintk(CVP_ERR, "Failed to read aon reg: %d\n", ret); + return ret; + } + res->aon_iova = aon_mapping_config[0]; + res->aon_size = aon_mapping_config[1]; + res->aon_phyaddr = aon_mapping_config[2]; + dprintk(CVP_CORE, "aon %#x %#x %#x \n", + res->hwmutex_iova, res->hwmutex_phyaddr, res->hwmutex_size); + return ret; } diff --git a/msm/eva/msm_cvp_resources.h b/msm/eva/msm_cvp_resources.h index 451e66f3be..9b2959975d 100644 --- a/msm/eva/msm_cvp_resources.h +++ b/msm/eva/msm_cvp_resources.h @@ -167,6 +167,9 @@ struct msm_cvp_platform_resources { phys_addr_t hwmutex_iova; phys_addr_t hwmutex_phyaddr; uint32_t hwmutex_size; + phys_addr_t aon_iova; + phys_addr_t aon_phyaddr; + uint32_t aon_size; uint32_t irq; uint32_t sku_version; struct allowed_clock_rates_table *allowed_clks_tbl; From a6054402828eabe41015e76590541280589489d5 Mon Sep 17 00:00:00 2001 From: Yu SI Date: Fri, 6 Jan 2023 16:27:36 -0800 Subject: [PATCH 164/317] msm: eva: updated AON mapping attribute for FW updated AON mapping attribute for FW Change-Id: I207e7aaf0413e9d71db1d7f98f99db8d28a831a8 --- msm/eva/cvp_hfi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index c4f60fa1fe..ab13eed27d 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1958,7 +1958,7 @@ static int __hwfence_regs_map(struct iris_hfi_device *device) rc = iommu_map(cb->domain, device->res->aon_iova, device->res->aon_phyaddr, device->res->aon_size, - IOMMU_READ | IOMMU_WRITE); + IOMMU_MMIO | IOMMU_READ | IOMMU_WRITE); if (rc) { dprintk(CVP_ERR, "map aon fail %d %#x %#x %#x\n", rc, device->res->aon_iova, From 9db0677db022c24cedb4fc1e0e6e076a38d4959c Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 4 Jan 2023 14:05:46 -0800 Subject: [PATCH 165/317] msm: eva: Enable EVA Power Collapse Change-Id: I26093a7fd828edaf9d02e2df57f02ba408ee2101 Signed-off-by: George Shen --- msm/eva/msm_cvp_platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 4e131657ba..ba8cb5a781 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -206,7 +206,7 @@ static struct msm_cvp_common_data sm8650_common_data[] = { }, { .key = "qcom,sw-power-collapse", - .value = 0, + .value = 1, }, { .key = "qcom,domain-attr-non-fatal-faults", From 5c1c699cc1ed7de514036129fbcc0cbad4b95008 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 12 Jan 2023 23:21:21 -0800 Subject: [PATCH 166/317] msm: eva: Release resources after core init fail Change-Id: Ic19fc13405c570a8747ce17df62d59d5c6d9d652 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 65 ++++++++++++++++++++++++++--------------------- 1 file changed, 36 insertions(+), 29 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index ab13eed27d..09770b807c 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -2160,6 +2160,9 @@ err_core_init: err_load_fw: err_no_mem: dprintk(CVP_ERR, "Core init failed\n"); + __release_subcaches(device); + __disable_subcaches(device); + __hwfence_regs_unmap(dev); mutex_unlock(&dev->lock); pm_relax(dev->res->pdev->dev.parent); return rc; @@ -3320,9 +3323,8 @@ irqreturn_t cvp_hfi_isr(int irq, void *dev) return IRQ_HANDLED; } -static int __handle_reset_clk(struct msm_cvp_platform_resources *res, - int reset_index, enum reset_state state, - enum action_stage stage) +static int __init_reset_clk(struct msm_cvp_platform_resources *res, + int reset_index) { int rc = 0; struct reset_control *rst; @@ -3334,36 +3336,40 @@ static int __handle_reset_clk(struct msm_cvp_platform_resources *res, rst_info = &rst_set->reset_tbl[reset_index]; rst = rst_info->rst; - dprintk(CVP_PWR, "reset_clk: name %s reset_state %d rst %pK stage=%d\n", - rst_set->reset_tbl[reset_index].name, state, rst, stage); + dprintk(CVP_PWR, "reset_clk: name %s rst %pK required_stage=%d\n", + rst_set->reset_tbl[reset_index].name, rst, rst_info->required_stage); - if (state == INIT) { - if (rst) - goto skip_reset_init; + if (rst) + goto skip_reset_init; - if (stage == CVP_ON_USE) { - rst = reset_control_get_exclusive_released(&res->pdev->dev, - rst_set->reset_tbl[reset_index].name); - if (IS_ERR(rst)) { - rc = PTR_ERR(rst); - rst_info->state = RESET_INIT; - } - } else if (stage == CVP_ON_INIT) { - rst = devm_reset_control_get(&res->pdev->dev, - rst_set->reset_tbl[reset_index].name); - if (IS_ERR(rst)) + if (rst_info->required_stage == CVP_ON_USE) { + rst = reset_control_get_exclusive_released(&res->pdev->dev, + rst_set->reset_tbl[reset_index].name); + if (IS_ERR(rst)) { rc = PTR_ERR(rst); - } else { - dprintk(CVP_ERR, "Invalid reset stage\n"); - return -EINVAL; + dprintk(CVP_ERR, "reset get exclusive fail %d\n", rc); + return rc; } - - rst_set->reset_tbl[reset_index].rst = rst; + dprintk(CVP_PWR, "reset_clk: name %s get exclusive rst %llx\n", + rst_set->reset_tbl[reset_index].name, rst); + } else if (rst_info->required_stage == CVP_ON_INIT) { + rst = devm_reset_control_get(&res->pdev->dev, + rst_set->reset_tbl[reset_index].name); + if (IS_ERR(rst)) { + rc = PTR_ERR(rst); + dprintk(CVP_ERR, "reset get fail %d\n", rc); + return rc; + } + dprintk(CVP_PWR, "reset_clk: name %s get rst %llx\n", + rst_set->reset_tbl[reset_index].name, rst); } else { - dprintk(CVP_ERR, "Invalid reset request\n"); - rc = -EINVAL; + dprintk(CVP_ERR, "Invalid reset stage\n"); + return -EINVAL; } + rst_set->reset_tbl[reset_index].rst = rst; + rst_info->state = RESET_INIT; + return 0; skip_reset_init: @@ -3454,8 +3460,9 @@ acquire_again: if (max_retries) { goto acquire_again; } else { - dprintk(CVP_ERR, "%s failed acquire\n", - __func__); + dprintk(CVP_ERR, + "%s acquire %s -EBUSY\n", + __func__, rcinfo->name); rc = -EINVAL; } } else { @@ -3684,7 +3691,7 @@ static int __init_resources(struct iris_hfi_device *device, } for (i = 0; i < device->res->reset_set.count; i++) { - rc = __handle_reset_clk(res, i, INIT, 0); + rc = __init_reset_clk(res, i); if (rc) { dprintk(CVP_ERR, "Failed to init reset clocks\n"); rc = -ENODEV; From d9076b962e099119cf2ca0dc911f847401e74961 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 18 Jan 2023 14:09:21 -0800 Subject: [PATCH 167/317] msm: eva: Skip sleep clock enable/disable It's always enabled by framework. Change-Id: I6f6c8fded0333e2b2fca0a73d5d60f96d65b9940 Signed-off-by: George Shen --- msm/eva/msm_cvp_clocks.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/msm/eva/msm_cvp_clocks.c b/msm/eva/msm_cvp_clocks.c index 807ef2ff73..790b8448a1 100644 --- a/msm/eva/msm_cvp_clocks.c +++ b/msm/eva/msm_cvp_clocks.c @@ -321,6 +321,12 @@ int msm_cvp_prepare_enable_clk(struct iris_hfi_device *device, * them. Since we don't really have a load at this point, * scale it to the lowest frequency possible */ + if (!cl->clk) { + dprintk(CVP_PWR, "%s %s already enabled by framework", + __func__, cl->name); + return 0; + } + if (cl->has_scaling) { if (device->mmrm_cvp != NULL) { // set min freq and cur freq to 0; @@ -375,6 +381,11 @@ int msm_cvp_disable_unprepare_clk(struct iris_hfi_device *device, iris_hfi_for_each_clock_reverse(device, cl) { if (strcmp(cl->name, name)) continue; + if (!cl->clk) { + dprintk(CVP_PWR, "%s %s always enabled by framework", + __func__, cl->name); + return 0; + } clk_disable_unprepare(cl->clk); dprintk(CVP_PWR, "Clock: %s disable and unprepare\n", cl->name); From 26bf3dba95e6b33aa0c2d98d2b69aac92226769f Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 24 Jan 2023 15:46:16 -0800 Subject: [PATCH 168/317] msm: eva: Update QoS, SMMU debug register offsets SMMU debug register block was relocated. New QoS registers was introduced. Without the change, S1 fault will end up as S2 fault. The EVA driver cannot dump appropriate debugging info. Change-Id: I5e833cee51a56164f7853baa91e8c6011ec41189 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 20 ++++++++--- msm/eva/cvp_hfi_io.h | 79 ++++++++++++++++++++++++++------------------ 2 files changed, 62 insertions(+), 37 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 09770b807c..d42a7f5a46 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -794,15 +794,25 @@ static void __set_registers(struct iris_hfi_device *device) __write_register(device, CVP_CPU_CS_AXI4_QOS, pdata->noc_qos->axi_qos); - __write_register(device, CVP_NOC_PRIORITYLUT_LOW, + __write_register(device, CVP_NOC_RGE_PRIORITYLUT_LOW, pdata->noc_qos->prioritylut_low); - __write_register(device, CVP_NOC_PRIORITYLUT_HIGH, + __write_register(device, CVP_NOC_RGE_PRIORITYLUT_HIGH, pdata->noc_qos->prioritylut_high); - __write_register(device, CVP_NOC_URGENCY_LOW, + __write_register(device, CVP_NOC_RGE_URGENCY_LOW, pdata->noc_qos->urgency_low); - __write_register(device, CVP_NOC_DANGERLUT_LOW, + __write_register(device, CVP_NOC_RGE_DANGERLUT_LOW, pdata->noc_qos->dangerlut_low); - __write_register(device, CVP_NOC_SAFELUT_LOW, + __write_register(device, CVP_NOC_RGE_SAFELUT_LOW, + pdata->noc_qos->safelut_low); + __write_register(device, CVP_NOC_CDM_PRIORITYLUT_LOW, + pdata->noc_qos->prioritylut_low); + __write_register(device, CVP_NOC_CDM_PRIORITYLUT_HIGH, + pdata->noc_qos->prioritylut_high); + __write_register(device, CVP_NOC_CDM_URGENCY_LOW, + pdata->noc_qos->urgency_low); + __write_register(device, CVP_NOC_CDM_DANGERLUT_LOW, + pdata->noc_qos->dangerlut_low); + __write_register(device, CVP_NOC_CDM_SAFELUT_LOW, pdata->noc_qos->safelut_low); } diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index 5ab6a9f8ac..697c47ca8c 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -179,21 +179,20 @@ * -------------------------------------------------------------------------- */ #define CVP_NOC_BASE_OFFS 0x000D0000 -#define CVP_NOC_ERR_SWID_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x80) -#define CVP_NOC_ERR_SWID_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0x84) -#define CVP_NOC_ERR_MAINCTL_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x88) -#define CVP_NOC_ERR_ERRVLD_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x90) -#define CVP_NOC_ERR_ERRCLR_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x98) -#define CVP_NOC_ERR_ERRLOG0_LOW_OFFS (CVP_NOC_BASE_OFFS + 0xA0) -#define CVP_NOC_ERR_ERRLOG0_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0xA4) -#define CVP_NOC_ERR_ERRLOG1_LOW_OFFS (CVP_NOC_BASE_OFFS + 0xA8) -#define CVP_NOC_ERR_ERRLOG1_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0xAC) -#define CVP_NOC_ERR_ERRLOG2_LOW_OFFS (CVP_NOC_BASE_OFFS + 0xB0) -#define CVP_NOC_ERR_ERRLOG2_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0xB4) -#define CVP_NOC_ERR_ERRLOG3_LOW_OFFS (CVP_NOC_BASE_OFFS + 0xB8) -#define CVP_NOC_ERR_ERRLOG3_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0xBC) +#define CVP_NOC_ERR_SWID_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x0) +#define CVP_NOC_ERR_SWID_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0x4) +#define CVP_NOC_ERR_MAINCTL_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x8) +#define CVP_NOC_ERR_ERRVLD_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x10) +#define CVP_NOC_ERR_ERRCLR_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x18) +#define CVP_NOC_ERR_ERRLOG0_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x20) +#define CVP_NOC_ERR_ERRLOG0_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0x24) +#define CVP_NOC_ERR_ERRLOG1_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x28) +#define CVP_NOC_ERR_ERRLOG1_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0x2C) +#define CVP_NOC_ERR_ERRLOG2_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x30) +#define CVP_NOC_ERR_ERRLOG2_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0x34) +#define CVP_NOC_ERR_ERRLOG3_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x38) +#define CVP_NOC_ERR_ERRLOG3_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0x3C) #define CVP_NOC_SBM_SENSELN0_LOW (CVP_NOC_BASE_OFFS + 0x300) -#define CVP_NOC_CPU_PENDING_MASK 0x3F80000 #define CVP_NOC_CORE_BASE_OFFS 0x00010000 #define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_LOW \ @@ -203,43 +202,59 @@ #define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN1_HIGH \ (CVP_NOC_CORE_BASE_OFFS + 0x710C) #define CVP_NOC_CORE_ERR_SWID_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0x1200) + (CVP_NOC_CORE_BASE_OFFS + 0xA000) #define CVP_NOC_CORE_ERR_SWID_HIGH_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0x1204) + (CVP_NOC_CORE_BASE_OFFS + 0xA004) #define CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0x1208) + (CVP_NOC_CORE_BASE_OFFS + 0xA008) #define CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0x1210) + (CVP_NOC_CORE_BASE_OFFS + 0xA010) #define CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0x1218) + (CVP_NOC_CORE_BASE_OFFS + 0xA018) #define CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0x1220) + (CVP_NOC_CORE_BASE_OFFS + 0xA020) #define CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0x1224) + (CVP_NOC_CORE_BASE_OFFS + 0xA024) #define CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0x1228) + (CVP_NOC_CORE_BASE_OFFS + 0xA028) #define CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0x122C) + (CVP_NOC_CORE_BASE_OFFS + 0xA02C) #define CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0x1230) + (CVP_NOC_CORE_BASE_OFFS + 0xA030) #define CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0x1234) + (CVP_NOC_CORE_BASE_OFFS + 0xA034) #define CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0x1238) + (CVP_NOC_CORE_BASE_OFFS + 0xA038) #define CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0x123C) + (CVP_NOC_CORE_BASE_OFFS + 0xA03C) + #define CVP_NOC_RCG_VNOC_NOC_CLK_FORCECLOCKON_LOW \ (CVP_NOC_CORE_BASE_OFFS + 0x2018) -#define CVP_NOC_PRIORITYLUT_LOW \ +/* NoC QoS registers */ +#define CVP_NOC_RGE_PRIORITYLUT_LOW \ (CVP_NOC_CORE_BASE_OFFS + 0x3030) -#define CVP_NOC_PRIORITYLUT_HIGH \ +#define CVP_NOC_RGE_PRIORITYLUT_HIGH \ (CVP_NOC_CORE_BASE_OFFS + 0x3034) -#define CVP_NOC_URGENCY_LOW \ +#define CVP_NOC_RGE_URGENCY_LOW \ (CVP_NOC_CORE_BASE_OFFS + 0x3038) -#define CVP_NOC_DANGERLUT_LOW \ +#define CVP_NOC_RGE_DANGERLUT_LOW \ (CVP_NOC_CORE_BASE_OFFS + 0x3040) -#define CVP_NOC_SAFELUT_LOW \ +#define CVP_NOC_RGE_SAFELUT_LOW \ (CVP_NOC_CORE_BASE_OFFS + 0x3048) +#define CVP_NOC_CDM_PRIORITYLUT_LOW \ + (CVP_NOC_CORE_BASE_OFFS + 0x3830) +#define CVP_NOC_CDM_PRIORITYLUT_HIGH \ + (CVP_NOC_CORE_BASE_OFFS + 0x3834) +#define CVP_NOC_CDM_URGENCY_LOW \ + (CVP_NOC_CORE_BASE_OFFS + 0x3838) +#define CVP_NOC_CDM_DANGERLUT_LOW \ + (CVP_NOC_CORE_BASE_OFFS + 0x3840) +#define CVP_NOC_CDM_SAFELUT_LOW \ + (CVP_NOC_CORE_BASE_OFFS + 0x3848) + + +/* End of NoC Qos */ + #define CVP_NOC_RCGCONTROLLER_MAINCTL_LOW \ (CVP_NOC_CORE_BASE_OFFS + 0xC008) #define CVP_NOC_RCGCONTROLLER_HYSTERESIS_LOW \ From a4f6f484b58d9d50a16a2b2164716e9c9a087be1 Mon Sep 17 00:00:00 2001 From: Naveen Ravi Date: Tue, 17 Jan 2023 12:03:24 -0800 Subject: [PATCH 169/317] msm: eva: handle WARPNCC Meta Data Buffer Offset due to FW 14 FW14 introduces bSendMsgPkt in all HFI frame packets including WARPNCC META Data Buffer Offset needs to be updated in KMD for WARPNCC Sync and Async Tests to work Change-Id: I4d1df315e0516efab39a7e91bf68c125c6321ca6 --- include/uapi/eva/media/msm_eva_private.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/include/uapi/eva/media/msm_eva_private.h b/include/uapi/eva/media/msm_eva_private.h index b64622de3f..d19bf8eabe 100644 --- a/include/uapi/eva/media/msm_eva_private.h +++ b/include/uapi/eva/media/msm_eva_private.h @@ -140,7 +140,14 @@ struct cvp_buf_type { #define EVA_KMD_WNCC_MAX_ADDRESSES 4095 #define EVA_KMD_WNCC_MAX_SRC_BUFS 2400 #define EVA_KMD_WNCC_SRC_BUF_ID_OFFSET 1 -#define EVA_KMD_WNCC_HFI_METADATA_BUFS_OFFSET (14 + sizeof(struct cvp_buf_type) / sizeof(__u32) * 5) + +/** + * Macro to get Meta Data Buffer Offset from the HFI Packet + * The number 15 denotes the position of the first Meta Data Buffer with respect to other fields + * If the WARPNCC HFI Frame Packet changes, this macro definition also has to be revised + */ + +#define EVA_KMD_WNCC_HFI_METADATA_BUFS_OFFSET (15 + sizeof(struct cvp_buf_type) / sizeof(__u32) * 5) struct eva_kmd_wncc_metadata { __u64 loc_x_dec : 12; From a9db98a35d9d9e0c4770ba97ecad64180a22c53f Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 30 Jan 2023 09:21:23 -0800 Subject: [PATCH 170/317] msm: eva: Fix KW issues Change-Id: Ia2ec86faf79959511f491025489cd5cecf56fec5 Signed-off-by: George Shen --- include/uapi/eva/media/msm_eva_private.h | 2 +- msm/eva/msm_cvp.c | 4 ++-- msm/eva/msm_cvp_dsp.c | 2 ++ msm/eva/msm_cvp_synx.h | 2 +- msm/eva/vm/cvp_vm_main.c | 3 ++- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/include/uapi/eva/media/msm_eva_private.h b/include/uapi/eva/media/msm_eva_private.h index d19bf8eabe..16a5a49283 100644 --- a/include/uapi/eva/media/msm_eva_private.h +++ b/include/uapi/eva/media/msm_eva_private.h @@ -291,7 +291,7 @@ struct eva_kmd_fence_ctrl { __u64 frame_id; __u32 num_fences; __u32 output_index; - struct eva_kmd_fence fences[MAX_HFI_FENCE_SIZE/2]; + struct eva_kmd_fence fences[MAX_HFI_FENCE_SIZE]; }; #define MAX_FENCE_DATA_SIZE (MAX_HFI_FENCE_SIZE + 6) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 5642f10c8d..6313f1944f 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -382,7 +382,7 @@ static int cvp_fence_thread(void *data) struct cvp_fence_command *f; struct cvp_hfi_cmd_session_hdr *pkt; u32 *synx; - u64 ktid; + u64 ktid = 0; dprintk(CVP_SYNX, "Enter %s\n", current->comm); @@ -570,7 +570,7 @@ static int cvp_populate_fences( struct eva_kmd_hfi_packet *in_pkt, { #ifdef CVP_CONFIG_SYNX_V2 u32 i, buf_offset; - struct eva_kmd_fence fences[MAX_HFI_FENCE_SIZE >> 2]; + struct eva_kmd_fence fences[MAX_HFI_FENCE_SIZE]; struct cvp_fence_command *f; struct cvp_hfi_cmd_session_hdr *cmd_hdr; struct cvp_fence_queue *q; diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 242642db32..867775c3b3 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -572,6 +572,8 @@ static void cvp_remove_dsp_sessions(void) return; list_for_each_safe(s, next_s, &frpc_node->dsp_sessions.list) { + if (!s) + return; inst = list_entry(s, struct msm_cvp_inst, dsp_list); if (inst) { diff --git a/msm/eva/msm_cvp_synx.h b/msm/eva/msm_cvp_synx.h index d4437dccb4..2249430d54 100644 --- a/msm/eva/msm_cvp_synx.h +++ b/msm/eva/msm_cvp_synx.h @@ -40,7 +40,7 @@ struct cvp_fence_command { u32 num_fences; u32 output_index; u32 type; - u32 synx[MAX_HFI_FENCE_SIZE/2]; + u32 synx[MAX_HFI_FENCE_SIZE]; struct cvp_hfi_cmd_session_hdr *pkt; }; diff --git a/msm/eva/vm/cvp_vm_main.c b/msm/eva/vm/cvp_vm_main.c index 143630dc8c..4fb3db342c 100644 --- a/msm/eva/vm/cvp_vm_main.c +++ b/msm/eva/vm/cvp_vm_main.c @@ -53,7 +53,8 @@ static int msm_cvp_vm_start(struct msm_cvp_core *core) { if (!core || !core->platform_data) { dprintk(CVP_ERR, "%s: Invalid params %pK %pK\n", - __func__, core, core->platform_data); + __func__, core, + (core == NULL)? NULL: core->platform_data); return -EINVAL; } From 5d1307dda22de939ac187f36138a92bf0a7fcd16 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 6 Feb 2023 14:45:46 -0800 Subject: [PATCH 171/317] msm: eva: Checks clocks before accesing NoC Checks AHB, MVS1, MVS1C, SLEEP, XO clocks, ensure they are turned on before initial accessing NoC registers. Change-Id: I429e2e410ac29aab893b490dbbd985914843ed9b Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 44 +++++++++++++++++++++++++++++++++++++++++--- msm/eva/cvp_hfi_io.h | 5 ++++- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index d42a7f5a46..a9a6494862 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -767,7 +767,39 @@ static int __read_register(struct iris_hfi_device *device, u32 reg) return rc; } -static void __set_registers(struct iris_hfi_device *device) +static bool __noc_access_ok(struct iris_hfi_device *device) +{ + int ret; + + ret = __read_register(device, CVP_CC_MVS1C_CBCR); + if (ret & 0x80000000) { + dprintk(CVP_ERR, "%s MVS1C off\n", __func__); + return false; + } + ret = __read_register(device, CVP_CC_MVS1_CBCR); + if (ret & 0x80000000) { + dprintk(CVP_ERR, "%s MVS1 off\n", __func__); + return false; + } + ret = __read_register(device, CVP_CC_AHB_CBCR); + if (ret & 0x80000000) { + dprintk(CVP_ERR, "%s AHB off\n", __func__); + return false; + } + ret = __read_register(device, CVP_CC_XO_CBCR); + if (ret & 0x80000000) { + dprintk(CVP_ERR, "%s XO off\n", __func__); + return false; + } + ret = __read_register(device, CVP_CC_SLEEP_CBCR); + if (ret & 0x80000000) { + dprintk(CVP_ERR, "%s SLEEP off\n", __func__); + return false; + } + return true; +} + +static int __set_registers(struct iris_hfi_device *device) { struct msm_cvp_core *core; struct msm_cvp_platform_data *pdata; @@ -777,7 +809,7 @@ static void __set_registers(struct iris_hfi_device *device) if (!device->res) { dprintk(CVP_ERR, "device resources null, cannot set registers\n"); - return; + return -EINVAL ; } core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); @@ -792,6 +824,9 @@ static void __set_registers(struct iris_hfi_device *device) reg_set->reg_tbl[i].value); } + if (!__noc_access_ok(device)) + return -EINVAL; + __write_register(device, CVP_CPU_CS_AXI4_QOS, pdata->noc_qos->axi_qos); __write_register(device, CVP_NOC_RGE_PRIORITYLUT_LOW, @@ -814,6 +849,7 @@ static void __set_registers(struct iris_hfi_device *device) pdata->noc_qos->dangerlut_low); __write_register(device, CVP_NOC_CDM_SAFELUT_LOW, pdata->noc_qos->safelut_low); + return 0; } /* @@ -4218,7 +4254,9 @@ static int __iris_power_on(struct iris_hfi_device *device) * Re-program all of the registers that get reset as a result of * regulator_disable() and _enable() */ - __set_registers(device); + rc = __set_registers(device); + if (rc) + goto fail_enable_core; dprintk(CVP_CORE, "Done with register set\n"); call_iris_op(device, interrupt_init, device); diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index 697c47ca8c..bbd3b605c7 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -272,11 +272,14 @@ #define CVP_AON_WRAPPER_CVP_NOC_CORE_SW_RESET (CVP_AON_BASE_OFFS + 0x1C) #define CVP_AON_WRAPPER_SPARE (CVP_AON_BASE_OFFS + 0x28) -#define CVP_CC_BASE_OFFS 0x000F8000 +#define CVP_CC_BASE_OFFS 0xF8000 #define CVP_CC_MVS1C_GDSCR (CVP_CC_BASE_OFFS + 0x78) #define CVP_CC_MVS1C_CBCR (CVP_CC_BASE_OFFS + 0x90) #define CVP_CC_MVS1_GDSCR (CVP_CC_BASE_OFFS + 0xCC) #define CVP_CC_MVS1_CBCR (CVP_CC_BASE_OFFS + 0xE0) +#define CVP_CC_AHB_CBCR (CVP_CC_BASE_OFFS + 0xF4) +#define CVP_CC_XO_CBCR (CVP_CC_BASE_OFFS + 0x124) +#define CVP_CC_SLEEP_CBCR (CVP_CC_BASE_OFFS + 0x150) #define CVP_GCC_VIDEO_AXI1_CBCR (0x22024) From 608f7035b6f9258a20013729fca8aabd7611bbc5 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 9 Feb 2023 16:41:01 -0800 Subject: [PATCH 172/317] msm: eva: moves synx_recovery ahead of f/w loading Before booting f/w, synx_recovery() shall be called as part of SSR. Change-Id: I1d03f073c964eaf5b26dd4fec5aac88b7d9de1a8 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index a9a6494862..e418b6e417 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -2081,6 +2081,14 @@ static int iris_hfi_core_init(void *device) goto err_load_fw; } +#ifdef CVP_CONFIG_SYNX_V2 + rc = cvp_synx_recover(); + if (rc) { + dprintk(CVP_ERR, "Failed to recover synx\n"); + goto err_core_init; + } +#endif + /* mmrm registration */ if (msm_cvp_mmrm_enabled) { rc = msm_cvp_mmrm_register(device); @@ -2150,14 +2158,6 @@ static int iris_hfi_core_init(void *device) __set_ubwc_config(device); __sys_set_idle_indicator(device, true); -#ifdef CVP_CONFIG_SYNX_V2 - rc = cvp_synx_recover(); - if (rc) { - dprintk(CVP_ERR, "Failed to recover synx\n"); - goto err_core_init; - } -#endif - if (dev->res->pm_qos.latency_us) { int err = 0; u32 i, cpu; From fe87e8f0fa67431dbc5873d409ebf6aa4465b2ad Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 7 Feb 2023 09:52:59 -0800 Subject: [PATCH 173/317] msm: eva: Add AON Timer mapping for fW Reorganize the way to store FW required register mappings. It will make future error check and debugging easier. Update MID value to name translation table. Change-Id: I6e3dbd837f2f2c297af16152754f27242aeb2637 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 105 ++++++++++++++++++++++-------------- msm/eva/msm_cvp_res_parse.c | 50 ++++++++++------- msm/eva/msm_cvp_resources.h | 23 +++++--- 3 files changed, 112 insertions(+), 66 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index e418b6e417..a52af9233d 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1974,42 +1974,59 @@ static int __hwfence_regs_map(struct iris_hfi_device *device) return -EINVAL; } - if (device->res->ipclite_phyaddr != 0) { - rc = iommu_map(cb->domain, device->res->ipclite_iova, - device->res->ipclite_phyaddr, - device->res->ipclite_size, + if (device->res->reg_mappings.ipclite_phyaddr != 0) { + rc = iommu_map(cb->domain, + device->res->reg_mappings.ipclite_iova, + device->res->reg_mappings.ipclite_phyaddr, + device->res->reg_mappings.ipclite_size, IOMMU_READ | IOMMU_WRITE); if (rc) { dprintk(CVP_ERR, "map ipclite fail %d %#x %#x %#x\n", - rc, device->res->ipclite_iova, - device->res->ipclite_phyaddr, - device->res->ipclite_size); + rc, device->res->reg_mappings.ipclite_iova, + device->res->reg_mappings.ipclite_phyaddr, + device->res->reg_mappings.ipclite_size); return rc; } } - if (device->res->hwmutex_phyaddr != 0) { - rc = iommu_map(cb->domain, device->res->hwmutex_iova, - device->res->hwmutex_phyaddr, - device->res->hwmutex_size, + if (device->res->reg_mappings.hwmutex_phyaddr != 0) { + rc = iommu_map(cb->domain, + device->res->reg_mappings.hwmutex_iova, + device->res->reg_mappings.hwmutex_phyaddr, + device->res->reg_mappings.hwmutex_size, IOMMU_MMIO | IOMMU_READ | IOMMU_WRITE); if (rc) { dprintk(CVP_ERR, "map hwmutex fail %d %#x %#x %#x\n", - rc, device->res->hwmutex_iova, - device->res->hwmutex_phyaddr, - device->res->hwmutex_size); + rc, device->res->reg_mappings.hwmutex_iova, + device->res->reg_mappings.hwmutex_phyaddr, + device->res->reg_mappings.hwmutex_size); return rc; } } - if (device->res->aon_phyaddr != 0) { - rc = iommu_map(cb->domain, device->res->aon_iova, - device->res->aon_phyaddr, - device->res->aon_size, + if (device->res->reg_mappings.aon_phyaddr != 0) { + rc = iommu_map(cb->domain, + device->res->reg_mappings.aon_iova, + device->res->reg_mappings.aon_phyaddr, + device->res->reg_mappings.aon_size, IOMMU_MMIO | IOMMU_READ | IOMMU_WRITE); if (rc) { dprintk(CVP_ERR, "map aon fail %d %#x %#x %#x\n", - rc, device->res->aon_iova, - device->res->aon_phyaddr, - device->res->aon_size); + rc, device->res->reg_mappings.aon_iova, + device->res->reg_mappings.aon_phyaddr, + device->res->reg_mappings.aon_size); + return rc; + } + } + if (device->res->reg_mappings.timer_phyaddr != 0) { + rc = iommu_map(cb->domain, + device->res->reg_mappings.timer_iova, + device->res->reg_mappings.timer_phyaddr, + device->res->reg_mappings.timer_size, + IOMMU_MMIO | IOMMU_READ | IOMMU_WRITE); + if (rc) { + dprintk(CVP_ERR, "map timer fail %d %#x %#x %#x\n", + rc, device->res->reg_mappings.timer_iova, + device->res->reg_mappings.timer_phyaddr, + device->res->reg_mappings.timer_size); return rc; } } @@ -2027,17 +2044,25 @@ static int __hwfence_regs_unmap(struct iris_hfi_device *device) return -EINVAL; } - if (device->res->ipclite_iova != 0) { - iommu_unmap(cb->domain, device->res->ipclite_iova, - device->res->ipclite_size); + if (device->res->reg_mappings.ipclite_iova != 0) { + iommu_unmap(cb->domain, + device->res->reg_mappings.ipclite_iova, + device->res->reg_mappings.ipclite_size); } - if (device->res->hwmutex_iova != 0) { - iommu_unmap(cb->domain, device->res->hwmutex_iova, - device->res->hwmutex_size); + if (device->res->reg_mappings.hwmutex_iova != 0) { + iommu_unmap(cb->domain, + device->res->reg_mappings.hwmutex_iova, + device->res->reg_mappings.hwmutex_size); } - if (device->res->aon_iova != 0) { - iommu_unmap(cb->domain, device->res->aon_iova, - device->res->aon_size); + if (device->res->reg_mappings.aon_iova != 0) { + iommu_unmap(cb->domain, + device->res->reg_mappings.aon_iova, + device->res->reg_mappings.aon_size); + } + if (device->res->reg_mappings.timer_iova != 0) { + iommu_unmap(cb->domain, + device->res->reg_mappings.timer_iova, + device->res->reg_mappings.timer_size); } return rc; } @@ -4880,18 +4905,18 @@ static int iris_hfi_get_core_capabilities(void *dev) static const char * const mid_names[16] = { "CVP_FW", "ARP_DATA", - "CVP_OD_NON_PIXEL", - "CVP_OD_ORIG_PIXEL", - "CVP_OD_WR_PIXEL", - "CVP_MPU_ORIG_PIXEL", - "CVP_MPU_REF_PIXEL", + "CVP_MPU_PIXEL", "CVP_MPU_NON_PIXEL", - "CVP_MPU_DFS", - "CVP_FDU_NON_PIXEL", "CVP_FDU_PIXEL", - "CVP_ICA_PIXEL", - "Invalid", - "Invalid", + "CVP_FDU_NON_PIXEL", + "CVP_GCE_PIXEL", + "CVP_GCE_NON_PIXEL", + "CVP_TOF_PIXEL", + "CVP_TOF_NON_PIXEL", + "CVP_VADL_PIXEL", + "CVP_VADL_NON_PIXEL", + "CVP_RGE_NON_PIXEL", + "CVP_CDM", "Invalid", "Invalid" }; diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index 7dd9fd45f3..251882ee6f 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -144,9 +144,10 @@ static int msm_cvp_load_ipcc_regs(struct msm_cvp_platform_resources *res) static int msm_cvp_load_regspace_mapping(struct msm_cvp_platform_resources *res) { int ret = 0; - unsigned int ipclite_mapping_config[3]; - unsigned int hwmutex_mapping_config[3]; - unsigned int aon_mapping_config[3]; + unsigned int ipclite_mapping_config[3] = {0}; + unsigned int hwmutex_mapping_config[3] = {0}; + unsigned int aon_mapping_config[3] = {0}; + unsigned int timer_config[3] = {0}; struct platform_device *pdev = res->pdev; ret = of_property_read_u32_array(pdev->dev.of_node, "ipclite_mappings", @@ -155,9 +156,9 @@ static int msm_cvp_load_regspace_mapping(struct msm_cvp_platform_resources *res) dprintk(CVP_ERR, "Failed to read ipclite reg: %d\n", ret); return ret; } - res->ipclite_iova = ipclite_mapping_config[0]; - res->ipclite_size = ipclite_mapping_config[1]; - res->ipclite_phyaddr = ipclite_mapping_config[2]; + res->reg_mappings.ipclite_iova = ipclite_mapping_config[0]; + res->reg_mappings.ipclite_size = ipclite_mapping_config[1]; + res->reg_mappings.ipclite_phyaddr = ipclite_mapping_config[2]; ret = of_property_read_u32_array(pdev->dev.of_node, "hwmutex_mappings", hwmutex_mapping_config, 3); @@ -165,13 +166,9 @@ static int msm_cvp_load_regspace_mapping(struct msm_cvp_platform_resources *res) dprintk(CVP_ERR, "Failed to read hwmutex reg: %d\n", ret); return ret; } - res->hwmutex_iova = hwmutex_mapping_config[0]; - res->hwmutex_size = hwmutex_mapping_config[1]; - res->hwmutex_phyaddr = hwmutex_mapping_config[2]; - dprintk(CVP_CORE, "ipclite %#x %#x %#x hwmutex %#x %#x %#x\n", - res->ipclite_iova, res->ipclite_phyaddr, res->ipclite_size, - res->hwmutex_iova, res->hwmutex_phyaddr, res->hwmutex_size); - + res->reg_mappings.hwmutex_iova = hwmutex_mapping_config[0]; + res->reg_mappings.hwmutex_size = hwmutex_mapping_config[1]; + res->reg_mappings.hwmutex_phyaddr = hwmutex_mapping_config[2]; ret = of_property_read_u32_array(pdev->dev.of_node, "aon_mappings", aon_mapping_config, 3); @@ -179,11 +176,28 @@ static int msm_cvp_load_regspace_mapping(struct msm_cvp_platform_resources *res) dprintk(CVP_ERR, "Failed to read aon reg: %d\n", ret); return ret; } - res->aon_iova = aon_mapping_config[0]; - res->aon_size = aon_mapping_config[1]; - res->aon_phyaddr = aon_mapping_config[2]; - dprintk(CVP_CORE, "aon %#x %#x %#x \n", - res->hwmutex_iova, res->hwmutex_phyaddr, res->hwmutex_size); + res->reg_mappings.aon_iova = aon_mapping_config[0]; + res->reg_mappings.aon_size = aon_mapping_config[1]; + res->reg_mappings.aon_phyaddr = aon_mapping_config[2]; + + ret = of_property_read_u32_array(pdev->dev.of_node, + "aon_timer_mappings", timer_config, 3); + if (ret) { + dprintk(CVP_ERR, "Failed to read timer reg: %d\n", ret); + return ret; + } + res->reg_mappings.timer_iova = timer_config[0]; + res->reg_mappings.timer_size = timer_config[1]; + res->reg_mappings.timer_phyaddr = timer_config[2]; + + dprintk(CVP_CORE, + "reg mappings %#x %#x %#x %#x %#x %#X %#x %#x %#x %#x %#x %#x\n", + res->reg_mappings.ipclite_iova, res->reg_mappings.ipclite_size, + res->reg_mappings.ipclite_phyaddr, res->reg_mappings.hwmutex_iova, + res->reg_mappings.hwmutex_size, res->reg_mappings.hwmutex_phyaddr, + res->reg_mappings.aon_iova, res->reg_mappings.aon_size, + res->reg_mappings.aon_phyaddr, res->reg_mappings.timer_iova, + res->reg_mappings.timer_size, res->reg_mappings.timer_phyaddr); return ret; } diff --git a/msm/eva/msm_cvp_resources.h b/msm/eva/msm_cvp_resources.h index 9b2959975d..c6fe037ea8 100644 --- a/msm/eva/msm_cvp_resources.h +++ b/msm/eva/msm_cvp_resources.h @@ -153,14 +153,7 @@ struct cvp_pm_qos { struct dev_pm_qos_request *pm_qos_hdls; }; -struct msm_cvp_platform_resources { - phys_addr_t firmware_base; - phys_addr_t register_base; - phys_addr_t ipcc_reg_base; - phys_addr_t gcc_reg_base; - uint32_t register_size; - uint32_t ipcc_reg_size; - uint32_t gcc_reg_size; +struct cvp_fw_reg_mappings { phys_addr_t ipclite_iova; phys_addr_t ipclite_phyaddr; uint32_t ipclite_size; @@ -170,6 +163,20 @@ struct msm_cvp_platform_resources { phys_addr_t aon_iova; phys_addr_t aon_phyaddr; uint32_t aon_size; + phys_addr_t timer_iova; + phys_addr_t timer_phyaddr; + uint32_t timer_size; +}; + +struct msm_cvp_platform_resources { + phys_addr_t firmware_base; + phys_addr_t register_base; + phys_addr_t ipcc_reg_base; + phys_addr_t gcc_reg_base; + uint32_t register_size; + uint32_t ipcc_reg_size; + uint32_t gcc_reg_size; + struct cvp_fw_reg_mappings reg_mappings; uint32_t irq; uint32_t sku_version; struct allowed_clock_rates_table *allowed_clks_tbl; From bc2a58caf44dae918559bdecc5508182a3b370f6 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 16 Feb 2023 22:49:21 -0800 Subject: [PATCH 174/317] msm: eva: Print error code if send hfi queue fail Fixing KW issue that blocks promotion. Change-Id: I51ed3c909e2dc32535cc8beaa1af1fb299f7f2ab Signed-off-by: George Shen --- msm/eva/msm_cvp_dsp.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 867775c3b3..6b93d184fd 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -568,11 +568,9 @@ static void cvp_remove_dsp_sessions(void) while ((frpc_node = pop_frpc_node())) { s = &frpc_node->dsp_sessions.list; - if (!s) - return; list_for_each_safe(s, next_s, &frpc_node->dsp_sessions.list) { - if (!s) + if (!s || !next_s) return; inst = list_entry(s, struct msm_cvp_inst, dsp_list); @@ -1372,8 +1370,8 @@ void cvp_dsp_send_hfi_queue(void) } if (rsp.ret == CPU2DSP_EFATAL || rsp.ret == CPU2DSP_EUNAVAILABLE) { - dprintk(CVP_ERR, "%s fatal error returned %d\n", - __func__, rsp.dsp_state); + dprintk(CVP_ERR, "%s fatal error returned %d %d\n", + __func__, rsp.dsp_state, rsp.ret); me->state = DSP_INVALID; cvp_hyp_assign_from_dsp(); goto exit; From 70fc47d3ebfaadd545e8df16fa71e28a81e004be Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 16 Feb 2023 20:24:36 -0800 Subject: [PATCH 175/317] msm: eva: New attribute for secure camera mapping Add attribute DMA_ATTR_QTI_SMMU_PROXY_MAP to dma_map_attrs. Change-Id: I747a550deb42c45da2c816682976d04968ad48b1 Signed-off-by: George Shen --- msm/eva/cvp_smem.c | 10 +++++++--- msm/eva/msm_cvp_res_parse.c | 14 +++++++++++--- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/msm/eva/cvp_smem.c b/msm/eva/cvp_smem.c index 2e1f09bd6b..ac3a86f268 100644 --- a/msm/eva/cvp_smem.c +++ b/msm/eva/cvp_smem.c @@ -99,6 +99,8 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, u32 align, * required buffer size */ attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC; + if (flags & SMEM_CAMERA) + attach->dma_map_attrs |= DMA_ATTR_QTI_SMMU_PROXY_MAP; if (res->sys_cache_present) attach->dma_map_attrs |= DMA_ATTR_IOMMU_USE_UPSTREAM_HINT; @@ -232,7 +234,9 @@ int msm_cvp_map_smem(struct msm_cvp_inst *inst, smem->flags |= (SMEM_SECURE | SMEM_PIXEL); else if (vmid_list[temp] == VMID_CP_NON_PIXEL) smem->flags |= (SMEM_SECURE | SMEM_NON_PIXEL); - else if (vmid_list[temp] == VMID_CP_CAMERA) + else if (vmid_list[temp] == VMID_CP_CAMERA || + /* To-do: what if the EVA driver runs in TVM */ + vmid_list[temp] == VMID_TVM) smem->flags |= (SMEM_SECURE | SMEM_CAMERA); dprintk(CVP_MEM, "inst %pK VM idx %d VM_ID %d fd %d pkt_type %#x\n", inst, temp, vmid_list[temp], smem->fd, smem->pkt_type); @@ -536,7 +540,7 @@ struct context_bank_info *msm_cvp_smem_get_context_bank( char *non_secure_cb = "cvp_hlos"; char *secure_nonpixel_cb = "cvp_sec_nonpixel"; char *secure_pixel_cb = "cvp_sec_pixel"; - char *dummy_cb = "cvp_dummy"; + char *camera_cb = "cvp_camera"; bool is_secure = (flags & SMEM_SECURE) ? true : false; if (flags & SMEM_PIXEL) @@ -545,7 +549,7 @@ struct context_bank_info *msm_cvp_smem_get_context_bank( search_str = secure_nonpixel_cb; else if (flags & SMEM_CAMERA) /* Secure Camera pixel buffer */ - search_str = dummy_cb; + search_str = camera_cb; else search_str = non_secure_cb; diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index 251882ee6f..1128493e55 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -1092,8 +1092,17 @@ static int msm_cvp_populate_context_bank(struct device *dev, } dprintk(CVP_CORE, "%s: context bank has name %s\n", __func__, cb->name); - if (!strcmp(cb->name, "cvp_dummy")) - goto success_setup_cb; + if (!strcmp(cb->name, "cvp_camera")) { + cb->is_secure = true; + rc = msm_cvp_setup_context_bank(&core->resources, cb, dev); + if (rc) { + dprintk(CVP_ERR, "Cannot setup context bank %s %d\n", + cb->name, rc); + goto err_setup_cb; + } + + return 0; + } rc = of_property_read_u32_array(np, "qcom,iommu-dma-addr-pool", (u32 *)&cb->addr_range, 2); @@ -1120,7 +1129,6 @@ static int msm_cvp_populate_context_bank(struct device *dev, cb->name, cb->addr_range.start, cb->addr_range.size, cb->buffer_type); -success_setup_cb: cb->domain = iommu_get_domain_for_dev(dev); if (IS_ERR_OR_NULL(cb->domain)) { dprintk(CVP_ERR, "Create domain failed\n"); From d665182aed3914c831f109ab5830708f4ff7eddd Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 21 Feb 2023 14:30:49 -0800 Subject: [PATCH 176/317] msm: eva: Add FW 17 support due to HFI change Non-secure ARP and CRC in BUFFER_TYPE, enabling IFPC. Change-Id: I551e29e7770cdfd83b0ed9f7f925fb8bd6e6a4a6 Signed-off-by: George Shen --- include/uapi/eva/media/msm_eva_private.h | 2 ++ msm/eva/msm_cvp_buf.c | 10 +++++----- msm/eva/msm_cvp_debug.c | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/include/uapi/eva/media/msm_eva_private.h b/include/uapi/eva/media/msm_eva_private.h index 16a5a49283..a33767bff3 100644 --- a/include/uapi/eva/media/msm_eva_private.h +++ b/include/uapi/eva/media/msm_eva_private.h @@ -129,6 +129,8 @@ struct cvp_buf_type { __u32 fence_type; __u32 input_handle; __u32 output_handle; + __u32 debug_flags; + __u32 crc; }; /** diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 848a7a0302..f1c5b4a063 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1794,10 +1794,10 @@ struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, if (!buffer_size) return NULL; - /* PERSIST buffer requires secure mapping - * Disable and wait for hyp_assign available + /* If PERSIST buffer requires secure mapping, uncomment + * below flags setting + * smem_flags |= SMEM_SECURE | SMEM_NON_PIXEL; */ - smem_flags |= SMEM_SECURE | SMEM_NON_PIXEL; buf = cvp_kmem_cache_zalloc(&cvp_driver->buf_cache, GFP_KERNEL); if (!buf) { @@ -1812,7 +1812,7 @@ struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, } buf->smem->flags = smem_flags; - rc = msm_cvp_smem_alloc(buffer_size, 1, 0, + rc = msm_cvp_smem_alloc(buffer_size, 1, 0, /* 0: no mapping in kernel space */ &(inst->core->resources), buf->smem); if (rc) { dprintk(CVP_ERR, "Failed to allocate ARP memory\n"); @@ -1954,7 +1954,7 @@ int cvp_allocate_dsp_bufs(struct msm_cvp_inst *inst, rc = msm_cvp_smem_alloc(buffer_size, 1, 0, &(inst->core->resources), buf->smem); if (rc) { - dprintk(CVP_ERR, "Failed to allocate ARP memory\n"); + dprintk(CVP_ERR, "Failed to allocate DSP buf\n"); goto err_no_mem; } buf->smem->pkt_type = buf->smem->buf_idx = 0; diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 8bf416327f..53f2516aa1 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -20,7 +20,7 @@ EXPORT_SYMBOL(msm_cvp_debug_out); int msm_cvp_fw_debug = 0x18; int msm_cvp_fw_debug_mode = 1; -int msm_cvp_fw_low_power_mode = 0; /*disable during initial stage*/ +int msm_cvp_fw_low_power_mode = 1; bool msm_cvp_fw_coverage = !true; bool msm_cvp_auto_pil = true; bool msm_cvp_cacheop_enabled = true; From 0aa70a481173f1c977001a79c1751e47b9edd4a4 Mon Sep 17 00:00:00 2001 From: Naveen Ravi Date: Fri, 24 Feb 2023 11:10:27 -0800 Subject: [PATCH 177/317] msm: eva: define ds config in eva kmd Change-Id: Ibbbf5d34e470d66168e4257aef53beaa5814b7cb --- msm/eva/cvp_hfi.h | 3 +++ msm/eva/msm_cvp_platform.c | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/msm/eva/cvp_hfi.h b/msm/eva/cvp_hfi.h index 85d7bf809a..8e31974c9f 100644 --- a/msm/eva/cvp_hfi.h +++ b/msm/eva/cvp_hfi.h @@ -183,6 +183,8 @@ (HFI_CMD_SESSION_CVP_START + 0x100) #define HFI_CMD_SESSION_CVP_ICA_CONFIG\ (HFI_CMD_SESSION_CVP_START + 0x101) +#define HFI_CMD_SESSION_CVP_DS_CONFIG\ + (HFI_CMD_SESSION_CVP_START + 0x02F) #define HFI_MSG_SESSION_CVP_START \ @@ -272,6 +274,7 @@ #define HFI_PERSIST_CMD_SIZE 11 +#define HFI_DS_CONFIG_CMD_SIZE 11 #define HFI_DS_CMD_SIZE 50 #define HFI_OF_CONFIG_CMD_SIZE 34 diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index ba8cb5a781..e093864a6f 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -456,6 +456,14 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { .resp = HAL_NO_RESP, .name = "REL_PERSIST", }, + [HFI_CMD_SESSION_CVP_DS_CONFIG - HFI_CMD_SESSION_CVP_START] = + { + .size = HFI_DS_CONFIG_CMD_SIZE, + .type = HFI_CMD_SESSION_CVP_DS_CONFIG, + .is_config_pkt = true, + .resp = HAL_NO_RESP, + .name = "DS_CONFIG", + }, [HFI_CMD_SESSION_CVP_DS - HFI_CMD_SESSION_CVP_START] = { .size = HFI_DS_CMD_SIZE, From 264f4c7c0d42b07eac4bd86b80677969807ccf8f Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 22 Feb 2023 23:20:08 -0800 Subject: [PATCH 178/317] msm: eva: Add session start/stop through FW New HFI allows FW stop session and notify driver of its completion. Driver is safe to reclaim resources allocated for the session. Change-Id: Ic6a08334a0bafd57f366a635c53f4f5f8f31f77e Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 47 +++++++++++++++ msm/eva/cvp_hfi.h | 8 +++ msm/eva/cvp_hfi_api.h | 3 + msm/eva/cvp_hfi_helper.h | 2 +- msm/eva/hfi_response_handler.c | 101 +++++++++++++++++++++++++++++++-- msm/eva/msm_cvp.c | 101 ++++++++++++++++++++++++++++++--- msm/eva/msm_cvp.h | 2 + msm/eva/msm_cvp_common.c | 10 ++-- msm/eva/msm_cvp_dsp.c | 92 ++++++++++++++++++++++++++---- msm/eva/msm_cvp_dsp.h | 21 ++++++- 10 files changed, 353 insertions(+), 34 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index a52af9233d..6481b70a67 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -2776,6 +2776,50 @@ static int iris_hfi_session_flush(void *sess) return rc; } +static int iris_hfi_session_start(void *sess) +{ + struct cvp_hal_session *session = sess; + struct iris_hfi_device *device; + int rc = 0; + + if (!session || !session->device) { + dprintk(CVP_ERR, "Invalid Params %s\n", __func__); + return -EINVAL; + } + + device = session->device; + + mutex_lock(&device->lock); + + rc = __send_session_cmd(session, HFI_CMD_SESSION_EVA_START); + + mutex_unlock(&device->lock); + + return rc; +} + +static int iris_hfi_session_stop(void *sess) +{ + struct cvp_hal_session *session = sess; + struct iris_hfi_device *device; + int rc = 0; + + if (!session || !session->device) { + dprintk(CVP_ERR, "Invalid Params %s\n", __func__); + return -EINVAL; + } + + device = session->device; + + mutex_lock(&device->lock); + + rc = __send_session_cmd(session, HFI_CMD_SESSION_EVA_STOP); + + mutex_unlock(&device->lock); + + return rc; +} + static void __process_fatal_error( struct iris_hfi_device *device) { @@ -3137,6 +3181,7 @@ static void **get_session_id(struct msm_cvp_cb_info *info) case HAL_SESSION_INIT_DONE: case HAL_SESSION_END_DONE: case HAL_SESSION_ABORT_DONE: + case HAL_SESSION_START_DONE: case HAL_SESSION_STOP_DONE: case HAL_SESSION_FLUSH_DONE: case HAL_SESSION_SET_BUFFER_DONE: @@ -5252,6 +5297,8 @@ static void iris_init_hfi_callbacks(struct cvp_hfi_device *hdev) hdev->core_trigger_ssr = iris_hfi_core_trigger_ssr; hdev->session_init = iris_hfi_session_init; hdev->session_end = iris_hfi_session_end; + hdev->session_start = iris_hfi_session_start; + hdev->session_stop = iris_hfi_session_stop; hdev->session_abort = iris_hfi_session_abort; hdev->session_clean = iris_hfi_session_clean; hdev->session_set_buffers = iris_hfi_session_set_buffers; diff --git a/msm/eva/cvp_hfi.h b/msm/eva/cvp_hfi.h index 8e31974c9f..1f2f2b0d40 100644 --- a/msm/eva/cvp_hfi.h +++ b/msm/eva/cvp_hfi.h @@ -179,6 +179,10 @@ (HFI_CMD_SESSION_CVP_START + 0x081) #define HFI_CMD_SESSION_CVP_SYNX\ (HFI_CMD_SESSION_CVP_START + 0x086) +#define HFI_CMD_SESSION_EVA_START\ + (HFI_CMD_SESSION_CVP_START + 0x088) +#define HFI_CMD_SESSION_EVA_STOP\ + (HFI_CMD_SESSION_CVP_START + 0x089) #define HFI_CMD_SESSION_CVP_ICA_FRAME\ (HFI_CMD_SESSION_CVP_START + 0x100) #define HFI_CMD_SESSION_CVP_ICA_CONFIG\ @@ -256,6 +260,10 @@ #define HFI_MSG_SESSION_CVP_FLUSH\ (HFI_MSG_SESSION_CVP_START + 0x004A) +#define HFI_MSG_SESSION_EVA_START\ + (HFI_MSG_SESSION_CVP_START + 0x0058) +#define HFI_MSG_SESSION_EVA_STOP\ + (HFI_MSG_SESSION_CVP_START + 0x0059) #define CVP_IFACEQ_MAX_PKT_SIZE 1024 #define CVP_IFACEQ_MED_PKT_SIZE 768 diff --git a/msm/eva/cvp_hfi_api.h b/msm/eva/cvp_hfi_api.h index 705db12cca..e69d057345 100644 --- a/msm/eva/cvp_hfi_api.h +++ b/msm/eva/cvp_hfi_api.h @@ -131,6 +131,7 @@ enum hal_command_response { HAL_SESSION_END_DONE, HAL_SESSION_SET_BUFFER_DONE, HAL_SESSION_ABORT_DONE, + HAL_SESSION_START_DONE, HAL_SESSION_STOP_DONE, HAL_SESSION_CVP_OPERATION_CONFIG, HAL_SESSION_FLUSH_DONE, @@ -254,6 +255,8 @@ struct cvp_hfi_device { int (*core_trigger_ssr)(void *device, enum hal_ssr_trigger_type); int (*session_init)(void *device, void *session_id, void **new_session); int (*session_end)(void *session); + int (*session_start)(void *session); + int (*session_stop)(void *session); int (*session_abort)(void *session); int (*session_set_buffers)(void *sess, u32 iova, u32 size); int (*session_release_buffers)(void *sess); diff --git a/msm/eva/cvp_hfi_helper.h b/msm/eva/cvp_hfi_helper.h index a66782d4d7..4423c17018 100644 --- a/msm/eva/cvp_hfi_helper.h +++ b/msm/eva/cvp_hfi_helper.h @@ -511,7 +511,7 @@ struct cvp_hfi_cmd_sys_test_ssr_packet { u32 trigger_type; }; -struct cvp_hfi_msg_sys_session_flush_done_packet { +struct cvp_hfi_msg_sys_session_ctrl_done_packet { u32 size; u32 packet_type; u32 session_id; diff --git a/msm/eva/hfi_response_handler.c b/msm/eva/hfi_response_handler.c index 8b14cc021f..f28de04bf4 100644 --- a/msm/eva/hfi_response_handler.c +++ b/msm/eva/hfi_response_handler.c @@ -170,8 +170,8 @@ static int hfi_process_sys_init_done(u32 device_id, status = hfi_map_err_status(pkt->error_type); if (status) { - dprintk(CVP_ERR, "%s: status %#x\n", - __func__, status); + dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n", + __func__, status, pkt->packet_type, pkt->error_type); goto err_no_prop; } @@ -212,7 +212,8 @@ enum cvp_status cvp_hfi_process_sys_init_done_prop_read( status = hfi_map_err_status(pkt->error_type); if (status) { - dprintk(CVP_ERR, "%s: status %#x\n", __func__, status); + dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n", + __func__, status, pkt->packet_type, pkt->error_type); return status; } @@ -246,6 +247,9 @@ static int hfi_process_session_init_done(u32 device_id, cmd_done.device_id = device_id; cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; cmd_done.status = hfi_map_err_status(pkt->error_type); + if (cmd_done.status) + dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n", + __func__, cmd_done.status, pkt->packet_type, pkt->error_type); cmd_done.data.session_init_done = session_init_done; cmd_done.size = sizeof(struct cvp_hal_session_init_done); @@ -272,6 +276,9 @@ static int hfi_process_session_end_done(u32 device_id, cmd_done.device_id = device_id; cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; cmd_done.status = hfi_map_err_status(pkt->error_type); + if (cmd_done.status) + dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n", + __func__, cmd_done.status, pkt->packet_type, pkt->error_type); cmd_done.size = 0; info->response_type = HAL_SESSION_END_DONE; @@ -299,6 +306,9 @@ static int hfi_process_session_abort_done(u32 device_id, cmd_done.device_id = device_id; cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; cmd_done.status = hfi_map_err_status(pkt->error_type); + if (cmd_done.status) + dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n", + __func__, cmd_done.status, pkt->packet_type, pkt->error_type); cmd_done.size = 0; info->response_type = HAL_SESSION_ABORT_DONE; @@ -326,6 +336,9 @@ static int hfi_process_session_set_buf_done(u32 device_id, cmd_done.device_id = device_id; cmd_done.session_id = (void *)(uintptr_t)get_msg_session_id(pkt); cmd_done.status = hfi_map_err_status(get_msg_errorcode(pkt)); + if (cmd_done.status) + dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n", + __func__, cmd_done.status, pkt->packet_type, pkt->error_type); cmd_done.size = 0; info->response_type = HAL_SESSION_SET_BUFFER_DONE; @@ -337,15 +350,15 @@ static int hfi_process_session_set_buf_done(u32 device_id, static int hfi_process_session_flush_done(u32 device_id, void *hdr, struct msm_cvp_cb_info *info) { - struct cvp_hfi_msg_sys_session_flush_done_packet *pkt = - (struct cvp_hfi_msg_sys_session_flush_done_packet *)hdr; + struct cvp_hfi_msg_sys_session_ctrl_done_packet *pkt = + (struct cvp_hfi_msg_sys_session_ctrl_done_packet *)hdr; struct msm_cvp_cb_cmd_done cmd_done = {0}; dprintk(CVP_SESS, "RECEIVED: SESSION_FLUSH_DONE[%#x]\n", pkt->session_id); if (!pkt || pkt->size < - sizeof(struct cvp_hfi_msg_sys_session_flush_done_packet)) { + sizeof(struct cvp_hfi_msg_sys_session_ctrl_done_packet)) { dprintk(CVP_ERR, "%s: bad packet/packet size: %d\n", __func__, pkt ? pkt->size : 0); return -E2BIG; @@ -353,6 +366,9 @@ static int hfi_process_session_flush_done(u32 device_id, cmd_done.device_id = device_id; cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; cmd_done.status = hfi_map_err_status(pkt->error_type); + if (cmd_done.status) + dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n", + __func__, cmd_done.status, pkt->packet_type, pkt->error_type); cmd_done.size = 0; info->response_type = HAL_SESSION_FLUSH_DONE; @@ -361,6 +377,67 @@ static int hfi_process_session_flush_done(u32 device_id, return 0; } +static int hfi_process_session_start_done(u32 device_id, + void *hdr, struct msm_cvp_cb_info *info) +{ + struct cvp_hfi_msg_sys_session_ctrl_done_packet *pkt = + (struct cvp_hfi_msg_sys_session_ctrl_done_packet *)hdr; + struct msm_cvp_cb_cmd_done cmd_done = {0}; + + dprintk(CVP_SESS, "RECEIVED: SESSION_START_DONE[%#x]\n", + pkt->session_id); + + if (!pkt || pkt->size < + sizeof(struct cvp_hfi_msg_sys_session_ctrl_done_packet)) { + dprintk(CVP_ERR, "%s: bad packet/packet size: %d\n", + __func__, pkt ? pkt->size : 0); + return -E2BIG; + } + cmd_done.device_id = device_id; + cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.status = hfi_map_err_status(pkt->error_type); + if (cmd_done.status) + dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n", + __func__, cmd_done.status, pkt->packet_type, pkt->error_type); + cmd_done.size = 0; + + info->response_type = HAL_SESSION_START_DONE; + info->response.cmd = cmd_done; + + return 0; +} + +static int hfi_process_session_stop_done(u32 device_id, + void *hdr, struct msm_cvp_cb_info *info) +{ + struct cvp_hfi_msg_sys_session_ctrl_done_packet *pkt = + (struct cvp_hfi_msg_sys_session_ctrl_done_packet *)hdr; + struct msm_cvp_cb_cmd_done cmd_done = {0}; + + dprintk(CVP_SESS, "RECEIVED: SESSION_STOP_DONE[%#x]\n", + pkt->session_id); + + if (!pkt || pkt->size < + sizeof(struct cvp_hfi_msg_sys_session_ctrl_done_packet)) { + dprintk(CVP_ERR, "%s: bad packet/packet size: %d\n", + __func__, pkt ? pkt->size : 0); + return -E2BIG; + } + cmd_done.device_id = device_id; + cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; + cmd_done.status = hfi_map_err_status(pkt->error_type); + if (cmd_done.status) + dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n", + __func__, cmd_done.status, pkt->packet_type, pkt->error_type); + cmd_done.size = 0; + + info->response_type = HAL_SESSION_STOP_DONE; + info->response.cmd = cmd_done; + + return 0; +} + + static int hfi_process_session_rel_buf_done(u32 device_id, void *hdr, struct msm_cvp_cb_info *info) { @@ -380,6 +457,9 @@ static int hfi_process_session_rel_buf_done(u32 device_id, cmd_done.device_id = device_id; cmd_done.session_id = (void *)(uintptr_t)get_msg_session_id(pkt); cmd_done.status = hfi_map_err_status(get_msg_errorcode(pkt)); + if (cmd_done.status) + dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n", + __func__, cmd_done.status, pkt->packet_type, pkt->error_type); cmd_done.size = 0; info->response_type = HAL_SESSION_RELEASE_BUFFER_DONE; @@ -458,6 +538,9 @@ static int hfi_process_session_dump_notify(u32 device_id, cmd_done.device_id = device_id; cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; cmd_done.status = hfi_map_err_status(pkt->error_type); + if (cmd_done.status) + dprintk(CVP_ERR, "%s: status %#x hfi type %#x err %#x\n", + __func__, cmd_done.status, pkt->packet_type, pkt->error_type); cmd_done.size = 0; info->response_type = HAL_SESSION_DUMP_NOTIFY; @@ -640,6 +723,12 @@ int cvp_hfi_process_msg_packet(u32 device_id, void *hdr, case HFI_MSG_SESSION_CVP_FLUSH: pkt_func = (pkt_func_def)hfi_process_session_flush_done; break; + case HFI_MSG_SESSION_EVA_START: + pkt_func = (pkt_func_def)hfi_process_session_start_done; + break; + case HFI_MSG_SESSION_EVA_STOP: + pkt_func = (pkt_func_def)hfi_process_session_stop_done; + break; case HFI_MSG_EVENT_NOTIFY_SNAPSHOT_READY: pkt_func = (pkt_func_def)hfi_process_session_dump_notify; break; diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 6313f1944f..e4cdbf107c 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -880,11 +880,18 @@ static int cvp_fence_thread_stop(struct msm_cvp_inst *inst) return 0; } -static int msm_cvp_session_start(struct msm_cvp_inst *inst, +int msm_cvp_session_start(struct msm_cvp_inst *inst, struct eva_kmd_arg *arg) { struct cvp_session_queue *sq; struct cvp_hfi_device *hdev; + int rc; + enum queue_state old_state; + + if (!inst || !inst->core) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } sq = &inst->session_queue; spin_lock(&sq->lock); @@ -892,27 +899,80 @@ static int msm_cvp_session_start(struct msm_cvp_inst *inst, dprintk(CVP_ERR, "session start failed queue not empty%d\n", sq->msg_count); spin_unlock(&sq->lock); - return -EINVAL; + rc = -EINVAL; + goto exit; } + old_state = sq->state; sq->state = QUEUE_START; spin_unlock(&sq->lock); + hdev = inst->core->device; if (inst->prop.type == HFI_SESSION_FD || inst->prop.type == HFI_SESSION_DMM) { spin_lock(&inst->core->resources.pm_qos.lock); inst->core->resources.pm_qos.off_vote_cnt++; spin_unlock(&inst->core->resources.pm_qos.lock); - hdev = inst->core->device; call_hfi_op(hdev, pm_qos_update, hdev->hfi_device_data); } - return cvp_fence_thread_start(inst); + /* + * cvp_fence_thread_start will increment reference to instance. + * It guarantees the EVA session won't be deleted. Use of session + * functions, such as session_start requires the session to be valid. + */ + rc = cvp_fence_thread_start(inst); + if (rc) + goto restore_state; + + /* Send SESSION_START command */ + rc = call_hfi_op(hdev, session_start, (void *)inst->session); + if (rc) { + dprintk(CVP_WARN, "%s: session start failed rc %d\n", + __func__, rc); + goto stop_thread; + } + + /* Wait for FW response */ + rc = wait_for_sess_signal_receipt(inst, HAL_SESSION_START_DONE); + if (rc) { + dprintk(CVP_WARN, "%s: wait for signal failed, rc %d\n", + __func__, rc); + goto stop_thread; + } + + dprintk(CVP_SESS, "session %llx (%#x) started\n", inst, hash32_ptr(inst->session)); + + return 0; + +stop_thread: + cvp_fence_thread_stop(inst); +restore_state: + spin_lock(&sq->lock); + sq->state = old_state; + spin_unlock(&sq->lock); +exit: + return rc; } -static int msm_cvp_session_stop(struct msm_cvp_inst *inst, +int msm_cvp_session_stop(struct msm_cvp_inst *inst, struct eva_kmd_arg *arg) { struct cvp_session_queue *sq; - struct eva_kmd_session_control *sc = &arg->data.session_ctrl; + struct eva_kmd_session_control *sc = NULL; + struct msm_cvp_inst *s; + struct cvp_hfi_device *hdev; + int rc; + + if (!inst || !inst->core) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + if (arg) + sc = &arg->data.session_ctrl; + + s = cvp_get_inst_validate(inst->core, inst); + if (!s) + return -ECONNRESET; sq = &inst->session_queue; @@ -920,9 +980,11 @@ static int msm_cvp_session_stop(struct msm_cvp_inst *inst, if (sq->msg_count) { dprintk(CVP_ERR, "session stop incorrect: queue not empty%d\n", sq->msg_count); - sc->ctrl_data[0] = sq->msg_count; + if (sc) + sc->ctrl_data[0] = sq->msg_count; spin_unlock(&sq->lock); - return -EUCLEAN; + rc = -EUCLEAN; + goto exit; } sq->state = QUEUE_STOP; @@ -930,9 +992,30 @@ static int msm_cvp_session_stop(struct msm_cvp_inst *inst, inst, hash32_ptr(inst->session)); spin_unlock(&sq->lock); + hdev = inst->core->device; + /* Send SESSION_STOP command */ + rc = call_hfi_op(hdev, session_stop, (void *)inst->session); + if (rc) { + dprintk(CVP_WARN, "%s: session stop failed rc %d\n", + __func__, rc); + goto stop_thread; + } + + /* Wait for FW response */ + rc = wait_for_sess_signal_receipt(inst, HAL_SESSION_STOP_DONE); + if (rc) { + dprintk(CVP_WARN, "%s: wait for signal failed, rc %d\n", + __func__, rc); + goto stop_thread; + } + +stop_thread: wake_up_all(&inst->session_queue.wq); - return cvp_fence_thread_stop(inst); + cvp_fence_thread_stop(inst); +exit: + cvp_put_inst(s); + return rc; } int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst) diff --git a/msm/eva/msm_cvp.h b/msm/eva/msm_cvp.h index d64f91ab22..eab8e0a3e9 100644 --- a/msm/eva/msm_cvp.h +++ b/msm/eva/msm_cvp.h @@ -35,6 +35,8 @@ int msm_cvp_session_deinit(struct msm_cvp_inst *inst); int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst); int msm_cvp_session_create(struct msm_cvp_inst *inst); int msm_cvp_session_delete(struct msm_cvp_inst *inst); +int msm_cvp_session_start(struct msm_cvp_inst *inst, struct eva_kmd_arg *arg); +int msm_cvp_session_stop(struct msm_cvp_inst *inst, struct eva_kmd_arg *arg); int msm_cvp_get_session_info(struct msm_cvp_inst *inst, u32 *session); int msm_cvp_update_power(struct msm_cvp_inst *inst); int cvp_clean_session_queues(struct msm_cvp_inst *inst); diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 3739bc6cc2..61e24755cf 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -503,7 +503,7 @@ static void handle_release_res_done(enum hal_command_response cmd, void *data) cvp_put_inst(inst); } -static void handle_session_flush(enum hal_command_response cmd, void *data) +static void handle_session_ctrl(enum hal_command_response cmd, void *data) { struct msm_cvp_cb_cmd_done *response = data; struct msm_cvp_inst *inst; @@ -523,8 +523,8 @@ static void handle_session_flush(enum hal_command_response cmd, void *data) } if (response->status) - dprintk(CVP_ERR, "HFI sess flush err 0x%x\n", - response->status); + dprintk(CVP_ERR, "HFI sess ctrl err 0x%x HAL cmd %d\n", + response->status, cmd); inst->error_code = response->status; signal_session_msg_receipt(cmd, inst); @@ -748,7 +748,9 @@ void cvp_handle_cmd_response(enum hal_command_response cmd, void *data) handle_event_change(cmd, data); break; case HAL_SESSION_FLUSH_DONE: - handle_session_flush(cmd, data); + case HAL_SESSION_START_DONE: + case HAL_SESSION_STOP_DONE: + handle_session_ctrl(cmd, data); break; case HAL_SYS_WATCHDOG_TIMEOUT: case HAL_SYS_ERROR: diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 6b93d184fd..e0e98ec5b0 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -457,17 +457,17 @@ static int cvp_dsp_rpmsg_callback(struct rpmsg_device *rpdev, goto exit; } } else if (rsp->type < CVP_DSP_MAX_CMD && - len == sizeof(struct cvp_dsp2cpu_cmd_msg)) { + len == sizeof(struct cvp_dsp2cpu_cmd)) { if (me->pending_dsp2cpu_cmd.type != CVP_INVALID_RPMSG_TYPE) { dprintk(CVP_ERR, "%s: DSP2CPU cmd:%d pending %d %d expect %d\n", __func__, rsp->type, me->pending_dsp2cpu_cmd.type, len, - sizeof(struct cvp_dsp2cpu_cmd_msg)); + sizeof(struct cvp_dsp2cpu_cmd)); goto exit; } memcpy(&me->pending_dsp2cpu_cmd, rsp, - sizeof(struct cvp_dsp2cpu_cmd_msg)); + sizeof(struct cvp_dsp2cpu_cmd)); complete(&me->completions[CPU2DSP_MAX_CMD]); } else { dprintk(CVP_ERR, "%s: Invalid type: %d\n", __func__, rsp->type); @@ -1240,7 +1240,7 @@ static void eva_fastrpc_driver_unregister(uint32_t handle, bool force_exit) { struct cvp_dsp_apps *me = &gfa_cv; struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; - struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; + struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; dprintk(CVP_DSP, "%s Unregister fastrpc driver hdl %#x pid %#x, f %d\n", __func__, handle, dsp2cpu_cmd->pid, (uint32_t)force_exit); @@ -1437,7 +1437,7 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) struct msm_cvp_inst *inst = NULL; uint64_t inst_handle = 0; int rc = 0; - struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; + struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; struct pid *pid_s = NULL; struct task_struct *task = NULL; @@ -1544,7 +1544,7 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) struct cvp_dsp_apps *me = &gfa_cv; struct msm_cvp_inst *inst; int rc; - struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; + struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; struct task_struct *task = NULL; struct cvp_hfi_device *hdev; @@ -1614,7 +1614,7 @@ static void __dsp_cvp_power_req(struct cvp_dsp_cmd_msg *cmd) struct cvp_dsp_apps *me = &gfa_cv; struct msm_cvp_inst *inst; int rc; - struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; + struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; cmd->ret = 0; dprintk(CVP_DSP, @@ -1672,7 +1672,7 @@ static void __dsp_cvp_buf_register(struct cvp_dsp_cmd_msg *cmd) struct eva_kmd_arg *kmd; struct eva_kmd_buffer *kmd_buf; int rc; - struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; + struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; cmd->ret = 0; @@ -1730,7 +1730,7 @@ static void __dsp_cvp_buf_deregister(struct cvp_dsp_cmd_msg *cmd) struct eva_kmd_arg *kmd; struct eva_kmd_buffer *kmd_buf; int rc; - struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; + struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; cmd->ret = 0; @@ -1782,7 +1782,7 @@ static void __dsp_cvp_mem_alloc(struct cvp_dsp_cmd_msg *cmd) struct msm_cvp_inst *inst; int rc; struct cvp_internal_buf *buf = NULL; - struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; + struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; uint64_t v_dsp_addr = 0; struct fastrpc_device *frpc_device = NULL; @@ -1867,7 +1867,7 @@ static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) struct cvp_internal_buf *buf = NULL; struct list_head *ptr = NULL, *next = NULL; struct msm_cvp_list *buf_list = NULL; - struct cvp_dsp2cpu_cmd_msg *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; + struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; struct fastrpc_device *frpc_device = NULL; struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; @@ -1948,6 +1948,64 @@ fail_fastrpc_dev_unmap_dma: cvp_put_fastrpc_node(frpc_node); } +static void __dsp_cvp_sess_start(struct cvp_dsp_cmd_msg *cmd) +{ + struct cvp_dsp_apps *me = &gfa_cv; + struct msm_cvp_inst *inst; + int rc; + struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; + + cmd->ret = 0; + + dprintk(CVP_DSP, + "%s sess id 0x%x, low 0x%x, high 0x%x, pid 0x%x\n", + __func__, dsp2cpu_cmd->session_id, + dsp2cpu_cmd->session_cpu_low, + dsp2cpu_cmd->session_cpu_high, + dsp2cpu_cmd->pid); + + inst = (struct msm_cvp_inst *)ptr_dsp2cpu( + dsp2cpu_cmd->session_cpu_high, + dsp2cpu_cmd->session_cpu_low); + + rc = msm_cvp_session_start(inst, (struct eva_kmd_arg *)NULL); + if (rc) { + dprintk(CVP_ERR, "%s Failed to start session\n", __func__); + cmd->ret = -1; + return; + } + dprintk(CVP_DSP, "%s session started\n", __func__); +} + +static void __dsp_cvp_sess_stop(struct cvp_dsp_cmd_msg *cmd) +{ + struct cvp_dsp_apps *me = &gfa_cv; + struct msm_cvp_inst *inst; + int rc; + struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; + + cmd->ret = 0; + + dprintk(CVP_DSP, + "%s sess id 0x%x, low 0x%x, high 0x%x, pid 0x%x\n", + __func__, dsp2cpu_cmd->session_id, + dsp2cpu_cmd->session_cpu_low, + dsp2cpu_cmd->session_cpu_high, + dsp2cpu_cmd->pid); + + inst = (struct msm_cvp_inst *)ptr_dsp2cpu( + dsp2cpu_cmd->session_cpu_high, + dsp2cpu_cmd->session_cpu_low); + + rc = msm_cvp_session_stop(inst, (struct eva_kmd_arg *)NULL); + if (rc) { + dprintk(CVP_ERR, "%s Failed to stop session\n", __func__); + cmd->ret = -1; + return; + } + dprintk(CVP_DSP, "%s session stoppd\n", __func__); +} + static int cvp_dsp_thread(void *data) { int rc = 0, old_state; @@ -2068,6 +2126,18 @@ wait_dsp: break; } + case DSP2CPU_START_SESSION: + { + __dsp_cvp_sess_start(&cmd); + + break; + } + case DSP2CPU_STOP_SESSION: + { + __dsp_cvp_sess_stop(&cmd); + + break; + } default: dprintk(CVP_ERR, "unrecognaized dsp cmds: %d\n", me->pending_dsp2cpu_cmd.type); diff --git a/msm/eva/msm_cvp_dsp.h b/msm/eva/msm_cvp_dsp.h index 0232a7ddc0..e94cefaa9b 100644 --- a/msm/eva/msm_cvp_dsp.h +++ b/msm/eva/msm_cvp_dsp.h @@ -96,7 +96,9 @@ enum CVP_DSP_COMMAND { DSP2CPU_DEREGISTER_BUFFER = 18, DSP2CPU_MEM_ALLOC = 19, DSP2CPU_MEM_FREE = 20, - CVP_DSP_MAX_CMD = 21, + DSP2CPU_START_SESSION = 21, + DSP2CPU_STOP_SESSION = 22, + CVP_DSP_MAX_CMD = 23, }; struct eva_power_req { @@ -127,6 +129,17 @@ struct eva_mem_remote { uint64_t v_dsp_addr; }; +/* + * command: defined as a packet initiated from one party. + * message: defined as a packet sent as response to a command + */ + +/* + * cvp_dsp_cmd_msg contains + * the message sent from CPU to DSP + * or + * the command sent from CPU to DSP + */ struct cvp_dsp_cmd_msg { uint32_t type; int32_t ret; @@ -153,6 +166,7 @@ struct cvp_dsp_cmd_msg { uint32_t reserved2; }; +/* cvp_dsp_rsp_msg contains the message sent from DSP to CPU */ struct cvp_dsp_rsp_msg { uint32_t type; int32_t ret; @@ -160,7 +174,8 @@ struct cvp_dsp_rsp_msg { uint32_t reserved[CVP_DSP_MAX_RESERVED - 1]; }; -struct cvp_dsp2cpu_cmd_msg { +/* cvp_dsp2cpu_cmd contains the command sent from DSP to cpu*/ +struct cvp_dsp2cpu_cmd { uint32_t type; uint32_t ver; uint32_t len; @@ -222,7 +237,7 @@ struct cvp_dsp_apps { uint64_t addr; uint32_t size; struct completion completions[CPU2DSP_MAX_CMD + 1]; - struct cvp_dsp2cpu_cmd_msg pending_dsp2cpu_cmd; + struct cvp_dsp2cpu_cmd pending_dsp2cpu_cmd; struct cvp_dsp_rsp_msg pending_dsp2cpu_rsp; struct task_struct *dsp_thread; /* dsp buffer mapping, set of dma function pointer */ From 9de86afd608272fda28128f706d9dc7b4188052e Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 27 Feb 2023 14:09:11 -0800 Subject: [PATCH 179/317] msm: eva: fix a missing frame issue during flush Racing happens when a new fence command submitted and flushing is requested from a different thread. Change-Id: I2d4f1e02c245f9a4a7eeb2e541ddb0e99b63b461 Signed-off-by: George Shen --- msm/eva/msm_cvp.c | 73 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 19 deletions(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index e4cdbf107c..f3b7f06764 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -41,10 +41,11 @@ int msm_cvp_get_session_info(struct msm_cvp_inst *inst, u32 *session) static bool cvp_msg_pending(struct cvp_session_queue *sq, struct cvp_session_msg **msg, u64 *ktid) { - struct cvp_session_msg *mptr, *dummy; + struct cvp_session_msg *mptr = NULL, *dummy; bool result = false; - mptr = NULL; + if (!sq) + return false; spin_lock(&sq->lock); if (sq->state == QUEUE_INIT || sq->state == QUEUE_INVALID) { /* The session is being deleted */ @@ -54,12 +55,14 @@ static bool cvp_msg_pending(struct cvp_session_queue *sq, } result = list_empty(&sq->msgs); if (!result) { + mptr = list_first_entry(&sq->msgs, + struct cvp_session_msg, + node); if (!ktid) { - mptr = - list_first_entry(&sq->msgs, struct cvp_session_msg, - node); - list_del_init(&mptr->node); - sq->msg_count--; + if (mptr) { + list_del_init(&mptr->node); + sq->msg_count--; + } } else { result = true; list_for_each_entry_safe(mptr, dummy, &sq->msgs, node) { @@ -245,6 +248,9 @@ static bool cvp_fence_wait(struct cvp_fence_queue *q, { struct cvp_fence_command *f; + if (!q) + return false; + *fence = NULL; mutex_lock(&q->lock); *state = q->state; @@ -645,28 +651,28 @@ static int cvp_populate_fences( struct eva_kmd_hfi_packet *in_pkt, */ buf_offset = offset; for (i = 0; i < num; i++) { - buf = (struct cvp_buf_type*)&in_pkt->pkt_data[buf_offset]; - buf_offset += sizeof(*buf) >> 2; + buf = (struct cvp_buf_type*)&in_pkt->pkt_data[buf_offset]; + buf_offset += sizeof(*buf) >> 2; - if (buf->output_handle) { - /* Check fence_type? */ - fences[f->num_fences].h_synx = buf->output_handle; - f->num_fences++; - buf->fence_type &= ~OUTPUT_FENCE_BITMASK; - buf->output_handle = 0; - } + if (buf->output_handle) { + /* Check fence_type? */ + fences[f->num_fences].h_synx = buf->output_handle; + f->num_fences++; + buf->fence_type &= ~OUTPUT_FENCE_BITMASK; + buf->output_handle = 0; + } } dprintk(CVP_SYNX, "%s:Output Fence passed - Number of Fences is %d\n", __func__, f->num_fences); if (f->num_fences == 0) - goto free_exit; + goto free_exit; rc = inst->core->synx_ftbl->cvp_import_synx(inst, f, - (u32*)fences); + (u32*)fences); if (rc) - goto free_exit; + goto free_exit; fence_cmd_queue: memcpy(f->pkt, cmd_hdr, cmd_hdr->size); @@ -733,6 +739,8 @@ static int cvp_enqueue_pkt(struct msm_cvp_inst* inst, } else { if (rc > 0) dprintk(CVP_SYNX, "Going fenced path\n"); + else if (map_type == MAP_FRAME) + msm_cvp_unmap_frame(inst, cmd_hdr->client_data.kdata); goto exit; } @@ -1354,6 +1362,15 @@ static int cvp_drain_fence_sched_list(struct msm_cvp_inst *inst) q = &inst->fence_cmd_queue; + if (!q) + return -EINVAL; + + f = list_first_entry(&q->sched_list, + struct cvp_fence_command, + list); + if (!f) + return rc; + mutex_lock(&q->lock); list_for_each_entry(f, &q->sched_list, list) { ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1); @@ -1398,9 +1415,18 @@ static void cvp_clean_fence_queue(struct msm_cvp_inst *inst, int synx_state) q = &inst->fence_cmd_queue; + if (!q) + return; + mutex_lock(&q->lock); q->mode = OP_DRAINING; + f = list_first_entry(&q->wait_list, + struct cvp_fence_command, + list); + if (!f) + goto check_sched; + list_for_each_entry_safe(f, d, &q->wait_list, list) { ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1); @@ -1415,6 +1441,15 @@ static void cvp_clean_fence_queue(struct msm_cvp_inst *inst, int synx_state) cvp_free_fence_data(f); } +check_sched: + f = list_first_entry(&q->sched_list, + struct cvp_fence_command, + list); + if (!f) { + mutex_unlock(&q->lock); + return; + } + list_for_each_entry(f, &q->sched_list, list) { ktid = f->pkt->client_data.kdata & (FENCE_BIT - 1); From 6aabaf324734678a5b8a2c27aaa50c342e60465b Mon Sep 17 00:00:00 2001 From: Sabharsh Sidhu Date: Fri, 17 Feb 2023 18:00:18 -0800 Subject: [PATCH 180/317] msm: eva: Improve error handling for pkt enqueuing Report error code for pkt enqueue failure - critical for reporting rejected frames in flush scenarios. Improve logging for unprocessed frames. Change-Id: Ic5d04a56122b0bbf94f69117ee0fde9f5993e275 Signed-off-by: Sabharsh Sidhu --- msm/eva/msm_cvp.c | 38 +++++++++++++++++++++++++------------- msm/eva/msm_cvp_core.c | 7 ++++--- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index f3b7f06764..c899b399b3 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -171,6 +171,7 @@ static int msm_cvp_session_process_hfi( unsigned int offset = 0, buf_num = 0, signal; struct cvp_session_queue *sq; struct msm_cvp_inst *s; + struct cvp_hfi_cmd_session_hdr *pkt_hdr; bool is_config_pkt; @@ -226,7 +227,8 @@ static int msm_cvp_session_process_hfi( } if (!is_buf_param_valid(buf_num, offset)) { dprintk(CVP_ERR, "Incorrect buffer num and offset in cmd\n"); - return -EINVAL; + rc = -EINVAL; + goto exit; } rc = msm_cvp_proc_oob(inst, in_pkt); @@ -235,7 +237,15 @@ static int msm_cvp_session_process_hfi( goto exit; } - cvp_enqueue_pkt(inst, in_pkt, offset, buf_num); + rc = cvp_enqueue_pkt(inst, in_pkt, offset, buf_num); + if (rc) { + pkt_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; + dprintk(CVP_ERR, "Failed to enqueue pkt, inst %pK " + "pkt_type %08x ktid %llu transaction_id %u\n", + inst, pkt_hdr->packet_type, + pkt_hdr->client_data.kdata, + pkt_hdr->client_data.transaction_id); + } exit: cvp_put_inst(inst); @@ -599,8 +609,10 @@ static int cvp_populate_fences( struct eva_kmd_hfi_packet *in_pkt, cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; rc = cvp_alloc_fence_data((&f), cmd_hdr->size); - if (rc) + if (rc) { + dprintk(CVP_ERR,"%s: Failed to alloc fence data", __func__); goto exit; + } f->type = cmd_hdr->packet_type; f->mode = OP_NORMAL; @@ -668,11 +680,11 @@ static int cvp_populate_fences( struct eva_kmd_hfi_packet *in_pkt, if (f->num_fences == 0) goto free_exit; - rc = inst->core->synx_ftbl->cvp_import_synx(inst, f, - (u32*)fences); - - if (rc) + rc = inst->core->synx_ftbl->cvp_import_synx(inst, f, (u32*)fences); + if (rc) { + dprintk(CVP_ERR,"%s: Failed to import fences", __func__); goto free_exit; + } fence_cmd_queue: memcpy(f->pkt, cmd_hdr, cmd_hdr->size); @@ -735,16 +747,16 @@ static int cvp_enqueue_pkt(struct msm_cvp_inst* inst, msm_cvp_unmap_frame(inst, cmd_hdr->client_data.kdata); } - goto exit; + } else if (rc > 0) { + dprintk(CVP_SYNX, "Going fenced path\n"); + rc = 0; } else { - if (rc > 0) - dprintk(CVP_SYNX, "Going fenced path\n"); - else if (map_type == MAP_FRAME) + dprintk(CVP_ERR,"%s: Failed to populate fences\n", + __func__); + if (map_type == MAP_FRAME) msm_cvp_unmap_frame(inst, cmd_hdr->client_data.kdata); - goto exit; } -exit: return rc; } diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index f6ef768357..1fbeef440d 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -345,11 +345,12 @@ wait_frame: if (!empty) { dprintk(CVP_WARN, - "Failed to process frames before session close\n"); + "Failed to process frames before session %pK close\n", + inst); mutex_lock(&inst->frames.lock); list_for_each_entry(frame, &inst->frames.list, list) - dprintk(CVP_WARN, "Unprocessed frame %d\n", - frame->pkt_type); + dprintk(CVP_WARN, "Unprocessed frame %08x ktid %llu\n", + frame->pkt_type, frame->ktid); mutex_unlock(&inst->frames.lock); inst->core->synx_ftbl->cvp_dump_fence_queue(inst); } From e3d980caa100ab19fdacd24ed5ba5ba70cb7bc5b Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 8 Mar 2023 11:52:12 -0800 Subject: [PATCH 181/317] msm: eva: Fix logging and timeout issues synx signal used wrong logging tag. PARAMs buffer is treated as persistent buffer to avoid unnecessary warning messages complaining mapping in-use when session closed. Change-Id: Ia44b943ba0d41d9f7fa276eabb369597552a4956 Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 2 ++ msm/eva/msm_cvp_internal.h | 2 +- msm/eva/msm_cvp_synx.c | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index f1c5b4a063..454dc26880 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1246,6 +1246,8 @@ static struct msm_cvp_smem *msm_cvp_session_get_smem(struct msm_cvp_inst *inst, smem->bitmap_index = MAX_DMABUF_NUMS; smem->pkt_type = pkt_type; smem->fd = buf->fd; + if (is_params_pkt(pkt_type)) + smem->flags |= SMEM_PERSIST; rc = msm_cvp_map_smem(inst, smem, "map cpu"); if (rc) goto exit; diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index 6c2c87e58e..d4b485e06b 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -199,7 +199,7 @@ enum msm_cvp_modes { }; #define MAX_NUM_MSGS_PER_SESSION 128 -#define CVP_MAX_WAIT_TIME 10000 +#define CVP_MAX_WAIT_TIME 2000 struct cvp_session_msg { struct list_head node; diff --git a/msm/eva/msm_cvp_synx.c b/msm/eva/msm_cvp_synx.c index b2d38dca65..dd59f0050a 100644 --- a/msm/eva/msm_cvp_synx.c +++ b/msm/eva/msm_cvp_synx.c @@ -197,7 +197,7 @@ static int cvp_wait_synx(struct synx_session *ssid, u32 *synx, u32 num_synx, *synx_state = synx_get_status(ssid, h_synx); if(*synx_state == SYNX_STATE_SIGNALED_SUCCESS) { - dprintk(CVP_DBG, "%s: SYNX SIGNAl STATE SUCCESS \n", __func__); + dprintk(CVP_SYNX, "%s: SYNX SIGNAl STATE SUCCESS \n", __func__); rc=0; i++; continue; From 79c9987bbe8a10b86087054a3466b640f845f808 Mon Sep 17 00:00:00 2001 From: Nagesh Gunna Date: Mon, 13 Mar 2023 19:31:48 +0530 Subject: [PATCH 182/317] eva-kernel: hfi q info at session timeout Printing hfi q info at the of session queue time out to get debug info on missed cmd/frame pkt. Change-Id: I9b324a6496699272f9f1b9cb794f3e322d5421ae Signed-off-by: Nagesh Gunna --- msm/eva/cvp_hfi.c | 8 ++++---- msm/eva/cvp_hfi_api.h | 2 +- msm/eva/msm_cvp.c | 5 ++++- msm/eva/msm_cvp_common.c | 28 ++++++++++++++++------------ 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 6481b70a67..6b040c34f2 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1177,10 +1177,6 @@ static void cvp_dump_csr(struct iris_hfi_device *dev) dprintk(CVP_ERR, "CVP_WRAPPER_CPU_STATUS: %x\n", reg); reg = __read_register(dev, CVP_CPU_CS_SCIACMDARG0); dprintk(CVP_ERR, "CVP_CPU_CS_SCIACMDARG0: %x\n", reg); - reg = __read_register(dev, CVP_WRAPPER_CPU_CLOCK_CONFIG); - dprintk(CVP_ERR, "CVP_WRAPPER_CPU_CLOCK_CONFIG: %x\n", reg); - reg = __read_register(dev, CVP_WRAPPER_CORE_CLOCK_CONFIG); - dprintk(CVP_ERR, "CVP_WRAPPER_CORE_CLOCK_CONFIG: %x\n", reg); reg = __read_register(dev, CVP_WRAPPER_INTR_STATUS); dprintk(CVP_ERR, "CVP_WRAPPER_INTR_STATUS: %x\n", reg); reg = __read_register(dev, CVP_CPU_CS_H2ASOFTINT); @@ -1191,6 +1187,10 @@ static void cvp_dump_csr(struct iris_hfi_device *dev) dprintk(CVP_ERR, "CVP_CC_MVS1C_GDSCR: %x\n", reg); reg = __read_register(dev, CVP_CC_MVS1C_CBCR); dprintk(CVP_ERR, "CVP_CC_MVS1C_CBCR: %x\n", reg); + reg = __read_register(dev, CVP_WRAPPER_CPU_CLOCK_CONFIG); + dprintk(CVP_ERR, "CVP_WRAPPER_CPU_CLOCK_CONFIG: %x\n", reg); + reg = __read_register(dev, CVP_WRAPPER_CORE_CLOCK_CONFIG); + dprintk(CVP_ERR, "CVP_WRAPPER_CORE_CLOCK_CONFIG: %x\n", reg); dev->reg_dumped = true; } diff --git a/msm/eva/cvp_hfi_api.h b/msm/eva/cvp_hfi_api.h index e69d057345..beaadd5ec7 100644 --- a/msm/eva/cvp_hfi_api.h +++ b/msm/eva/cvp_hfi_api.h @@ -311,5 +311,5 @@ unsigned int get_msg_errorcode(void *msg); int get_msg_opconfigs(void *msg, unsigned int *session_id, unsigned int *error_type, unsigned int *config_id); extern const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX]; - +void print_hfi_queue_info(struct cvp_hfi_device *hdev); #endif /*__CVP_HFI_API_H__ */ diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index c899b399b3..d6c17ba007 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -9,7 +9,7 @@ #include "msm_cvp_buf.h" #include "cvp_comm_def.h" #include "cvp_power.h" - +#include "cvp_hfi_api.h" static int cvp_enqueue_pkt(struct msm_cvp_inst* inst, struct eva_kmd_hfi_packet *in_pkt, unsigned int in_offset, @@ -94,6 +94,9 @@ static int cvp_wait_process_message(struct msm_cvp_inst *inst, if (wait_event_timeout(sq->wq, cvp_msg_pending(sq, &msg, ktid), timeout) == 0) { dprintk(CVP_WARN, "session queue wait timeout\n"); + if(inst && inst->core && inst->core->device){ + print_hfi_queue_info(inst->core->device); + } rc = -ETIMEDOUT; goto exit; } diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 61e24755cf..a3438d89c1 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -58,16 +58,26 @@ static void dump_hfi_queue(struct iris_hfi_device *device) read_ptr = (u32 *)((qinfo->q_array.align_virtual_addr) + (read_idx << 2)); dprintk(CVP_ERR, - "queue payload: %x %x %x %x %x %x %x %x\n", + "queue payload: %x %x %x %x %x %x %x %x %x\n", read_ptr[0], read_ptr[1], read_ptr[2], read_ptr[3], read_ptr[4], read_ptr[5], - read_ptr[6], read_ptr[7]); + read_ptr[6], read_ptr[7], read_ptr[8]); } } mutex_unlock(&device->lock); } +void print_hfi_queue_info(struct cvp_hfi_device *hdev) +{ + if(hdev && hdev->hfi_device_data){ + call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data); + dump_hfi_queue(hdev->hfi_device_data); + } +} + + + struct msm_cvp_core *get_cvp_core(int core_id) { struct msm_cvp_core *core; @@ -378,8 +388,7 @@ int wait_for_sess_signal_receipt(struct msm_cvp_inst *inst, if (!rc) { dprintk(CVP_WARN, "Wait interrupted or timed out: %d\n", SESSION_MSG_INDEX(cmd)); - call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data); - dump_hfi_queue(hdev->hfi_device_data); + print_hfi_queue_info(hdev); rc = -ETIMEDOUT; } else if (inst->state == MSM_CVP_CORE_INVALID) { rc = -ECONNRESET; @@ -862,8 +871,7 @@ static int msm_comm_session_abort(struct msm_cvp_inst *inst) if (!rc) { dprintk(CVP_ERR, "%s: inst %pK session %x abort timed out\n", __func__, inst, hash32_ptr(inst->session)); - call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data); - dump_hfi_queue(hdev->hfi_device_data); + print_hfi_queue_info(hdev); msm_cvp_comm_generate_sys_error(inst); rc = -EBUSY; } else { @@ -947,8 +955,7 @@ int msm_cvp_comm_check_core_init(struct msm_cvp_core *core) dprintk(CVP_ERR, "%s: Wait interrupted or timed out: %d\n", __func__, SYS_MSG_INDEX(HAL_SYS_INIT_DONE)); hdev = core->device; - call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data); - dump_hfi_queue(hdev->hfi_device_data); + print_hfi_queue_info(hdev); rc = -EIO; goto exit; } else { @@ -1336,10 +1343,7 @@ void msm_cvp_ssr_handler(struct work_struct *work) s = cvp_get_inst_validate(inst->core, inst); if (!s) return; - - call_hfi_op(hdev, flush_debug_queue, - hdev->hfi_device_data); - dump_hfi_queue(hdev->hfi_device_data); + print_hfi_queue_info(hdev); msm_cvp_comm_kill_session(inst); cvp_put_inst(s); } else { From d723781ea33190a619e75944f78d4fdaf9fb4c70 Mon Sep 17 00:00:00 2001 From: Jingyu Su Date: Tue, 14 Mar 2023 17:55:50 -0700 Subject: [PATCH 183/317] msm: eva: Switch to qcom_scm_assign_mem() from hyp_assign_phys() Switch to upstream friendly qcom_scm_assign_mem from hyp_assign_phys. Change-Id: I2b6f1af346166794c87a205cffddbcdfb112e16a Signed-off-by: Jingyu Su --- msm/eva/msm_cvp_dsp.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index e0e98ec5b0..bfdbb2ad06 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "msm_cvp_core.h" #include "msm_cvp.h" @@ -14,11 +15,6 @@ static atomic_t nr_maps; struct cvp_dsp_apps gfa_cv; -static int hlosVM[HLOS_VM_NUM] = {VMID_HLOS}; -static int dspVM[DSP_VM_NUM] = {VMID_HLOS, VMID_CDSP_Q6}; -static int dspVMperm[DSP_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC, - PERM_READ | PERM_WRITE | PERM_EXEC }; -static int hlosVMperm[HLOS_VM_NUM] = { PERM_READ | PERM_WRITE | PERM_EXEC }; static int cvp_reinit_dsp(void); @@ -141,9 +137,14 @@ static int cvp_hyp_assign_to_dsp(uint64_t addr, uint32_t size) int rc = 0; struct cvp_dsp_apps *me = &gfa_cv; + uint64_t hlosVMid = BIT(VMID_HLOS); + struct qcom_scm_vmperm dspVM[DSP_VM_NUM] = { + {VMID_HLOS, PERM_READ | PERM_WRITE | PERM_EXEC}, + {VMID_CDSP_Q6, PERM_READ | PERM_WRITE | PERM_EXEC} + }; + if (!me->hyp_assigned) { - rc = hyp_assign_phys(addr, size, hlosVM, HLOS_VM_NUM, dspVM, - dspVMperm, DSP_VM_NUM); + rc = qcom_scm_assign_mem(addr, size, &hlosVMid, dspVM, DSP_VM_NUM); if (rc) { dprintk(CVP_ERR, "%s failed. rc=%d\n", __func__, rc); return rc; @@ -161,9 +162,13 @@ static int cvp_hyp_assign_from_dsp(void) int rc = 0; struct cvp_dsp_apps *me = &gfa_cv; + uint64_t dspVMids = BIT(VMID_HLOS) | BIT(VMID_CDSP_Q6); + struct qcom_scm_vmperm hlosVM[HLOS_VM_NUM] = { + {VMID_HLOS, PERM_READ | PERM_WRITE | PERM_EXEC}, + }; + if (me->hyp_assigned) { - rc = hyp_assign_phys(me->addr, me->size, dspVM, DSP_VM_NUM, - hlosVM, hlosVMperm, HLOS_VM_NUM); + rc = qcom_scm_assign_mem(me->addr, me->size, &dspVMids, hlosVM, HLOS_VM_NUM); if (rc) { dprintk(CVP_ERR, "%s failed. rc=%d\n", __func__, rc); return rc; @@ -568,6 +573,8 @@ static void cvp_remove_dsp_sessions(void) while ((frpc_node = pop_frpc_node())) { s = &frpc_node->dsp_sessions.list; + if (!s) + return; list_for_each_safe(s, next_s, &frpc_node->dsp_sessions.list) { if (!s || !next_s) From f466a36b98dea9eb118a1bbf9eb0a43143853186 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 27 Feb 2023 16:21:29 -0800 Subject: [PATCH 184/317] msm: eva: Print SID programming registers During SMMU fault. Change-Id: Ic66736ed5d5c97ec6344c295c0ec0f1ca01cf19a Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 2 ++ msm/eva/msm_cvp_res_parse.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 6b040c34f2..20820de289 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -2447,6 +2447,8 @@ static int iris_debug_hook(void *device) dprintk(CVP_ERR, "ARP_THREAD_3_SECURE_ENABLE %#x\n", val); + if (true) + return 0; /***** GCE ******* * Bit 0 of below register is CDM secure enable for GCE * CDM buffer will be in CB4 if set diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index 1128493e55..054eb25cff 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -1050,7 +1050,7 @@ int msm_cvp_smmu_fault_handler(struct iommu_domain *domain, hdev = core->device->hfi_device_data; if (hdev) { hdev->error = CVP_ERR_NOC_ERROR; - /* call_hfi_op(core->device, debug_hook, hdev); */ + call_hfi_op(core->device, debug_hook, hdev); } mutex_unlock(&core->lock); /* From e9bc85d9302038bd6a5f7a22fbbb59cee0afb406 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 16 Mar 2023 17:10:19 -0700 Subject: [PATCH 185/317] msm: eva: Return correct fence number In case of the fence command setup thread being pre-empted, the fence command can be processed by HW even before the setup thread returns. In that case, the setup thread may be using wrong fence number, causing it resends the HFI packet that has been processed. The consequence could be SMMU fault. Change-Id: I8be9808e993a27a1c7664e68a5382d145a8bc3cc Signed-off-by: George Shen --- msm/eva/msm_cvp.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index d6c17ba007..51e1aa725c 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -588,7 +588,7 @@ static int cvp_populate_fences( struct eva_kmd_hfi_packet *in_pkt, unsigned int offset, unsigned int num, struct msm_cvp_inst *inst) { #ifdef CVP_CONFIG_SYNX_V2 - u32 i, buf_offset; + u32 i, buf_offset, fence_cnt; struct eva_kmd_fence fences[MAX_HFI_FENCE_SIZE]; struct cvp_fence_command *f; struct cvp_hfi_cmd_session_hdr *cmd_hdr; @@ -690,6 +690,7 @@ static int cvp_populate_fences( struct eva_kmd_hfi_packet *in_pkt, } fence_cmd_queue: + fence_cnt = f->num_fences; memcpy(f->pkt, cmd_hdr, cmd_hdr->size); f->pkt->client_data.kdata |= FENCE_BIT; @@ -699,7 +700,7 @@ fence_cmd_queue: wake_up(&inst->fence_cmd_queue.wq); - return f->num_fences; + return fence_cnt; free_exit: cvp_free_fence_data(f); From db7c8ad7190161bcbc862d086e770aa9096b79c1 Mon Sep 17 00:00:00 2001 From: Sabharsh Sidhu Date: Mon, 6 Mar 2023 17:32:28 -0800 Subject: [PATCH 186/317] msm: eva: Add CVP_CMD debug logging Add cmd logging functionality as an alternative to pkt logging. This has advantages related to log dropping and log mangling. Change-Id: I0ff6801445821e1224f83fa7e2eb8bf8a849962b --- msm/eva/cvp_hfi.c | 20 ++++++++++++++++++++ msm/eva/msm_cvp.c | 14 +++++++++++++- msm/eva/msm_cvp_buf.c | 16 ++++++++++++++-- msm/eva/msm_cvp_debug.h | 5 ++++- 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 20820de289..badebb9585 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -405,6 +405,7 @@ static int __write_queue(struct cvp_iface_q_info *qinfo, u8 *packet, bool *rx_req_is_set) { struct cvp_hfi_queue_header *queue; + struct cvp_hfi_cmd_session_hdr *cmd_pkt; u32 packet_size_in_words, new_write_idx; u32 empty_space, read_idx, write_idx; u32 *write_ptr; @@ -423,6 +424,14 @@ static int __write_queue(struct cvp_iface_q_info *qinfo, u8 *packet, return -ENOENT; } + cmd_pkt = (struct cvp_hfi_cmd_session_hdr *)packet; + dprintk(CVP_CMD, "%s: " + "pkt_type %08x sess_id %08x trans_id %u ktid %llu\n", + __func__, cmd_pkt->packet_type, + cmd_pkt->session_id, + cmd_pkt->client_data.transaction_id, + cmd_pkt->client_data.kdata & (FENCE_BIT - 1)); + if (msm_cvp_debug & CVP_PKT) { dprintk(CVP_PKT, "%s: %pK\n", __func__, qinfo); __dump_packet(packet, CVP_PKT); @@ -495,6 +504,7 @@ static int __read_queue(struct cvp_iface_q_info *qinfo, u8 *packet, u32 *pb_tx_req_is_set) { struct cvp_hfi_queue_header *queue; + struct cvp_hfi_msg_session_hdr *msg_pkt; u32 packet_size_in_words, new_read_idx; u32 *read_ptr; u32 receive_request = 0; @@ -613,6 +623,16 @@ static int __read_queue(struct cvp_iface_q_info *qinfo, u8 *packet, spin_unlock(&qinfo->hfi_lock); + if (!(queue->qhdr_type & HFI_Q_ID_CTRL_TO_HOST_DEBUG_Q)) { + msg_pkt = (struct cvp_hfi_msg_session_hdr *)packet; + dprintk(CVP_CMD, "%s: " + "pkt_type %08x sess_id %08x trans_id %u ktid %llu\n", + __func__, msg_pkt->packet_type, + msg_pkt->session_id, + msg_pkt->client_data.transaction_id, + msg_pkt->client_data.kdata & (FENCE_BIT - 1)); + } + if ((msm_cvp_debug & CVP_PKT) && !(queue->qhdr_type & HFI_Q_ID_CTRL_TO_HOST_DEBUG_Q)) { dprintk(CVP_PKT, "%s: %pK\n", __func__, qinfo); diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 51e1aa725c..1ad2670ef5 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -187,6 +187,13 @@ static int msm_cvp_session_process_hfi( if (!s) return -ECONNRESET; + pkt_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; + dprintk(CVP_CMD, "%s: " + "pkt_type %08x sess_id %08x trans_id %u ktid %llu\n", + __func__, pkt_hdr->packet_type, + pkt_hdr->session_id, + pkt_hdr->client_data.transaction_id, + pkt_hdr->client_data.kdata & (FENCE_BIT - 1)); pkt_idx = get_pkt_index((struct cvp_hal_session_cmd_pkt *)in_pkt); if (pkt_idx < 0) { @@ -242,7 +249,6 @@ static int msm_cvp_session_process_hfi( rc = cvp_enqueue_pkt(inst, in_pkt, offset, buf_num); if (rc) { - pkt_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; dprintk(CVP_ERR, "Failed to enqueue pkt, inst %pK " "pkt_type %08x ktid %llu transaction_id %u\n", inst, pkt_hdr->packet_type, @@ -728,6 +734,12 @@ static int cvp_enqueue_pkt(struct msm_cvp_inst* inst, cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; /* The kdata will be overriden by transaction ID if the cmd has buf */ cmd_hdr->client_data.kdata = 0; + dprintk(CVP_CMD, "%s: " + "pkt_type %08x sess_id %08x trans_id %u ktid %llu\n", + __func__, cmd_hdr->packet_type, + cmd_hdr->session_id, + cmd_hdr->client_data.transaction_id, + cmd_hdr->client_data.kdata & (FENCE_BIT - 1)); if (map_type == MAP_PERSIST) rc = msm_cvp_map_user_persist(inst, in_pkt, in_offset, in_buf_num); diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 454dc26880..548e9446db 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1474,8 +1474,14 @@ void msm_cvp_unmap_frame(struct msm_cvp_inst *inst, u64 ktid) } mutex_unlock(&inst->frames.lock); - if (found) + if (found) { + dprintk(CVP_CMD, "%s: " + "pkt_type %08x sess_id %08x trans_id <> ktid %llu\n", + __func__, frame->pkt_type, + hash32_ptr(inst->session), + frame->ktid); msm_cvp_unmap_frame_buf(inst, frame); + } else dprintk(CVP_WARN, "%s frame %llu not found!\n", __func__, ktid); } @@ -1542,12 +1548,18 @@ int msm_cvp_map_frame(struct msm_cvp_inst *inst, if (!offset || !buf_num) return 0; - cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; ktid = atomic64_inc_return(&inst->core->kernel_trans_id); ktid &= (FENCE_BIT - 1); cmd_hdr->client_data.kdata = ktid; + dprintk(CVP_CMD, "%s: " + "pkt_type %08x sess_id %08x trans_id %u ktid %llu\n", + __func__, cmd_hdr->packet_type, + cmd_hdr->session_id, + cmd_hdr->client_data.transaction_id, + cmd_hdr->client_data.kdata & (FENCE_BIT - 1)); + frame = cvp_kmem_cache_zalloc(&cvp_driver->frame_cache, GFP_KERNEL); if (!frame) return -ENOMEM; diff --git a/msm/eva/msm_cvp_debug.h b/msm/eva/msm_cvp_debug.h index b5e427088b..ceaf821bd3 100644 --- a/msm/eva/msm_cvp_debug.h +++ b/msm/eva/msm_cvp_debug.h @@ -26,6 +26,7 @@ enum cvp_msg_prio { CVP_ERR = 0x000001, CVP_WARN = 0x000002, CVP_INFO = 0x000004, + CVP_CMD = 0x000008, CVP_PROF = 0x000010, CVP_PKT = 0x000020, CVP_MEM = 0x000040, @@ -38,7 +39,7 @@ enum cvp_msg_prio { CVP_SESS = 0x002000, CVP_HFI = 0x004000, CVP_VM = 0x008000, - CVP_DBG = CVP_MEM | CVP_SYNX | CVP_CORE | CVP_REG | + CVP_DBG = CVP_MEM | CVP_SYNX | CVP_CORE | CVP_REG | CVP_CMD | CVP_PWR | CVP_DSP | CVP_SESS | CVP_HFI | CVP_PKT | CVP_VM, }; @@ -104,6 +105,8 @@ static inline char *get_debug_level_str(int level) return "warn"; case CVP_INFO: return "info"; + case CVP_CMD: + return "cmd"; case CVP_DBG: return "dbg"; case CVP_PROF: From 5d311208172016b7473e28acfdc2201b80cf3d64 Mon Sep 17 00:00:00 2001 From: George Shen Date: Sun, 19 Mar 2023 21:40:01 -0700 Subject: [PATCH 187/317] msm: eva: Save buffer mappings of last frame Help debugging SMMU fault. Change-Id: I93f041b9c117f1cce0d4a8ad9f723d9d31b02010 Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 24 ++++++++++++++++++++++++ msm/eva/msm_cvp_buf.h | 6 ++++++ msm/eva/msm_cvp_internal.h | 1 + 3 files changed, 31 insertions(+) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 548e9446db..df49bc5e7f 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1449,6 +1449,24 @@ static void msm_cvp_unmap_frame_buf(struct msm_cvp_inst *inst, cvp_kmem_cache_free(&cvp_driver->frame_cache, frame); } +static void backup_frame_buffers(struct msm_cvp_inst *inst, + struct msm_cvp_frame *frame) +{ + /* Save frame buffers before unmap them */ + int i = frame->nr; + + if (i == 0 || i > MAX_FRAME_BUFFER_NUMS) + return; + + inst->last_frame.ktid = frame->ktid; + inst->last_frame.nr = frame->nr; + + do { + i--; + inst->last_frame.smem[i] = *(frame->bufs[i].smem); + } while (i); +} + void msm_cvp_unmap_frame(struct msm_cvp_inst *inst, u64 ktid) { struct msm_cvp_frame *frame, *dummy1; @@ -1480,6 +1498,8 @@ void msm_cvp_unmap_frame(struct msm_cvp_inst *inst, u64 ktid) __func__, frame->pkt_type, hash32_ptr(inst->session), frame->ktid); + /* Save the previous frame mappings for debug */ + backup_frame_buffers(inst, frame); msm_cvp_unmap_frame_buf(inst, frame); } else @@ -1788,6 +1808,10 @@ void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) list_for_each_entry(buf, &inst->persistbufs.list, list) _log_buf(snap, SMEM_PERSIST, inst, buf, log); mutex_unlock(&inst->persistbufs.lock); + + dprintk(CVP_ERR, "last frame ktid %llx\n", inst->last_frame.ktid); + for (i = 0; i < inst->last_frame.nr; i++) + _log_smem(snap, inst, &inst->last_frame.smem[i], log); } struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index e73e455fd8..495965eab0 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -140,6 +140,12 @@ struct msm_cvp_frame { u32 pkt_type; }; +struct cvp_frame_bufs { + u64 ktid; + u32 nr; + struct msm_cvp_smem smem[MAX_FRAME_BUFFER_NUMS]; +}; + void print_cvp_buffer(u32 tag, const char *str, struct msm_cvp_inst *inst, struct cvp_internal_buf *cbuf); diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index d4b485e06b..5cb9e6c957 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -385,6 +385,7 @@ struct msm_cvp_inst { struct msm_cvp_list cvpdspbufs; struct msm_cvp_list cvpwnccbufs; struct msm_cvp_list frames; + struct cvp_frame_bufs last_frame; u32 cvpwnccbufs_num; struct msm_cvp_wncc_buffer* cvpwnccbufs_table; struct completion completions[SESSION_MSG_END - SESSION_MSG_START + 1]; From a33d13c191c1899de5769e016163ce561aa93ded Mon Sep 17 00:00:00 2001 From: Palak Joshi Date: Thu, 16 Mar 2023 18:22:13 +0530 Subject: [PATCH 188/317] msm: eva: Updated error handling in case of core init fails. Removed release and disable subcache in case of core init fails, as subcache deinit is done as part of load FW failure error handling and also as part of unload FW. Change-Id: Ic1a6bf75eacaa8a4ccb95a7155e720932a372a58 Signed-off-by: Palak Joshi --- msm/eva/cvp_hfi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index badebb9585..131fe69dcf 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -2249,11 +2249,9 @@ err_core_init: msm_cvp_mmrm_deregister(dev); } err_load_fw: + __hwfence_regs_unmap(dev); err_no_mem: dprintk(CVP_ERR, "Core init failed\n"); - __release_subcaches(device); - __disable_subcaches(device); - __hwfence_regs_unmap(dev); mutex_unlock(&dev->lock); pm_relax(dev->res->pdev->dev.parent); return rc; From dcaf2dcdfb9f741b93b8720b791d4490a85f612e Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 16 Mar 2023 22:21:12 -0700 Subject: [PATCH 189/317] msm: eva: Remove unused dsp power flags Avoid mis-use of old flag that could lead to failure in powering collapse EVA when a session becomes idle for 3s. Change-Id: I954bc0972b1f627b274b78659c34626127619af5 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 36 ++++++++++-------------------------- msm/eva/msm_cvp_dsp.c | 36 +++++++++++++++++++++++++++++++----- msm/eva/msm_cvp_dsp.h | 15 +++------------ 3 files changed, 44 insertions(+), 43 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 131fe69dcf..fc534afddd 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -247,30 +247,15 @@ static void __dump_packet(u8 *packet, enum cvp_msg_prio log_level) } } -static int __dsp_suspend(struct iris_hfi_device *device, bool force, u32 flags) +static int __dsp_suspend(struct iris_hfi_device *device, bool force) { int rc; - struct cvp_hal_session *temp; if (msm_cvp_dsp_disable) return 0; - list_for_each_entry(temp, &device->sess_head, list) { - /* if forceful suspend, don't check session pause info */ - if (force) - continue; - - /* don't suspend if cvp session is not paused */ - if (!(temp->flags & SESSION_PAUSE)) { - dprintk(CVP_DSP, - "%s: cvp session %x not paused %d\n", - __func__, hash32_ptr(temp), gfa_cv.state); - return -EBUSY; - } - } - dprintk(CVP_DSP, "%s: suspend dsp\n", __func__); - rc = cvp_dsp_suspend(flags); + rc = cvp_dsp_suspend(force); if (rc) { dprintk(CVP_ERR, "%s: dsp suspend failed with error %d\n", __func__, rc); @@ -281,7 +266,7 @@ static int __dsp_suspend(struct iris_hfi_device *device, bool force, u32 flags) return 0; } -static int __dsp_resume(struct iris_hfi_device *device, u32 flags) +static int __dsp_resume(struct iris_hfi_device *device) { int rc; @@ -289,7 +274,7 @@ static int __dsp_resume(struct iris_hfi_device *device, u32 flags) return 0; dprintk(CVP_DSP, "%s: resume dsp\n", __func__); - rc = cvp_dsp_resume(flags); + rc = cvp_dsp_resume(); if (rc) { dprintk(CVP_ERR, "%s: dsp resume failed with error %d\n", @@ -301,7 +286,7 @@ static int __dsp_resume(struct iris_hfi_device *device, u32 flags) return rc; } -static int __dsp_shutdown(struct iris_hfi_device *device, u32 flags) +static int __dsp_shutdown(struct iris_hfi_device *device) { int rc; @@ -309,7 +294,7 @@ static int __dsp_shutdown(struct iris_hfi_device *device, u32 flags) return 0; dprintk(CVP_DSP, "%s: shutdown dsp\n", __func__); - rc = cvp_dsp_shutdown(flags); + rc = cvp_dsp_shutdown(); if (rc) { dprintk(CVP_ERR, "%s: dsp shutdown failed with error %d\n", @@ -2285,7 +2270,7 @@ static int iris_hfi_core_release(void *dev) __resume(device); __set_state(device, IRIS_STATE_DEINIT); - __dsp_shutdown(device, 0); + __dsp_shutdown(device); __disable_subcaches(device); __unload_fw(device); @@ -2938,7 +2923,6 @@ static int __power_collapse(struct iris_hfi_device *device, bool force) { int rc = 0; u32 wfi_status = 0, idle_status = 0, pc_ready = 0; - u32 flags = 0; int count = 0; const int max_tries = 150; @@ -2959,7 +2943,7 @@ static int __power_collapse(struct iris_hfi_device *device, bool force) return -EINVAL; } - rc = __dsp_suspend(device, force, flags); + rc = __dsp_suspend(device, force); if (rc == -EBUSY) goto exit; else if (rc) @@ -4788,7 +4772,7 @@ static void power_off_iris2(struct iris_hfi_device *device) static inline int __resume(struct iris_hfi_device *device) { int rc = 0; - u32 flags = 0, reg_gdsc, reg_cbcr; + u32 reg_gdsc, reg_cbcr; struct msm_cvp_core *core; if (!device) { @@ -4848,7 +4832,7 @@ static inline int __resume(struct iris_hfi_device *device) __set_subcaches(device); - __dsp_resume(device, flags); + __dsp_resume(device); dprintk(CVP_PWR, "Resumed from power collapse\n"); exit: diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index bfdbb2ad06..c0e1532ae7 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -487,7 +487,27 @@ exit: return 0; } -int cvp_dsp_suspend(uint32_t session_flag) +static bool dsp_session_exist(void) +{ + struct msm_cvp_core *core; + struct msm_cvp_inst *inst = NULL; + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (core) { + mutex_lock(&core->lock); + list_for_each_entry(inst, &core->instances, list) { + if (inst->session_type == MSM_CVP_DSP) { + mutex_unlock(&core->lock); + return true; + } + } + mutex_unlock(&core->lock); + } + + return false; +} + +int cvp_dsp_suspend(bool force) { int rc = 0; struct cvp_dsp_cmd_msg cmd; @@ -495,6 +515,13 @@ int cvp_dsp_suspend(uint32_t session_flag) struct cvp_dsp_rsp_msg rsp; bool retried = false; + + /* If not forced to suspend, check if DSP requested PC earlier */ + if (force == false) + if (dsp_session_exist()) + if (me->state != DSP_SUSPEND) + return -EBUSY; + cmd.type = CPU2DSP_SUSPEND; mutex_lock(&me->tx_lock); @@ -546,7 +573,7 @@ exit: return rc; } -int cvp_dsp_resume(uint32_t session_flag) +int cvp_dsp_resume(void) { int rc = 0; struct cvp_dsp_cmd_msg cmd; @@ -610,7 +637,7 @@ static void cvp_remove_dsp_sessions(void) dprintk(CVP_WARN, "%s: EVA SSR handled for CDSP\n", __func__); } -int cvp_dsp_shutdown(uint32_t session_flag) +int cvp_dsp_shutdown(void) { struct cvp_dsp_apps *me = &gfa_cv; int rc = 0; @@ -860,7 +887,6 @@ void cvp_dsp_init_hfi_queue_hdr(struct iris_hfi_device *device) static int __reinit_dsp(void) { int rc; - uint32_t flag = 0; uint64_t addr; uint32_t size; struct cvp_dsp_apps *me = &gfa_cv; @@ -880,7 +906,7 @@ static int __reinit_dsp(void) } /* Force shutdown DSP */ - rc = cvp_dsp_shutdown(flag); + rc = cvp_dsp_shutdown(); if (rc) return rc; /* diff --git a/msm/eva/msm_cvp_dsp.h b/msm/eva/msm_cvp_dsp.h index e94cefaa9b..d384fea97b 100644 --- a/msm/eva/msm_cvp_dsp.h +++ b/msm/eva/msm_cvp_dsp.h @@ -251,29 +251,20 @@ extern struct cvp_dsp_apps gfa_cv; /* * API for CVP driver to suspend CVP session during * power collapse - * - * @param session_flag - * Flag to share details of session. */ -int cvp_dsp_suspend(uint32_t session_flag); +int cvp_dsp_suspend(bool force); /* * API for CVP driver to resume CVP session during * power collapse - * - * @param session_flag - * Flag to share details of session. */ -int cvp_dsp_resume(uint32_t session_flag); +int cvp_dsp_resume(void); /* * API for CVP driver to shutdown CVP session during * cvp subsystem error. - * - * @param session_flag - * Flag to share details of session. */ -int cvp_dsp_shutdown(uint32_t session_flag); +int cvp_dsp_shutdown(void); /* * API to register iova buffer address with CDSP From 84334be2a145638d2efeb0496f576ab1f80d0155 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 27 Mar 2023 23:30:30 -0700 Subject: [PATCH 190/317] msm: eva: Define kernel timeout in one place Easy to maintain. Change-Id: Iacf8ae5481c08d69259f41db26ac6ac2216a54f6 Signed-off-by: George Shen --- msm/eva/msm_cvp.c | 9 ++++++--- msm/eva/msm_cvp_internal.h | 1 - 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 1ad2670ef5..263181233f 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -149,7 +149,8 @@ static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst, if (!s) return -ECONNRESET; - wait_time = msecs_to_jiffies(CVP_MAX_WAIT_TIME); + wait_time = msecs_to_jiffies( + inst->core->resources.msm_cvp_hw_rsp_timeout); sq = &inst->session_queue; rc = cvp_wait_process_message(inst, sq, NULL, wait_time, out_pkt); @@ -332,7 +333,8 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, goto exit; } - timeout = msecs_to_jiffies(CVP_MAX_WAIT_TIME); + timeout = msecs_to_jiffies( + inst->core->resources.msm_cvp_hw_rsp_timeout); rc = cvp_wait_process_message(inst, sq, &ktid, timeout, (struct eva_kmd_hfi_packet *)&hdr); @@ -1407,7 +1409,8 @@ static int cvp_drain_fence_sched_list(struct msm_cvp_inst *inst) ++count; } mutex_unlock(&q->lock); - wait_time = count * CVP_MAX_WAIT_TIME * 1000; + wait_time = count * 1000; + wait_time *= inst->core->resources.msm_cvp_hw_rsp_timeout; dprintk(CVP_SYNX, "%s: wait %d us for %d fence command\n", __func__, wait_time, count); diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index 5cb9e6c957..a599e1d4ce 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -199,7 +199,6 @@ enum msm_cvp_modes { }; #define MAX_NUM_MSGS_PER_SESSION 128 -#define CVP_MAX_WAIT_TIME 2000 struct cvp_session_msg { struct list_head node; From 9d1d8dfa53d990fdb9fb75b73cc8ccad2e3c951b Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 31 Mar 2023 10:03:42 -0700 Subject: [PATCH 191/317] msm: eva: Use ratelimited kernel logging In case of error recurring frequently. Change-Id: I5d8f9b3a65a3d1faa6646c38dbd2e96d3beeca1b Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 2 +- msm/eva/msm_cvp_core.c | 8 ++++---- msm/eva/msm_cvp_debug.h | 12 ++++++++++++ msm/eva/msm_cvp_ioctl.c | 6 +++--- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index df49bc5e7f..491bf2bc4e 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1917,7 +1917,7 @@ int cvp_release_arp_buffers(struct msm_cvp_inst *inst) __func__, rc); mutex_lock(&inst->persistbufs.lock); } else { - dprintk(CVP_WARN, "Fail to send Rel prst buf\n"); + dprintk_rl(CVP_WARN, "Fail to send Rel prst buf\n"); } } diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 1fbeef440d..ef549ecd58 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -182,7 +182,7 @@ void *msm_cvp_open(int core_id, int session_type, struct task_struct *task) goto err_invalid_core; } - pr_info( + pr_info_ratelimited( CVP_DBG_TAG "%s opening cvp instance: %pK type %d cnt %d\n", "sess", task->comm, inst, session_type, instance_count); mutex_init(&inst->sync_lock); @@ -356,7 +356,7 @@ wait_frame: } if (cvp_release_arp_buffers(inst)) - dprintk(CVP_ERR, + dprintk_rl(CVP_WARN, "Failed to release persist buffers\n"); if (inst->prop.type == HFI_SESSION_FD @@ -412,7 +412,7 @@ int msm_cvp_destroy(struct msm_cvp_inst *inst) __deinit_fence_queue(inst); core->synx_ftbl->cvp_sess_deinit_synx(inst); - pr_info( + pr_info_ratelimited( CVP_DBG_TAG "closed cvp instance: %pK session_id = %d type %d %d\n", inst->proc_name, inst, hash32_ptr(inst->session), @@ -448,7 +448,7 @@ int msm_cvp_close(void *instance) int rc = 0; if (!inst || !inst->core) { - dprintk(CVP_ERR, "%s: invalid params\n", __func__); + dprintk_rl(CVP_ERR, "%s: invalid params\n", __func__); return -EINVAL; } diff --git a/msm/eva/msm_cvp_debug.h b/msm/eva/msm_cvp_debug.h index ceaf821bd3..ce75d2ded2 100644 --- a/msm/eva/msm_cvp_debug.h +++ b/msm/eva/msm_cvp_debug.h @@ -82,6 +82,18 @@ extern bool cvp_kernel_fence_enabled; } \ } while (0) +/* dprintk_rl is designed for printing frequent recurring errors */ +#define dprintk_rl(__level, __fmt, arg...) \ + do { \ + if (msm_cvp_debug & __level) { \ + if (msm_cvp_debug_out == CVP_OUT_PRINTK) { \ + pr_info_ratelimited(CVP_DBG_TAG __fmt, \ + get_debug_level_str(__level), \ + ## arg); \ + } \ + } \ + } while (0) + #define MSM_CVP_ERROR(value) \ do { if (value) \ dprintk(CVP_ERR, "BugOn"); \ diff --git a/msm/eva/msm_cvp_ioctl.c b/msm/eva/msm_cvp_ioctl.c index e273b92821..437b4bc6cf 100644 --- a/msm/eva/msm_cvp_ioctl.c +++ b/msm/eva/msm_cvp_ioctl.c @@ -302,7 +302,7 @@ static int convert_from_user(struct eva_kmd_arg *kp, int pkt_idx; if (!kp || !up) { - dprintk(CVP_ERR, "%s: invalid params\n", __func__); + dprintk_rl(CVP_ERR, "%s: invalid params\n", __func__); return -EINVAL; } @@ -439,7 +439,7 @@ static int convert_from_user(struct eva_kmd_arg *kp, break; } default: - dprintk(CVP_ERR, "%s: unknown cmd type 0x%x\n", + dprintk_rl(CVP_ERR, "%s: unknown cmd type 0x%x\n", __func__, kp->type); rc = -EINVAL; break; @@ -615,7 +615,7 @@ static long cvp_ioctl(struct msm_cvp_inst *inst, return -ENOMEM; if (convert_from_user(karg, arg, inst)) { - dprintk(CVP_ERR, "%s: failed to get from user cmd %x\n", + dprintk_rl(CVP_ERR, "%s: failed to get from user cmd %x\n", __func__, karg->type); kfree(karg); return -EFAULT; From c0feafd278a205462636b7b41133031c61c24064 Mon Sep 17 00:00:00 2001 From: Prakruthi Deepak Heragu Date: Wed, 1 Mar 2023 11:15:58 -0800 Subject: [PATCH 192/317] msm: eva: Rename Gunyah RM APIs As we are merging upstream patches, resolve conflicts of namespaces in downstream gunyah modules. Change-Id: I6bc4719132e30e984974077c9923d3753faf539a Signed-off-by: Prakruthi Deepak Heragu --- msm/eva/vm/cvp_vm_msgq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/eva/vm/cvp_vm_msgq.c b/msm/eva/vm/cvp_vm_msgq.c index ea2c9b1b5f..907b58cf4c 100644 --- a/msm/eva/vm/cvp_vm_msgq.c +++ b/msm/eva/vm/cvp_vm_msgq.c @@ -187,10 +187,10 @@ static int cvp_msgq_cb(struct notifier_block *nb, if (vm_status_payload->vm_status != GH_RM_VM_STATUS_READY) return -12; - if (gh_rm_get_vmid(msgq_config->peer_id, &peer_vmid)) + if (ghd_rm_get_vmid(msgq_config->peer_id, &peer_vmid)) return -13; - if (gh_rm_get_vmid(GH_PRIMARY_VM, &self_vmid)) + if (ghd_rm_get_vmid(GH_PRIMARY_VM, &self_vmid)) return -14; if (peer_vmid != vm_status_payload->vmid) From cde58caa653da94ede45825825f297bc15e5de19 Mon Sep 17 00:00:00 2001 From: Jingyu Su Date: Thu, 6 Apr 2023 16:28:17 -0700 Subject: [PATCH 193/317] msm: eva: Remove two calls to qcom_clk_set_flags() in cvp_hfi.c Change-Id: I6ffd3e045999ce701825aaec66f38255fd98cff2 Signed-off-by: Jingyu Su --- msm/eva/cvp_hfi.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index fc534afddd..39aabf4f02 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -4190,8 +4190,6 @@ static int __power_on_controller(struct iris_hfi_device *device) { int rc = 0; - struct clock_info *cl = NULL; - rc = __enable_regulator(device, "cvp"); if (rc) { dprintk(CVP_ERR, "Failed to enable ctrler: %d\n", rc); @@ -4233,14 +4231,6 @@ static int __power_on_controller(struct iris_hfi_device *device) goto fail_enable_clk; } - iris_hfi_for_each_clock(device, cl) { - if (strcmp(cl->name, "cvp_clk")) { - qcom_clk_set_flags(cl->clk, CLKFLAG_RETAIN_PERIPH); - qcom_clk_set_flags(cl->clk, CLKFLAG_RETAIN_MEM); - break; - } - } - dprintk(CVP_PWR, "EVA controller powered on\n"); return 0; From 815ffdf422e67521e19c5f998b975b25cacf4b66 Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 31 Mar 2023 14:51:48 -0700 Subject: [PATCH 194/317] msm: eva: Fix NoC Hang When accessing NoC Acquire xo_reset before accessing CVP NoC. There is a chance the NoC clock, XO clock is disabled during XO reset. Acquiring xo_reset will block the XO clock reset. Change-Id: I51ab201beafbd1a4b998ee33a9d23c1efa3e2a14 Signed-off-by: George Shen --- msm/eva/cvp.c | 1 - msm/eva/cvp_hfi.c | 195 ++++++++++++++++++------------------ msm/eva/cvp_hfi_io.h | 10 ++ msm/eva/msm_cvp_common.c | 40 +------- msm/eva/msm_cvp_internal.h | 1 - msm/eva/msm_cvp_res_parse.c | 2 - msm/eva/msm_cvp_resources.h | 1 - 7 files changed, 109 insertions(+), 141 deletions(-) diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index aef273fb8e..b21c8fed4f 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -146,7 +146,6 @@ static int msm_cvp_initialize_core(struct platform_device *pdev, init_completion(&core->completions[i]); } - INIT_DELAYED_WORK(&core->fw_unload_work, msm_cvp_fw_unload_handler); INIT_WORK(&core->ssr_work, msm_cvp_ssr_handler); init_cycle_info(&core->dyn_clk); core->ssr_count = 0; diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 39aabf4f02..aa54362383 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -100,6 +100,7 @@ static void power_off_iris2(struct iris_hfi_device *device); static int __set_ubwc_config(struct iris_hfi_device *device); static void __noc_error_info_iris2(struct iris_hfi_device *device); static int __enable_hw_power_collapse(struct iris_hfi_device *device); +static int __disable_hw_power_collapse(struct iris_hfi_device *device); static int __power_off_controller(struct iris_hfi_device *device); static int __hwfence_regs_map(struct iris_hfi_device *device); @@ -386,6 +387,25 @@ err_reg_handoff_failed: return rc; } +static int __take_back_regulators(struct iris_hfi_device *device) +{ + struct regulator_info *rinfo; + int rc = 0; + + iris_hfi_for_each_regulator(device, rinfo) { + rc = __acquire_regulator(rinfo, device); + /* + * if one regulator hand off failed, driver should take + * the control for other regulators back. + */ + if (rc) + return rc; + } + + return rc; +} + + static int __write_queue(struct cvp_iface_q_info *qinfo, u8 *packet, bool *rx_req_is_set) { @@ -772,38 +792,6 @@ static int __read_register(struct iris_hfi_device *device, u32 reg) return rc; } -static bool __noc_access_ok(struct iris_hfi_device *device) -{ - int ret; - - ret = __read_register(device, CVP_CC_MVS1C_CBCR); - if (ret & 0x80000000) { - dprintk(CVP_ERR, "%s MVS1C off\n", __func__); - return false; - } - ret = __read_register(device, CVP_CC_MVS1_CBCR); - if (ret & 0x80000000) { - dprintk(CVP_ERR, "%s MVS1 off\n", __func__); - return false; - } - ret = __read_register(device, CVP_CC_AHB_CBCR); - if (ret & 0x80000000) { - dprintk(CVP_ERR, "%s AHB off\n", __func__); - return false; - } - ret = __read_register(device, CVP_CC_XO_CBCR); - if (ret & 0x80000000) { - dprintk(CVP_ERR, "%s XO off\n", __func__); - return false; - } - ret = __read_register(device, CVP_CC_SLEEP_CBCR); - if (ret & 0x80000000) { - dprintk(CVP_ERR, "%s SLEEP off\n", __func__); - return false; - } - return true; -} - static int __set_registers(struct iris_hfi_device *device) { struct msm_cvp_core *core; @@ -829,8 +817,11 @@ static int __set_registers(struct iris_hfi_device *device) reg_set->reg_tbl[i].value); } - if (!__noc_access_ok(device)) + i = call_iris_op(device, reset_control_acquire_name, device, "cvp_xo_reset"); + if (i) { + dprintk(CVP_WARN, "%s Fail acquire xo_reset\n", __func__); return -EINVAL; + } __write_register(device, CVP_CPU_CS_AXI4_QOS, pdata->noc_qos->axi_qos); @@ -854,6 +845,22 @@ static int __set_registers(struct iris_hfi_device *device) pdata->noc_qos->dangerlut_low); __write_register(device, CVP_NOC_CDM_SAFELUT_LOW, pdata->noc_qos->safelut_low); + + /* Below registers write moved from FW to SW to enable UBWC */ + __write_register(device, CVP_NOC_RGE_NIU_DECCTL_LOW, + 0x1); + __write_register(device, CVP_NOC_RGE_NIU_ENCCTL_LOW, + 0x1); + __write_register(device, CVP_NOC_GCE_VADL_TOF_NIU_DECCTL_LOW, + 0x1); + __write_register(device, CVP_NOC_GCE_VADL_TOF_NIU_ENCCTL_LOW, + 0x1); + __write_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS, + 0x3); + __write_register(device, CVP_NOC_MAIN_SIDEBANDMANAGER_FAULTINEN0_LOW, + 0x1); + + call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); return 0; } @@ -2269,6 +2276,9 @@ static int iris_hfi_core_release(void *dev) __resume(device); __set_state(device, IRIS_STATE_DEINIT); + rc = __tzbsp_set_cvp_state(TZ_SUBSYS_STATE_SUSPEND); + if (rc) + dprintk(CVP_WARN, "Failed to suspend cvp FW%d\n", rc); __dsp_shutdown(device); @@ -3896,6 +3906,23 @@ disable_regulator_failed: return rc; } +static int __disable_hw_power_collapse(struct iris_hfi_device *device) +{ + int rc = 0; + + if (!msm_cvp_fw_low_power_mode) { + dprintk(CVP_PWR, "Not enabling hardware power collapse\n"); + return 0; + } + + rc = __take_back_regulators(device); + if (rc) + dprintk(CVP_WARN, + "%s : Failed to disable HW power collapse %d\n", + __func__, rc); + return rc; +} + static int __enable_hw_power_collapse(struct iris_hfi_device *device) { int rc = 0; @@ -4317,6 +4344,7 @@ static int __iris_power_on(struct iris_hfi_device *device) /* * Re-program all of the registers that get reset as a result of * regulator_disable() and _enable() + * calling below function requires CORE powered on */ rc = __set_registers(device); if (rc) @@ -4379,6 +4407,7 @@ static void __print_sidebandmanager_regs(struct iris_hfi_device *device) u32 sbm_ln0_low, axi_cbcr; u32 main_sbm_ln0_low = 0xdeadbeef, main_sbm_ln0_high = 0xdeadbeef; u32 main_sbm_ln1_high = 0xdeadbeef, cpu_cs_x2rpmh; + int rc; sbm_ln0_low = __read_register(device, CVP_NOC_SBM_SENSELN0_LOW); @@ -4403,12 +4432,18 @@ static void __print_sidebandmanager_regs(struct iris_hfi_device *device) goto exit; } + rc = call_iris_op(device, reset_control_acquire_name, device, "cvp_xo_reset"); + if (rc) { + dprintk(CVP_WARN, "%s Fail acquire xo_reset\n", __func__); + goto exit; + } main_sbm_ln0_low = __read_register(device, CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_LOW); main_sbm_ln0_high = __read_register(device, CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_HIGH); main_sbm_ln1_high = __read_register(device, CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN1_HIGH); + call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); exit: cpu_cs_x2rpmh = cpu_cs_x2rpmh & (~CVP_CPU_CS_X2RPMh_SWOVERRIDE_BMSK); @@ -4431,33 +4466,6 @@ static int __power_off_controller(struct iris_hfi_device *device) __write_register(device, CVP_CPU_CS_X2RPMh, 0x3); /* HPG 6.2.2 Step 2, noc to low power */ -#ifndef CONFIG_EVA_PINEAPPLE - __write_register(device, CVP_AON_WRAPPER_CVP_NOC_LPI_CONTROL, 0x1); - while (!reg_status && count < max_count) { - lpi_status = - __read_register(device, - CVP_AON_WRAPPER_CVP_NOC_LPI_STATUS); - reg_status = lpi_status & BIT(0); - /* Wait for Core noc lpi status to be set */ - usleep_range(50, 100); - count++; - } - dprintk(CVP_PWR, - "Core Noc: lpi_status %x noc_status %x (count %d)\n", - lpi_status, reg_status, count); - if (count == max_count) { - u32 pc_ready, wfi_status; - - wfi_status = __read_register(device, CVP_WRAPPER_CPU_STATUS); - pc_ready = __read_register(device, CVP_CTRL_STATUS); - - dprintk(CVP_WARN, - "Core NOC not in qaccept status %x %x %x %x\n", - reg_status, lpi_status, wfi_status, pc_ready); - - __print_sidebandmanager_regs(device); - } -#endif /* New addition to put CPU/Tensilica to low power */ reg_status = 0; @@ -4623,6 +4631,15 @@ static int __power_off_core(struct iris_hfi_device *device) msm_cvp_disable_unprepare_clk(device, "core_clk"); msm_cvp_disable_unprepare_clk(device, "video_cc_mvs1_clk_src"); return 0; + } else if (!(value & 0x2)) { + /* + * HW_CONTROL PC disabled, then core is powered on for + * CVP NoC access + */ + __disable_regulator(device, "cvp-core"); + msm_cvp_disable_unprepare_clk(device, "core_clk"); + msm_cvp_disable_unprepare_clk(device, "video_cc_mvs1_clk_src"); + return 0; } dprintk(CVP_PWR, "Driver controls Core power off now\n"); @@ -4656,41 +4673,6 @@ static int __power_off_core(struct iris_hfi_device *device) warn_flag = 1; } -#ifndef CONFIG_EVA_PINEAPPLE - /* Apply partial reset on MSF interface and wait for ACK */ - __write_register(device, CVP_NOC_RESET_REQ, 0x7); - count = 0; - do { - value = __read_register(device, CVP_NOC_RESET_ACK); - if ((value & 0x7) == 0x7) - break; - else - usleep_range(100, 200); - count++; - } while (count < max_count); - - if (count == max_count) { - dprintk(CVP_WARN, "Core NoC reset assert failed %x\n", value); - warn_flag = 1; - } - - /* De-assert partial reset on MSF interface and wait for ACK */ - __write_register(device, CVP_NOC_RESET_REQ, 0x0); - count = 0; - do { - value = __read_register(device, CVP_NOC_RESET_ACK); - if ((value & 0x1) == 0x0) - break; - else - usleep_range(100, 200); - count++; - } while (count < max_count); - - if (count == max_count) { - dprintk(CVP_WARN, "Core NoC reset de-assert failed\n"); - warn_flag = 1; - } -#else count = 0; max_count = 1000; __write_register(device, CVP_AON_WRAPPER_CVP_NOC_LPI_CONTROL, 0x1); @@ -4720,7 +4702,6 @@ static int __power_off_core(struct iris_hfi_device *device) } __write_register(device, CVP_AON_WRAPPER_CVP_NOC_LPI_CONTROL, 0x0); -#endif if (warn_flag) __print_sidebandmanager_regs(device); @@ -4732,6 +4713,8 @@ static int __power_off_core(struct iris_hfi_device *device) __write_register(device, CVP_WRAPPER_CORE_CLOCK_CONFIG, config); + __disable_hw_power_collapse(device); + usleep_range(100, 200); __disable_regulator(device, "cvp-core"); msm_cvp_disable_unprepare_clk(device, "core_clk"); msm_cvp_disable_unprepare_clk(device, "video_cc_mvs1_clk_src"); @@ -4982,8 +4965,9 @@ static void __noc_error_info_iris2(struct iris_hfi_device *device) { struct msm_cvp_core *core; struct cvp_noc_log *noc_log; - u32 val = 0, regi, i; + u32 val = 0, regi, regii, regiii, i; bool log_required = false; + int rc; core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); @@ -4998,6 +4982,15 @@ static void __noc_error_info_iris2(struct iris_hfi_device *device) } noc_log->used = 1; + __disable_hw_power_collapse(device); + + val = __read_register(device, CVP_CC_MVS1_GDSCR); + regi = __read_register(device, CVP_AON_WRAPPER_CVP_NOC_CORE_CLK_CONTROL); + regii = __read_register(device, CVP_CC_MVS1_CBCR); + regiii = __read_register(device, CVP_WRAPPER_CORE_CLOCK_CONFIG); + dprintk(CVP_ERR, "noc reg check: %#x %#x %#x %#x\n", + val, regi, regii, regiii); + val = __read_register(device, CVP_NOC_ERR_SWID_LOW_OFFS); __err_log(log_required, &noc_log->err_ctrl_swid_low, "CVP_NOC_ERL_MAIN_SWID_LOW", val); @@ -5038,6 +5031,12 @@ static void __noc_error_info_iris2(struct iris_hfi_device *device) __err_log(log_required, &noc_log->err_ctrl_errlog3_high, "CVP_NOC_ERL_MAIN_ERRLOG3_HIGH", val); + rc = call_iris_op(device, reset_control_acquire_name, device, "cvp_xo_reset"); + if (rc) { + dprintk(CVP_WARN, "%s Fail acquire xo_reset\n", __func__); + return; + } + val = __read_register(device, CVP_NOC_CORE_ERR_SWID_LOW_OFFS); __err_log(log_required, &noc_log->err_core_swid_low, "CVP_NOC__CORE_ERL_MAIN_SWID_LOW", val); @@ -5078,6 +5077,8 @@ static void __noc_error_info_iris2(struct iris_hfi_device *device) val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS); __err_log(log_required, &noc_log->err_core_errlog3_high, "CVP_NOC_CORE_ERL_MAIN_ERRLOG3_HIGH", val); + __write_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS, 0x1); + call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); #define CVP_SS_CLK_HALT 0x8 #define CVP_SS_CLK_EN 0xC #define CVP_SS_ARP_TEST_BUS_CONTROL 0x700 diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index bbd3b605c7..0f9bd0223b 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -195,6 +195,16 @@ #define CVP_NOC_SBM_SENSELN0_LOW (CVP_NOC_BASE_OFFS + 0x300) #define CVP_NOC_CORE_BASE_OFFS 0x00010000 +#define CVP_NOC_RGE_NIU_DECCTL_LOW \ + (CVP_NOC_CORE_BASE_OFFS + 0x3108) +#define CVP_NOC_RGE_NIU_ENCCTL_LOW \ + (CVP_NOC_CORE_BASE_OFFS + 0x3188) +#define CVP_NOC_GCE_VADL_TOF_NIU_DECCTL_LOW \ + (CVP_NOC_CORE_BASE_OFFS + 0x3508) +#define CVP_NOC_GCE_VADL_TOF_NIU_ENCCTL_LOW \ + (CVP_NOC_CORE_BASE_OFFS + 0x3588) +#define CVP_NOC_MAIN_SIDEBANDMANAGER_FAULTINEN0_LOW \ + (CVP_NOC_CORE_BASE_OFFS + 0x7040) #define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_LOW \ (CVP_NOC_CORE_BASE_OFFS + 0x7100) #define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_HIGH \ diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index a3438d89c1..d98431ed57 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -632,8 +632,6 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) if (hfi_device->error == CVP_ERR_NOC_ERROR) { dprintk(CVP_WARN, "Got NOC error"); msm_cvp_noc_error_info(core); - hfi_device->error = 0xdead; - MSM_CVP_ERROR(true); } call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data); list_for_each_entry(inst, &core->instances, list) { @@ -653,6 +651,7 @@ static void handle_sys_error(enum hal_command_response cmd, void *data) if (!core->trigger_ssr) { cvp_print_inst(CVP_WARN, inst); + if (hfi_device->error != CVP_ERR_NOC_ERROR) msm_cvp_print_inst_bufs(inst, false); } } @@ -1446,43 +1445,6 @@ int msm_cvp_comm_kill_session(struct msm_cvp_inst *inst) return rc; } -void msm_cvp_fw_unload_handler(struct work_struct *work) -{ - struct msm_cvp_core *core = NULL; - struct cvp_hfi_device *hdev = NULL; - int rc = 0; - - core = container_of(work, struct msm_cvp_core, fw_unload_work.work); - if (!core || !core->device) { - dprintk(CVP_ERR, "%s - invalid work or core handle\n", - __func__); - return; - } - - hdev = core->device; - - mutex_lock(&core->lock); - if (list_empty(&core->instances) && - core->state != CVP_CORE_UNINIT) { - if (core->state > CVP_CORE_INIT) { - dprintk(CVP_CORE, "Calling cvp_hal_core_release\n"); - rc = call_hfi_op(hdev, core_release, - hdev->hfi_device_data); - if (rc) { - dprintk(CVP_ERR, - "Failed to release core, id = %d\n", - core->id); - mutex_unlock(&core->lock); - return; - } - } - core->state = CVP_CORE_UNINIT; - kfree(core->capabilities); - core->capabilities = NULL; - } - mutex_unlock(&core->lock); -} - static int set_internal_buf_on_fw(struct msm_cvp_inst *inst, struct msm_cvp_smem *handle) { diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index a599e1d4ce..0bb6b56130 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -412,7 +412,6 @@ int msm_cvp_trigger_ssr(struct msm_cvp_core *core, int msm_cvp_noc_error_info(struct msm_cvp_core *core); void msm_cvp_comm_handle_thermal_event(void); -void msm_cvp_fw_unload_handler(struct work_struct *work); void msm_cvp_ssr_handler(struct work_struct *work); /* * XXX: normally should be in msm_cvp_core.h, but that's meant for public APIs, diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index 054eb25cff..aac7c27c94 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -860,8 +860,6 @@ int cvp_read_platform_resources_from_drv_data( "qcom,enable-thermal-mitigation"); res->msm_cvp_pwr_collapse_delay = find_key_value(platform_data, "qcom,power-collapse-delay"); - res->msm_cvp_firmware_unload_delay = find_key_value(platform_data, - "qcom,fw-unload-delay"); res->msm_cvp_hw_rsp_timeout = find_key_value(platform_data, "qcom,hw-resp-timeout"); res->msm_cvp_dsp_rsp_timeout = find_key_value(platform_data, diff --git a/msm/eva/msm_cvp_resources.h b/msm/eva/msm_cvp_resources.h index c6fe037ea8..5f9ccb10ef 100644 --- a/msm/eva/msm_cvp_resources.h +++ b/msm/eva/msm_cvp_resources.h @@ -206,7 +206,6 @@ struct msm_cvp_platform_resources { uint32_t max_secure_inst_count; int msm_cvp_hw_rsp_timeout; int msm_cvp_dsp_rsp_timeout; - int msm_cvp_firmware_unload_delay; uint32_t msm_cvp_pwr_collapse_delay; bool non_fatal_pagefaults; bool fatal_ssr; From 2532f316af8e0a8a11776f01b095bf3821f4ca1e Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 11 Apr 2023 09:59:14 -0700 Subject: [PATCH 195/317] msm: eva: Use correct error code in __dsp_suspend Incorrect error code misleads driver to trigger SSR. Change-Id: I6e64c6b79be973c4e5b0b9968dc3b952855a2004 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 8 +++++--- msm/eva/msm_cvp_dsp.c | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index aa54362383..685ad8dfdd 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -258,9 +258,11 @@ static int __dsp_suspend(struct iris_hfi_device *device, bool force) dprintk(CVP_DSP, "%s: suspend dsp\n", __func__); rc = cvp_dsp_suspend(force); if (rc) { - dprintk(CVP_ERR, "%s: dsp suspend failed with error %d\n", - __func__, rc); - return -EINVAL; + if (rc != -EBUSY) + dprintk(CVP_ERR, + "%s: dsp suspend failed with error %d\n", + __func__, rc); + return rc; } dprintk(CVP_DSP, "%s: dsp suspended\n", __func__); diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index c0e1532ae7..30680c220e 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -248,7 +248,7 @@ static int delete_dsp_session(struct msm_cvp_inst *inst, frpc_node->cvp_fastrpc_device, buf); if (rc) - dprintk(CVP_WARN, + dprintk_rl(CVP_WARN, "%s Failed to unmap buffer 0x%x\n", __func__, rc); @@ -1952,7 +1952,7 @@ static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) rc = eva_fastrpc_dev_unmap_dma(frpc_device, buf); if (rc) { - dprintk(CVP_ERR, + dprintk_rl(CVP_ERR, "%s Failed to unmap buffer 0x%x\n", __func__, rc); cmd->ret = -1; From ab30e5fc6f84de6c403e84bc092f64f5193c0df5 Mon Sep 17 00:00:00 2001 From: Naveen Ravi Date: Wed, 8 Mar 2023 10:10:14 -0800 Subject: [PATCH 196/317] msm: eva: fence override mode Change-Id: I0cd8b3dc234168f365d8664f3a4d0c09094a1da1 --- msm/eva/cvp_hfi_api.h | 2 ++ msm/eva/msm_cvp.c | 65 +++++++++++++++++++++++++++++--------- msm/eva/msm_cvp_debug.c | 4 +-- msm/eva/msm_cvp_debug.h | 2 +- msm/eva/msm_cvp_platform.c | 25 +++++++++++++++ 5 files changed, 80 insertions(+), 18 deletions(-) diff --git a/msm/eva/cvp_hfi_api.h b/msm/eva/cvp_hfi_api.h index beaadd5ec7..5fd28f3600 100644 --- a/msm/eva/cvp_hfi_api.h +++ b/msm/eva/cvp_hfi_api.h @@ -245,6 +245,7 @@ struct msm_cvp_hfi_defs { bool checksum_enabled; enum hal_command_response resp; char name[PKT_NAME_LEN]; + bool force_kernel_fence; }; struct cvp_hfi_device { @@ -303,6 +304,7 @@ void cvp_hfi_deinitialize(enum msm_cvp_hfi_type hfi_type, struct cvp_hfi_device *hdev); int get_pkt_index(struct cvp_hal_session_cmd_pkt *hdr); +int get_pkt_fenceoverride(struct cvp_hal_session_cmd_pkt* hdr); int get_pkt_index_from_type(u32 pkt_type); int get_hfi_version(void); unsigned int get_msg_size(struct cvp_hfi_msg_session_hdr *hdr); diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 263181233f..d86347edf8 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -603,9 +603,15 @@ static int cvp_populate_fences( struct eva_kmd_hfi_packet *in_pkt, struct cvp_fence_queue *q; enum op_mode mode; struct cvp_buf_type *buf; + bool override; int rc = 0; + override = get_pkt_fenceoverride((struct cvp_hal_session_cmd_pkt*)in_pkt); + + dprintk(CVP_SYNX, "%s:Fence Override is %d\n",__func__, override); + dprintk(CVP_SYNX, "%s:Kernel Fence is %d\n", __func__, cvp_kernel_fence_enabled); + q = &inst->fence_cmd_queue; mutex_lock(&q->lock); @@ -632,24 +638,53 @@ static int cvp_populate_fences( struct eva_kmd_hfi_packet *in_pkt, f->output_index = 0; buf_offset = offset; - if (!cvp_kernel_fence_enabled) { - for (i = 0; i < num; i++) { - buf = (struct cvp_buf_type *)&in_pkt->pkt_data[buf_offset]; - buf_offset += sizeof(*buf) >> 2; - - if (buf->input_handle || buf->output_handle) { - f->num_fences++; - if (buf->input_handle) - f->output_index++; - } + if (cvp_kernel_fence_enabled == 0) + { + goto soc_fence; + } + else if (cvp_kernel_fence_enabled == 1) + { + goto kernel_fence; + } + else if (cvp_kernel_fence_enabled == 2) + { + if (override == true) + goto kernel_fence; + else if (override == false) + goto soc_fence; + else + { + dprintk(CVP_ERR, "%s: invalid params", __func__); + rc = -EINVAL; + goto exit; } - f->signature = 0xB0BABABE; - if (f->num_fences) - goto fence_cmd_queue; - - goto free_exit; + } + else + { + dprintk(CVP_ERR, "%s: invalid params", __func__); + rc = -EINVAL; + goto exit; } +soc_fence: + for (i = 0; i < num; i++) { + buf = (struct cvp_buf_type*)&in_pkt->pkt_data[buf_offset]; + buf_offset += sizeof(*buf) >> 2; + + if (buf->input_handle || buf->output_handle) { + f->num_fences++; + if (buf->input_handle) + f->output_index++; + } + } + f->signature = 0xB0BABABE; + if (f->num_fences) + goto fence_cmd_queue; + + goto free_exit; + + +kernel_fence: /* First pass to find INPUT synx handles */ for (i = 0; i < num; i++) { buf = (struct cvp_buf_type *)&in_pkt->pkt_data[buf_offset]; diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 53f2516aa1..e4d18c3fe8 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -36,7 +36,7 @@ bool msm_cvp_mmrm_enabled = !true; #endif bool msm_cvp_dcvs_disable = !true; int msm_cvp_minidump_enable = !1; -bool cvp_kernel_fence_enabled = true; +int cvp_kernel_fence_enabled = 2; #define MAX_DBG_BUF_SIZE 4096 @@ -258,7 +258,7 @@ struct dentry *msm_cvp_debugfs_init_drv(void) &msm_cvp_minidump_enable); debugfs_create_bool("fw_coverage", 0644, dir, &msm_cvp_fw_coverage); debugfs_create_bool("auto_pil", 0644, dir, &msm_cvp_auto_pil); - debugfs_create_bool("kernel_fence", 0644, dir, &cvp_kernel_fence_enabled); + debugfs_create_u32("kernel_fence", 0644, dir, &cvp_kernel_fence_enabled); debugfs_create_bool("disable_thermal_mitigation", 0644, dir, &msm_cvp_thermal_mitigation_disabled); debugfs_create_bool("enable_cacheop", 0644, dir, diff --git a/msm/eva/msm_cvp_debug.h b/msm/eva/msm_cvp_debug.h index ce75d2ded2..25caafac24 100644 --- a/msm/eva/msm_cvp_debug.h +++ b/msm/eva/msm_cvp_debug.h @@ -69,7 +69,7 @@ extern bool msm_cvp_dsp_disable; extern bool msm_cvp_mmrm_enabled; extern bool msm_cvp_dcvs_disable; extern int msm_cvp_minidump_enable; -extern bool cvp_kernel_fence_enabled; +extern int cvp_kernel_fence_enabled; #define dprintk(__level, __fmt, arg...) \ do { \ diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index e093864a6f..2702460f81 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -359,6 +359,7 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { .is_config_pkt = false, .resp = HAL_NO_RESP, .name = "DFS_FRAME", + .force_kernel_fence = false, }, [HFI_CMD_SESSION_CVP_SGM_OF_CONFIG - HFI_CMD_SESSION_CVP_START] = { @@ -375,6 +376,7 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { .is_config_pkt = false, .resp = HAL_NO_RESP, .name = "SGM_OF_FRAME", + .force_kernel_fence = false, }, [HFI_CMD_SESSION_CVP_WARP_NCC_CONFIG - HFI_CMD_SESSION_CVP_START] = { @@ -391,6 +393,7 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { .is_config_pkt = false, .resp = HAL_NO_RESP, .name = "WARP_NCC_FRAME", + .force_kernel_fence = false, }, [HFI_CMD_SESSION_CVP_WARP_CONFIG - HFI_CMD_SESSION_CVP_START] = { @@ -415,6 +418,7 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { .is_config_pkt = false, .resp = HAL_NO_RESP, .name = "WARP_FRAME", + .force_kernel_fence = false, }, [HFI_CMD_SESSION_CVP_DMM_CONFIG - HFI_CMD_SESSION_CVP_START] = { @@ -439,6 +443,7 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { .is_config_pkt = false, .resp = HAL_NO_RESP, .name = "DMM_FRAME", + .force_kernel_fence = true, }, [HFI_CMD_SESSION_CVP_SET_PERSIST_BUFFERS - HFI_CMD_SESSION_CVP_START] = { @@ -487,6 +492,7 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { .is_config_pkt = false, .resp = HAL_NO_RESP, .name = "TME_FRAME", + .force_kernel_fence = false, }, [HFI_CMD_SESSION_CVP_CV_ODT_CONFIG - HFI_CMD_SESSION_CVP_START] = { @@ -535,6 +541,7 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { .is_config_pkt = false, .resp = HAL_NO_RESP, .name = "NCC_FRAME", + .force_kernel_fence = false, }, [HFI_CMD_SESSION_CVP_ICA_CONFIG - HFI_CMD_SESSION_CVP_START] = { @@ -551,6 +558,7 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { .is_config_pkt = false, .resp = HAL_NO_RESP, .name = "ICA_FRAME", + .force_kernel_fence = false, }, [HFI_CMD_SESSION_CVP_HCD_CONFIG - HFI_CMD_SESSION_CVP_START] = { @@ -567,6 +575,7 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { .is_config_pkt = false, .resp = HAL_NO_RESP, .name = "HCD_FRAME", + .force_kernel_fence = false, }, [HFI_CMD_SESSION_CVP_DC_CONFIG - HFI_CMD_SESSION_CVP_START] = { @@ -583,6 +592,7 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { .is_config_pkt = false, .resp = HAL_NO_RESP, .name = "DC_FRAME", + .force_kernel_fence = false, }, [HFI_CMD_SESSION_CVP_DCM_CONFIG - HFI_CMD_SESSION_CVP_START] = { @@ -599,6 +609,7 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { .is_config_pkt = false, .resp = HAL_NO_RESP, .name = "DCM_FRAME", + .force_kernel_fence = false, }, [HFI_CMD_SESSION_CVP_PYS_HCD_CONFIG - HFI_CMD_SESSION_CVP_START] = { @@ -615,6 +626,7 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { .is_config_pkt = false, .resp = HAL_NO_RESP, .name = "PYS_HCD_FRAME", + .force_kernel_fence = true, }, [HFI_CMD_SESSION_CVP_SET_MODEL_BUFFERS - HFI_CMD_SESSION_CVP_START] = { @@ -711,6 +723,7 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { .is_config_pkt = false, .resp = HAL_NO_RESP, .name = "XRA_PATCH_FRAME", + .force_kernel_fence = false, }, [HFI_CMD_SESSION_CVP_XRA_PATCH_CONFIG - HFI_CMD_SESSION_CVP_START] = { @@ -727,6 +740,7 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { .is_config_pkt = false, .resp = HAL_NO_RESP, .name = "XRA_MATCH_FRAME", + .force_kernel_fence = false, }, [HFI_CMD_SESSION_CVP_XRA_MATCH_CONFIG - HFI_CMD_SESSION_CVP_START] = { @@ -743,6 +757,7 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { .is_config_pkt = false, .resp = HAL_NO_RESP, .name = "RGE_FRAME", + .force_kernel_fence = true, }, [HFI_CMD_SESSION_CVP_RGE_CONFIG - HFI_CMD_SESSION_CVP_START] = { @@ -759,6 +774,7 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { .is_config_pkt = false, .resp = HAL_NO_RESP, .name = "ITOF_FRAME", + .force_kernel_fence = true, }, [HFI_CMD_SESSION_EVA_ITOF_CONFIG - HFI_CMD_SESSION_CVP_START] = { @@ -791,6 +807,7 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { .is_config_pkt = false, .resp = HAL_NO_RESP, .name = "DLFL_FRAME", + .force_kernel_fence = false, }, [HFI_CMD_SESSION_EVA_DLFL_CONFIG - HFI_CMD_SESSION_CVP_START] = { @@ -823,6 +840,7 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { .is_config_pkt = false, .resp = HAL_NO_RESP, .name = "DME_FRAME", + .force_kernel_fence = true, }, }; @@ -839,6 +857,13 @@ int get_pkt_index(struct cvp_hal_session_cmd_pkt *hdr) return -EINVAL; } +int get_pkt_fenceoverride(struct cvp_hal_session_cmd_pkt* hdr) +{ + return cvp_hfi_defs[hdr->packet_type - HFI_CMD_SESSION_CVP_START].force_kernel_fence; +} + + + int get_pkt_index_from_type(u32 pkt_type) { if ((pkt_type < HFI_CMD_SESSION_CVP_START) || From 00f7039e3ca20337438f6aabdbf434f530c95de8 Mon Sep 17 00:00:00 2001 From: Palak Joshi Date: Wed, 8 Feb 2023 19:46:06 +0530 Subject: [PATCH 197/317] msm: eva: Added EVA FW/HW hung detection mechanism using WD ISR Recovery mechanism is added to invoke SSR when WD ISR is triggered. Change-Id: I6f7a289f822c6f1a50494cd6a4855a2c3ba2cc72 Signed-off-by: Palak Joshi --- msm/eva/cvp_core_hfi.h | 2 ++ msm/eva/cvp_hfi.c | 45 +++++++++++++++++++++++++++++++++++++ msm/eva/cvp_hfi_io.h | 5 +++-- msm/eva/msm_cvp_common.c | 2 +- msm/eva/msm_cvp_common.h | 1 + msm/eva/msm_cvp_debug.c | 3 +++ msm/eva/msm_cvp_debug.h | 1 + msm/eva/msm_cvp_res_parse.c | 5 +++++ msm/eva/msm_cvp_resources.h | 1 + msm/eva/vm/cvp_vm_main.c | 8 +++++++ 10 files changed, 70 insertions(+), 3 deletions(-) diff --git a/msm/eva/cvp_core_hfi.h b/msm/eva/cvp_core_hfi.h index 21f85ed00c..f93b0db0bc 100644 --- a/msm/eva/cvp_core_hfi.h +++ b/msm/eva/cvp_core_hfi.h @@ -200,6 +200,7 @@ struct cvp_iface_q_info { struct cvp_hal_data { u32 irq; + u32 irq_wd; phys_addr_t firmware_base; u8 __iomem *register_base; u8 __iomem *gcc_reg_base; @@ -279,6 +280,7 @@ struct iris_hfi_device { }; irqreturn_t cvp_hfi_isr(int irq, void *dev); +irqreturn_t iris_hfi_isr_wd(int irq, void *dev); void cvp_iris_hfi_delete_device(void *device); int cvp_iris_hfi_initialize(struct cvp_hfi_device *hdev, u32 device_id, diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 685ad8dfdd..cfb79d8f04 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -35,6 +35,7 @@ // ysi - added for debug #include +#include "msm_cvp_common.h" #define REG_ADDR_OFFSET_BITMASK 0x000FFFFF #define QDSS_IOVA_START 0x80001000 @@ -3455,6 +3456,43 @@ irqreturn_t cvp_hfi_isr(int irq, void *dev) return IRQ_HANDLED; } +static void iris_hfi_wd_work_handler(struct work_struct *work) +{ + struct msm_cvp_core *core; + struct iris_hfi_device *device; + struct msm_cvp_cb_cmd_done response = {0}; + enum hal_command_response cmd = HAL_SYS_WATCHDOG_TIMEOUT; + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (core) + device = core->device->hfi_device_data; + else + return; + if (msm_cvp_hw_wd_recovery) { + dprintk(CVP_ERR, "Cleaning up as HW WD recovery is enable %d\n", + msm_cvp_hw_wd_recovery); + response.device_id = device->device_id; + handle_sys_error(cmd, (void *) &response); + enable_irq(device->cvp_hal_data->irq_wd); + } + else { + dprintk(CVP_ERR, "Crashing the device as HW WD recovery is disable %d\n", + msm_cvp_hw_wd_recovery); + BUG_ON(1); + } +} + +static DECLARE_WORK(iris_hfi_wd_work, iris_hfi_wd_work_handler); + +irqreturn_t iris_hfi_isr_wd(int irq, void *dev) +{ + struct iris_hfi_device *device = dev; + dprintk(CVP_ERR, "Got HW WDOG IRQ! \n"); + disable_irq_nosync(irq); + queue_work(device->cvp_workq, &iris_hfi_wd_work); + return IRQ_HANDLED; + +} + static int __init_reset_clk(struct msm_cvp_platform_resources *res, int reset_index) { @@ -4168,6 +4206,13 @@ static void interrupt_init_iris2(struct iris_hfi_device *device) __write_register(device, CVP_WRAPPER_INTR_MASK, mask_val); dprintk(CVP_REG, "Init irq: reg: %x, mask value %x\n", CVP_WRAPPER_INTR_MASK, mask_val); + + mask_val = 0; + mask_val = __read_register(device, CVP_SS_IRQ_MASK); + mask_val &= ~(CVP_SS_INTR_BMASK); + __write_register(device, CVP_SS_IRQ_MASK, mask_val); + dprintk(CVP_REG, "Init irq_wd: reg: %x, mask value %x\n", + CVP_SS_IRQ_MASK, mask_val); } static void setup_dsp_uc_memmap_vpu5(struct iris_hfi_device *device) diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index 0f9bd0223b..a28e459e95 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -96,10 +96,11 @@ #define CVP_WRAPPER_INTR_STATUS_A2HWD_BMSK 0x8 #define CVP_WRAPPER_INTR_STATUS_A2H_BMSK 0x4 +#define CVP_SS_IRQ_MASK (CVP_TOP_BASE_OFFS + 0x04) +#define CVP_SS_INTR_BMASK (0x100) #define CVP_WRAPPER_INTR_MASK (CVP_WRAPPER_BASE_OFFS + 0x10) #define CVP_FATAL_INTR_BMSK (CVP_WRAPPER_INTR_MASK_CPU_NOC_BMSK | \ - CVP_WRAPPER_INTR_MASK_CORE_NOC_BMSK | \ - CVP_WRAPPER_INTR_MASK_A2HWD_BMSK) + CVP_WRAPPER_INTR_MASK_CORE_NOC_BMSK ) #define CVP_WRAPPER_INTR_MASK_CPU_NOC_BMSK 0x40 #define CVP_WRAPPER_INTR_MASK_CORE_NOC_BMSK 0x20 #define CVP_WRAPPER_INTR_MASK_A2HWD_BMSK 0x8 diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index d98431ed57..94a016c6de 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -589,7 +589,7 @@ static void msm_comm_clean_notify_client(struct msm_cvp_core *core) mutex_unlock(&core->lock); } -static void handle_sys_error(enum hal_command_response cmd, void *data) +void handle_sys_error(enum hal_command_response cmd, void *data) { struct msm_cvp_cb_cmd_done *response = data; struct msm_cvp_core *core = NULL; diff --git a/msm/eva/msm_cvp_common.h b/msm/eva/msm_cvp_common.h index 5320c6766e..4d66055d98 100644 --- a/msm/eva/msm_cvp_common.h +++ b/msm/eva/msm_cvp_common.h @@ -23,6 +23,7 @@ int msm_cvp_comm_suspend(int core_id); void msm_cvp_comm_session_clean(struct msm_cvp_inst *inst); int msm_cvp_comm_kill_session(struct msm_cvp_inst *inst); void msm_cvp_comm_generate_sys_error(struct msm_cvp_inst *inst); +void handle_sys_error(enum hal_command_response cmd, void *data); int msm_cvp_comm_smem_cache_operations(struct msm_cvp_inst *inst, struct msm_cvp_smem *mem, enum smem_cache_ops cache_ops); int msm_cvp_comm_check_core_init(struct msm_cvp_core *core); diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index e4d18c3fe8..160491c3ea 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -37,6 +37,7 @@ bool msm_cvp_mmrm_enabled = !true; bool msm_cvp_dcvs_disable = !true; int msm_cvp_minidump_enable = !1; int cvp_kernel_fence_enabled = 2; +int msm_cvp_hw_wd_recovery = 1; #define MAX_DBG_BUF_SIZE 4096 @@ -453,6 +454,8 @@ struct dentry *msm_cvp_debugfs_init_core(struct msm_cvp_core *core, dprintk(CVP_ERR, "debugfs_create: ssr_stall fail\n"); goto failed_create_dir; } + debugfs_create_u32("hw_wd_recovery", 0644, dir, + &msm_cvp_hw_wd_recovery); failed_create_dir: return dir; } diff --git a/msm/eva/msm_cvp_debug.h b/msm/eva/msm_cvp_debug.h index 25caafac24..fca0fb8fa1 100644 --- a/msm/eva/msm_cvp_debug.h +++ b/msm/eva/msm_cvp_debug.h @@ -70,6 +70,7 @@ extern bool msm_cvp_mmrm_enabled; extern bool msm_cvp_dcvs_disable; extern int msm_cvp_minidump_enable; extern int cvp_kernel_fence_enabled; +extern int msm_cvp_hw_wd_recovery; #define dprintk(__level, __fmt, arg...) \ do { \ diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index aac7c27c94..3010c85b8d 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -900,6 +900,11 @@ int cvp_read_platform_resources_from_dt( dprintk(CVP_CORE, "%s: res->irq:%d \n", __func__, res->irq); + //Parsing for WD interrupt + res->irq_wd = platform_get_irq(pdev, 1); + + dprintk(CVP_CORE, "%s: res->irq_wd:%d \n", + __func__, res->irq_wd); rc = msm_cvp_load_subcache_info(res); if (rc) dprintk(CVP_WARN, "Failed to load subcache info: %d\n", rc); diff --git a/msm/eva/msm_cvp_resources.h b/msm/eva/msm_cvp_resources.h index 5f9ccb10ef..d1e823eb2c 100644 --- a/msm/eva/msm_cvp_resources.h +++ b/msm/eva/msm_cvp_resources.h @@ -178,6 +178,7 @@ struct msm_cvp_platform_resources { uint32_t gcc_reg_size; struct cvp_fw_reg_mappings reg_mappings; uint32_t irq; + uint32_t irq_wd; uint32_t sku_version; struct allowed_clock_rates_table *allowed_clks_tbl; u32 allowed_clks_tbl_size; diff --git a/msm/eva/vm/cvp_vm_main.c b/msm/eva/vm/cvp_vm_main.c index 4fb3db342c..b84f21cb6b 100644 --- a/msm/eva/vm/cvp_vm_main.c +++ b/msm/eva/vm/cvp_vm_main.c @@ -130,6 +130,7 @@ static int msm_cvp_vm_init_reg_and_irq(struct iris_hfi_device *device, } hal->irq = res->irq; + hal->irq_wd = res->irq_wd; hal->firmware_base = res->firmware_base; hal->register_base = devm_ioremap(&res->pdev->dev, res->register_base, res->register_size); @@ -159,6 +160,13 @@ static int msm_cvp_vm_init_reg_and_irq(struct iris_hfi_device *device, goto error_irq_fail; } + rc = request_irq(res->irq_wd, iris_hfi_isr_wd, IRQF_TRIGGER_HIGH, + "msm_cvp", device); + if (unlikely(rc)) { + dprintk(CVP_ERR, "() :request_irq for WD failed\n"); + goto error_irq_fail; + } + disable_irq_nosync(res->irq); dprintk(CVP_INFO, "firmware_base = %pa, register_base = %pa, register_size = %d\n", From 23fb4cfeac2c160ba671b6255704b28c5b898271 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 24 Apr 2023 12:13:24 -0700 Subject: [PATCH 198/317] msm: eva: Wait EVA ready for sess deletion Avoid EVA in middle of processing frames when CDSP SSR caused force session deletion. Change-Id: I245f13086173c832a098b5f5aad5b38f38bd28b3 Signed-off-by: George Shen --- msm/eva/msm_cvp_dsp.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 30680c220e..32a27db026 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -435,6 +435,8 @@ static void cvp_dsp_rpmsg_remove(struct rpmsg_device *rpdev) mutex_unlock(&me->tx_lock); mutex_unlock(&me->rx_lock); + /* Wait HW finish current frame processing */ + usleep_range(20000, 50000); cvp_remove_dsp_sessions(); dprintk(CVP_WARN, "%s: CDSP SSR handled nr_maps %d\n", __func__, From fec60a4a003ec55de7e586d6746bc60f90bb5c24 Mon Sep 17 00:00:00 2001 From: Naveen Ravi Date: Mon, 24 Apr 2023 22:37:47 -0700 Subject: [PATCH 199/317] msm: eva: change warp frame to kw fence Change-Id: I271eb88f166e22c81d9f0d9245faefd1277602f0 --- msm/eva/msm_cvp_platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 2702460f81..0cfa12a35d 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -418,7 +418,7 @@ const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX] = { .is_config_pkt = false, .resp = HAL_NO_RESP, .name = "WARP_FRAME", - .force_kernel_fence = false, + .force_kernel_fence = true, }, [HFI_CMD_SESSION_CVP_DMM_CONFIG - HFI_CMD_SESSION_CVP_START] = { From 564ed96df09ae414ce94afe3ba975d0a9ccc9adc Mon Sep 17 00:00:00 2001 From: Jingyu Su Date: Tue, 18 Apr 2023 14:42:08 -0700 Subject: [PATCH 200/317] msm: eva: fix KASAN stack-out-of-bounds issue in __iface_cmdq_write_relaxed Change-Id: Id5b07cf778804ac7865f150e72331be6e94cb80d Signed-off-by: Jingyu Su --- msm/eva/cvp_hfi.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index cfb79d8f04..30ae7c516b 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -433,12 +433,17 @@ static int __write_queue(struct cvp_iface_q_info *qinfo, u8 *packet, } cmd_pkt = (struct cvp_hfi_cmd_session_hdr *)packet; - dprintk(CVP_CMD, "%s: " - "pkt_type %08x sess_id %08x trans_id %u ktid %llu\n", - __func__, cmd_pkt->packet_type, - cmd_pkt->session_id, - cmd_pkt->client_data.transaction_id, - cmd_pkt->client_data.kdata & (FENCE_BIT - 1)); + + if (cmd_pkt->size >= sizeof(struct cvp_hfi_cmd_session_hdr)) + dprintk(CVP_CMD, "%s: " + "pkt_type %08x sess_id %08x trans_id %u ktid %llu\n", + __func__, cmd_pkt->packet_type, + cmd_pkt->session_id, + cmd_pkt->client_data.transaction_id, + cmd_pkt->client_data.kdata & (FENCE_BIT - 1)); + else + dprintk(CVP_CMD, "%s: " + "pkt_type %08x", __func__, cmd_pkt->packet_type); if (msm_cvp_debug & CVP_PKT) { dprintk(CVP_PKT, "%s: %pK\n", __func__, qinfo); From 28d5691237211556830292e49e424f401956adb9 Mon Sep 17 00:00:00 2001 From: Sabharsh Sidhu Date: Fri, 14 Apr 2023 15:50:36 -0700 Subject: [PATCH 201/317] msm: eva: Update WarpNCC-related UAPI Update UAPI for future backward compatibility. Add mechanism to dynamically specify WarpNCC metadata buffer offset instead of using macro. Add UMD-KMD shared definitions header file. Change-Id: If8ea7046e692eef1a784d2744228846b6f752d0d Signed-off-by: Sabharsh Sidhu Signed-off-by: George Shen --- include/uapi/eva/media/msm_eva_private.h | 68 +------------------ msm/eva/eva_shared_def.h | 86 ++++++++++++++++++++++++ msm/eva/msm_cvp.h | 1 + msm/eva/msm_cvp_buf.c | 58 ++++++++++++---- 4 files changed, 134 insertions(+), 79 deletions(-) create mode 100644 msm/eva/eva_shared_def.h diff --git a/include/uapi/eva/media/msm_eva_private.h b/include/uapi/eva/media/msm_eva_private.h index a33767bff3..405929d100 100644 --- a/include/uapi/eva/media/msm_eva_private.h +++ b/include/uapi/eva/media/msm_eva_private.h @@ -119,72 +119,6 @@ struct eva_kmd_client_data { __u32 client_data1; __u32 client_data2; }; -struct cvp_buf_type { - __s32 fd; - __u32 size; - __u32 offset; - __u32 flags; - __u32 reserved1; - __u32 reserved2; - __u32 fence_type; - __u32 input_handle; - __u32 output_handle; - __u32 debug_flags; - __u32 crc; -}; - -/** - * Structures and macros for Out-of-Band (OOB) buffer - * that may accompany HFI packet data - */ - -#define EVA_KMD_WNCC_MAX_LAYERS 4 -#define EVA_KMD_WNCC_MAX_ADDRESSES 4095 -#define EVA_KMD_WNCC_MAX_SRC_BUFS 2400 -#define EVA_KMD_WNCC_SRC_BUF_ID_OFFSET 1 - -/** - * Macro to get Meta Data Buffer Offset from the HFI Packet - * The number 15 denotes the position of the first Meta Data Buffer with respect to other fields - * If the WARPNCC HFI Frame Packet changes, this macro definition also has to be revised - */ - -#define EVA_KMD_WNCC_HFI_METADATA_BUFS_OFFSET (15 + sizeof(struct cvp_buf_type) / sizeof(__u32) * 5) - -struct eva_kmd_wncc_metadata { - __u64 loc_x_dec : 12; - __u64 loc_x_frac : 9; - __u64 loc_y_dec : 12; - __u64 loc_y_frac : 9; - __u64 iova_lsb : 22; /* Populated in KMD */ - __u64 iova_msb : 10; /* Populated in KMD */ - __u64 scale_idx : 2; - __s64 aff_coeff_3 : 13; - __s64 aff_coeff_2 : 13; - __s64 aff_coeff_1 : 13; - __s64 aff_coeff_0 : 13; -}; - -struct eva_kmd_oob_wncc { - __u32 num_layers; - struct eva_kmd_wncc_layer { - __u32 num_addrs; - struct eva_kmd_wncc_addr { - __u32 buffer_id; - __u32 offset; - } addrs[EVA_KMD_WNCC_MAX_ADDRESSES]; - } layers[EVA_KMD_WNCC_MAX_LAYERS]; -}; - -#define EVA_KMD_OOB_INVALID 0 -#define EVA_KMD_OOB_WNCC 1 - -struct eva_kmd_oob_buf { - __u32 oob_type; - union { - struct eva_kmd_oob_wncc wncc; - }; -}; /** * Structures and macros for KMD arg data @@ -194,7 +128,7 @@ struct eva_kmd_oob_buf { struct eva_kmd_hfi_packet { __u32 pkt_data[MAX_HFI_PKT_SIZE]; - struct eva_kmd_oob_buf *oob_buf; + void *oob_buf; }; #define EVA_KMD_PROP_HFI_VERSION 1 diff --git a/msm/eva/eva_shared_def.h b/msm/eva/eva_shared_def.h new file mode 100644 index 0000000000..b2a41c722e --- /dev/null +++ b/msm/eva/eva_shared_def.h @@ -0,0 +1,86 @@ +/** + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +/** + * This file contains definitions that are common to UMD and KMD + * but shall not be added to the UAPI to allow for better UAPI + * backward compatibility. Identical copies of this file must be + * used by both UMD and KMD for desired functioning. + */ + +#ifndef _EVA_SHARED_DEF_H_ +#define _EVA_SHARED_DEF_H_ + +/** + * Structure corresponding to HFI_CVP_BUFFER_TYPE + */ + +struct cvp_buf_type { + __s32 fd; + __u32 size; + __u32 offset; + __u32 flags; + __u32 reserved1; + __u32 reserved2; + __u32 fence_type; + __u32 input_handle; + __u32 output_handle; + __u32 debug_flags; + __u32 crc; +}; + +/** + * Structures and macros for Warp-NCC Out-of-Band (OOB) buffer + */ + +#define EVA_KMD_WNCC_MAX_LAYERS 4 +#define EVA_KMD_WNCC_MAX_ADDRESSES 4095 +#define EVA_KMD_WNCC_MAX_SRC_BUFS 2400 +#define EVA_KMD_WNCC_SRC_BUF_ID_OFFSET 1 + +struct eva_kmd_wncc_metadata { + __u64 loc_x_dec : 12; + __u64 loc_x_frac : 9; + __u64 loc_y_dec : 12; + __u64 loc_y_frac : 9; + __u64 iova_lsb : 22; /* Populated in KMD */ + __u64 iova_msb : 10; /* Populated in KMD */ + __u64 scale_idx : 2; + __s64 aff_coeff_3 : 13; + __s64 aff_coeff_2 : 13; + __s64 aff_coeff_1 : 13; + __s64 aff_coeff_0 : 13; +}; + +struct eva_kmd_oob_wncc { + __u32 metadata_bufs_offset; + __u32 num_layers; + struct eva_kmd_wncc_layer { + __u32 num_addrs; + struct eva_kmd_wncc_addr { + __u32 buffer_id; + __u32 offset; + } addrs[EVA_KMD_WNCC_MAX_ADDRESSES]; + } layers[EVA_KMD_WNCC_MAX_LAYERS]; +}; + +/** + * Structure and macros for Out-of-Band (OOB) buffer + * that may accompany HFI packet data + */ + +#define EVA_KMD_OOB_INVALID 0 +#define EVA_KMD_OOB_WNCC 1 + +struct eva_kmd_oob_buf { + __u32 oob_type; + union { + struct eva_kmd_oob_wncc wncc; + }; +}; + +#endif diff --git a/msm/eva/msm_cvp.h b/msm/eva/msm_cvp.h index eab8e0a3e9..4f78e5327e 100644 --- a/msm/eva/msm_cvp.h +++ b/msm/eva/msm_cvp.h @@ -11,6 +11,7 @@ #include "msm_cvp_clocks.h" #include "msm_cvp_debug.h" #include "msm_cvp_dsp.h" +#include "eva_shared_def.h" static inline bool is_buf_param_valid(u32 buf_num, u32 offset) { diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 491bf2bc4e..83ea6fadad 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -15,6 +15,7 @@ #include "msm_cvp_debug.h" #include "msm_cvp_core.h" #include "msm_cvp_dsp.h" +#include "eva_shared_def.h" #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 16, 0)) #define eva_buf_map dma_buf_map @@ -42,7 +43,8 @@ static void _wncc_print_cvpwnccbufs_table(struct msm_cvp_inst* inst); static int _wncc_unmap_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, - unsigned int num_layers, struct eva_kmd_wncc_metadata** wncc_metadata); + unsigned int num_layers, unsigned int metadata_bufs_offset, + struct eva_kmd_wncc_metadata** wncc_metadata); void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log); @@ -750,6 +752,7 @@ static int _wncc_copy_oob_from_user(struct eva_kmd_hfi_packet* in_pkt, { int rc = 0; u32 oob_type; + struct eva_kmd_oob_buf* oob_buf_u; struct eva_kmd_oob_wncc* wncc_oob_u; struct eva_kmd_oob_wncc* wncc_oob_k; unsigned int i; @@ -760,12 +763,13 @@ static int _wncc_copy_oob_from_user(struct eva_kmd_hfi_packet* in_pkt, return -EINVAL; } - if (!access_ok(in_pkt->oob_buf, sizeof(*in_pkt->oob_buf))) { + oob_buf_u = in_pkt->oob_buf; + if (!access_ok(oob_buf_u, sizeof(*oob_buf_u))) { dprintk(CVP_ERR, "%s: invalid OOB buf pointer", __func__); return -EINVAL; } - rc = get_user(oob_type, &in_pkt->oob_buf->oob_type); + rc = get_user(oob_type, &oob_buf_u->oob_type); if (rc) return rc; if (oob_type != EVA_KMD_OOB_WNCC) { @@ -774,9 +778,20 @@ static int _wncc_copy_oob_from_user(struct eva_kmd_hfi_packet* in_pkt, return -EINVAL; } - wncc_oob_u = &in_pkt->oob_buf->wncc; + wncc_oob_u = &oob_buf_u->wncc; wncc_oob_k = wncc_oob; + rc = get_user(wncc_oob_k->metadata_bufs_offset, + &wncc_oob_u->metadata_bufs_offset); + if (rc) + return rc; + if (wncc_oob_k->metadata_bufs_offset > ((sizeof(in_pkt->pkt_data) + - sizeof(struct cvp_buf_type)) / sizeof(__u32))) { + dprintk(CVP_ERR, "%s: invalid wncc metadata bufs offset", + __func__); + return -EINVAL; + } + rc = get_user(wncc_oob_k->num_layers, &wncc_oob_u->num_layers); if (rc) return rc; @@ -817,7 +832,8 @@ static int _wncc_copy_oob_from_user(struct eva_kmd_hfi_packet* in_pkt, } static int _wncc_map_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, - unsigned int num_layers, struct eva_kmd_wncc_metadata** wncc_metadata) + unsigned int num_layers, unsigned int metadata_bufs_offset, + struct eva_kmd_wncc_metadata** wncc_metadata) { int rc = 0, i; struct cvp_buf_type* wncc_metadata_bufs; @@ -829,9 +845,15 @@ static int _wncc_map_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, dprintk(CVP_ERR, "%s: invalid params", __func__); return -EINVAL; } + if (metadata_bufs_offset > ((sizeof(in_pkt->pkt_data) + - sizeof(struct cvp_buf_type)) / sizeof(__u32))) { + dprintk(CVP_ERR, "%s: invalid wncc metadata bufs offset", + __func__); + return -EINVAL; + } wncc_metadata_bufs = (struct cvp_buf_type*) - &in_pkt->pkt_data[EVA_KMD_WNCC_HFI_METADATA_BUFS_OFFSET]; + &in_pkt->pkt_data[metadata_bufs_offset]; for (i = 0; i < num_layers; i++) { dmabuf = dma_buf_get(wncc_metadata_bufs[i].fd); if (IS_ERR(dmabuf)) { @@ -872,13 +894,15 @@ static int _wncc_map_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, } if (rc) - _wncc_unmap_metadata_bufs(in_pkt, i, wncc_metadata); + _wncc_unmap_metadata_bufs(in_pkt, i, metadata_bufs_offset, + wncc_metadata); return rc; } static int _wncc_unmap_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, - unsigned int num_layers, struct eva_kmd_wncc_metadata** wncc_metadata) + unsigned int num_layers, unsigned int metadata_bufs_offset, + struct eva_kmd_wncc_metadata** wncc_metadata) { int rc = 0, i; struct cvp_buf_type* wncc_metadata_bufs; @@ -890,9 +914,15 @@ static int _wncc_unmap_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, dprintk(CVP_ERR, "%s: invalid params", __func__); return -EINVAL; } + if (metadata_bufs_offset > ((sizeof(in_pkt->pkt_data) + - sizeof(struct cvp_buf_type)) / sizeof(__u32))) { + dprintk(CVP_ERR, "%s: invalid wncc metadata bufs offset", + __func__); + return -EINVAL; + } wncc_metadata_bufs = (struct cvp_buf_type*) - &in_pkt->pkt_data[EVA_KMD_WNCC_HFI_METADATA_BUFS_OFFSET]; + &in_pkt->pkt_data[metadata_bufs_offset]; for (i = 0; i < num_layers; i++) { if (!wncc_metadata[i]) { rc = -EINVAL; @@ -944,8 +974,10 @@ static int msm_cvp_proc_oob_wncc(struct msm_cvp_inst* inst, wncc_oob = (struct eva_kmd_oob_wncc*)kzalloc( sizeof(struct eva_kmd_oob_wncc), GFP_KERNEL); - if (!wncc_oob) + if (!wncc_oob) { + dprintk(CVP_ERR, "%s: OOB buf allocation failed", __func__); return -ENOMEM; + } rc = _wncc_copy_oob_from_user(in_pkt, wncc_oob); if (rc) { dprintk(CVP_ERR, "%s: OOB buf copying failed", __func__); @@ -953,7 +985,8 @@ static int msm_cvp_proc_oob_wncc(struct msm_cvp_inst* inst, } rc = _wncc_map_metadata_bufs(in_pkt, - wncc_oob->num_layers, wncc_metadata); + wncc_oob->num_layers, wncc_oob->metadata_bufs_offset, + wncc_metadata); if (rc) { dprintk(CVP_ERR, "%s: failed to map wncc metadata bufs", __func__); @@ -1022,7 +1055,8 @@ static int msm_cvp_proc_oob_wncc(struct msm_cvp_inst* inst, wncc_oob->layers[0].num_addrs, wncc_metadata); if (_wncc_unmap_metadata_bufs(in_pkt, - wncc_oob->num_layers, wncc_metadata)) { + wncc_oob->num_layers, wncc_oob->metadata_bufs_offset, + wncc_metadata)) { dprintk(CVP_ERR, "%s: failed to unmap wncc metadata bufs", __func__); } From 1f5a03e9a6174ac97196a99232df615f5ff7f039 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 20 Apr 2023 11:13:46 -0700 Subject: [PATCH 202/317] msm: eva: Use pool allocator to allocate wncc oobs Keep wncc working in case of kernel heap leakage. wncc buffer requires 128kb. Driver will pre-allocate and store 8 buffers in the pool if wncc use case starts. Save all recently de-register wncc buffer mappings through deregister_buffer API. Change-Id: Iaa422bed9d3dd6f6cfe349a4931bfde28a3e3a51 Signed-off-by: George Shen --- msm/eva/cvp.c | 3 + msm/eva/msm_cvp_buf.c | 114 +++++++++++++++++++++++++++++++++++-- msm/eva/msm_cvp_buf.h | 15 +++++ msm/eva/msm_cvp_internal.h | 1 + 4 files changed, 127 insertions(+), 6 deletions(-) diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index b21c8fed4f..cecdb7a766 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -21,6 +21,7 @@ #include "msm_cvp_internal.h" #include "msm_cvp_res_parse.h" #include "msm_cvp_resources.h" +#include "msm_cvp_buf.h" #include "cvp_hfi_api.h" #include "cvp_private.h" #include "msm_cvp_clocks.h" @@ -625,6 +626,7 @@ static int __init msm_cvp_init(void) cvp_driver->frame_cache.cache = KMEM_CACHE(msm_cvp_frame, 0); cvp_driver->buf_cache.cache = KMEM_CACHE(cvp_internal_buf, 0); cvp_driver->smem_cache.cache = KMEM_CACHE(msm_cvp_smem, 0); + mutex_init(&wncc_buf_pool.lock); return rc; } @@ -640,6 +642,7 @@ static void __exit msm_cvp_exit(void) platform_driver_unregister(&msm_cvp_driver); debugfs_remove_recursive(cvp_driver->debugfs_root); mutex_destroy(&cvp_driver->lock); + mutex_destroy(&wncc_buf_pool.lock); kfree(cvp_driver); cvp_driver = NULL; } diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 83ea6fadad..f4e4de9f18 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -41,6 +41,8 @@ inst->dma_cache.usage_bitmap); \ } while (0) +struct cvp_oob_pool wncc_buf_pool; + static void _wncc_print_cvpwnccbufs_table(struct msm_cvp_inst* inst); static int _wncc_unmap_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, unsigned int num_layers, unsigned int metadata_bufs_offset, @@ -626,6 +628,15 @@ int msm_cvp_unmap_buf_wncc(struct msm_cvp_inst *inst, mutex_unlock(&inst->cvpwnccbufs.lock); return -EINVAL; } + if (cbuf->smem->device_addr) { + u64 idx = inst->unused_wncc_bufs.ktid; + inst->unused_wncc_bufs.smem[idx] = *(cbuf->smem); + inst->unused_wncc_bufs.nr++; + inst->unused_wncc_bufs.nr = + (inst->unused_wncc_bufs.nr > MAX_FRAME_BUFFER_NUMS)? + MAX_FRAME_BUFFER_NUMS : inst->unused_wncc_bufs.nr; + inst->unused_wncc_bufs.ktid = ++idx % MAX_FRAME_BUFFER_NUMS; + } mutex_unlock(&inst->cvpwnccbufs.lock); if (cbuf->smem->device_addr) { @@ -957,11 +968,89 @@ static int _wncc_unmap_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, return rc; } +static int init_wncc_bufs(void) +{ + int i; + + for (i = 0; i < NUM_WNCC_BUFS; i++) { + wncc_buf_pool.bufs[i] = (struct eva_kmd_oob_wncc*)kzalloc( + sizeof(struct eva_kmd_oob_wncc), GFP_KERNEL); + if (!wncc_buf_pool.bufs[i]) { + i--; + goto exit_fail; + } + } + wncc_buf_pool.used_bitmap = 0; + wncc_buf_pool.allocated = true; + return 0; + +exit_fail: + while (i >= 0) { + kfree(wncc_buf_pool.bufs[i]); + i--; + } + return -ENOMEM; +} + +static int alloc_wncc_buf(struct wncc_oob_buf *wob) +{ + int rc, i; + + mutex_lock(&wncc_buf_pool.lock); + if (!wncc_buf_pool.allocated) { + rc = init_wncc_bufs(); + if (rc) { + mutex_unlock(&wncc_buf_pool.lock); + return rc; + } + } + + for (i = 0; i < NUM_WNCC_BUFS; i++) { + if (!(wncc_buf_pool.used_bitmap & BIT(i))) { + wncc_buf_pool.used_bitmap |= BIT(i); + wob->bitmap_idx = i; + wob->buf = wncc_buf_pool.bufs[i]; + mutex_unlock(&wncc_buf_pool.lock); + return 0; + } + } + mutex_unlock(&wncc_buf_pool.lock); + wob->bitmap_idx = 0xff; + wob->buf = (struct eva_kmd_oob_wncc*)kzalloc( + sizeof(struct eva_kmd_oob_wncc), GFP_KERNEL); + if (!wob->buf) + rc = -ENOMEM; + else + rc = 0; + + return rc; +} + +static void free_wncc_buf(struct wncc_oob_buf *wob) +{ + if (!wob) + return; + + if (wob->bitmap_idx == 0xff) { + kfree(wob->buf); + return; + } + + if (wob->bitmap_idx < NUM_WNCC_BUFS) { + mutex_lock(&wncc_buf_pool.lock); + wncc_buf_pool.used_bitmap &= ~BIT(wob->bitmap_idx); + memset(wob->buf, 0, sizeof(struct eva_kmd_oob_wncc)); + wob->buf = NULL; + mutex_unlock(&wncc_buf_pool.lock); + } +} + static int msm_cvp_proc_oob_wncc(struct msm_cvp_inst* inst, struct eva_kmd_hfi_packet* in_pkt) { int rc = 0; struct eva_kmd_oob_wncc* wncc_oob; + struct wncc_oob_buf wob; struct eva_kmd_wncc_metadata* wncc_metadata[EVA_KMD_WNCC_MAX_LAYERS]; unsigned int i, j; bool empty = false; @@ -972,12 +1061,11 @@ static int msm_cvp_proc_oob_wncc(struct msm_cvp_inst* inst, return -EINVAL; } - wncc_oob = (struct eva_kmd_oob_wncc*)kzalloc( - sizeof(struct eva_kmd_oob_wncc), GFP_KERNEL); - if (!wncc_oob) { - dprintk(CVP_ERR, "%s: OOB buf allocation failed", __func__); + rc = alloc_wncc_buf(&wob); + if (rc) return -ENOMEM; - } + + wncc_oob = wob.buf; rc = _wncc_copy_oob_from_user(in_pkt, wncc_oob); if (rc) { dprintk(CVP_ERR, "%s: OOB buf copying failed", __func__); @@ -1062,7 +1150,7 @@ static int msm_cvp_proc_oob_wncc(struct msm_cvp_inst* inst, } exit: - kfree(wncc_oob); + free_wncc_buf(&wob); return rc; } @@ -1497,6 +1585,15 @@ static void backup_frame_buffers(struct msm_cvp_inst *inst, do { i--; + if (frame->bufs[i].smem->bitmap_index < MAX_DMABUF_NUMS) { + /* + * Frame buffer info can be found in dma_cache table, + * Skip saving + */ + inst->last_frame.nr = 0; + return; + } + inst->last_frame.smem[i] = *(frame->bufs[i].smem); } while (i); } @@ -1846,6 +1943,11 @@ void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) dprintk(CVP_ERR, "last frame ktid %llx\n", inst->last_frame.ktid); for (i = 0; i < inst->last_frame.nr; i++) _log_smem(snap, inst, &inst->last_frame.smem[i], log); + + dprintk(CVP_ERR, "unmapped wncc bufs\n"); + for (i = 0; i < inst->unused_wncc_bufs.nr; i++) + _log_smem(snap, inst, &inst->unused_wncc_bufs.smem[i], log); + } struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index 495965eab0..4bbfa191ef 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -146,6 +146,21 @@ struct cvp_frame_bufs { struct msm_cvp_smem smem[MAX_FRAME_BUFFER_NUMS]; }; +struct wncc_oob_buf { + u32 bitmap_idx; + struct eva_kmd_oob_wncc *buf; +}; + +#define NUM_WNCC_BUFS 8 +struct cvp_oob_pool { + struct mutex lock; + bool allocated; + u32 used_bitmap; + struct eva_kmd_oob_wncc *bufs[NUM_WNCC_BUFS]; +}; + +extern struct cvp_oob_pool wncc_buf_pool; + void print_cvp_buffer(u32 tag, const char *str, struct msm_cvp_inst *inst, struct cvp_internal_buf *cbuf); diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index 0bb6b56130..a684846eb9 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -385,6 +385,7 @@ struct msm_cvp_inst { struct msm_cvp_list cvpwnccbufs; struct msm_cvp_list frames; struct cvp_frame_bufs last_frame; + struct cvp_frame_bufs unused_wncc_bufs; u32 cvpwnccbufs_num; struct msm_cvp_wncc_buffer* cvpwnccbufs_table; struct completion completions[SESSION_MSG_END - SESSION_MSG_START + 1]; From 4e3d3a91bde3f8d1d510939202925372425ece8a Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 19 Apr 2023 21:56:08 -0700 Subject: [PATCH 203/317] msm: eva: Change FW boot sequence Match MPTest sequence to facilitate presilicon bringup. Change-Id: Iafd4443eb0f9d6045e61eb2dd33b6663dc3f1334 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 119 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 99 insertions(+), 20 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 30ae7c516b..35a68baaf6 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -48,7 +48,6 @@ struct cvp_tzbsp_memprot { u32 cp_nonpixel_size; }; -#define TZBSP_PIL_SET_STATE 0xA #define TZBSP_CVP_PAS_ID 26 /* Poll interval in uS */ @@ -56,8 +55,8 @@ struct cvp_tzbsp_memprot { enum tzbsp_subsys_state { TZ_SUBSYS_STATE_SUSPEND = 0, - TZ_SUBSYS_STATE_RESUME = 1, - TZ_SUBSYS_STATE_RESTORE_THRESHOLD = 2, + TZ_SUBSYS_STATE_RESUME = 1, + TZ_SUBSYS_STATE_RESTORE_THRESHOLD = 2, }; const struct msm_cvp_gov_data CVP_DEFAULT_BUS_VOTE = { @@ -84,6 +83,7 @@ static bool __is_session_valid(struct iris_hfi_device *device, static int __iface_cmdq_write(struct iris_hfi_device *device, void *pkt); static int __load_fw(struct iris_hfi_device *device); +static int __power_on_init(struct iris_hfi_device *device); static void __unload_fw(struct iris_hfi_device *device); static int __tzbsp_set_cvp_state(enum tzbsp_subsys_state state); static int __enable_subcaches(struct iris_hfi_device *device); @@ -1075,6 +1075,70 @@ static inline void check_tensilica_in_reset(struct iris_hfi_device *device) X2RPMh, wait_mode, fal10_veto); } +static const char boot_states[0x40][32] = { + "NOT INIT", + "RST_START", + "INIT_MEMCTL", + "INTENABLE_RST", + "LITBASE_RST", + "PREFETCH_EN", + "MPU_INIT", + "CTRL_INIT_READ", + "MEMCTL_L1_FIX", + "RESTORE_EXTRA_NW", + "CORE_RESTORE", + "COLD_BOOT", + "DISABLE_CACHE", + "BEFORE_MPU_C", + "RET_MPU_C", + "IN_MPU_C", + "IN_MPU_DEFAULT", + "IN_MPU_SYNX", + "UCR_SIZE_FAIL", + "UCR_ADDR_FAIL", + "UCR1_SIZE_FAIL", + "UCR1_ADDR_FAIL", + "UCR_OVERLAPPED_UCR1", + "UCR1_OVERLAPPED_UCR", + "UCR_EQ_UCR1", + "MPU_CHECK_DONE", + "BEFORE_INT_LOCK", + "AFTER_INT_LOCK", + "BEFORE_INT_UNLOCK", + "AFTER_INT_UNLOCK", + "CALL_START", + "MAIN_ENTRY", + "VENUS_INIT_ENTRY", + "VSYS_INIT_ENTRY", + "BEFORE_XOS_CLK", + "AFTER_XOS_CLK", + "LOG_MUTEX_INIT", + "CREATE_FRAMEWORK_ENTRY", + "DTG_INIT", + "IDLE_TASK_INIT", + "VENUS_CORE_INIT", + "HW_CORES_INIT", + "RST_THREAD_INIT", + "HOST_THREAD_INIT", + "ALL_THREADS_INIT", + "TASK_MEMPOOL", + "SESSION_MUTEX", + "SIGNALS_INIT", + "RST_SIGNAL_INIT", + "INTR_EN_HOST", + "INTR_REG_HOST", + "INTR_EN_DSP", + "INTR_REG_DSP", + "X2HSOFTINTEN", + "H2XSOFTINTEN", + "CPU2DSPINTEN", + "DSP2CPUINT_SWRESET", + "THREADS_START", + "RST_THREAD_START", + "HST_THREAD_START", + "HST_THREAD_ENTRY" +}; + static inline int __boot_firmware(struct iris_hfi_device *device) { int rc = 0, loop = 10; @@ -1108,8 +1172,9 @@ static inline int __boot_firmware(struct iris_hfi_device *device) skip_core_power_check: ctrl_init_val = BIT(0); + /* RUMI: CVP_CTRL_INIT in MPTest has bit 0 and 3 set */ __write_register(device, CVP_CTRL_INIT, ctrl_init_val); - while (!ctrl_status && count < max_tries) { + while (!(ctrl_status & CVP_CTRL_INIT_STATUS__M) && count < max_tries) { ctrl_status = __read_register(device, CVP_CTRL_STATUS); if ((ctrl_status & CVP_CTRL_ERROR_STATUS__M) == 0x4) { dprintk(CVP_ERR, "invalid setting for UC_REGION\n"); @@ -1125,8 +1190,9 @@ skip_core_power_check: if (!(ctrl_status & CVP_CTRL_INIT_STATUS__M)) { ctrl_init_val = __read_register(device, CVP_CTRL_INIT); dprintk(CVP_ERR, - "Failed to boot FW status: %x %x\n", - ctrl_status, ctrl_init_val); + "Failed to boot FW status: %x %x %s\n", + ctrl_status, ctrl_init_val, + boot_states[(ctrl_status >> 9) & 0x3f]); check_tensilica_in_reset(device); rc = -ENODEV; } @@ -2120,9 +2186,9 @@ static int iris_hfi_core_init(void *device) __hwfence_regs_map(dev); - rc = __load_fw(dev); + rc = __power_on_init(dev); if (rc) { - dprintk(CVP_ERR, "Failed to load Iris FW\n"); + dprintk(CVP_ERR, "Failed to power on init EVA\n"); goto err_load_fw; } @@ -2171,6 +2237,12 @@ static int iris_hfi_core_init(void *device) __write_register(dev, CVP_MMAP_ADDR, ipcc_iova); } + rc = __load_fw(dev); + if (rc) { + dprintk(CVP_ERR, "Failed to load Iris FW\n"); + goto err_core_init; + } + rc = __boot_firmware(dev); if (rc) { dprintk(CVP_ERR, "Failed to start core\n"); @@ -4825,6 +4897,10 @@ static inline int __resume(struct iris_hfi_device *device) dprintk(CVP_ERR, "CVP power on failed gdsc %x cbcr %x\n", reg_gdsc, reg_cbcr); + __setup_ucregion_memory_map(device); + + /* RUMI: set CVP_CTRL_INIT register to disable synx in FW */ + /* Reboot the firmware */ rc = __tzbsp_set_cvp_state(TZ_SUBSYS_STATE_RESUME); if (rc) { @@ -4832,8 +4908,6 @@ static inline int __resume(struct iris_hfi_device *device) goto err_set_cvp_state; } - __setup_ucregion_memory_map(device); - /* Wait for boot completion */ rc = __boot_firmware(device); if (rc) { @@ -4874,7 +4948,7 @@ err_iris_power_on: return rc; } -static int __load_fw(struct iris_hfi_device *device) +static int __power_on_init(struct iris_hfi_device *device) { int rc = 0; @@ -4882,36 +4956,41 @@ static int __load_fw(struct iris_hfi_device *device) rc = __init_resources(device, device->res); if (rc) { dprintk(CVP_ERR, "Failed to init resources: %d\n", rc); - goto fail_init_res; + return rc; } rc = __initialize_packetization(device); if (rc) { dprintk(CVP_ERR, "Failed to initialize packetization\n"); - goto fail_init_pkt; + goto fail_iris_init; } rc = __iris_power_on(device); if (rc) { dprintk(CVP_ERR, "Failed to power on iris in in load_fw\n"); - goto fail_iris_power_on; + goto fail_iris_init; } + return rc; +fail_iris_init: + __deinit_resources(device); + return rc; +} + +static int __load_fw(struct iris_hfi_device *device) +{ + int rc = 0; + if ((!device->res->use_non_secure_pil && !device->res->firmware_base) - || device->res->use_non_secure_pil) { + || device->res->use_non_secure_pil) { rc = load_cvp_fw_impl(device); if (rc) goto fail_load_fw; } - return rc; fail_load_fw: call_iris_op(device, power_off, device); -fail_iris_power_on: -fail_init_pkt: - __deinit_resources(device); -fail_init_res: return rc; } From 2bdff6770e96151e240e37b47a39907eb832de4a Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 1 May 2023 08:22:20 -0700 Subject: [PATCH 204/317] msm: eva: Enhance session error handling Ensure smmu fault dump before calling BUG_ON. Rely on WD timeout for FW hang debugging. Change-Id: I0d7fba31dbc602b244af74da6774885c56af0fcc Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 21 ++++++++--- msm/eva/msm_cvp_common.c | 73 ++++--------------------------------- msm/eva/msm_cvp_dsp.h | 2 +- msm/eva/msm_cvp_res_parse.c | 2 +- 4 files changed, 25 insertions(+), 73 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index f4e4de9f18..e916a71621 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -633,9 +633,9 @@ int msm_cvp_unmap_buf_wncc(struct msm_cvp_inst *inst, inst->unused_wncc_bufs.smem[idx] = *(cbuf->smem); inst->unused_wncc_bufs.nr++; inst->unused_wncc_bufs.nr = - (inst->unused_wncc_bufs.nr > MAX_FRAME_BUFFER_NUMS)? - MAX_FRAME_BUFFER_NUMS : inst->unused_wncc_bufs.nr; - inst->unused_wncc_bufs.ktid = ++idx % MAX_FRAME_BUFFER_NUMS; + (inst->unused_wncc_bufs.nr > NUM_WNCC_BUFS)? + NUM_WNCC_BUFS : inst->unused_wncc_bufs.nr; + inst->unused_wncc_bufs.ktid = ++idx % NUM_WNCC_BUFS; } mutex_unlock(&inst->cvpwnccbufs.lock); @@ -1880,6 +1880,7 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) return rc; } +#define MAX_NUM_FRAMES_DUMP 4 void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) { struct cvp_internal_buf *buf; @@ -1916,10 +1917,18 @@ void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) dprintk(CVP_ERR, "frame buffer list\n"); mutex_lock(&inst->frames.lock); list_for_each_entry(frame, &inst->frames.list, list) { - dprintk(CVP_ERR, "frame no %d tid %llx bufs\n", i++, frame->ktid); - for (c = 0; c < frame->nr; c++) - _log_smem(snap, inst, frame->bufs[c].smem, log); + i++; + if (i <= MAX_NUM_FRAMES_DUMP) { + dprintk(CVP_ERR, "frame no %d tid %llx bufs\n", + i, frame->ktid); + for (c = 0; c < frame->nr; c++) + _log_smem(snap, inst, frame->bufs[c].smem, + log); + } } + if (i > MAX_NUM_FRAMES_DUMP) + dprintk(CVP_ERR, "Skipped %d frames' buffers\n", + (i - MAX_NUM_FRAMES_DUMP)); mutex_unlock(&inst->frames.lock); mutex_lock(&inst->cvpdspbufs.lock); diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 94a016c6de..19f7825fc5 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -22,11 +22,6 @@ static void handle_session_error(enum hal_command_response cmd, void *data); -static void msm_cvp_comm_generate_session_error(struct msm_cvp_inst *inst) -{ - dprintk(CVP_WARN, "%s function is deprecated\n", __func__); -} - static void dump_hfi_queue(struct iris_hfi_device *device) { struct cvp_hfi_queue_header *queue; @@ -567,28 +562,6 @@ static void handle_session_error(enum hal_command_response cmd, void *data) cvp_put_inst(inst); } -static void msm_comm_clean_notify_client(struct msm_cvp_core *core) -{ - struct msm_cvp_inst *inst = NULL; - - if (!core) { - dprintk(CVP_ERR, "%s: Invalid params\n", __func__); - return; - } - - dprintk(CVP_WARN, "%s: Core %pK\n", __func__, core); - mutex_lock(&core->lock); - - list_for_each_entry(inst, &core->instances, list) { - mutex_lock(&inst->lock); - inst->state = MSM_CVP_CORE_INVALID; - mutex_unlock(&inst->lock); - dprintk(CVP_WARN, - "%s Send sys error for inst %pK\n", __func__, inst); - } - mutex_unlock(&core->lock); -} - void handle_sys_error(enum hal_command_response cmd, void *data) { struct msm_cvp_cb_cmd_done *response = data; @@ -848,11 +821,18 @@ static int msm_comm_session_abort(struct msm_cvp_inst *inst) int rc = 0, abort_completion = 0; struct cvp_hfi_device *hdev; + if (!inst || !inst->core || !inst->core->device) { dprintk(CVP_ERR, "%s invalid params\n", __func__); return -EINVAL; } + hdev = inst->core->device; + print_hfi_queue_info(hdev); + if (1) + return 0; + + /* Activate code below for Watchdog timeout testing */ abort_completion = SESSION_MSG_INDEX(HAL_SESSION_ABORT_DONE); dprintk(CVP_WARN, "%s: inst %pK session %x\n", __func__, @@ -882,44 +862,7 @@ exit: static void handle_thermal_event(struct msm_cvp_core *core) { - int rc = 0; - struct msm_cvp_inst *inst; - - if (!core || !core->device) { - dprintk(CVP_ERR, "%s Invalid params\n", __func__); - return; - } - mutex_lock(&core->lock); - list_for_each_entry(inst, &core->instances, list) { - if (!inst->session) - continue; - - mutex_unlock(&core->lock); - if (inst->state >= MSM_CVP_OPEN_DONE && - inst->state < MSM_CVP_CLOSE_DONE) { - dprintk(CVP_WARN, "%s: abort inst %pK\n", - __func__, inst); - rc = msm_comm_session_abort(inst); - if (rc) { - dprintk(CVP_ERR, - "%s session_abort failed rc: %d\n", - __func__, rc); - goto err_sess_abort; - } - change_cvp_inst_state(inst, MSM_CVP_CORE_INVALID); - dprintk(CVP_WARN, - "%s Send sys error for inst %pK\n", - __func__, inst); - } else { - msm_cvp_comm_generate_session_error(inst); - } - mutex_lock(&core->lock); - } - mutex_unlock(&core->lock); - return; - -err_sess_abort: - msm_comm_clean_notify_client(core); + dprintk(CVP_WARN, "Deprecated thermal_event handler\n"); } void msm_cvp_comm_handle_thermal_event(void) diff --git a/msm/eva/msm_cvp_dsp.h b/msm/eva/msm_cvp_dsp.h index d384fea97b..d96e6a4229 100644 --- a/msm/eva/msm_cvp_dsp.h +++ b/msm/eva/msm_cvp_dsp.h @@ -15,7 +15,7 @@ #include #ifdef CVP_FASTRPC_ENABLED -#include +#include #else struct fastrpc_device { int handle; diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index 3010c85b8d..49f8fb0fc2 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -1038,13 +1038,13 @@ int msm_cvp_smmu_fault_handler(struct iommu_domain *domain, return -EINVAL; } + mutex_lock(&core->lock); core->smmu_fault_count++; if (!core->last_fault_addr) core->last_fault_addr = iova; dprintk(CVP_ERR, "%s - faulting address: %lx, %d\n", __func__, iova, core->smmu_fault_count); - mutex_lock(&core->lock); log = (core->log.snapshot_index > 0)? false : true; list_for_each_entry(inst, &core->instances, list) { cvp_print_inst(CVP_ERR, inst); From 73f3cecfbd2c3d94c92d458124b21eb6fa28dfd2 Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 2 May 2023 09:30:04 -0700 Subject: [PATCH 205/317] msm: eva: Support Synx V2 only Simplify code base for future generations of driver. Change-Id: I9ed940184da3b2224c74092ac31163de29c84f64 Signed-off-by: George Shen --- include/uapi/eva/media/msm_eva_private.h | 5 - msm/eva/cvp_comm_def.h | 1 - msm/eva/cvp_hfi.c | 2 - msm/eva/cvp_hfi_helper.h | 11 - msm/eva/msm_cvp.c | 2 - msm/eva/msm_cvp_synx.c | 272 ----------------------- 6 files changed, 293 deletions(-) diff --git a/include/uapi/eva/media/msm_eva_private.h b/include/uapi/eva/media/msm_eva_private.h index 405929d100..df4b04f154 100644 --- a/include/uapi/eva/media/msm_eva_private.h +++ b/include/uapi/eva/media/msm_eva_private.h @@ -213,12 +213,7 @@ struct eva_kmd_hfi_fence_packet { }; struct eva_kmd_fence { -#ifdef CVP_CONFIG_SYNX_V2 __u32 h_synx; -#else - __s32 h_synx; - __u32 secure_key; -#endif }; struct eva_kmd_fence_ctrl { diff --git a/msm/eva/cvp_comm_def.h b/msm/eva/cvp_comm_def.h index a922f2d2c4..dc84108e1c 100644 --- a/msm/eva/cvp_comm_def.h +++ b/msm/eva/cvp_comm_def.h @@ -36,7 +36,6 @@ enum queue_state { #ifdef CONFIG_EVA_PINEAPPLE #define CVP_MMRM_ENABLED 1 -#define CVP_CONFIG_SYNX_V2 1 #define CVP_SYNX_ENABLED 1 #define CVP_FASTRPC_ENABLED 1 #endif /* End of CONFIG_EVA_PINEAPPLE */ diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 35a68baaf6..0e4c376cd3 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -2192,13 +2192,11 @@ static int iris_hfi_core_init(void *device) goto err_load_fw; } -#ifdef CVP_CONFIG_SYNX_V2 rc = cvp_synx_recover(); if (rc) { dprintk(CVP_ERR, "Failed to recover synx\n"); goto err_core_init; } -#endif /* mmrm registration */ if (msm_cvp_mmrm_enabled) { diff --git a/msm/eva/cvp_hfi_helper.h b/msm/eva/cvp_hfi_helper.h index 4423c17018..2f2c929bb2 100644 --- a/msm/eva/cvp_hfi_helper.h +++ b/msm/eva/cvp_hfi_helper.h @@ -308,7 +308,6 @@ struct cvp_hfi_client { u32 reserved2; } __packed; -#ifdef CVP_CONFIG_SYNX_V2 struct cvp_hfi_buf_type { u32 iova; u32 size; @@ -320,16 +319,6 @@ struct cvp_hfi_buf_type { u32 input_handle; u32 output_handle; }; -#else -struct cvp_hfi_buf_type { - u32 iova; - u32 size; - u32 offset; - u32 flags; - u32 reserved1; - u32 reserved2; -}; -#endif struct cvp_hfi_cmd_session_set_buffers_packet { u32 size; diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index d86347edf8..df2854ac3a 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -595,7 +595,6 @@ exit: static int cvp_populate_fences( struct eva_kmd_hfi_packet *in_pkt, unsigned int offset, unsigned int num, struct msm_cvp_inst *inst) { -#ifdef CVP_CONFIG_SYNX_V2 u32 i, buf_offset, fence_cnt; struct eva_kmd_fence fences[MAX_HFI_FENCE_SIZE]; struct cvp_fence_command *f; @@ -748,7 +747,6 @@ fence_cmd_queue: free_exit: cvp_free_fence_data(f); exit: -#endif /* CVP_CONFIG_SYNX_V2 */ return rc; } diff --git a/msm/eva/msm_cvp_synx.c b/msm/eva/msm_cvp_synx.c index dd59f0050a..732b8753bb 100644 --- a/msm/eva/msm_cvp_synx.c +++ b/msm/eva/msm_cvp_synx.c @@ -12,8 +12,6 @@ #ifdef CVP_SYNX_ENABLED -#ifdef CVP_CONFIG_SYNX_V2 - static int cvp_sess_init_synx_v2(struct msm_cvp_inst *inst) { @@ -283,276 +281,6 @@ static struct msm_cvp_synx_ops cvp_synx = { }; -#else -static int cvp_sess_init_synx_v1(struct msm_cvp_inst *inst) -{ - struct synx_initialization_params params; - - params.name = "cvp-kernel-client"; - if (synx_initialize(&inst->synx_session_id, ¶ms)) { - - dprintk(CVP_ERR, "%s synx_initialize failed\n", __func__); - return -EFAULT; - } - - return 0; -} - -static int cvp_sess_deinit_synx_v1(struct msm_cvp_inst *inst) -{ - if (!inst) { - dprintk(CVP_ERR, "Used invalid sess in deinit_synx\n"); - return -EINVAL; - } - synx_uninitialize(inst->synx_session_id); - return 0; -} - -static void cvp_dump_fence_queue_v1(struct msm_cvp_inst *inst) -{ - struct cvp_fence_queue *q; - struct cvp_fence_command *f; - struct synx_session ssid; - int i; - - q = &inst->fence_cmd_queue; - ssid = inst->synx_session_id; - mutex_lock(&q->lock); - dprintk(CVP_WARN, "inst %x fence q mode %d, ssid %d\n", - hash32_ptr(inst->session), q->mode, ssid.client_id); - - dprintk(CVP_WARN, "fence cmdq wait list:\n"); - list_for_each_entry(f, &q->wait_list, list) { - dprintk(CVP_WARN, "frame pkt type 0x%x\n", f->pkt->packet_type); - for (i = 0; i < f->output_index; i++) - dprintk(CVP_WARN, "idx %d client hdl %d, state %d\n", - i, f->synx[i], - synx_get_status(ssid, f->synx[i])); - } - - dprintk(CVP_WARN, "fence cmdq schedule list:\n"); - list_for_each_entry(f, &q->sched_list, list) { - dprintk(CVP_WARN, "frame pkt type 0x%x\n", f->pkt->packet_type); - for (i = 0; i < f->output_index; i++) - dprintk(CVP_WARN, "idx %d client hdl %d, state %d\n", - i, f->synx[i], - synx_get_status(ssid, f->synx[i])); - } - mutex_unlock(&q->lock); -} - -static int cvp_import_synx_v1(struct msm_cvp_inst *inst, - struct cvp_fence_command *fc, - u32 *fence) -{ - int rc = 0, rr = 0; - int i; - struct eva_kmd_fence *fs; - struct synx_import_params params; - s32 h_synx; - struct synx_session ssid; - - if (fc->signature != 0xFEEDFACE) { - dprintk(CVP_ERR, "%s Deprecated synx path\n", __func__); - return -EINVAL; - } - - fs = (struct eva_kmd_fence *)fence; - ssid = inst->synx_session_id; - - for (i = 0; i < fc->num_fences; ++i) { - h_synx = fs[i].h_synx; - - if (h_synx) { - params.h_synx = h_synx; - params.secure_key = fs[i].secure_key; - params.new_h_synx = &fc->synx[i]; - - rc = synx_import(ssid, ¶ms); - if (rc) { - dprintk(CVP_ERR, - "%s: %d synx_import failed\n", - __func__, h_synx); - rr = rc; - } - } - } - - return rr; -} - -static int cvp_release_synx_v1(struct msm_cvp_inst *inst, - struct cvp_fence_command *fc) -{ - int rc = 0; - int i; - s32 h_synx; - struct synx_session ssid; - - if (fc->signature != 0xFEEDFACE) { - dprintk(CVP_ERR, "%s deprecated synx_path\n", __func__); - return -EINVAL; - } - - ssid = inst->synx_session_id; - for (i = 0; i < fc->num_fences; ++i) { - h_synx = fc->synx[i]; - if (h_synx) { - rc = synx_release(ssid, h_synx); - if (rc) - dprintk(CVP_ERR, - "%s: synx_release %d, %d failed\n", - __func__, h_synx, i); - } - } - return rc; -} - -static int cvp_cancel_synx_impl(struct msm_cvp_inst *inst, - enum cvp_synx_type type, - struct cvp_fence_command *fc, - int synx_state) -{ - int rc = 0; - int i; - int h_synx; - struct synx_session ssid; - int start = 0, end = 0; - - ssid = inst->synx_session_id; - - if (type == CVP_INPUT_SYNX) { - start = 0; - end = fc->output_index; - } else if (type == CVP_OUTPUT_SYNX) { - start = fc->output_index; - end = fc->num_fences; - } else { - dprintk(CVP_ERR, "%s Incorrect synx type\n", __func__); - return -EINVAL; - } - - for (i = start; i < end; ++i) { - h_synx = fc->synx[i]; - if (h_synx) { - rc = synx_signal(ssid, h_synx, synx_state); - dprintk(CVP_SYNX, "Cancel synx %d session %llx\n", - h_synx, inst); - if (rc) - dprintk(CVP_ERR, - "%s: synx_signal %d %d %d failed\n", - __func__, h_synx, i, synx_state); - } - } - - return rc; - - -} - -static int cvp_cancel_synx_v1(struct msm_cvp_inst *inst, enum cvp_synx_type type, - struct cvp_fence_command *fc, int synx_state) -{ - if (fc->signature != 0xFEEDFACE) { - dprintk(CVP_ERR, "%s deprecated synx path\n", __func__); - return -EINVAL; - } - - return cvp_cancel_synx_impl(inst, type, fc, synx_state); -} - -static int cvp_wait_synx(struct synx_session ssid, u32 *synx, u32 num_synx, - u32 *synx_state) -{ - int i = 0, rc = 0; - unsigned long timeout_ms = 2000; - int h_synx; - - while (i < num_synx) { - h_synx = synx[i]; - if (h_synx) { - rc = synx_wait(ssid, h_synx, timeout_ms); - if (rc) { - *synx_state = synx_get_status(ssid, h_synx); - if (*synx_state == SYNX_STATE_SIGNALED_CANCEL) { - dprintk(CVP_SYNX, - "%s: synx_wait %d cancel %d state %d\n", - current->comm, i, rc, *synx_state); - } else { - dprintk(CVP_ERR, - "%s: synx_wait %d failed %d state %d\n", - current->comm, i, rc, *synx_state); - *synx_state = SYNX_STATE_SIGNALED_ERROR; - } - return rc; - } - dprintk(CVP_SYNX, "Wait synx %d returned succes\n", - h_synx); - } - ++i; - } - return rc; -} - -static int cvp_signal_synx(struct synx_session ssid, u32 *synx, u32 num_synx, - u32 synx_state) -{ - int i = 0, rc = 0; - int h_synx; - - while (i < num_synx) { - h_synx = synx[i]; - if (h_synx) { - rc = synx_signal(ssid, h_synx, synx_state); - if (rc) { - dprintk(CVP_ERR, - "%s: synx_signal %d %d failed\n", - current->comm, h_synx, i); - synx_state = SYNX_STATE_SIGNALED_ERROR; - } - dprintk(CVP_SYNX, "Signaled synx %d\n", h_synx); - } - ++i; - } - return rc; -} - -static int cvp_synx_ops_v1(struct msm_cvp_inst *inst, enum cvp_synx_type type, - struct cvp_fence_command *fc, u32 *synx_state) -{ - struct synx_session ssid; - - ssid = inst->synx_session_id; - - if (fc->signature != 0xFEEDFACE) { - dprintk(CVP_ERR, "%s deprecated synx, type %d\n", __func__); - return -EINVAL; - } - - if (type == CVP_INPUT_SYNX) { - return cvp_wait_synx(ssid, fc->synx, fc->output_index, - synx_state); - } else if (type == CVP_OUTPUT_SYNX) { - return cvp_signal_synx(ssid, &fc->synx[fc->output_index], - (fc->num_fences - fc->output_index), - *synx_state); - } else { - dprintk(CVP_ERR, "%s Incorrect SYNX type\n", __func__); - return -EINVAL; - } -} - -static struct msm_cvp_synx_ops cvp_synx = { - .cvp_sess_init_synx = cvp_sess_init_synx_v1, - .cvp_sess_deinit_synx = cvp_sess_deinit_synx_v1, - .cvp_release_synx = cvp_release_synx_v1, - .cvp_import_synx = cvp_import_synx_v1, - .cvp_synx_ops = cvp_synx_ops_v1, - .cvp_cancel_synx = cvp_cancel_synx_v1, - .cvp_dump_fence_queue = cvp_dump_fence_queue_v1, -}; - -#endif /* End of CVP_CONFIG_SYNX_V2 */ #else static int cvp_sess_init_synx_stub(struct msm_cvp_inst *inst) { From 267b6bd153503803f8649ab915525b1386dc560a Mon Sep 17 00:00:00 2001 From: Jingyu Su Date: Tue, 2 May 2023 00:44:44 -0700 Subject: [PATCH 206/317] msm: eva: Fix Kw p1 issue Validate s->next is not NULL before dereferencing Change-Id: I8112eb20aab939b917243e283583ab9d0884e3e8 Signed-off-by: Jingyu Su --- msm/eva/msm_cvp_dsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 32a27db026..a30ab9f9a7 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -602,7 +602,7 @@ static void cvp_remove_dsp_sessions(void) while ((frpc_node = pop_frpc_node())) { s = &frpc_node->dsp_sessions.list; - if (!s) + if (!s || !(s->next)) return; list_for_each_safe(s, next_s, &frpc_node->dsp_sessions.list) { From 55c9e97cabd66815ac7e84720035ca5c7608b942 Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 5 May 2023 12:10:07 -0700 Subject: [PATCH 207/317] msm: eva: Enhance DSP debugging Validate session pointer passed in by DSP driver and save the most recently un-mapped DSP buffers for SMMU fault debugging. Change-Id: I1beebcce190874e3129fc1bd3806ffee61eb6d4d Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 18 +++++++++++++++--- msm/eva/msm_cvp_dsp.c | 39 +++++++++++++++++++++++++++++--------- msm/eva/msm_cvp_internal.h | 1 + 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index e916a71621..14d805773b 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -329,6 +329,7 @@ int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) goto exit; } + atomic_inc(&smem->refcount); cbuf->smem = smem; cbuf->fd = buf->fd; cbuf->size = buf->size; @@ -383,18 +384,25 @@ int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) break; } } - mutex_unlock(&inst->cvpdspbufs.lock); if (!found) { + mutex_unlock(&inst->cvpdspbufs.lock); print_client_buffer(CVP_ERR, "invalid", inst, buf); return -EINVAL; } if (cbuf->smem->device_addr) { + u64 idx = inst->unused_dsp_bufs.ktid; + inst->unused_dsp_bufs.smem[idx] = *(cbuf->smem); + inst->unused_dsp_bufs.nr++; + inst->unused_dsp_bufs.nr = + (inst->unused_dsp_bufs.nr > MAX_FRAME_BUFFER_NUMS)? + MAX_FRAME_BUFFER_NUMS : inst->unused_dsp_bufs.nr; + inst->unused_dsp_bufs.ktid = ++idx % MAX_FRAME_BUFFER_NUMS; + msm_cvp_unmap_smem(inst, cbuf->smem, "unmap dsp"); msm_cvp_smem_put_dma_buf(cbuf->smem->dma_buf); + atomic_dec(&cbuf->smem->refcount); } - - mutex_lock(&inst->cvpdspbufs.lock); list_del(&cbuf->list); mutex_unlock(&inst->cvpdspbufs.lock); @@ -1957,6 +1965,10 @@ void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) for (i = 0; i < inst->unused_wncc_bufs.nr; i++) _log_smem(snap, inst, &inst->unused_wncc_bufs.smem[i], log); + dprintk(CVP_ERR, "unmapped dsp bufs\n"); + for (i = 0; i < inst->unused_dsp_bufs.nr; i++) + _log_smem(snap, inst, &inst->unused_dsp_bufs.smem[i], log); + } struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index a30ab9f9a7..7965147e76 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1430,8 +1430,10 @@ exit: mutex_unlock(&device->lock); } /* 32 or 64 bit CPU Side Ptr <-> 2 32 bit DSP Pointers. Dirty Fix. */ -static void *ptr_dsp2cpu(uint32_t session_cpu_high, uint32_t session_cpu_low) +static void *get_inst_from_dsp(uint32_t session_cpu_high, uint32_t session_cpu_low) { + struct msm_cvp_core *core; + struct msm_cvp_inst *sess_inst; void *inst; if ((session_cpu_high == 0) && (sizeof(void *) == BITPTRSIZE32)) { @@ -1444,7 +1446,26 @@ static void *ptr_dsp2cpu(uint32_t session_cpu_high, uint32_t session_cpu_low) "%s Invalid _cpu_high = 0x%x _cpu_low = 0x%x\n", __func__, session_cpu_high, session_cpu_low); inst = NULL; + return inst; } + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (core) { + mutex_lock(&core->lock); + list_for_each_entry(sess_inst, &core->instances, list) { + if (sess_inst->session_type == MSM_CVP_DSP) { + if (sess_inst == (struct msm_cvp_inst *)inst) { + mutex_unlock(&core->lock); + return inst; + } + } + } + mutex_unlock(&core->lock); + inst = NULL; + } else { + return NULL; + } + return inst; } @@ -1602,7 +1623,7 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) } cvp_put_fastrpc_node(frpc_node); - inst = (struct msm_cvp_inst *)ptr_dsp2cpu( + inst = (struct msm_cvp_inst *)get_inst_from_dsp( dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->session_cpu_low); if (!inst || !is_cvp_inst_valid(inst)) { @@ -1658,7 +1679,7 @@ static void __dsp_cvp_power_req(struct cvp_dsp_cmd_msg *cmd) dsp2cpu_cmd->session_cpu_low, dsp2cpu_cmd->session_cpu_high); - inst = (struct msm_cvp_inst *)ptr_dsp2cpu( + inst = (struct msm_cvp_inst *)get_inst_from_dsp( dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->session_cpu_low); @@ -1725,7 +1746,7 @@ static void __dsp_cvp_buf_register(struct cvp_dsp_cmd_msg *cmd) return; } - inst = (struct msm_cvp_inst *)ptr_dsp2cpu( + inst = (struct msm_cvp_inst *)get_inst_from_dsp( dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->session_cpu_low); @@ -1783,7 +1804,7 @@ static void __dsp_cvp_buf_deregister(struct cvp_dsp_cmd_msg *cmd) return; } - inst = (struct msm_cvp_inst *)ptr_dsp2cpu( + inst = (struct msm_cvp_inst *)get_inst_from_dsp( dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->session_cpu_low); @@ -1840,7 +1861,7 @@ static void __dsp_cvp_mem_alloc(struct cvp_dsp_cmd_msg *cmd) } frpc_device = frpc_node->cvp_fastrpc_device; - inst = (struct msm_cvp_inst *)ptr_dsp2cpu( + inst = (struct msm_cvp_inst *)get_inst_from_dsp( dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->session_cpu_low); @@ -1916,7 +1937,7 @@ static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->pid); - inst = (struct msm_cvp_inst *)ptr_dsp2cpu( + inst = (struct msm_cvp_inst *)get_inst_from_dsp( dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->session_cpu_low); if (!inst) { @@ -1999,7 +2020,7 @@ static void __dsp_cvp_sess_start(struct cvp_dsp_cmd_msg *cmd) dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->pid); - inst = (struct msm_cvp_inst *)ptr_dsp2cpu( + inst = (struct msm_cvp_inst *)get_inst_from_dsp( dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->session_cpu_low); @@ -2028,7 +2049,7 @@ static void __dsp_cvp_sess_stop(struct cvp_dsp_cmd_msg *cmd) dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->pid); - inst = (struct msm_cvp_inst *)ptr_dsp2cpu( + inst = (struct msm_cvp_inst *)get_inst_from_dsp( dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->session_cpu_low); diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index a684846eb9..7d26a14ae2 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -385,6 +385,7 @@ struct msm_cvp_inst { struct msm_cvp_list cvpwnccbufs; struct msm_cvp_list frames; struct cvp_frame_bufs last_frame; + struct cvp_frame_bufs unused_dsp_bufs; struct cvp_frame_bufs unused_wncc_bufs; u32 cvpwnccbufs_num; struct msm_cvp_wncc_buffer* cvpwnccbufs_table; From efdc66a2828775e46dbc01f15b945a8604cdbc6c Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 9 May 2023 10:49:06 -0700 Subject: [PATCH 208/317] msm: eva: Init fence queue before its use Fence queue could be used during SSR, which may happen right after session is created. Relocate fence queue init to the point before session creation becomes visible to SSR handling. Change-Id: Ie21537383b44bbdf40d87af434df0e55a677a85d Signed-off-by: George Shen --- msm/eva/msm_cvp_core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index ef549ecd58..3dfcef5dd4 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -219,6 +219,7 @@ void *msm_cvp_open(int core_id, int session_type, struct task_struct *task) msm_cvp_session_init(inst); + __init_fence_queue(inst); mutex_lock(&core->lock); mutex_lock(&core->clk_lock); list_add_tail(&inst->list, &core->instances); @@ -226,8 +227,6 @@ void *msm_cvp_open(int core_id, int session_type, struct task_struct *task) mutex_unlock(&core->clk_lock); mutex_unlock(&core->lock); - __init_fence_queue(inst); - rc = __init_session_queue(inst); if (rc) goto fail_init; From 36fa77e4d759e77f5bff5bd22b24851c9ac03076 Mon Sep 17 00:00:00 2001 From: Naveen Ravi Date: Tue, 2 May 2023 09:33:09 -0700 Subject: [PATCH 209/317] msm: eva: add Bazel Build Support for EVA KMD Change-Id: I93af2eb7c5cc2cf0ee4bff5b6d838c18d886d21a --- BUILD.bazel | 38 +++++++++++++ eva_module_build.bzl | 129 +++++++++++++++++++++++++++++++++++++++++++ eva_modules.bzl | 45 +++++++++++++++ pineapple.bzl | 17 ++++++ 4 files changed, 229 insertions(+) create mode 100644 BUILD.bazel create mode 100644 eva_module_build.bzl create mode 100644 eva_modules.bzl create mode 100644 pineapple.bzl diff --git a/BUILD.bazel b/BUILD.bazel new file mode 100644 index 0000000000..29bceb2efd --- /dev/null +++ b/BUILD.bazel @@ -0,0 +1,38 @@ +load("//build/kernel/kleaf:kernel.bzl", "ddk_headers") + +package( + default_visibility = [ + "//visibility:public"], +) + +ddk_headers( + name = "eva_drivers_configs", + hdrs = [ + "config/waipioevaconf.h" + ], + includes = ["config"] +) +ddk_headers( + name = "uapi_headers", + hdrs = glob([ + "include/uapi/eva/media/*.h", + ]), + includes = ["include/uapi/eva"] +) +ddk_headers( + name = "msm_headers", + hdrs = glob([ + "msm/eva/*.h", + "msm/eva/vm/*.h", + ]), + includes = ["msm","msm/eva"] +) + +ddk_headers( + name = "eva_drivers_headers", + hdrs = [":eva_drivers_configs", ":uapi_headers", ":msm_headers"] +) + + +load(":pineapple.bzl", "define_pineapple") +define_pineapple() diff --git a/eva_module_build.bzl b/eva_module_build.bzl new file mode 100644 index 0000000000..73410a8fa3 --- /dev/null +++ b/eva_module_build.bzl @@ -0,0 +1,129 @@ +load( + "//build/kernel/kleaf:kernel.bzl", + "ddk_module", + "ddk_submodule", + "kernel_module", + "kernel_modules_install", +) +load("//build/bazel_common_rules/dist:dist.bzl", "copy_to_dist_dir") + +def _register_module_to_map(module_map, name, path, config_option, srcs, config_srcs, deps, config_deps): + processed_config_srcs = {} + processed_config_deps = {} + + for config_src_name in config_srcs: + config_src = config_srcs[config_src_name] + + if type(config_src) == "list": + processed_config_srcs[config_src_name] = {True: config_src} + else: + processed_config_srcs[config_src_name] = config_src + + for config_deps_name in config_deps: + config_dep = config_deps[config_deps_name] + + if type(config_dep) == "list": + processed_config_deps[config_deps_name] = {True: config_dep} + else: + processed_config_deps[config_deps_name] = config_dep + + module = struct( + name = name, + path = path, + srcs = srcs, + config_srcs = processed_config_srcs, + config_option = config_option, + deps = deps, + config_deps = processed_config_deps, + ) + + module_map[name] = module + +def _get_config_choices(map, options): + choices = [] + + for option in map: + choices.extend(map[option].get(option in options, [])) + + return choices + +def _get_kernel_build_options(modules, config_options): + all_options = {option: True for option in config_options} + all_options = all_options | {module.config_option: True for module in modules if module.config_option} + + return all_options + +def _get_kernel_build_module_srcs(module, options, formatter): + srcs = module.srcs + _get_config_choices(module.config_srcs, options) + module_path = "{}/".format(module.path) if module.path else "" + globbed_srcs = native.glob(["{}{}".format(module_path, formatter(src)) for src in srcs]) + + return globbed_srcs + +def _get_kernel_build_module_deps(module, options, formatter): + deps = module.deps + _get_config_choices(module.config_deps, options) + deps = [formatter(dep) for dep in deps] + + return deps + +def create_module_registry(hdrs = []): + module_map = {} + + def register(name, path = None, config_option = None, srcs = [], config_srcs = {}, deps = [], config_deps = {}): + _register_module_to_map(module_map, name, path, config_option, srcs, config_srcs, deps, config_deps) + + return struct( + register = register, + get = module_map.get, + hdrs = hdrs, + module_map = module_map, + ) + +def define_target_variant_modules(target, variant, registry, modules, config_options = []): + kernel_build = "{}_{}".format(target, variant) + kernel_build_label = "//msm-kernel:{}".format(kernel_build) + modules = [registry.get(module_name) for module_name in modules] + options = _get_kernel_build_options(modules, config_options) + build_print = lambda message: print("{}: {}".format(kernel_build, message)) + formatter = lambda s: s.replace("%b", kernel_build).replace("%t", target) + + headers = ["//msm-kernel:all_headers"] + registry.hdrs + all_module_rules = [] + + for module in modules: + rule_name = "{}_{}".format(kernel_build, module.name) + module_srcs = _get_kernel_build_module_srcs(module, options, formatter) + + if not module_srcs: + continue + + ddk_submodule( + name = rule_name, + srcs = module_srcs, + out = "{}.ko".format(module.name), + deps = headers + _get_kernel_build_module_deps(module, options, formatter), + local_defines = options.keys(), + ) + + all_module_rules.append(rule_name) + + ddk_module( + name = "{}_modules".format(kernel_build), + kernel_build = kernel_build_label, + deps = all_module_rules, + ) + + copy_to_dist_dir( + name = "{}_modules_dist".format(kernel_build), + data = [":{}_modules".format(kernel_build)], + dist_dir = "out/target/product/{}/dlkm/lib/modules/".format(kernel_build), + flat = True, + wipe_dist_dir = False, + allow_duplicate_filenames = False, + mode_overrides = {"**/*": "644"}, + ) + + +def define_consolidate_gki_modules(target, registry, modules, config_options = []): + define_target_variant_modules(target, "consolidate", registry, modules, config_options) + define_target_variant_modules(target, "gki", registry, modules, config_options) diff --git a/eva_modules.bzl b/eva_modules.bzl new file mode 100644 index 0000000000..75a0cf20c6 --- /dev/null +++ b/eva_modules.bzl @@ -0,0 +1,45 @@ +load(":eva_module_build.bzl", "create_module_registry") + +EVA_KERNEL_ROOT = "eva-kernel" + +eva_modules = create_module_registry([":eva_drivers_headers"]) +register_eva_module = eva_modules.register + +register_eva_module( + name = "msm-eva", + path = "msm", + srcs = [ + "eva/cvp.c", + "eva/cvp_core_hfi.c", + "eva/cvp_dump.c", + "eva/cvp_fw_load.c", + "eva/cvp_hfi.c", + "eva/cvp_power.c", + "eva/cvp_smem.c", + "eva/hfi_packetization.c", + "eva/hfi_response_handler.c", + "eva/msm_cvp.c", + "eva/msm_cvp_buf.c", + "eva/msm_cvp_clocks.c", + "eva/msm_cvp_common.c", + "eva/msm_cvp_core.c", + "eva/msm_cvp_debug.c", + "eva/msm_cvp_dsp.c", + "eva/msm_cvp_ioctl.c", + "eva/msm_cvp_platform.c", + "eva/msm_cvp_res_parse.c", + "eva/msm_cvp_synx.c", + "eva/vm/cvp_vm_main.c", + "eva/vm/cvp_vm_msgq.c", + "eva/vm/cvp_vm_resource.c", + ], + config_deps = { + "TARGET_SYNX_ENABLE": [ + "//vendor/qcom/opensource/synx-kernel:synx_headers", + "//vendor/qcom/opensource/synx-kernel:%b_modules" + ], + "TARGET_DSP_ENABLE": [ + "//vendor/qcom/opensource/dsp-kernel:%b_frpc-adsprpc" + ], + }, +) diff --git a/pineapple.bzl b/pineapple.bzl new file mode 100644 index 0000000000..e6ad2cf204 --- /dev/null +++ b/pineapple.bzl @@ -0,0 +1,17 @@ +load(":eva_modules.bzl", "eva_modules") +load(":eva_module_build.bzl", "define_consolidate_gki_modules") + +def define_pineapple(): + define_consolidate_gki_modules( + target = "pineapple", + registry = eva_modules, + modules = [ + "msm-eva", + ], + config_options = [ + #"CONFIG_TARGET_SYNX_ENABLE", + "TARGET_SYNX_ENABLE", + "TARGET_DSP_ENABLE", + "CONFIG_EVA_PINEAPPLE" + ], + ) From 115a7bf5c7bf5a878f4f9f000af4c198b035e0d8 Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 12 May 2023 20:17:31 -0700 Subject: [PATCH 210/317] msm: eva: Enhance power and perf logging Use CVP_PWR instead of CVP_PROF. Add AON timer reading. Avoid SSR if core init failed. Change-Id: I1dd40edc893009a2f2794e3431bb08398ec6352b Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 12 ++++++++++-- msm/eva/cvp_power.c | 37 +++++++++++++++++++------------------ msm/eva/msm_cvp_common.c | 6 +++--- msm/eva/msm_cvp_common.h | 1 + msm/eva/msm_cvp_core.c | 6 +++--- 5 files changed, 36 insertions(+), 26 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 0e4c376cd3..4823bfd58b 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -162,6 +162,15 @@ static int cvp_synx_recover(void) #define ROW_SIZE 32 +unsigned long long get_aon_time(void) +{ + unsigned long long val; + + asm volatile("mrs %0, cntvct_el0" : "=r" (val)); + + return val; +} + int get_hfi_version(void) { struct msm_cvp_core *core; @@ -3561,7 +3570,7 @@ static DECLARE_WORK(iris_hfi_wd_work, iris_hfi_wd_work_handler); irqreturn_t iris_hfi_isr_wd(int irq, void *dev) { struct iris_hfi_device *device = dev; - dprintk(CVP_ERR, "Got HW WDOG IRQ! \n"); + dprintk(CVP_ERR, "Got HW WDOG IRQ at %llu! \n", get_aon_time()); disable_irq_nosync(irq); queue_work(device->cvp_workq, &iris_hfi_wd_work); return IRQ_HANDLED; @@ -4910,7 +4919,6 @@ static inline int __resume(struct iris_hfi_device *device) rc = __boot_firmware(device); if (rc) { dprintk(CVP_ERR, "Failed to reset cvp core\n"); - msm_cvp_trigger_ssr(core, SSR_ERR_FATAL); goto err_reset_core; } diff --git a/msm/eva/cvp_power.c b/msm/eva/cvp_power.c index 7e39db27d2..626d3b6752 100644 --- a/msm/eva/cvp_power.c +++ b/msm/eva/cvp_power.c @@ -31,6 +31,9 @@ static bool is_subblock_profile_existed(struct msm_cvp_inst *inst) inst->prop.cycles[HFI_HW_LSR]); } +static char hw_names[HFI_MAX_HW_THREADS][8] = {{"FDU"}, {"OD"}, {"MPU"}, {"ICA"}, + {"VADL"}, {"TOF"}, {"RGE"}, {"XRA"}, + {"LSR"}}; static void aggregate_power_update(struct msm_cvp_core *core, struct cvp_power_level *nrt_pwr, struct cvp_power_level *rt_pwr, @@ -57,17 +60,18 @@ static void aggregate_power_update(struct msm_cvp_core *core, } else { i = 1; } - dprintk(CVP_PROF, "pwrUpdate fdu od mpu ica vadl tof rge xra lsr\n"); for (j = 0; j < HFI_MAX_HW_THREADS; j++) - dprintk(CVP_PROF, "%u ", inst->prop.cycles[j]); - dprintk(CVP_PROF, "\n"); + if (inst->prop.cycles[j]) + dprintk(CVP_PWR, "pwrUpdate %s %u\n", + hw_names[j], inst->prop.cycles[j]); - dprintk(CVP_PROF, "pwrUpdate fdu_o od_o ica_o mpu_o vadl_o tof_o rge_o xra_o lsr_o\n"); for (j = 0; j < HFI_MAX_HW_THREADS; j++) - dprintk(CVP_PROF, "%u ", inst->prop.op_cycles[j]); - dprintk(CVP_PROF, "\n"); + if (inst->prop.op_cycles[j]) + dprintk(CVP_PWR, "pwrUpdate_OP %s %u\n", + hw_names[j], inst->prop.op_cycles[j]); - dprintk(CVP_PROF, " fw %u fw_o %u\n", inst->prop.fw_cycles, inst->prop.fw_op_cycles); + dprintk(CVP_PWR, " fw %u fw_o %u\n", inst->prop.fw_cycles, + inst->prop.fw_op_cycles); for (j = 0; j < HFI_MAX_HW_THREADS; j++) blocks_sum[i][j] += inst->prop.cycles[j]; @@ -89,20 +93,17 @@ static void aggregate_power_update(struct msm_cvp_core *core, (op_bw_max[i] >= inst->prop.ddr_op_bw) ? op_bw_max[i] : inst->prop.ddr_op_bw; - dprintk(CVP_PWR, "%s:%d - fps fdu mpu od ica vadl tof rge xra lsf\n", - __func__, __LINE__); - for (j = 0; j < HFI_MAX_HW_THREADS; j++) { - dprintk(CVP_PWR, " %d ", inst->prop.fps[j]); + if (inst->prop.fps[j]) + dprintk(CVP_PWR, "fps %s %d ", hw_names[j], + inst->prop.fps[j]); core->dyn_clk.sum_fps[j] += inst->prop.fps[j]; } - dprintk(CVP_PWR, "\n"); - dprintk(CVP_PWR, "%s:%d - sum_fps fdu mpu od ica vadl tof rge xra lsf\n", - __func__, __LINE__); for (j = 0; j < HFI_MAX_HW_THREADS; j++) - dprintk(CVP_PWR, " %d ", core->dyn_clk.sum_fps[j]); - dprintk(CVP_PWR, "\n"); + if (core->dyn_clk.sum_fps[j]) + dprintk(CVP_PWR, "sum_fps %s %d ", hw_names[j], + core->dyn_clk.sum_fps[j]); } for (i = 0; i < 2; i++) { @@ -168,7 +169,7 @@ static int adjust_bw_freqs(void) min_bw = max_bw/10; aggregate_power_update(core, &nrt_pwr, &rt_pwr, cvp_max_rate); - dprintk(CVP_PROF, "PwrUpdate nrt %u %u rt %u %u\n", + dprintk(CVP_PWR, "PwrUpdate nrt %u %u rt %u %u\n", nrt_pwr.core_sum, nrt_pwr.op_core_sum, rt_pwr.core_sum, rt_pwr.op_core_sum); @@ -201,7 +202,7 @@ static int adjust_bw_freqs(void) bw_sum = (bw_sum > max_bw) ? max_bw : bw_sum; bw_sum = (bw_sum < min_bw) ? min_bw : bw_sum; - dprintk(CVP_PROF, "%s %lld %lld\n", __func__, + dprintk(CVP_PWR, "%s %lld %lld\n", __func__, core_sum, bw_sum); if (!cl->has_scaling) { dprintk(CVP_ERR, "Cannot scale CVP clock\n"); diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 19f7825fc5..31d4a73c19 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -625,7 +625,7 @@ void handle_sys_error(enum hal_command_response cmd, void *data) if (!core->trigger_ssr) { cvp_print_inst(CVP_WARN, inst); if (hfi_device->error != CVP_ERR_NOC_ERROR) - msm_cvp_print_inst_bufs(inst, false); + msm_cvp_print_inst_bufs(inst, false); } } @@ -1298,8 +1298,8 @@ void msm_cvp_ssr_handler(struct work_struct *work) send_again: mutex_lock(&core->lock); if (core->state == CVP_CORE_INIT_DONE) { - dprintk(CVP_WARN, "%s: ssr type %d\n", __func__, - core->ssr_type); + dprintk(CVP_WARN, "%s: ssr type %d at %llu\n", __func__, + core->ssr_type, get_aon_time()); /* * In current implementation user-initiated SSR triggers * a fatal error from hardware. However, there is no way diff --git a/msm/eva/msm_cvp_common.h b/msm/eva/msm_cvp_common.h index 4d66055d98..b9dc2e06f2 100644 --- a/msm/eva/msm_cvp_common.h +++ b/msm/eva/msm_cvp_common.h @@ -33,4 +33,5 @@ int cvp_comm_set_arp_buffers(struct msm_cvp_inst *inst); int cvp_comm_release_persist_buffers(struct msm_cvp_inst *inst); int msm_cvp_noc_error_info(struct msm_cvp_core *core); int cvp_print_inst(u32 tag, struct msm_cvp_inst *inst); +unsigned long long get_aon_time(void); #endif diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 3dfcef5dd4..814aca34f5 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -325,9 +325,9 @@ wait_dsp: mutex_unlock(&inst->cvpdspbufs.lock); if (!empty) - dprintk(CVP_WARN, "Failed flush DSP frame retried %d\n", - (inst->core->resources.msm_cvp_hw_rsp_timeout >> 5) - - max_retries); + dprintk(CVP_WARN, "Failed sess %pK DSP frame retried %d\n", + inst, + (inst->core->resources.msm_cvp_hw_rsp_timeout >> 5)); max_retries = inst->core->resources.msm_cvp_hw_rsp_timeout >> 1; wait_frame: mutex_lock(&inst->frames.lock); From 4e37a3a40b586dc9d1917554d042dbf10e726adb Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 8 May 2023 12:04:47 -0700 Subject: [PATCH 211/317] msm: eva: Adopt Fastrpc Feature Request To support multi-PDs per user process. Fastrpc handle is no longer PID. Add change to support the FR. Change-Id: I39d7043f048597f1e4e728c48d588f12bb740b56 Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 2 +- msm/eva/msm_cvp_core.c | 2 +- msm/eva/msm_cvp_dsp.c | 106 ++++++++++++++++++++++++------------- msm/eva/msm_cvp_dsp.h | 7 +-- msm/eva/msm_cvp_internal.h | 2 +- 5 files changed, 75 insertions(+), 44 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 14d805773b..22efd8ad15 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1853,7 +1853,7 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) msm_cvp_unmap_smem(inst, cbuf->smem, "unmap dsp"); msm_cvp_smem_put_dma_buf(cbuf->smem->dma_buf); } else if (cbuf->ownership == DSP) { - rc = cvp_dsp_fastrpc_unmap(inst->process_id, cbuf); + rc = cvp_dsp_fastrpc_unmap(inst->dsp_handle, cbuf); if (rc) dprintk(CVP_ERR, "%s: failed to unmap buf from DSP\n", diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 814aca34f5..e9825c4bed 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -466,7 +466,7 @@ int msm_cvp_close(void *instance) msm_cvp_comm_session_clean(inst); if (inst->session_type == MSM_CVP_DSP) - cvp_dsp_del_sess(inst->process_id, inst); + cvp_dsp_del_sess(inst->dsp_handle, inst); kref_put(&inst->kref, close_helper); return 0; diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 7965147e76..6d928b2089 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1019,7 +1019,6 @@ static int cvp_fastrpc_probe(struct fastrpc_device *rpc_dev) frpc_node = cvp_get_fastrpc_node_with_handle(rpc_dev->handle); if (frpc_node) { frpc_node->cvp_fastrpc_device = rpc_dev; - // static structure with signal and pid complete(&frpc_node->fastrpc_probe_completion); cvp_put_fastrpc_node(frpc_node); } @@ -1117,6 +1116,27 @@ static int eva_fastrpc_dev_unmap_dma(struct fastrpc_device *frpc_device, #endif /* End of CVP_FASTRPC_ENABLED */ } +static int eva_fastrpc_dev_get_pid(struct fastrpc_device *frpc_device, int *pid) +{ +#ifdef CVP_FASTRPC_ENABLED + struct fastrpc_dev_get_hlos_pid get_pid = {0}; + int rc = 0; + + rc = __fastrpc_driver_invoke(frpc_device, FASTRPC_DEV_GET_HLOS_PID, + (unsigned long)(&get_pid)); + if (rc) { + dprintk(CVP_ERR, "%s Failed to get PID %x\n", + __func__, rc); + return rc; + } + *pid = get_pid.hlos_pid; + + return rc; +#else + return -ENODEV; +#endif /* End of CVP_FASTRPC_ENABLED */ +} + static void eva_fastrpc_driver_add_sess( struct cvp_dsp_fastrpc_driver_entry *frpc, struct msm_cvp_inst *inst) @@ -1131,16 +1151,16 @@ static void eva_fastrpc_driver_add_sess( dprintk(CVP_DSP, "add dsp sess %pK fastrpc_driver %pK\n", inst, frpc); } -int cvp_dsp_fastrpc_unmap(uint32_t process_id, struct cvp_internal_buf *buf) +int cvp_dsp_fastrpc_unmap(uint32_t handle, struct cvp_internal_buf *buf) { struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; struct fastrpc_device *frpc_device = NULL; int rc = 0; - frpc_node = cvp_get_fastrpc_node_with_handle(process_id); + frpc_node = cvp_get_fastrpc_node_with_handle(handle); if (!frpc_node) { - dprintk(CVP_ERR, "%s no frpc node for process id %d\n", - __func__, process_id); + dprintk(CVP_ERR, "%s no frpc node for dsp handle %d\n", + __func__, handle); return -EINVAL; } frpc_device = frpc_node->cvp_fastrpc_device; @@ -1153,17 +1173,17 @@ int cvp_dsp_fastrpc_unmap(uint32_t process_id, struct cvp_internal_buf *buf) return rc; } -int cvp_dsp_del_sess(uint32_t process_id, struct msm_cvp_inst *inst) +int cvp_dsp_del_sess(uint32_t handle, struct msm_cvp_inst *inst) { struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; struct list_head *ptr = NULL, *next = NULL; struct msm_cvp_inst *sess; bool found = false; - frpc_node = cvp_get_fastrpc_node_with_handle(process_id); + frpc_node = cvp_get_fastrpc_node_with_handle(handle); if (!frpc_node) { - dprintk(CVP_ERR, "%s no frpc node for process id %d\n", - __func__, process_id); + dprintk(CVP_ERR, "%s no frpc node for dsp handle %d\n", + __func__, handle); return -EINVAL; } mutex_lock(&frpc_node->dsp_sessions.lock); @@ -1194,12 +1214,12 @@ static int eva_fastrpc_driver_register(uint32_t handle) struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; bool skip_deregister = true; - dprintk(CVP_DSP, "%s -> cvp_get_fastrpc_node_with_handle pid 0x%x\n", + dprintk(CVP_DSP, "%s -> cvp_get_fastrpc_node_with_handle hdl 0x%x\n", __func__, handle); frpc_node = cvp_get_fastrpc_node_with_handle(handle); if (frpc_node == NULL) { - dprintk(CVP_DSP, "%s new fastrpc node pid 0x%x\n", + dprintk(CVP_DSP, "%s new fastrpc node hdl 0x%x\n", __func__, handle); frpc_node = kzalloc(sizeof(*frpc_node), GFP_KERNEL); if (!frpc_node) { @@ -1251,7 +1271,7 @@ static int eva_fastrpc_driver_register(uint32_t handle) goto fail_fastrpc_driver_register; } } else { - dprintk(CVP_DSP, "%s fastrpc probe hndl %pK pid 0x%x\n", + dprintk(CVP_DSP, "%s fastrpc probe frpc_node %pK hdl 0x%x\n", __func__, frpc_node, handle); cvp_put_fastrpc_node(frpc_node); } @@ -1277,7 +1297,7 @@ static void eva_fastrpc_driver_unregister(uint32_t handle, bool force_exit) struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; - dprintk(CVP_DSP, "%s Unregister fastrpc driver hdl %#x pid %#x, f %d\n", + dprintk(CVP_DSP, "%s Unregister fastrpc driver hdl %#x hdl %#x, f %d\n", __func__, handle, dsp2cpu_cmd->pid, (uint32_t)force_exit); if (handle != dsp2cpu_cmd->pid) @@ -1492,45 +1512,57 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) struct cvp_dsp_apps *me = &gfa_cv; struct msm_cvp_inst *inst = NULL; uint64_t inst_handle = 0; + uint32_t pid; int rc = 0; struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; struct pid *pid_s = NULL; struct task_struct *task = NULL; struct cvp_hfi_device *hdev; + struct fastrpc_device *frpc_device; cmd->ret = 0; dprintk(CVP_DSP, - "%s sess Type %d Mask %d Prio %d Sec %d pid 0x%x\n", + "%s sess Type %d Mask %d Prio %d Sec %d hdl 0x%x\n", __func__, dsp2cpu_cmd->session_type, dsp2cpu_cmd->kernel_mask, dsp2cpu_cmd->session_prio, dsp2cpu_cmd->is_secure, dsp2cpu_cmd->pid); - pid_s = find_get_pid(dsp2cpu_cmd->pid); - if (pid_s == NULL) { - dprintk(CVP_WARN, "%s incorrect pid\n", __func__); + rc = eva_fastrpc_driver_register(dsp2cpu_cmd->pid); + if (rc) { + dprintk(CVP_ERR, "%s Register fastrpc driver fail\n", __func__); cmd->ret = -1; return; } - dprintk(CVP_DSP, "%s get pid_s 0x%x from pidA 0x%x\n", __func__, + frpc_node = cvp_get_fastrpc_node_with_handle(dsp2cpu_cmd->pid); + if (!frpc_node || !frpc_node->cvp_fastrpc_device) { + dprintk(CVP_WARN, "%s cannot get fastrpc node from %x\n", + __func__, dsp2cpu_cmd->pid); + goto fail_lookup; + } + frpc_device = frpc_node->cvp_fastrpc_device; + + rc = eva_fastrpc_dev_get_pid(frpc_device, &pid); + if (rc) { + dprintk(CVP_ERR, + "%s Failed to map buffer 0x%x\n", __func__, rc); + goto fail_lookup; + } + pid_s = find_get_pid(pid); + if (pid_s == NULL) { + dprintk(CVP_WARN, "%s incorrect pid %x\n", __func__, pid); + goto fail_lookup; + } + dprintk(CVP_DSP, "%s get pid_s 0x%x from hdl 0x%x\n", __func__, pid_s, dsp2cpu_cmd->pid); task = get_pid_task(pid_s, PIDTYPE_TGID); if (!task) { dprintk(CVP_WARN, "%s task doesn't exist\n", __func__); - cmd->ret = -1; - return; - } - - rc = eva_fastrpc_driver_register(dsp2cpu_cmd->pid); - if (rc) { - dprintk(CVP_ERR, "%s Register fastrpc driver fail\n", __func__); - put_task_struct(task); - cmd->ret = -1; - return; + goto fail_lookup; } inst = msm_cvp_open(MSM_CORE_CVP, MSM_CVP_DSP, task); @@ -1539,7 +1571,7 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) goto fail_msm_cvp_open; } - inst->process_id = dsp2cpu_cmd->pid; + inst->dsp_handle = dsp2cpu_cmd->pid; inst->prop.kernel_mask = dsp2cpu_cmd->kernel_mask; inst->prop.type = dsp2cpu_cmd->session_type; inst->prop.priority = dsp2cpu_cmd->session_prio; @@ -1565,11 +1597,8 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) cmd->session_cpu_high = (uint32_t)((inst_handle & HIGH32) >> 32); cmd->session_cpu_low = (uint32_t)(inst_handle & LOW32); - frpc_node = cvp_get_fastrpc_node_with_handle(dsp2cpu_cmd->pid); - if (frpc_node) { - eva_fastrpc_driver_add_sess(frpc_node, inst); - cvp_put_fastrpc_node(frpc_node); - } + eva_fastrpc_driver_add_sess(frpc_node, inst); + cvp_put_fastrpc_node(frpc_node); inst->task = task; dprintk(CVP_DSP, @@ -1589,9 +1618,10 @@ fail_get_session_info: fail_session_create: msm_cvp_close(inst); fail_msm_cvp_open: + put_task_struct(task); +fail_lookup: /* unregister fastrpc driver */ eva_fastrpc_driver_unregister(dsp2cpu_cmd->pid, false); - put_task_struct(task); cmd->ret = -1; } @@ -1791,7 +1821,7 @@ static void __dsp_cvp_buf_deregister(struct cvp_dsp_cmd_msg *cmd) cmd->ret = 0; dprintk(CVP_DSP, - "%s : sess id 0x%x, low 0x%x, high 0x%x, pid 0x%x\n", + "%s : sess id 0x%x, low 0x%x, high 0x%x, hdl 0x%x\n", __func__, dsp2cpu_cmd->session_id, dsp2cpu_cmd->session_cpu_low, dsp2cpu_cmd->session_cpu_high, @@ -1847,7 +1877,7 @@ static void __dsp_cvp_mem_alloc(struct cvp_dsp_cmd_msg *cmd) cmd->ret = 0; dprintk(CVP_DSP, - "%s sess id 0x%x, low 0x%x, high 0x%x, pid 0x%x\n", + "%s sess id 0x%x, low 0x%x, high 0x%x, hdl 0x%x\n", __func__, dsp2cpu_cmd->session_id, dsp2cpu_cmd->session_cpu_low, dsp2cpu_cmd->session_cpu_high, @@ -1931,7 +1961,7 @@ static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) cmd->ret = 0; dprintk(CVP_DSP, - "%s sess id 0x%x, low 0x%x, high 0x%x, pid 0x%x\n", + "%s sess id 0x%x, low 0x%x, high 0x%x, hnl 0x%x\n", __func__, dsp2cpu_cmd->session_id, dsp2cpu_cmd->session_cpu_low, dsp2cpu_cmd->session_cpu_high, diff --git a/msm/eva/msm_cvp_dsp.h b/msm/eva/msm_cvp_dsp.h index d96e6a4229..b198643c11 100644 --- a/msm/eva/msm_cvp_dsp.h +++ b/msm/eva/msm_cvp_dsp.h @@ -28,6 +28,7 @@ enum fastrpc_driver_status { enum fastrpc_driver_invoke_nums { FASTRPC_DEV_MAP_DMA = 1, FASTRPC_DEV_UNMAP_DMA, + FASTRPC_DEV_GET_HLOS_PID, }; struct fastrpc_driver { @@ -210,7 +211,7 @@ enum DRIVER_NAME_STATUS { struct cvp_dsp_fastrpc_driver_entry { struct list_head list; - uint32_t handle; + uint32_t handle; /*handle is not PID*/ uint32_t session_cnt; uint32_t driver_name_idx; atomic_t refcount; @@ -298,9 +299,9 @@ int cvp_dsp_deregister_buffer(uint32_t session_id, uint32_t buff_fd, uint32_t buff_offset, uint32_t buff_index, uint32_t buff_fd_iova); -int cvp_dsp_fastrpc_unmap(uint32_t process_id, struct cvp_internal_buf *buf); +int cvp_dsp_fastrpc_unmap(uint32_t handle, struct cvp_internal_buf *buf); -int cvp_dsp_del_sess(uint32_t process_id, struct msm_cvp_inst *inst); +int cvp_dsp_del_sess(uint32_t handle, struct msm_cvp_inst *inst); void cvp_dsp_send_debug_mask(void); diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index 7d26a14ae2..203b7afb1a 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -370,7 +370,7 @@ struct msm_cvp_inst { struct mutex sync_lock, lock; struct msm_cvp_core *core; enum session_type session_type; - u32 process_id; + u32 dsp_handle; struct task_struct *task; atomic_t smem_count; struct cvp_session_queue session_queue; From 6315e184ca361310da1e78618a65435053c1c4ba Mon Sep 17 00:00:00 2001 From: Aniruddh Sharma Date: Thu, 4 May 2023 14:12:57 +0530 Subject: [PATCH 212/317] msm: eva: Fix for use after free of inst node inst node gets deleted in delete_dsp_session call but again after this call we try to access inst to delete the dsp session list. This will lead to use after free issue. Change-Id: Ic4e1736b06f8e49895f70428124b245e1d2ce782 Signed-off-by: Aniruddh Sharma --- msm/eva/msm_cvp_dsp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 6d928b2089..5e1571fdd7 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -611,11 +611,11 @@ static void cvp_remove_dsp_sessions(void) inst = list_entry(s, struct msm_cvp_inst, dsp_list); if (inst) { - delete_dsp_session(inst, frpc_node); mutex_lock(&frpc_node->dsp_sessions.lock); list_del(&inst->dsp_list); frpc_node->session_cnt--; mutex_unlock(&frpc_node->dsp_sessions.lock); + delete_dsp_session(inst, frpc_node); } } From 40bd33147d38ac58f6424e866269df41fc440e2f Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 17 May 2023 10:42:06 -0700 Subject: [PATCH 213/317] msm: eva: Fix an issue in DSP sess create failure Avoid using invalid session id in case of DSP session failed. Increase the number of per IOCTL session properties setting from 8 to 64. Change-Id: Ia9979001fe6e0ed247067d7b12314c327897fead Signed-off-by: George Shen --- include/uapi/eva/media/msm_eva_private.h | 2 +- msm/eva/msm_cvp.c | 9 +++++++-- msm/eva/msm_cvp_dsp.c | 3 +-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/include/uapi/eva/media/msm_eva_private.h b/include/uapi/eva/media/msm_eva_private.h index df4b04f154..4aae22dc3e 100644 --- a/include/uapi/eva/media/msm_eva_private.h +++ b/include/uapi/eva/media/msm_eva_private.h @@ -180,7 +180,7 @@ struct eva_kmd_hfi_packet { #define EVA_KMD_PROP_PWR_FPS_LSR 0x30 -#define MAX_KMD_PROP_NUM_PER_PACKET 8 +#define MAX_KMD_PROP_NUM_PER_PACKET 64 #define MAX_KMD_PROP_TYPE (EVA_KMD_PROP_PWR_FPS_ICA + 1) struct eva_kmd_sys_property { diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index df2854ac3a..c57f554aa5 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -825,7 +825,7 @@ int msm_cvp_session_delete(struct msm_cvp_inst *inst) int msm_cvp_session_create(struct msm_cvp_inst *inst) { - int rc = 0; + int rc = 0, rc1 = 0; struct cvp_session_queue *sq; if (!inst || !inst->core) @@ -846,7 +846,7 @@ int msm_cvp_session_create(struct msm_cvp_inst *inst) if (rc) { dprintk(CVP_ERR, "Failed to move instance to open done state\n"); - goto fail_init; + goto fail_create; } rc = cvp_comm_set_arp_buffers(inst); @@ -861,8 +861,13 @@ int msm_cvp_session_create(struct msm_cvp_inst *inst) spin_lock(&sq->lock); sq->state = QUEUE_ACTIVE; spin_unlock(&sq->lock); + return rc; fail_init: + rc1 = msm_cvp_comm_try_state(inst, MSM_CVP_CLOSE_DONE); + if (rc1) + dprintk(CVP_ERR, "%s: close failed\n", __func__); +fail_create: return rc; } diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 5e1571fdd7..289867ff51 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1581,7 +1581,7 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) rc = msm_cvp_session_create(inst); if (rc) { dprintk(CVP_ERR, "Warning: send Session Create failed\n"); - goto fail_session_create; + goto fail_msm_cvp_open; } else { dprintk(CVP_DSP, "%s DSP Session Create done\n", __func__); } @@ -1615,7 +1615,6 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) return; fail_get_session_info: -fail_session_create: msm_cvp_close(inst); fail_msm_cvp_open: put_task_struct(task); From 37a21d759b3a716ad9637239efbad0b1313c3df4 Mon Sep 17 00:00:00 2001 From: George Shen Date: Sat, 20 May 2023 16:07:37 -0700 Subject: [PATCH 214/317] msm: eva: Recover EVA SMMU fault Needs extra change to enable EVA SMMU fault. This change clears all the obstacles to achieve the goal. Change-Id: Ia93ff2132ff53741f3c20d4271083f6f93824cac Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 9 +++++++++ msm/eva/cvp_hfi_io.h | 2 ++ msm/eva/cvp_smem.c | 34 ++++++++++++++++++++++++++++++++++ msm/eva/msm_cvp_buf.h | 2 ++ msm/eva/msm_cvp_res_parse.c | 9 +++++++-- 5 files changed, 54 insertions(+), 2 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 4823bfd58b..73d8ca8415 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -2342,6 +2343,7 @@ static int iris_hfi_core_release(void *dev) struct iris_hfi_device *device = dev; struct cvp_hal_session *session, *next; struct dev_pm_qos_request *qos_hdl; + u32 ipcc_iova; if (!device) { dprintk(CVP_ERR, "invalid device\n"); @@ -2370,6 +2372,8 @@ static int iris_hfi_core_release(void *dev) __dsp_shutdown(device); __disable_subcaches(device); + ipcc_iova = __read_register(device, CVP_MMAP_ADDR); + msm_cvp_unmap_ipcc_regs(ipcc_iova); __unload_fw(device); __hwfence_regs_unmap(device); @@ -2521,6 +2525,11 @@ static int iris_debug_hook(void *device) dprintk(CVP_ERR, "%s Invalid device\n", __func__); return -ENODEV; } + __write_register(dev, CVP_WRAPPER_CORE_CLOCK_CONFIG, 0x11); + __write_register(dev, CVP_WRAPPER_TZ_CPU_CLOCK_CONFIG, 0x1); + dprintk(CVP_ERR, "Halt Tensilica and core and axi\n"); + return 0; + /******* FDU & MPU *****/ #define CVP0_CVP_SS_FDU_SECURE_ENABLE 0x90 #define CVP0_CVP_SS_MPU_SECURE_ENABLE 0x94 diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index a28e459e95..46322c5b83 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef __CVP_HFI_IO_H__ @@ -111,6 +112,7 @@ #define CVP_WRAPPER_TZ_BASE_OFFS 0x000C0000 +#define CVP_WRAPPER_TZ_CPU_CLOCK_CONFIG (CVP_WRAPPER_TZ_BASE_OFFS) #define CVP_WRAPPER_INTR_CLEAR_A2HWD_BMSK 0x10 #define CVP_WRAPPER_INTR_CLEAR_A2HWD_SHFT 0x4 #define CVP_WRAPPER_INTR_CLEAR_A2H_BMSK 0x4 diff --git a/msm/eva/cvp_smem.c b/msm/eva/cvp_smem.c index ac3a86f268..673db56b3f 100644 --- a/msm/eva/cvp_smem.c +++ b/msm/eva/cvp_smem.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -606,3 +607,36 @@ int msm_cvp_map_ipcc_regs(u32 *iova) } return 0; } + +int msm_cvp_unmap_ipcc_regs(u32 iova) +{ + struct context_bank_info *cb; + struct msm_cvp_core *core; + struct cvp_hfi_device *hfi_ops; + struct iris_hfi_device *dev = NULL; + u32 size; + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + if (core) { + hfi_ops = core->device; + if (hfi_ops) + dev = hfi_ops->hfi_device_data; + } + + if (!dev) + return -EINVAL; + + size = dev->res->ipcc_reg_size; + + if (!iova || !size) + return -EINVAL; + + cb = msm_cvp_smem_get_context_bank(dev->res, 0); + if (!cb) { + dprintk(CVP_ERR, "%s: fail to get context bank\n", __func__); + return -EINVAL; + } + dma_unmap_resource(cb->dev, iova, size, DMA_BIDIRECTIONAL, 0); + + return 0; +} diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index 4bbfa191ef..ddf15853e3 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -1,6 +1,7 @@ /* 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. */ #ifndef _MSM_CVP_BUF_H_ @@ -194,6 +195,7 @@ int msm_cvp_smem_cache_operations(struct dma_buf *dbuf, unsigned long offset, unsigned long size); int msm_cvp_map_ipcc_regs(u32 *iova); +int msm_cvp_unmap_ipcc_regs(u32 iova); /* CVP driver internal buffer management functions*/ struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index 49f8fb0fc2..f9bb54170d 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1038,12 +1039,16 @@ int msm_cvp_smmu_fault_handler(struct iommu_domain *domain, return -EINVAL; } + dprintk(CVP_ERR, "%s - faulting address: %lx fault cnt %d\n", + __func__, iova, core->smmu_fault_count); + if (core->smmu_fault_count > 0) { + core->smmu_fault_count++; + return -ENOSYS; + } mutex_lock(&core->lock); core->smmu_fault_count++; if (!core->last_fault_addr) core->last_fault_addr = iova; - dprintk(CVP_ERR, "%s - faulting address: %lx, %d\n", - __func__, iova, core->smmu_fault_count); log = (core->log.snapshot_index > 0)? false : true; list_for_each_entry(inst, &core->instances, list) { From 064e37991293eafc1f874fe6589615775a876f45 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 22 May 2023 17:44:39 -0700 Subject: [PATCH 215/317] msm: eva: Avoid printing freed dma_buf name Drop dma_buf name from debugging property of smem. fd can provide similar debug value for EVA clients. Change-Id: I8a6ccf394f274e990efa6e3eef33e1fd84b362df Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 10 +++++----- msm/eva/msm_cvp_common.c | 5 ++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 22efd8ad15..f34d302c18 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1,6 +1,7 @@ // 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 @@ -73,13 +74,13 @@ int print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, if (!atomic_read(&smem->refcount)) dprintk(tag, - " UNUSED mapping %s: 0x%llx %s size %d iova %#x idx %d pkt_type %s buf_idx %#x fd %d", - str, smem->dma_buf, smem->dma_buf->name, + " UNUSED mapping %s: 0x%llx size %d iova %#x idx %d pkt_type %s buf_idx %#x fd %d", + str, smem->dma_buf, smem->size, smem->device_addr, smem->bitmap_index, name, smem->buf_idx, smem->fd); else dprintk(tag, - "%s: %x : 0x%llx %s size %d flags %#x iova %#x idx %d ref %d pkt_type %s buf_idx %#x fd %d", - str, hash32_ptr(inst->session), smem->dma_buf, smem->dma_buf->name, + "%s: %x : 0x%llx size %d flags %#x iova %#x idx %d ref %d pkt_type %s buf_idx %#x fd %d", + str, hash32_ptr(inst->session), smem->dma_buf, smem->size, smem->flags, smem->device_addr, smem->bitmap_index, atomic_read(&smem->refcount), name, smem->buf_idx, smem->fd); @@ -1968,7 +1969,6 @@ void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) dprintk(CVP_ERR, "unmapped dsp bufs\n"); for (i = 0; i < inst->unused_dsp_bufs.nr; i++) _log_smem(snap, inst, &inst->unused_dsp_bufs.smem[i], log); - } struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 31d4a73c19..d8695bab11 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -622,11 +623,9 @@ void handle_sys_error(enum hal_command_response cmd, void *data) wake_up_all(&inst->event_handler.wq); } - if (!core->trigger_ssr) { - cvp_print_inst(CVP_WARN, inst); + if (!core->trigger_ssr) if (hfi_device->error != CVP_ERR_NOC_ERROR) msm_cvp_print_inst_bufs(inst, false); - } } /* handle the hw error before core released to get full debug info */ From 57b03d2f4ede9ab8cdd9b65407f985d98df0364d Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 17 May 2023 10:42:06 -0700 Subject: [PATCH 216/317] msm: eva: Fix an issue in DSP sess create failure Avoid using invalid session id in case of DSP session failed. Increase the number of per IOCTL session properties setting from 8 to 64. Change-Id: Ia9979001fe6e0ed247067d7b12314c327897fead Signed-off-by: George Shen --- include/uapi/eva/media/msm_eva_private.h | 2 +- msm/eva/msm_cvp.c | 9 +++++++-- msm/eva/msm_cvp_dsp.c | 3 +-- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/include/uapi/eva/media/msm_eva_private.h b/include/uapi/eva/media/msm_eva_private.h index df4b04f154..4aae22dc3e 100644 --- a/include/uapi/eva/media/msm_eva_private.h +++ b/include/uapi/eva/media/msm_eva_private.h @@ -180,7 +180,7 @@ struct eva_kmd_hfi_packet { #define EVA_KMD_PROP_PWR_FPS_LSR 0x30 -#define MAX_KMD_PROP_NUM_PER_PACKET 8 +#define MAX_KMD_PROP_NUM_PER_PACKET 64 #define MAX_KMD_PROP_TYPE (EVA_KMD_PROP_PWR_FPS_ICA + 1) struct eva_kmd_sys_property { diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index df2854ac3a..c57f554aa5 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -825,7 +825,7 @@ int msm_cvp_session_delete(struct msm_cvp_inst *inst) int msm_cvp_session_create(struct msm_cvp_inst *inst) { - int rc = 0; + int rc = 0, rc1 = 0; struct cvp_session_queue *sq; if (!inst || !inst->core) @@ -846,7 +846,7 @@ int msm_cvp_session_create(struct msm_cvp_inst *inst) if (rc) { dprintk(CVP_ERR, "Failed to move instance to open done state\n"); - goto fail_init; + goto fail_create; } rc = cvp_comm_set_arp_buffers(inst); @@ -861,8 +861,13 @@ int msm_cvp_session_create(struct msm_cvp_inst *inst) spin_lock(&sq->lock); sq->state = QUEUE_ACTIVE; spin_unlock(&sq->lock); + return rc; fail_init: + rc1 = msm_cvp_comm_try_state(inst, MSM_CVP_CLOSE_DONE); + if (rc1) + dprintk(CVP_ERR, "%s: close failed\n", __func__); +fail_create: return rc; } diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 7965147e76..6dbd93611d 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1549,7 +1549,7 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) rc = msm_cvp_session_create(inst); if (rc) { dprintk(CVP_ERR, "Warning: send Session Create failed\n"); - goto fail_session_create; + goto fail_msm_cvp_open; } else { dprintk(CVP_DSP, "%s DSP Session Create done\n", __func__); } @@ -1586,7 +1586,6 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) return; fail_get_session_info: -fail_session_create: msm_cvp_close(inst); fail_msm_cvp_open: /* unregister fastrpc driver */ From df2c05337f7b28cd7f39eb35a0f8a1d0aa9814c9 Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 12 May 2023 20:17:31 -0700 Subject: [PATCH 217/317] msm: eva: Enhance power and perf logging Use CVP_PWR instead of CVP_PROF. Add AON timer reading. Avoid SSR if core init failed. Change-Id: I1dd40edc893009a2f2794e3431bb08398ec6352b Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 12 ++++++++++-- msm/eva/cvp_power.c | 37 +++++++++++++++++++------------------ msm/eva/msm_cvp_common.c | 6 +++--- msm/eva/msm_cvp_common.h | 1 + msm/eva/msm_cvp_core.c | 6 +++--- 5 files changed, 36 insertions(+), 26 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 0e4c376cd3..4823bfd58b 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -162,6 +162,15 @@ static int cvp_synx_recover(void) #define ROW_SIZE 32 +unsigned long long get_aon_time(void) +{ + unsigned long long val; + + asm volatile("mrs %0, cntvct_el0" : "=r" (val)); + + return val; +} + int get_hfi_version(void) { struct msm_cvp_core *core; @@ -3561,7 +3570,7 @@ static DECLARE_WORK(iris_hfi_wd_work, iris_hfi_wd_work_handler); irqreturn_t iris_hfi_isr_wd(int irq, void *dev) { struct iris_hfi_device *device = dev; - dprintk(CVP_ERR, "Got HW WDOG IRQ! \n"); + dprintk(CVP_ERR, "Got HW WDOG IRQ at %llu! \n", get_aon_time()); disable_irq_nosync(irq); queue_work(device->cvp_workq, &iris_hfi_wd_work); return IRQ_HANDLED; @@ -4910,7 +4919,6 @@ static inline int __resume(struct iris_hfi_device *device) rc = __boot_firmware(device); if (rc) { dprintk(CVP_ERR, "Failed to reset cvp core\n"); - msm_cvp_trigger_ssr(core, SSR_ERR_FATAL); goto err_reset_core; } diff --git a/msm/eva/cvp_power.c b/msm/eva/cvp_power.c index 7e39db27d2..626d3b6752 100644 --- a/msm/eva/cvp_power.c +++ b/msm/eva/cvp_power.c @@ -31,6 +31,9 @@ static bool is_subblock_profile_existed(struct msm_cvp_inst *inst) inst->prop.cycles[HFI_HW_LSR]); } +static char hw_names[HFI_MAX_HW_THREADS][8] = {{"FDU"}, {"OD"}, {"MPU"}, {"ICA"}, + {"VADL"}, {"TOF"}, {"RGE"}, {"XRA"}, + {"LSR"}}; static void aggregate_power_update(struct msm_cvp_core *core, struct cvp_power_level *nrt_pwr, struct cvp_power_level *rt_pwr, @@ -57,17 +60,18 @@ static void aggregate_power_update(struct msm_cvp_core *core, } else { i = 1; } - dprintk(CVP_PROF, "pwrUpdate fdu od mpu ica vadl tof rge xra lsr\n"); for (j = 0; j < HFI_MAX_HW_THREADS; j++) - dprintk(CVP_PROF, "%u ", inst->prop.cycles[j]); - dprintk(CVP_PROF, "\n"); + if (inst->prop.cycles[j]) + dprintk(CVP_PWR, "pwrUpdate %s %u\n", + hw_names[j], inst->prop.cycles[j]); - dprintk(CVP_PROF, "pwrUpdate fdu_o od_o ica_o mpu_o vadl_o tof_o rge_o xra_o lsr_o\n"); for (j = 0; j < HFI_MAX_HW_THREADS; j++) - dprintk(CVP_PROF, "%u ", inst->prop.op_cycles[j]); - dprintk(CVP_PROF, "\n"); + if (inst->prop.op_cycles[j]) + dprintk(CVP_PWR, "pwrUpdate_OP %s %u\n", + hw_names[j], inst->prop.op_cycles[j]); - dprintk(CVP_PROF, " fw %u fw_o %u\n", inst->prop.fw_cycles, inst->prop.fw_op_cycles); + dprintk(CVP_PWR, " fw %u fw_o %u\n", inst->prop.fw_cycles, + inst->prop.fw_op_cycles); for (j = 0; j < HFI_MAX_HW_THREADS; j++) blocks_sum[i][j] += inst->prop.cycles[j]; @@ -89,20 +93,17 @@ static void aggregate_power_update(struct msm_cvp_core *core, (op_bw_max[i] >= inst->prop.ddr_op_bw) ? op_bw_max[i] : inst->prop.ddr_op_bw; - dprintk(CVP_PWR, "%s:%d - fps fdu mpu od ica vadl tof rge xra lsf\n", - __func__, __LINE__); - for (j = 0; j < HFI_MAX_HW_THREADS; j++) { - dprintk(CVP_PWR, " %d ", inst->prop.fps[j]); + if (inst->prop.fps[j]) + dprintk(CVP_PWR, "fps %s %d ", hw_names[j], + inst->prop.fps[j]); core->dyn_clk.sum_fps[j] += inst->prop.fps[j]; } - dprintk(CVP_PWR, "\n"); - dprintk(CVP_PWR, "%s:%d - sum_fps fdu mpu od ica vadl tof rge xra lsf\n", - __func__, __LINE__); for (j = 0; j < HFI_MAX_HW_THREADS; j++) - dprintk(CVP_PWR, " %d ", core->dyn_clk.sum_fps[j]); - dprintk(CVP_PWR, "\n"); + if (core->dyn_clk.sum_fps[j]) + dprintk(CVP_PWR, "sum_fps %s %d ", hw_names[j], + core->dyn_clk.sum_fps[j]); } for (i = 0; i < 2; i++) { @@ -168,7 +169,7 @@ static int adjust_bw_freqs(void) min_bw = max_bw/10; aggregate_power_update(core, &nrt_pwr, &rt_pwr, cvp_max_rate); - dprintk(CVP_PROF, "PwrUpdate nrt %u %u rt %u %u\n", + dprintk(CVP_PWR, "PwrUpdate nrt %u %u rt %u %u\n", nrt_pwr.core_sum, nrt_pwr.op_core_sum, rt_pwr.core_sum, rt_pwr.op_core_sum); @@ -201,7 +202,7 @@ static int adjust_bw_freqs(void) bw_sum = (bw_sum > max_bw) ? max_bw : bw_sum; bw_sum = (bw_sum < min_bw) ? min_bw : bw_sum; - dprintk(CVP_PROF, "%s %lld %lld\n", __func__, + dprintk(CVP_PWR, "%s %lld %lld\n", __func__, core_sum, bw_sum); if (!cl->has_scaling) { dprintk(CVP_ERR, "Cannot scale CVP clock\n"); diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 19f7825fc5..31d4a73c19 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -625,7 +625,7 @@ void handle_sys_error(enum hal_command_response cmd, void *data) if (!core->trigger_ssr) { cvp_print_inst(CVP_WARN, inst); if (hfi_device->error != CVP_ERR_NOC_ERROR) - msm_cvp_print_inst_bufs(inst, false); + msm_cvp_print_inst_bufs(inst, false); } } @@ -1298,8 +1298,8 @@ void msm_cvp_ssr_handler(struct work_struct *work) send_again: mutex_lock(&core->lock); if (core->state == CVP_CORE_INIT_DONE) { - dprintk(CVP_WARN, "%s: ssr type %d\n", __func__, - core->ssr_type); + dprintk(CVP_WARN, "%s: ssr type %d at %llu\n", __func__, + core->ssr_type, get_aon_time()); /* * In current implementation user-initiated SSR triggers * a fatal error from hardware. However, there is no way diff --git a/msm/eva/msm_cvp_common.h b/msm/eva/msm_cvp_common.h index 4d66055d98..b9dc2e06f2 100644 --- a/msm/eva/msm_cvp_common.h +++ b/msm/eva/msm_cvp_common.h @@ -33,4 +33,5 @@ int cvp_comm_set_arp_buffers(struct msm_cvp_inst *inst); int cvp_comm_release_persist_buffers(struct msm_cvp_inst *inst); int msm_cvp_noc_error_info(struct msm_cvp_core *core); int cvp_print_inst(u32 tag, struct msm_cvp_inst *inst); +unsigned long long get_aon_time(void); #endif diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 3dfcef5dd4..814aca34f5 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -325,9 +325,9 @@ wait_dsp: mutex_unlock(&inst->cvpdspbufs.lock); if (!empty) - dprintk(CVP_WARN, "Failed flush DSP frame retried %d\n", - (inst->core->resources.msm_cvp_hw_rsp_timeout >> 5) - - max_retries); + dprintk(CVP_WARN, "Failed sess %pK DSP frame retried %d\n", + inst, + (inst->core->resources.msm_cvp_hw_rsp_timeout >> 5)); max_retries = inst->core->resources.msm_cvp_hw_rsp_timeout >> 1; wait_frame: mutex_lock(&inst->frames.lock); From 89f8cc73960045ce0f3f1673c903fb730e30ea5e Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 22 May 2023 17:44:39 -0700 Subject: [PATCH 218/317] msm: eva: Avoid printing freed dma_buf name Drop dma_buf name from debugging property of smem. fd can provide similar debug value for EVA clients. Change-Id: I8a6ccf394f274e990efa6e3eef33e1fd84b362df Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 10 +++++----- msm/eva/msm_cvp_common.c | 5 ++--- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 14d805773b..7a6615b6e9 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1,6 +1,7 @@ // 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 @@ -73,13 +74,13 @@ int print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, if (!atomic_read(&smem->refcount)) dprintk(tag, - " UNUSED mapping %s: 0x%llx %s size %d iova %#x idx %d pkt_type %s buf_idx %#x fd %d", - str, smem->dma_buf, smem->dma_buf->name, + " UNUSED mapping %s: 0x%llx size %d iova %#x idx %d pkt_type %s buf_idx %#x fd %d", + str, smem->dma_buf, smem->size, smem->device_addr, smem->bitmap_index, name, smem->buf_idx, smem->fd); else dprintk(tag, - "%s: %x : 0x%llx %s size %d flags %#x iova %#x idx %d ref %d pkt_type %s buf_idx %#x fd %d", - str, hash32_ptr(inst->session), smem->dma_buf, smem->dma_buf->name, + "%s: %x : 0x%llx size %d flags %#x iova %#x idx %d ref %d pkt_type %s buf_idx %#x fd %d", + str, hash32_ptr(inst->session), smem->dma_buf, smem->size, smem->flags, smem->device_addr, smem->bitmap_index, atomic_read(&smem->refcount), name, smem->buf_idx, smem->fd); @@ -1968,7 +1969,6 @@ void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) dprintk(CVP_ERR, "unmapped dsp bufs\n"); for (i = 0; i < inst->unused_dsp_bufs.nr; i++) _log_smem(snap, inst, &inst->unused_dsp_bufs.smem[i], log); - } struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 31d4a73c19..d8695bab11 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -622,11 +623,9 @@ void handle_sys_error(enum hal_command_response cmd, void *data) wake_up_all(&inst->event_handler.wq); } - if (!core->trigger_ssr) { - cvp_print_inst(CVP_WARN, inst); + if (!core->trigger_ssr) if (hfi_device->error != CVP_ERR_NOC_ERROR) msm_cvp_print_inst_bufs(inst, false); - } } /* handle the hw error before core released to get full debug info */ From 4bd20f9c7c25a5cd73c4d99e64e172d853df08a2 Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 30 May 2023 11:48:33 -0700 Subject: [PATCH 219/317] msm: eva: Fix a race in frame buf un-mapping Fix the racing in buf-unmap between session close and frame processing in fence path. Change-Id: Ia7e7ac6549a856b97c583c00f526a81c575a3cb2 Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 63 +++++++++++++++++++++++++------------------ 1 file changed, 37 insertions(+), 26 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index f34d302c18..bffef9e1e0 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -188,7 +188,7 @@ static bool __is_buf_valid(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) { struct cvp_hal_session *session; - struct cvp_internal_buf *cbuf = NULL; + struct cvp_internal_buf *cbuf = (struct cvp_internal_buf *)0xdeadbeef; bool found = false; if (!inst || !inst->core || !buf) { @@ -363,7 +363,7 @@ int msm_cvp_unmap_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) { int rc = 0; bool found; - struct cvp_internal_buf *cbuf; + struct cvp_internal_buf *cbuf = (struct cvp_internal_buf *)0xdeadbeef; struct cvp_hal_session *session; if (!inst || !inst->core || !buf) { @@ -417,7 +417,7 @@ int msm_cvp_map_buf_wncc(struct msm_cvp_inst *inst, { int rc = 0, i; bool found = false; - struct cvp_internal_buf* cbuf; + struct cvp_internal_buf* cbuf = (struct cvp_internal_buf *)0xdeadbeef; struct msm_cvp_smem* smem = NULL; struct dma_buf* dma_buf = NULL; @@ -579,7 +579,7 @@ int msm_cvp_unmap_buf_wncc(struct msm_cvp_inst *inst, { int rc = 0; bool found; - struct cvp_internal_buf *cbuf; + struct cvp_internal_buf *cbuf = (struct cvp_internal_buf *)0xdeadbeef; uint32_t buf_id, buf_idx; if (!inst || !inst->core || !buf) { @@ -771,7 +771,7 @@ static int _wncc_copy_oob_from_user(struct eva_kmd_hfi_packet* in_pkt, struct eva_kmd_oob_wncc* wncc_oob) { int rc = 0; - u32 oob_type; + u32 oob_type = 0; struct eva_kmd_oob_buf* oob_buf_u; struct eva_kmd_oob_wncc* wncc_oob_u; struct eva_kmd_oob_wncc* wncc_oob_k; @@ -1221,8 +1221,8 @@ static struct msm_cvp_smem *msm_cvp_session_find_smem(struct msm_cvp_inst *inst, u32 pkt_type) { struct msm_cvp_smem *smem; - struct msm_cvp_frame *frame; - struct cvp_internal_buf *buf; + struct msm_cvp_frame *frame = (struct msm_cvp_frame *)0xdeadbeef; + struct cvp_internal_buf *buf = (struct cvp_internal_buf *)0xdeadbeef; int i; if (inst->dma_cache.nr > MAX_DMABUF_NUMS) @@ -1424,7 +1424,8 @@ static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, { u32 iova = 0; struct msm_cvp_smem *smem = NULL; - struct list_head *ptr, *next; + struct list_head *ptr = (struct list_head *)0xdead; + struct list_head *next = (struct list_head *)0xdead; struct cvp_internal_buf *pbuf; struct dma_buf *dma_buf; @@ -1439,6 +1440,8 @@ static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, mutex_lock(&inst->persistbufs.lock); list_for_each_safe(ptr, next, &inst->persistbufs.list) { + if (!ptr) + return 0; pbuf = list_entry(ptr, struct cvp_internal_buf, list); if (dma_buf == pbuf->smem->dma_buf) { pbuf->size = @@ -1609,7 +1612,7 @@ static void backup_frame_buffers(struct msm_cvp_inst *inst, void msm_cvp_unmap_frame(struct msm_cvp_inst *inst, u64 ktid) { - struct msm_cvp_frame *frame, *dummy1; + struct msm_cvp_frame *frame = (struct msm_cvp_frame *)0xdeadbeef, *dummy1; bool found; if (!inst) { @@ -1627,22 +1630,20 @@ void msm_cvp_unmap_frame(struct msm_cvp_inst *inst, u64 ktid) if (frame->ktid == ktid) { found = true; list_del(&frame->list); + dprintk(CVP_CMD, "%s: " + "pkt_type %08x sess_id %08x trans_id <> ktid %llu\n", + __func__, frame->pkt_type, + hash32_ptr(inst->session), + frame->ktid); + /* Save the previous frame mappings for debug */ + backup_frame_buffers(inst, frame); + msm_cvp_unmap_frame_buf(inst, frame); break; } } mutex_unlock(&inst->frames.lock); - if (found) { - dprintk(CVP_CMD, "%s: " - "pkt_type %08x sess_id %08x trans_id <> ktid %llu\n", - __func__, frame->pkt_type, - hash32_ptr(inst->session), - frame->ktid); - /* Save the previous frame mappings for debug */ - backup_frame_buffers(inst, frame); - msm_cvp_unmap_frame_buf(inst, frame); - } - else + if (!found) dprintk(CVP_WARN, "%s frame %llu not found!\n", __func__, ktid); } @@ -1698,7 +1699,7 @@ int msm_cvp_map_frame(struct msm_cvp_inst *inst, u64 ktid; struct msm_cvp_frame *frame; struct cvp_hfi_cmd_session_hdr *cmd_hdr; - struct msm_cvp_inst *instance; + struct msm_cvp_inst *instance = (struct msm_cvp_inst *)0xdeadbeef; struct msm_cvp_core *core = NULL; core = get_cvp_core(MSM_CORE_CVP); @@ -1767,11 +1768,12 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) { int rc = 0, i; struct cvp_internal_buf *cbuf, *dummy; - struct msm_cvp_frame *frame, *dummy1; + struct msm_cvp_frame *frame = (struct msm_cvp_frame *)0xdeadbeef, *dummy1; struct msm_cvp_smem *smem; struct cvp_hal_session *session; struct eva_kmd_buffer buf; - struct list_head *ptr, *next; + struct list_head *ptr = (struct list_head *)0xdead; + struct list_head *next = (struct list_head *)0xdead; session = (struct cvp_hal_session *)inst->session; @@ -1784,6 +1786,8 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) mutex_lock(&inst->persistbufs.lock); list_for_each_safe(ptr, next, &inst->persistbufs.list) { + if (!ptr) + return -EINVAL; cbuf = list_entry(ptr, struct cvp_internal_buf, list); smem = cbuf->smem; if (!smem) { @@ -1839,6 +1843,7 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) } mutex_unlock(&inst->dma_cache.lock); + cbuf = (struct cvp_internal_buf *)0xdeadbeef; mutex_lock(&inst->cvpdspbufs.lock); list_for_each_entry_safe(cbuf, dummy, &inst->cvpdspbufs.list, list) { print_internal_buffer(CVP_MEM, "remove dspbufs", inst, cbuf); @@ -1892,12 +1897,15 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) #define MAX_NUM_FRAMES_DUMP 4 void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) { - struct cvp_internal_buf *buf; - struct msm_cvp_frame *frame; + struct cvp_internal_buf *buf = (struct cvp_internal_buf *)0xdeadbeef; + struct msm_cvp_frame *frame = (struct msm_cvp_frame *)0xdeadbeef; struct msm_cvp_core *core; struct inst_snapshot *snap = NULL; int i = 0, c = 0; + if (!cvp_driver->cores) + return; + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); if (log && core->log.snapshot_index < 16) { snap = &core->log.snapshot[core->log.snapshot_index]; @@ -2035,7 +2043,8 @@ fail_kzalloc: int cvp_release_arp_buffers(struct msm_cvp_inst *inst) { struct msm_cvp_smem *smem; - struct list_head *ptr, *next; + struct list_head *ptr = (struct list_head *)0xdead; + struct list_head *next = (struct list_head *)0xdead; struct cvp_internal_buf *buf; int rc = 0; struct msm_cvp_core *core; @@ -2079,6 +2088,8 @@ int cvp_release_arp_buffers(struct msm_cvp_inst *inst) } list_for_each_safe(ptr, next, &inst->persistbufs.list) { + if (!ptr) + return -EINVAL; buf = list_entry(ptr, struct cvp_internal_buf, list); smem = buf->smem; if (!smem) { From 364d2b1f7ed6bef48cb13a780d120053f16772b7 Mon Sep 17 00:00:00 2001 From: Gopireddy Arunteja Reddy Date: Wed, 24 May 2023 17:03:01 +0530 Subject: [PATCH 220/317] msm: eva: Bw vote by checking bus node name In adjust_bw_freq function, we are assigning bus node based on index that will give side effect if bus node order got changed. So, assigning bus node based on bus name and vote appropriately. Change-Id: Ied0e1f691439d499e4133a52ef55d36c430586c1 Signed-off-by: Gopireddy Arunteja Reddy --- msm/eva/cvp_power.c | 23 ++++++++++++++++------- msm/eva/msm_cvp_clocks.c | 2 ++ 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/msm/eva/cvp_power.c b/msm/eva/cvp_power.c index 626d3b6752..42b4ed39e9 100644 --- a/msm/eva/cvp_power.c +++ b/msm/eva/cvp_power.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only * - * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. */ @@ -144,15 +144,15 @@ static int adjust_bw_freqs(void) { struct msm_cvp_core *core; struct iris_hfi_device *hdev; - struct bus_info *bus; + struct bus_info *bus = NULL; struct clock_set *clocks; struct clock_info *cl; struct allowed_clock_rates_table *tbl = NULL; unsigned int tbl_size; - unsigned int cvp_min_rate, cvp_max_rate, max_bw, min_bw; + unsigned int cvp_min_rate, cvp_max_rate, max_bw = 0, min_bw = 0; struct cvp_power_level rt_pwr = {0}, nrt_pwr = {0}; unsigned long tmp, core_sum, op_core_sum, bw_sum; - int i, rc = 0; + int i, rc = 0, bus_count = 0; unsigned long ctrl_freq; core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); @@ -164,9 +164,18 @@ static int adjust_bw_freqs(void) tbl_size = core->resources.allowed_clks_tbl_size; cvp_min_rate = tbl[0].clock_rate; cvp_max_rate = tbl[tbl_size - 1].clock_rate; - bus = &core->resources.bus_set.bus_tbl[1]; - max_bw = bus->range[1]; - min_bw = max_bw/10; + + for (bus_count = 0; bus_count < core->resources.bus_set.count; bus_count++) { + if (!strcmp(core->resources.bus_set.bus_tbl[bus_count].name, "cvp-ddr")) { + bus = &core->resources.bus_set.bus_tbl[bus_count]; + max_bw = bus->range[1]; + min_bw = max_bw/10; + } + } + if (!bus) { + dprintk(CVP_ERR, "bus node is NULL for cvp-ddr\n"); + return -EINVAL; + } aggregate_power_update(core, &nrt_pwr, &rt_pwr, cvp_max_rate); dprintk(CVP_PWR, "PwrUpdate nrt %u %u rt %u %u\n", diff --git a/msm/eva/msm_cvp_clocks.c b/msm/eva/msm_cvp_clocks.c index 790b8448a1..cf795ca44a 100644 --- a/msm/eva/msm_cvp_clocks.c +++ b/msm/eva/msm_cvp_clocks.c @@ -464,6 +464,8 @@ int msm_cvp_set_bw(struct bus_info *bus, unsigned long bw) if (!bus->client) return -EINVAL; + dprintk(CVP_PWR, "bus->name = %s to bw = %u\n", + bus->name, bw); rc = icc_set_bw(bus->client, bw, 0); if (rc) From 43c37a29e10a6ab6e1e1a5bc775aef0c2e049099 Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 23 May 2023 15:55:47 -0700 Subject: [PATCH 221/317] msm: eva: Send EVA session error to UMD Through POLL SSR event, only notify the error session. Other sessions will not be impacted. This is different than SSR handling. Change-Id: I5acb4e21c19909b16350816621ae085d54fe05ac Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 5 +- msm/eva/hfi_response_handler.c | 8 +- msm/eva/msm_cvp.c | 132 +++------------------------------ msm/eva/msm_cvp_buf.c | 2 +- msm/eva/msm_cvp_common.c | 83 +++++++++++++-------- 5 files changed, 69 insertions(+), 161 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 73d8ca8415..859ee78604 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -3305,10 +3305,8 @@ static void **get_session_id(struct msm_cvp_cb_info *info) case HAL_SESSION_PROPERTY_INFO: case HAL_SESSION_EVENT_CHANGE: case HAL_SESSION_DUMP_NOTIFY: - session_id = &info->response.cmd.session_id; - break; case HAL_SESSION_ERROR: - session_id = &info->response.data.session_id; + session_id = &info->response.cmd.session_id; break; case HAL_RESPONSE_UNUSED: default: @@ -3525,6 +3523,7 @@ err_no_work: } dprintk(CVP_HFI, "Processing response %d of %d, type %d\n", (i + 1), num_responses, r->response_type); + /* callback = void cvp_handle_cmd_response() */ device->callback(r->response_type, rsp); } diff --git a/msm/eva/hfi_response_handler.c b/msm/eva/hfi_response_handler.c index f28de04bf4..0ded7e6026 100644 --- a/msm/eva/hfi_response_handler.c +++ b/msm/eva/hfi_response_handler.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -93,8 +94,9 @@ static int hfi_process_session_error(u32 device_id, cmd_done.device_id = device_id; cmd_done.session_id = (void *)(uintptr_t)pkt->session_id; cmd_done.status = hfi_map_err_status(pkt->event_data1); + cmd_done.size = pkt->event_data2; info->response.cmd = cmd_done; - dprintk(CVP_INFO, "Received: SESSION_ERROR with event id : %#x %#x\n", + dprintk(CVP_WARN, "Received: SESSION_ERROR with event data 1 2: %#x %#x\n", pkt->event_data1, pkt->event_data2); switch (pkt->event_data1) { /* Ignore below errors */ @@ -108,7 +110,7 @@ static int hfi_process_session_error(u32 device_id, "%s: session %x id %#x, data1 %#x, data2 %#x\n", __func__, pkt->session_id, pkt->event_id, pkt->event_data1, pkt->event_data2); - info->response_type = HAL_RESPONSE_UNUSED; + info->response_type = HAL_SESSION_ERROR; break; } @@ -135,8 +137,6 @@ static int hfi_process_event_notify(u32 device_id, return hfi_process_sys_error(device_id, pkt, info); case HFI_EVENT_SESSION_ERROR: - dprintk(CVP_INFO, "HFI_EVENT_SESSION_ERROR[%#x]\n", - pkt->session_id); return hfi_process_session_error(device_id, pkt, info); default: diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index c57f554aa5..9635e61a5e 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include "msm_cvp.h" @@ -94,9 +95,8 @@ static int cvp_wait_process_message(struct msm_cvp_inst *inst, if (wait_event_timeout(sq->wq, cvp_msg_pending(sq, &msg, ktid), timeout) == 0) { dprintk(CVP_WARN, "session queue wait timeout\n"); - if(inst && inst->core && inst->core->device){ + if (inst && inst->core && inst->core->device && inst->state != MSM_CVP_CORE_INVALID) print_hfi_queue_info(inst->core->device); - } rc = -ETIMEDOUT; goto exit; } @@ -184,6 +184,11 @@ static int msm_cvp_session_process_hfi( return -EINVAL; } + if (inst->state == MSM_CVP_CORE_INVALID) { + dprintk(CVP_ERR, "sess %pK INVALIDim reject new HFIs\n", inst); + return -ECONNRESET; + } + s = cvp_get_inst_validate(inst->core, inst); if (!s) return -ECONNRESET; @@ -474,121 +479,8 @@ exit: static int msm_cvp_session_process_hfi_fence(struct msm_cvp_inst *inst, struct eva_kmd_arg *arg) { - int rc = 0; - int idx; - struct eva_kmd_hfi_fence_packet *fence_pkt; - struct eva_kmd_hfi_synx_packet *synx_pkt; - struct eva_kmd_fence_ctrl *kfc; - struct cvp_hfi_cmd_session_hdr *pkt; - unsigned int offset = 0, buf_num = 0, in_offset, in_buf_num; - struct msm_cvp_inst *s; - struct cvp_fence_command *f; - struct cvp_fence_queue *q; - u32 *fence; - enum op_mode mode; - bool is_config_pkt; - - if (!inst || !inst->core || !arg || !inst->core->device) { - dprintk(CVP_ERR, "%s: invalid params\n", __func__); - return -EINVAL; - } - - s = cvp_get_inst_validate(inst->core, inst); - if (!s) - return -ECONNRESET; - - q = &inst->fence_cmd_queue; - - mutex_lock(&q->lock); - mode = q->mode; - mutex_unlock(&q->lock); - - if (mode == OP_DRAINING) { - dprintk(CVP_SYNX, "%s: flush in progress\n", __func__); - rc = -EBUSY; - goto exit; - } - - in_offset = arg->buf_offset; - in_buf_num = arg->buf_num; - - fence_pkt = &arg->data.hfi_fence_pkt; - pkt = (struct cvp_hfi_cmd_session_hdr *)&fence_pkt->pkt_data; - idx = get_pkt_index((struct cvp_hal_session_cmd_pkt *)pkt); - - if (idx < 0 || - (pkt->size > MAX_HFI_FENCE_OFFSET * sizeof(unsigned int))) { - dprintk(CVP_ERR, "%s incorrect packet %d %#x\n", __func__, - pkt->size, pkt->packet_type); - goto exit; - } else { - is_config_pkt = cvp_hfi_defs[idx].is_config_pkt; - } - - if (in_offset && in_buf_num) { - offset = in_offset; - buf_num = in_buf_num; - } - - if (!is_buf_param_valid(buf_num, offset)) { - dprintk(CVP_ERR, "Incorrect buf num and offset in cmd\n"); - goto exit; - } - - if (is_config_pkt) - pr_info(CVP_DBG_TAG "inst %pK config %s\n", - "pkt", inst, cvp_hfi_defs[idx].name); - - rc = msm_cvp_map_frame(inst, (struct eva_kmd_hfi_packet *)pkt, offset, - buf_num); - if (rc) - goto exit; - - rc = cvp_alloc_fence_data(&f, pkt->size); - if (rc) - goto exit; - - f->type = cvp_hfi_defs[idx].type; - f->mode = OP_NORMAL; - - synx_pkt = &arg->data.hfi_synx_pkt; - if (synx_pkt->fence_data[0] != 0xFEEDFACE) { - dprintk(CVP_ERR, "%s deprecated synx path\n", __func__); - cvp_free_fence_data(f); - msm_cvp_unmap_frame(inst, pkt->client_data.kdata); - goto exit; - } else { - kfc = &synx_pkt->fc; - fence = (u32 *)&kfc->fences; - f->frame_id = kfc->frame_id; - f->signature = 0xFEEDFACE; - f->num_fences = kfc->num_fences; - f->output_index = kfc->output_index; - } - - - dprintk(CVP_SYNX, "%s: frameID %llu ktid %llu\n", - __func__, f->frame_id, pkt->client_data.kdata); - - memcpy(f->pkt, pkt, pkt->size); - - f->pkt->client_data.kdata |= FENCE_BIT; - - rc = inst->core->synx_ftbl->cvp_import_synx(inst, f, fence); - if (rc) { - cvp_free_fence_data(f); - goto exit; - } - - mutex_lock(&q->lock); - list_add_tail(&f->list, &inst->fence_cmd_queue.wait_list); - mutex_unlock(&q->lock); - - wake_up(&inst->fence_cmd_queue.wq); - -exit: - cvp_put_inst(s); - return rc; + dprintk(CVP_WARN, "Deprecated IOCTL command %s\n", __func__); + return -EINVAL; } @@ -1534,7 +1426,6 @@ check_sched: int cvp_clean_session_queues(struct msm_cvp_inst *inst) { struct cvp_fence_queue *q; - struct cvp_session_queue *sq; u32 count = 0, max_retries = 100; q = &inst->fence_cmd_queue; @@ -1563,11 +1454,6 @@ retry: return -EBUSY; goto retry; - - sq = &inst->session_queue_fence; - spin_lock(&sq->lock); - sq->state = QUEUE_INVALID; - spin_unlock(&sq->lock); } static int cvp_flush_all(struct msm_cvp_inst *inst) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index bffef9e1e0..89e734e2d5 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -2079,7 +2079,7 @@ int cvp_release_arp_buffers(struct msm_cvp_inst *inst) HAL_SESSION_RELEASE_BUFFER_DONE); if (rc) dprintk(CVP_WARN, - "%s: wait for signal failed, rc %d\n", + "%s: wait release_arp signal failed, rc %d\n", __func__, rc); mutex_lock(&inst->persistbufs.lock); } else { diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index d8695bab11..8429137ac8 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -384,7 +384,8 @@ int wait_for_sess_signal_receipt(struct msm_cvp_inst *inst, if (!rc) { dprintk(CVP_WARN, "Wait interrupted or timed out: %d\n", SESSION_MSG_INDEX(cmd)); - print_hfi_queue_info(hdev); + if (inst->state != MSM_CVP_CORE_INVALID) + print_hfi_queue_info(hdev); rc = -ETIMEDOUT; } else if (inst->state == MSM_CVP_CORE_INVALID) { rc = -ECONNRESET; @@ -541,6 +542,8 @@ static void handle_session_error(enum hal_command_response cmd, void *data) struct msm_cvp_cb_cmd_done *response = data; struct cvp_hfi_device *hdev = NULL; struct msm_cvp_inst *inst = NULL; + unsigned long flags = 0; + int i; if (!response) { dprintk(CVP_ERR, @@ -559,6 +562,19 @@ static void handle_session_error(enum hal_command_response cmd, void *data) hdev = inst->core->device; dprintk(CVP_ERR, "Sess error 0x%x received for inst %pK sess %x\n", response->status, inst, hash32_ptr(inst->session)); + cvp_print_inst(CVP_WARN, inst); + if (inst->state != MSM_CVP_CORE_INVALID) { + change_cvp_inst_state(inst, MSM_CVP_CORE_INVALID); + if (cvp_clean_session_queues(inst)) + dprintk(CVP_WARN, "Failed to clean sess queues\n"); + for (i = 0; i < ARRAY_SIZE(inst->completions); i++) + complete(&inst->completions[i]); + spin_lock_irqsave(&inst->event_handler.lock, flags); + inst->event_handler.event = CVP_SSR_EVENT; + spin_unlock_irqrestore( + &inst->event_handler.lock, flags); + wake_up_all(&inst->event_handler.wq); + } cvp_put_inst(inst); } @@ -994,13 +1010,6 @@ int msm_cvp_deinit_core(struct msm_cvp_inst *inst) hdev = core->device; mutex_lock(&core->lock); - if (core->state == CVP_CORE_UNINIT) { - dprintk(CVP_INFO, "CVP core: %d is already in state: %d\n", - core->id, core->state); - goto core_already_uninited; - } - -core_already_uninited: change_cvp_inst_state(inst, MSM_CVP_CORE_UNINIT); mutex_unlock(&core->lock); return 0; @@ -1113,38 +1122,48 @@ int msm_cvp_comm_suspend(int core_id) static int get_flipped_state(int present_state, int desired_state) { - int flipped_state = present_state; + int flipped_state; + + if (present_state == MSM_CVP_CORE_INIT_DONE && desired_state > MSM_CVP_CLOSE) + flipped_state = MSM_CVP_CORE_UNINIT; + else if (present_state == MSM_CVP_CORE_INVALID) + flipped_state = MSM_CVP_CLOSE; + else + flipped_state = present_state; - if (flipped_state < MSM_CVP_CLOSE && desired_state > MSM_CVP_CLOSE) { - flipped_state = MSM_CVP_CLOSE + (MSM_CVP_CLOSE - flipped_state); - flipped_state &= 0xFFFE; - flipped_state = flipped_state - 1; - } else if (flipped_state > MSM_CVP_CLOSE - && desired_state < MSM_CVP_CLOSE) { - flipped_state = MSM_CVP_CLOSE - - (flipped_state - MSM_CVP_CLOSE + 1); - flipped_state &= 0xFFFE; - flipped_state = flipped_state - 1; - } return flipped_state; } +static char state_names[MSM_CVP_CORE_INVALID + 1][32] = { + "Invlid entry", + "CORE_UNINIT_DONE", + "CORE_INIT", + "CORE_INIT_DONE", + "OPEN", + "OPEN_DONE", + "CLOSE", + "CLOSE_DONE", + "CORE_UNINIT", + "CORE_INVALID" +}; + int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state) { int rc = 0; int flipped_state; + struct msm_cvp_core *core; + + core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); if (!inst) { dprintk(CVP_ERR, "%s: invalid params %pK", __func__, inst); return -EINVAL; } - dprintk(CVP_SESS, - "Trying to move inst: %pK (%#x) from: %#x to %#x\n", - inst, hash32_ptr(inst->session), inst->state, state); mutex_lock(&inst->sync_lock); - if (inst->state == MSM_CVP_CORE_INVALID) { - dprintk(CVP_ERR, "%s: inst %pK is in invalid\n", + if (inst->state == MSM_CVP_CORE_INVALID && + core->state == CVP_CORE_UNINIT) { + dprintk(CVP_ERR, "%s: inst %pK & core are in invalid\n", __func__, inst); mutex_unlock(&inst->sync_lock); return -EINVAL; @@ -1152,8 +1171,10 @@ int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state) flipped_state = get_flipped_state(inst->state, state); dprintk(CVP_SESS, - "inst: %pK (%#x) flipped_state = %#x %x\n", - inst, hash32_ptr(inst->session), flipped_state, state); + "inst: %pK (%#x) cur_state %s dest_state %s flipped_state = %s\n", + inst, hash32_ptr(inst->session), state_names[inst->state], + state_names[state], state_names[flipped_state]); + switch (flipped_state) { case MSM_CVP_CORE_UNINIT_DONE: case MSM_CVP_CORE_INIT: @@ -1208,9 +1229,11 @@ int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state) if (rc == -ETIMEDOUT) { dprintk(CVP_ERR, - "Timedout move from state: %d to %d\n", - inst->state, state); - msm_cvp_comm_kill_session(inst); + "Timedout move from state: %s to %s\n", + state_names[inst->state], + state_names[state]); + if (inst->state != MSM_CVP_CORE_INVALID) + msm_cvp_comm_kill_session(inst); } return rc; } From 0ae23cf0798557dce58d8604baff1d61af62fb78 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 1 Jun 2023 10:55:54 -0700 Subject: [PATCH 222/317] msm: eva: fix a compilation issue That breaks kernel compilation due to PW setting override. Change-Id: I9b15fe2676a9f2350684066363c4915fa3203016 Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 89e734e2d5..e6cf5a9243 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1903,9 +1903,6 @@ void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) struct inst_snapshot *snap = NULL; int i = 0, c = 0; - if (!cvp_driver->cores) - return; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); if (log && core->log.snapshot_index < 16) { snap = &core->log.snapshot[core->log.snapshot_index]; From df291cad8316c98d186a2cacaacf65fc68902410 Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 26 May 2023 10:04:30 -0700 Subject: [PATCH 223/317] msm: eva: Give EVA IRQ thread realtime priority To ensure consistent EVA feature performance. Change-Id: I8068984bb677b7eef388b114efc36520be9f8d76 Signed-off-by: George Shen --- msm/eva/cvp_core_hfi.h | 2 ++ msm/eva/cvp_hfi.c | 18 ++++-------------- msm/eva/vm/cvp_vm_main.c | 6 +++--- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/msm/eva/cvp_core_hfi.h b/msm/eva/cvp_core_hfi.h index f93b0db0bc..9f41bb2632 100644 --- a/msm/eva/cvp_core_hfi.h +++ b/msm/eva/cvp_core_hfi.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef __H_CVP_CORE_HFI_H__ @@ -280,6 +281,7 @@ struct iris_hfi_device { }; irqreturn_t cvp_hfi_isr(int irq, void *dev); +irqreturn_t iris_hfi_core_work_handler(int irq, void *data); irqreturn_t iris_hfi_isr_wd(int irq, void *dev); void cvp_iris_hfi_delete_device(void *device); diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 859ee78604..a15f799a99 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -3456,7 +3456,7 @@ exit: return packet_count; } -static void iris_hfi_core_work_handler(struct work_struct *work) +irqreturn_t iris_hfi_core_work_handler(int irq, void *data) { struct msm_cvp_core *core; struct iris_hfi_device *device; @@ -3468,11 +3468,9 @@ static void iris_hfi_core_work_handler(struct work_struct *work) if (core) device = core->device->hfi_device_data; else - return; + return IRQ_HANDLED; mutex_lock(&device->lock); - - if (!__core_in_valid_state(device)) { if (warning_on) { dprintk(CVP_WARN, "%s Core not in init state\n", @@ -3531,21 +3529,13 @@ err_no_work: if (!(intr_status & CVP_WRAPPER_INTR_STATUS_A2HWD_BMSK)) enable_irq(device->cvp_hal_data->irq); - /* - * XXX: Don't add any code beyond here. Reacquiring locks after release - * it above doesn't guarantee the atomicity that we're aiming for. - */ + return IRQ_HANDLED; } -static DECLARE_WORK(iris_hfi_work, iris_hfi_core_work_handler); - irqreturn_t cvp_hfi_isr(int irq, void *dev) { - struct iris_hfi_device *device = dev; - disable_irq_nosync(irq); - queue_work(device->cvp_workq, &iris_hfi_work); - return IRQ_HANDLED; + return IRQ_WAKE_THREAD; } static void iris_hfi_wd_work_handler(struct work_struct *work) diff --git a/msm/eva/vm/cvp_vm_main.c b/msm/eva/vm/cvp_vm_main.c index b84f21cb6b..e53eb138bb 100644 --- a/msm/eva/vm/cvp_vm_main.c +++ b/msm/eva/vm/cvp_vm_main.c @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only * - * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #include #include @@ -153,8 +153,8 @@ static int msm_cvp_vm_init_reg_and_irq(struct iris_hfi_device *device, } device->cvp_hal_data = hal; - rc = request_irq(res->irq, cvp_hfi_isr, IRQF_TRIGGER_HIGH, - "msm_cvp", device); + rc = request_threaded_irq(res->irq, cvp_hfi_isr, iris_hfi_core_work_handler, + IRQF_TRIGGER_HIGH, "msm_cvp", device); if (unlikely(rc)) { dprintk(CVP_ERR, "%s: request_irq failed rc: %d\n", __func__, rc); goto error_irq_fail; From 304e2cf9c0dbcc5b9a806771bafbec977b3f6919 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 1 Jun 2023 19:34:57 -0700 Subject: [PATCH 224/317] msm: eva: Allocate 1MB debug buffer for FW For FW to hold debug info. Simplify driver structure for easy dump in T32. Change-Id: Ib310a3d9fe3437d5ce49783eb813fbb2d8bd3216 Signed-off-by: George Shen --- msm/eva/cvp.c | 36 +++------ msm/eva/cvp_core_hfi.c | 4 +- msm/eva/cvp_core_hfi.h | 5 +- msm/eva/cvp_hfi.c | 41 ++++------ msm/eva/cvp_hfi_api.h | 3 +- msm/eva/cvp_power.c | 4 +- msm/eva/cvp_smem.c | 4 +- msm/eva/hfi_response_handler.c | 4 +- msm/eva/msm_cvp.c | 1 - msm/eva/msm_cvp_buf.c | 4 +- msm/eva/msm_cvp_common.c | 140 ++++++--------------------------- msm/eva/msm_cvp_common.h | 3 +- msm/eva/msm_cvp_core.c | 19 ++--- msm/eva/msm_cvp_core.h | 9 +-- msm/eva/msm_cvp_debug.c | 21 ++--- msm/eva/msm_cvp_dsp.c | 13 +-- msm/eva/msm_cvp_internal.h | 7 +- 17 files changed, 92 insertions(+), 226 deletions(-) diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index cecdb7a766..aa210c52ea 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -36,13 +37,11 @@ struct msm_cvp_drv *cvp_driver; static int cvp_open(struct inode *inode, struct file *filp) { - struct msm_cvp_core *core = container_of(inode->i_cdev, - struct msm_cvp_core, cdev); struct msm_cvp_inst *inst; - dprintk(CVP_SESS, "%s: core->id: %d\n", __func__, core->id); + dprintk(CVP_SESS, "%s\n", __func__); - inst = msm_cvp_open(core->id, MSM_CVP_USER, current); + inst = msm_cvp_open(MSM_CVP_USER, current); if (!inst) { dprintk(CVP_ERR, "Failed to create cvp instance\n"); return -ENOMEM; @@ -185,7 +184,7 @@ static ssize_t pwr_collapse_delay_store(struct device *dev, else if (!val) return -EINVAL; - core = get_cvp_core(MSM_CORE_CVP); + core = cvp_driver->cvp_core; if (!core) return -EINVAL; core->resources.msm_cvp_pwr_collapse_delay = val; @@ -198,7 +197,7 @@ static ssize_t pwr_collapse_delay_show(struct device *dev, { struct msm_cvp_core *core = NULL; - core = get_cvp_core(MSM_CORE_CVP); + core = cvp_driver->cvp_core; if (!core) return -EINVAL; @@ -266,7 +265,7 @@ static ssize_t boot_store(struct device *dev, if (val == 1 && booted == 0) { struct msm_cvp_inst *inst; - inst = msm_cvp_open(MSM_CORE_CVP, MSM_CVP_BOOT, current); + inst = msm_cvp_open(MSM_CVP_BOOT, current); if (!inst) { dprintk(CVP_ERR, "Failed to create cvp instance\n"); @@ -281,7 +280,7 @@ static ssize_t boot_store(struct device *dev, } else if (val == 2) { struct msm_cvp_inst *inst; - inst = msm_cvp_open(MSM_CORE_CVP, MSM_CVP_USER, current); + inst = msm_cvp_open(MSM_CVP_USER, current); if (!inst) { dprintk(CVP_ERR, "Failed to create eva instance\n"); @@ -347,8 +346,6 @@ static int msm_probe_cvp_device(struct platform_device *pdev) goto err_core_init; } - core->id = MSM_CORE_CVP; - rc = alloc_chrdev_region(&core->dev_num, 0, 1, DRIVER_NAME); if (rc < 0) { dprintk(CVP_ERR, "alloc_chrdev_region failed: %d\n", @@ -383,17 +380,6 @@ static int msm_probe_cvp_device(struct platform_device *pdev) goto error_cdev_add; } - /* finish setting up the 'core' */ - mutex_lock(&cvp_driver->lock); - if (cvp_driver->num_cores + 1 > MSM_CVP_CORES_MAX) { - mutex_unlock(&cvp_driver->lock); - dprintk(CVP_ERR, "Maximum cores already exist, core_no = %d\n", - cvp_driver->num_cores); - goto err_cores_exceeded; - } - cvp_driver->num_cores++; - mutex_unlock(&cvp_driver->lock); - rc = sysfs_create_group(&core->dev->kobj, &msm_cvp_core_attr_group); if (rc) { dprintk(CVP_ERR, @@ -404,11 +390,10 @@ static int msm_probe_cvp_device(struct platform_device *pdev) /* VM manager shall be started before HFI init */ vm_manager.vm_ops->vm_start(core); - core->device = cvp_hfi_initialize(core->hfi_type, core->id, + core->device = cvp_hfi_initialize(core->hfi_type, &core->resources, &cvp_handle_cmd_response); if (IS_ERR_OR_NULL(core->device)) { mutex_lock(&cvp_driver->lock); - cvp_driver->num_cores--; mutex_unlock(&cvp_driver->lock); rc = PTR_ERR(core->device) ?: -EBADHANDLE; @@ -422,7 +407,7 @@ static int msm_probe_cvp_device(struct platform_device *pdev) cvp_synx_ftbl_init(core); mutex_lock(&cvp_driver->lock); - list_add_tail(&core->list, &cvp_driver->cores); + cvp_driver->cvp_core = core; mutex_unlock(&cvp_driver->lock); cvp_driver->debugfs_root = msm_cvp_debugfs_init_drv(); @@ -567,7 +552,7 @@ static int msm_cvp_pm_suspend(struct device *dev) return -EINVAL; } - rc = msm_cvp_suspend(core->id); + rc = msm_cvp_suspend(); if (rc == -ENOTSUPP) rc = 0; else if (rc) @@ -610,7 +595,6 @@ static int __init msm_cvp_init(void) return -ENOMEM; } - INIT_LIST_HEAD(&cvp_driver->cores); mutex_init(&cvp_driver->lock); rc = platform_driver_register(&msm_cvp_driver); diff --git a/msm/eva/cvp_core_hfi.c b/msm/eva/cvp_core_hfi.c index 832fe0117b..3ebbf2f987 100644 --- a/msm/eva/cvp_core_hfi.c +++ b/msm/eva/cvp_core_hfi.c @@ -9,7 +9,7 @@ #include "cvp_core_hfi.h" struct cvp_hfi_device *cvp_hfi_initialize(enum msm_cvp_hfi_type hfi_type, - u32 device_id, struct msm_cvp_platform_resources *res, + struct msm_cvp_platform_resources *res, hfi_cmd_response_callback callback) { struct cvp_hfi_device *hdev = NULL; @@ -21,7 +21,7 @@ struct cvp_hfi_device *cvp_hfi_initialize(enum msm_cvp_hfi_type hfi_type, return NULL; } - rc = cvp_iris_hfi_initialize(hdev, device_id, res, callback); + rc = cvp_iris_hfi_initialize(hdev, res, callback); if (rc) { if (rc != -EPROBE_DEFER) diff --git a/msm/eva/cvp_core_hfi.h b/msm/eva/cvp_core_hfi.h index 9f41bb2632..d44cb54271 100644 --- a/msm/eva/cvp_core_hfi.h +++ b/msm/eva/cvp_core_hfi.h @@ -95,7 +95,7 @@ struct cvp_hfi_mem_map { (i * sizeof(struct cvp_hfi_queue_header))) #define QDSS_SIZE 4096 -#define SFR_SIZE 4096 +#define SFR_SIZE 1048576 #define QUEUE_SIZE (CVP_IFACEQ_TABLE_SIZE + \ (CVP_IFACEQ_QUEUE_SIZE * CVP_IFACEQ_NUMQ)) @@ -242,7 +242,6 @@ struct iris_hfi_device { struct list_head sess_head; u32 version; u32 intr_status; - u32 device_id; u32 clk_freq; u32 last_packet_type; u32 error; @@ -285,7 +284,7 @@ irqreturn_t iris_hfi_core_work_handler(int irq, void *data); irqreturn_t iris_hfi_isr_wd(int irq, void *dev); void cvp_iris_hfi_delete_device(void *device); -int cvp_iris_hfi_initialize(struct cvp_hfi_device *hdev, u32 device_id, +int cvp_iris_hfi_initialize(struct cvp_hfi_device *hdev, struct msm_cvp_platform_resources *res, hfi_cmd_response_callback callback); diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index a15f799a99..5a722683b1 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -177,7 +177,7 @@ int get_hfi_version(void) struct msm_cvp_core *core; struct iris_hfi_device *hfi; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; hfi = (struct iris_hfi_device *)core->device->hfi_device_data; return hfi->version; @@ -189,7 +189,7 @@ unsigned int get_msg_size(struct cvp_hfi_msg_session_hdr *hdr) struct iris_hfi_device *device; u32 minor_ver; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (core) device = core->device->hfi_device_data; else @@ -823,7 +823,7 @@ static int __set_registers(struct iris_hfi_device *device) return -EINVAL ; } - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; pdata = core->platform_data; reg_set = &device->res->reg_set; @@ -2936,7 +2936,6 @@ static void __process_fatal_error( { struct msm_cvp_cb_cmd_done cmd_done = {0}; - cmd_done.device_id = device->device_id; device->callback(HAL_SYS_ERROR, &cmd_done); } @@ -2965,7 +2964,7 @@ static void iris_hfi_pm_handler(struct work_struct *work) struct msm_cvp_core *core; struct iris_hfi_device *device; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (core) device = core->device->hfi_device_data; else @@ -3357,7 +3356,7 @@ static int __response_handler(struct iris_hfi_device *device) struct msm_cvp_cb_info info = { .response_type = HAL_SYS_WATCHDOG_TIMEOUT, .response.cmd = { - .device_id = device->device_id, + .device_id = 0, } }; @@ -3386,8 +3385,7 @@ static int __response_handler(struct iris_hfi_device *device) int rc = 0; print_msg_hdr(hdr); - rc = cvp_hfi_process_msg_packet(device->device_id, - raw_packet, info); + rc = cvp_hfi_process_msg_packet(0, raw_packet, info); if (rc) { dprintk(CVP_WARN, "Corrupt/unknown packet found, discarding\n"); @@ -3464,7 +3462,7 @@ irqreturn_t iris_hfi_core_work_handler(int irq, void *data) u32 intr_status; static bool warning_on = true; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (core) device = core->device->hfi_device_data; else @@ -3544,7 +3542,7 @@ static void iris_hfi_wd_work_handler(struct work_struct *work) struct iris_hfi_device *device; struct msm_cvp_cb_cmd_done response = {0}; enum hal_command_response cmd = HAL_SYS_WATCHDOG_TIMEOUT; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (core) device = core->device->hfi_device_data; else @@ -3552,7 +3550,7 @@ static void iris_hfi_wd_work_handler(struct work_struct *work) if (msm_cvp_hw_wd_recovery) { dprintk(CVP_ERR, "Cleaning up as HW WD recovery is enable %d\n", msm_cvp_hw_wd_recovery); - response.device_id = device->device_id; + response.device_id = 0; handle_sys_error(cmd, (void *) &response); enable_irq(device->cvp_hal_data->irq_wd); } @@ -4887,7 +4885,7 @@ static inline int __resume(struct iris_hfi_device *device) return -EINVAL; } - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; dprintk(CVP_PWR, "Resuming from power collapse\n"); rc = __iris_power_on(device); @@ -5104,7 +5102,7 @@ static void __noc_error_info_iris2(struct iris_hfi_device *device) bool log_required = false; int rc; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (!core->ssr_count && core->resources.max_ssr_allowed > 1) log_required = true; @@ -5286,8 +5284,7 @@ void __init_cvp_ops(struct iris_hfi_device *device) device->vpu_ops = &iris2_ops; } -static struct iris_hfi_device *__add_device(u32 device_id, - struct msm_cvp_platform_resources *res, +static struct iris_hfi_device *__add_device(struct msm_cvp_platform_resources *res, hfi_cmd_response_callback callback) { struct iris_hfi_device *hdevice = NULL; @@ -5298,8 +5295,6 @@ static struct iris_hfi_device *__add_device(u32 device_id, return NULL; } - dprintk(CVP_INFO, "%s: device_id: %d\n", __func__, device_id); - hdevice = kzalloc(sizeof(*hdevice), GFP_KERNEL); if (!hdevice) { dprintk(CVP_ERR, "failed to allocate new device\n"); @@ -5325,7 +5320,6 @@ static struct iris_hfi_device *__add_device(u32 device_id, goto err_cleanup; hdevice->res = res; - hdevice->device_id = device_id; hdevice->callback = callback; __init_cvp_ops(hdevice); @@ -5361,8 +5355,7 @@ exit: return NULL; } -static struct iris_hfi_device *__get_device(u32 device_id, - struct msm_cvp_platform_resources *res, +static struct iris_hfi_device *__get_device(struct msm_cvp_platform_resources *res, hfi_cmd_response_callback callback) { if (!res || !callback) { @@ -5370,7 +5363,7 @@ static struct iris_hfi_device *__get_device(u32 device_id, return NULL; } - return __add_device(device_id, res, callback); + return __add_device(res, callback); } void cvp_iris_hfi_delete_device(void *device) @@ -5381,7 +5374,7 @@ void cvp_iris_hfi_delete_device(void *device) if (!device) return; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (core) dev = core->device->hfi_device_data; @@ -5448,7 +5441,7 @@ static void iris_init_hfi_callbacks(struct cvp_hfi_device *hdev) hdev->debug_hook = iris_debug_hook; } -int cvp_iris_hfi_initialize(struct cvp_hfi_device *hdev, u32 device_id, +int cvp_iris_hfi_initialize(struct cvp_hfi_device *hdev, struct msm_cvp_platform_resources *res, hfi_cmd_response_callback callback) { @@ -5461,7 +5454,7 @@ int cvp_iris_hfi_initialize(struct cvp_hfi_device *hdev, u32 device_id, goto err_iris_hfi_init; } - hdev->hfi_device_data = __get_device(device_id, res, callback); + hdev->hfi_device_data = __get_device(res, callback); if (IS_ERR_OR_NULL(hdev->hfi_device_data)) { rc = PTR_ERR(hdev->hfi_device_data) ?: -EINVAL; diff --git a/msm/eva/cvp_hfi_api.h b/msm/eva/cvp_hfi_api.h index 5fd28f3600..f21daf5b9c 100644 --- a/msm/eva/cvp_hfi_api.h +++ b/msm/eva/cvp_hfi_api.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef __CVP_HFI_API_H__ @@ -298,7 +299,7 @@ enum cvp_status hfi_process_session_init_done_prop_read( struct cvp_hal_session_init_done *session_init_done); struct cvp_hfi_device *cvp_hfi_initialize(enum msm_cvp_hfi_type hfi_type, - u32 device_id, struct msm_cvp_platform_resources *res, + struct msm_cvp_platform_resources *res, hfi_cmd_response_callback callback); void cvp_hfi_deinitialize(enum msm_cvp_hfi_type hfi_type, struct cvp_hfi_device *hdev); diff --git a/msm/eva/cvp_power.c b/msm/eva/cvp_power.c index 42b4ed39e9..e9e6ce2952 100644 --- a/msm/eva/cvp_power.c +++ b/msm/eva/cvp_power.c @@ -155,7 +155,7 @@ static int adjust_bw_freqs(void) int i, rc = 0, bus_count = 0; unsigned long ctrl_freq; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; hdev = core->device->hfi_device_data; clocks = &core->resources.clock_set; @@ -444,7 +444,7 @@ unsigned int msm_cvp_get_hw_aggregate_cycles(enum hfi_hw_thread hwblk) struct msm_cvp_inst *inst; unsigned long cycles_sum = 0; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (!core) { dprintk(CVP_ERR, "%s: invalid core\n", __func__); diff --git a/msm/eva/cvp_smem.c b/msm/eva/cvp_smem.c index 673db56b3f..1dcf884ec6 100644 --- a/msm/eva/cvp_smem.c +++ b/msm/eva/cvp_smem.c @@ -579,7 +579,7 @@ int msm_cvp_map_ipcc_regs(u32 *iova) phys_addr_t paddr; u32 size; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (core) { hfi_ops = core->device; if (hfi_ops) @@ -616,7 +616,7 @@ int msm_cvp_unmap_ipcc_regs(u32 iova) struct iris_hfi_device *dev = NULL; u32 size; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (core) { hfi_ops = core->device; if (hfi_ops) diff --git a/msm/eva/hfi_response_handler.c b/msm/eva/hfi_response_handler.c index 0ded7e6026..0cb9559f63 100644 --- a/msm/eva/hfi_response_handler.c +++ b/msm/eva/hfi_response_handler.c @@ -523,7 +523,7 @@ static int hfi_process_session_dump_notify(u32 device_id, return -E2BIG; } session_id = get_msg_session_id(pkt); - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; inst = cvp_get_inst_from_id(core, session_id); if (!inst) { dprintk(CVP_ERR, "%s: invalid session\n", __func__); @@ -568,7 +568,7 @@ static int hfi_process_session_cvp_msg(u32 device_id, return -E2BIG; } session_id = get_msg_session_id(pkt); - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; inst = cvp_get_inst_from_id(core, session_id); if (!inst) { diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 9635e61a5e..62cba335d7 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -1647,7 +1647,6 @@ int msm_cvp_session_init(struct msm_cvp_inst *inst) inst, hash32_ptr(inst->session)); /* set default frequency */ - inst->clk_data.core_id = 0; inst->clk_data.min_freq = 1000; inst->clk_data.ddr_bw = 1000; inst->clk_data.sys_cache_bw = 1000; diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index e6cf5a9243..9001440cd6 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1702,7 +1702,7 @@ int msm_cvp_map_frame(struct msm_cvp_inst *inst, struct msm_cvp_inst *instance = (struct msm_cvp_inst *)0xdeadbeef; struct msm_cvp_core *core = NULL; - core = get_cvp_core(MSM_CORE_CVP); + core = cvp_driver->cvp_core; if (!core) return -EINVAL; @@ -1903,7 +1903,7 @@ void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) struct inst_snapshot *snap = NULL; int i = 0, c = 0; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (log && core->log.snapshot_index < 16) { snap = &core->log.snapshot[core->log.snapshot_index]; snap->session = inst->session; diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 8429137ac8..3b03d87a27 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -72,31 +72,6 @@ void print_hfi_queue_info(struct cvp_hfi_device *hdev) } } - - -struct msm_cvp_core *get_cvp_core(int core_id) -{ - struct msm_cvp_core *core; - int found = 0; - - if (core_id > MSM_CVP_CORES_MAX) { - dprintk(CVP_ERR, "Core id = %d is greater than max = %d\n", - core_id, MSM_CVP_CORES_MAX); - return NULL; - } - mutex_lock(&cvp_driver->lock); - list_for_each_entry(core, &cvp_driver->cores, list) { - if (core->id == core_id) { - found = 1; - break; - } - } - mutex_unlock(&cvp_driver->lock); - if (found) - return core; - return NULL; -} - static void handle_sys_init_done(enum hal_command_response cmd, void *data) { struct msm_cvp_cb_cmd_done *response = data; @@ -116,7 +91,7 @@ static void handle_sys_init_done(enum hal_command_response cmd, void *data) "Failed to get valid response for sys init\n"); return; } - core = get_cvp_core(response->device_id); + core = cvp_driver->cvp_core; if (!core) { dprintk(CVP_ERR, "Wrong device_id received\n"); return; @@ -239,8 +214,7 @@ static void handle_session_set_buf_done(enum hal_command_response cmd, return; } - inst = cvp_get_inst(get_cvp_core(response->device_id), - response->session_id); + inst = cvp_get_inst(cvp_driver->cvp_core, response->session_id); if (!inst) { dprintk(CVP_WARN, "set_buf_done has an inactive session\n"); return; @@ -275,8 +249,7 @@ static void handle_session_release_buf_done(enum hal_command_response cmd, return; } - inst = cvp_get_inst(get_cvp_core(response->device_id), - response->session_id); + inst = cvp_get_inst(cvp_driver->cvp_core, response->session_id); if (!inst) { dprintk(CVP_WARN, "%s: Got a response for an inactive session\n", @@ -321,7 +294,7 @@ static void handle_sys_release_res_done( "Failed to get valid response for sys init\n"); return; } - core = get_cvp_core(response->device_id); + core = cvp_driver->cvp_core; if (!core) { dprintk(CVP_ERR, "Wrong device_id received\n"); return; @@ -428,8 +401,7 @@ static void handle_session_init_done(enum hal_command_response cmd, void *data) return; } - inst = cvp_get_inst(get_cvp_core(response->device_id), - response->session_id); + inst = cvp_get_inst(cvp_driver->cvp_core, response->session_id); if (!inst) { dprintk(CVP_WARN, "%s:Got a response for an inactive session\n", @@ -471,8 +443,7 @@ static void handle_session_dump_notify(enum hal_command_response cmd, return; } - inst = cvp_get_inst(get_cvp_core(response->device_id), - response->session_id); + inst = cvp_get_inst(cvp_driver->cvp_core, response->session_id); if (!inst) { dprintk(CVP_WARN, "%s:Got a response for an inactive session\n", __func__); @@ -497,8 +468,7 @@ static void handle_release_res_done(enum hal_command_response cmd, void *data) return; } - inst = cvp_get_inst(get_cvp_core(response->device_id), - response->session_id); + inst = cvp_get_inst(cvp_driver->cvp_core, response->session_id); if (!inst) { dprintk(CVP_WARN, "%s:Got a response for an inactive session\n", __func__); @@ -520,8 +490,7 @@ static void handle_session_ctrl(enum hal_command_response cmd, void *data) return; } - inst = cvp_get_inst(get_cvp_core(response->device_id), - response->session_id); + inst = cvp_get_inst(cvp_driver->cvp_core, response->session_id); if (!inst) { dprintk(CVP_WARN, "%s:Got a response for an inactive session\n", __func__); @@ -551,8 +520,7 @@ static void handle_session_error(enum hal_command_response cmd, void *data) return; } - inst = cvp_get_inst(get_cvp_core(response->device_id), - response->session_id); + inst = cvp_get_inst(cvp_driver->cvp_core, response->session_id); if (!inst) { dprintk(CVP_WARN, "%s: response for an inactive session\n", __func__); @@ -596,7 +564,7 @@ void handle_sys_error(enum hal_command_response cmd, void *data) return; } - core = get_cvp_core(response->device_id); + core = cvp_driver->cvp_core; if (!core) { dprintk(CVP_ERR, "Got SYS_ERR but unable to identify core\n"); @@ -702,8 +670,7 @@ static void handle_session_close(enum hal_command_response cmd, void *data) return; } - inst = cvp_get_inst(get_cvp_core(response->device_id), - response->session_id); + inst = cvp_get_inst(cvp_driver->cvp_core, response->session_id); if (!inst) { dprintk(CVP_WARN, "%s: response for an inactive session\n", __func__); @@ -784,53 +751,6 @@ static inline enum msm_cvp_thermal_level msm_comm_cvp_thermal_level(int level) } } -static bool is_core_turbo(struct msm_cvp_core *core, unsigned long freq) -{ - int i = 0; - struct allowed_clock_rates_table *allowed_clks_tbl = NULL; - u32 max_freq = 0; - - allowed_clks_tbl = core->resources.allowed_clks_tbl; - for (i = 0; i < core->resources.allowed_clks_tbl_size; i++) { - if (max_freq < allowed_clks_tbl[i].clock_rate) - max_freq = allowed_clks_tbl[i].clock_rate; - } - return freq >= max_freq; -} - -static bool is_thermal_permissible(struct msm_cvp_core *core) -{ - enum msm_cvp_thermal_level tl; - unsigned long freq = 0; - bool is_turbo = false; - - if (!core->resources.thermal_mitigable) - return true; - - if (msm_cvp_thermal_mitigation_disabled) { - dprintk(CVP_CORE, - "Thermal mitigation not enabled. debugfs %d\n", - msm_cvp_thermal_mitigation_disabled); - return true; - } - - tl = msm_comm_cvp_thermal_level(cvp_driver->thermal_level); - freq = core->curr_freq; - - is_turbo = is_core_turbo(core, freq); - dprintk(CVP_CORE, - "Core freq %ld Thermal level %d Turbo mode %d\n", - freq, tl, is_turbo); - - if (is_turbo && tl >= CVP_THERMAL_LOW) { - dprintk(CVP_ERR, - "CVP session not allowed. Turbo mode %d Thermal level %d\n", - is_turbo, tl); - return false; - } - return true; -} - static int msm_comm_session_abort(struct msm_cvp_inst *inst) { int rc = 0, abort_completion = 0; @@ -875,22 +795,9 @@ exit: return rc; } -static void handle_thermal_event(struct msm_cvp_core *core) -{ - dprintk(CVP_WARN, "Deprecated thermal_event handler\n"); -} - void msm_cvp_comm_handle_thermal_event(void) { - struct msm_cvp_core *core; - - list_for_each_entry(core, &cvp_driver->cores, list) { - if (!is_thermal_permissible(core)) { - dprintk(CVP_WARN, - "Thermal level critical, stop all active sessions!\n"); - handle_thermal_event(core); - } - } + dprintk(CVP_WARN, "deprecated %s called\n", __func__); } int msm_cvp_comm_check_core_init(struct msm_cvp_core *core) @@ -900,8 +807,8 @@ int msm_cvp_comm_check_core_init(struct msm_cvp_core *core) mutex_lock(&core->lock); if (core->state >= CVP_CORE_INIT_DONE) { - dprintk(CVP_INFO, "CVP core: %d is already in state: %d\n", - core->id, core->state); + dprintk(CVP_INFO, "CVP core: is already in state: %d\n", + core->state); goto exit; } dprintk(CVP_CORE, "Waiting for SYS_INIT_DONE\n"); @@ -952,8 +859,8 @@ static int msm_comm_init_core(struct msm_cvp_inst *inst) hdev = core->device; mutex_lock(&core->lock); if (core->state >= CVP_CORE_INIT) { - dprintk(CVP_CORE, "CVP core: %d is already in state: %d\n", - core->id, core->state); + dprintk(CVP_CORE, "CVP core: is already in state: %d\n", + core->state); goto core_already_inited; } if (!core->capabilities) { @@ -974,8 +881,7 @@ static int msm_comm_init_core(struct msm_cvp_inst *inst) dprintk(CVP_CORE, "%s: core %pK\n", __func__, core); rc = call_hfi_op(hdev, core_init, hdev->hfi_device_data); if (rc) { - dprintk(CVP_ERR, "Failed to init core, id = %d\n", - core->id); + dprintk(CVP_ERR, "Failed to init core\n"); goto fail_core_init; } core->state = CVP_CORE_INIT; @@ -1095,17 +1001,16 @@ exit: return rc; } -int msm_cvp_comm_suspend(int core_id) +int msm_cvp_comm_suspend(void) { struct cvp_hfi_device *hdev; struct msm_cvp_core *core; int rc = 0; - core = get_cvp_core(core_id); + core = cvp_driver->cvp_core; if (!core) { dprintk(CVP_ERR, - "%s: Failed to find core for core_id = %d\n", - __func__, core_id); + "%s: Failed to find cvp core\n", __func__); return -EINVAL; } @@ -1153,7 +1058,7 @@ int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state) int flipped_state; struct msm_cvp_core *core; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (!inst) { dprintk(CVP_ERR, "%s: invalid params %pK", __func__, inst); @@ -1362,7 +1267,6 @@ void msm_cvp_comm_generate_sys_error(struct msm_cvp_inst *inst) } dprintk(CVP_WARN, "%s: inst %pK\n", __func__, inst); core = inst->core; - response.device_id = (u32) core->id; handle_sys_error(cmd, (void *) &response); } @@ -1480,7 +1384,7 @@ bool is_cvp_inst_valid(struct msm_cvp_inst *inst) struct msm_cvp_core *core; struct msm_cvp_inst *sess; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (!core) return false; diff --git a/msm/eva/msm_cvp_common.h b/msm/eva/msm_cvp_common.h index b9dc2e06f2..f434e91304 100644 --- a/msm/eva/msm_cvp_common.h +++ b/msm/eva/msm_cvp_common.h @@ -16,10 +16,9 @@ struct msm_cvp_inst *cvp_get_inst_validate(struct msm_cvp_core *core, bool is_cvp_inst_valid(struct msm_cvp_inst *inst); void cvp_change_inst_state(struct msm_cvp_inst *inst, enum instance_state state); -struct msm_cvp_core *get_cvp_core(int core_id); int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state); int msm_cvp_deinit_core(struct msm_cvp_inst *inst); -int msm_cvp_comm_suspend(int core_id); +int msm_cvp_comm_suspend(void); void msm_cvp_comm_session_clean(struct msm_cvp_inst *inst); int msm_cvp_comm_kill_session(struct msm_cvp_inst *inst); void msm_cvp_comm_generate_sys_error(struct msm_cvp_inst *inst); diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index e9825c4bed..2fe425e9b5 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -138,7 +139,7 @@ static void __deinit_session_queue(struct msm_cvp_inst *inst) wake_up_all(&inst->session_queue.wq); } -void *msm_cvp_open(int core_id, int session_type, struct task_struct *task) +void *msm_cvp_open(int session_type, struct task_struct *task) { struct msm_cvp_inst *inst = NULL; struct msm_cvp_core *core = NULL; @@ -146,16 +147,9 @@ void *msm_cvp_open(int core_id, int session_type, struct task_struct *task) int i = 0; u32 instance_count; - if (core_id >= MSM_CVP_CORES_MAX || - session_type >= MSM_CVP_MAX_DEVICES) { - dprintk(CVP_ERR, "Invalid input, core_id = %d, session = %d\n", - core_id, session_type); - goto err_invalid_core; - } - core = get_cvp_core(core_id); + core = cvp_driver->cvp_core; if (!core) { - dprintk(CVP_ERR, - "Failed to find core for core_id = %d\n", core_id); + dprintk(CVP_ERR, "%s CVP core not initialized\n", __func__); goto err_invalid_core; } @@ -210,7 +204,6 @@ void *msm_cvp_open(int core_id, int session_type, struct task_struct *task) inst->clk_data.ddr_bw = 0; inst->clk_data.sys_cache_bw = 0; inst->clk_data.bitrate = 0; - inst->clk_data.core_id = 0; for (i = SESSION_MSG_INDEX(SESSION_MSG_START); i <= SESSION_MSG_INDEX(SESSION_MSG_END); i++) { @@ -473,8 +466,8 @@ int msm_cvp_close(void *instance) } EXPORT_SYMBOL(msm_cvp_close); -int msm_cvp_suspend(int core_id) +int msm_cvp_suspend(void) { - return msm_cvp_comm_suspend(core_id); + return msm_cvp_comm_suspend(); } EXPORT_SYMBOL(msm_cvp_suspend); diff --git a/msm/eva/msm_cvp_core.h b/msm/eva/msm_cvp_core.h index 15c12fd8c0..dd0f706dc0 100644 --- a/msm/eva/msm_cvp_core.h +++ b/msm/eva/msm_cvp_core.h @@ -20,11 +20,6 @@ #define DDR_TYPE_LPDDR4Y 0x8 #define DDR_TYPE_LPDDR5 0x9 -enum core_id { - MSM_CORE_CVP = 0, - MSM_CVP_CORES_MAX, -}; - enum session_type { MSM_CVP_USER = 1, MSM_CVP_KERNEL, @@ -34,9 +29,9 @@ enum session_type { MSM_CVP_MAX_DEVICES = MSM_CVP_UNKNOWN, }; -void *msm_cvp_open(int core_id, int session_type, struct task_struct *task); +void *msm_cvp_open(int session_type, struct task_struct *task); int msm_cvp_close(void *instance); -int msm_cvp_suspend(int core_id); +int msm_cvp_suspend(void); int msm_cvp_poll(void *instance, struct file *filp, struct poll_table_struct *pt); int msm_cvp_private(void *cvp_inst, unsigned int cmd, diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 160491c3ea..381ed94987 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -90,7 +91,7 @@ static ssize_t core_info_read(struct file *file, char __user *buf, hdev = core->device; cur += write_str(cur, end - cur, "===============================\n"); - cur += write_str(cur, end - cur, "CORE %d: %pK\n", core->id, core); + cur += write_str(cur, end - cur, "CORE %d: %pK\n", 0, core); cur += write_str(cur, end - cur, "===============================\n"); cur += write_str(cur, end - cur, "Core state: %d\n", core->state); rc = call_hfi_op(hdev, get_fw_info, hdev->hfi_device_data, &fw_info); @@ -181,7 +182,7 @@ static int cvp_power_get(void *data, u64 *val) struct msm_cvp_core *core; struct iris_hfi_device *hfi_device; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (!core) return 0; hfi_ops = core->device; @@ -206,7 +207,7 @@ static int cvp_power_set(void *data, u64 val) struct iris_hfi_device *hfi_device; int rc = 0; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (!core) return -EINVAL; @@ -288,7 +289,7 @@ static int _clk_rate_set(void *data, u64 val) struct allowed_clock_rates_table *tbl = NULL; unsigned int tbl_size, i; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; dev = core->device; tbl = core->resources.allowed_clks_tbl; tbl_size = core->resources.allowed_clks_tbl_size; @@ -324,7 +325,7 @@ static int _clk_rate_get(void *data, u64 *val) struct msm_cvp_core *core; struct iris_hfi_device *hdev; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; hdev = core->device->hfi_device_data; if (msm_cvp_clock_voting) *val = msm_cvp_clock_voting; @@ -357,7 +358,7 @@ DEFINE_DEBUGFS_ATTRIBUTE(dsp_debug_fops, _dsp_dbg_get, _dsp_dbg_set, "%llu\n"); static int _max_ssr_set(void *data, u64 val) { struct msm_cvp_core *core; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (core) { if (val < 1) { dprintk(CVP_WARN, @@ -373,7 +374,7 @@ static int _max_ssr_set(void *data, u64 val) static int _max_ssr_get(void *data, u64 *val) { struct msm_cvp_core *core; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (core) *val = core->resources.max_ssr_allowed; @@ -385,7 +386,7 @@ DEFINE_DEBUGFS_ATTRIBUTE(max_ssr_fops, _max_ssr_get, _max_ssr_set, "%llu\n"); static int _ssr_stall_set(void *data, u64 val) { struct msm_cvp_core *core; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (core) core->resources.fatal_ssr = (val >= 1) ? true : false; @@ -395,7 +396,7 @@ static int _ssr_stall_set(void *data, u64 val) static int _ssr_stall_get(void *data, u64 *val) { struct msm_cvp_core *core; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (core) *val = core->resources.fatal_ssr ? 1 : 0; @@ -416,7 +417,7 @@ struct dentry *msm_cvp_debugfs_init_core(struct msm_cvp_core *core, goto failed_create_dir; } - snprintf(debugfs_name, MAX_DEBUGFS_NAME, "core%d", core->id); + snprintf(debugfs_name, MAX_DEBUGFS_NAME, "core%d", 0); dir = debugfs_create_dir(debugfs_name, parent); if (IS_ERR_OR_NULL(dir)) { dir = NULL; diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 289867ff51..78ee7f944f 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include #include @@ -494,7 +495,7 @@ static bool dsp_session_exist(void) struct msm_cvp_core *core; struct msm_cvp_inst *inst = NULL; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (core) { mutex_lock(&core->lock); list_for_each_entry(inst, &core->instances, list) { @@ -896,7 +897,7 @@ static int __reinit_dsp(void) struct msm_cvp_core *core; struct iris_hfi_device *device; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (core && core->device) device = core->device->hfi_device_data; else @@ -1365,7 +1366,7 @@ void cvp_dsp_send_hfi_queue(void) uint32_t size; int rc; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (core && core->device) device = core->device->hfi_device_data; else @@ -1469,7 +1470,7 @@ static void *get_inst_from_dsp(uint32_t session_cpu_high, uint32_t session_cpu_l return inst; } - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (core) { mutex_lock(&core->lock); list_for_each_entry(sess_inst, &core->instances, list) { @@ -1565,7 +1566,7 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) goto fail_lookup; } - inst = msm_cvp_open(MSM_CORE_CVP, MSM_CVP_DSP, task); + inst = msm_cvp_open(MSM_CVP_DSP, task); if (!inst) { dprintk(CVP_ERR, "%s Failed create instance\n", __func__); goto fail_msm_cvp_open; @@ -2099,7 +2100,7 @@ static int cvp_dsp_thread(void *data) struct cvp_hfi_device *hdev; struct msm_cvp_core *core; - core = list_first_entry(&cvp_driver->cores, struct msm_cvp_core, list); + core = cvp_driver->cvp_core; if (!core) { dprintk(CVP_ERR, "%s: Failed to find core\n", __func__); rc = -EINVAL; diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index 203b7afb1a..e81a0b3d5a 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _MSM_CVP_INTERNAL_H_ @@ -135,8 +136,7 @@ struct cvp_kmem_cache { struct msm_cvp_drv { struct mutex lock; - struct list_head cores; - int num_cores; + struct msm_cvp_core *cvp_core; struct dentry *debugfs_root; int thermal_level; u32 sku_version; @@ -170,7 +170,6 @@ struct cvp_clock_data { u32 ddr_bw; u32 sys_cache_bw; u32 operating_rate; - u32 core_id; bool low_latency_mode; bool turbo_mode; }; @@ -331,10 +330,8 @@ struct cvp_debug_log { }; struct msm_cvp_core { - struct list_head list; struct mutex lock; struct mutex clk_lock; - int id; dev_t dev_num; struct cdev cdev; struct class *class; From 0eedd436e144efa0869fa4cf8e1ee754e9cf7c29 Mon Sep 17 00:00:00 2001 From: Palak Joshi Date: Sat, 3 Jun 2023 12:01:26 +0530 Subject: [PATCH 225/317] msm: eva: Identify the actual number of silver cores available with target As PM QOS request needs to done for silver cores only for EVA and number of silver cores would be different for different target so, better to identify the actual number of available silver cores. Added cpu_possible check to confirm if cpu is available or not. Change-Id: Ibccc7688200732c3c666041a8fe414b4f2818993 Signed-off-by: Palak Joshi --- msm/eva/cvp_hfi.c | 6 ++++++ msm/eva/msm_cvp_res_parse.c | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 5a722683b1..0a0f3bcf5c 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -2027,6 +2027,8 @@ static void cvp_pm_qos_update(struct iris_hfi_device *device, bool vote_on) if (device->res->pm_qos.latency_us && device->res->pm_qos.pm_qos_hdls) for (i = 0; i < device->res->pm_qos.silver_count; i++) { + if (!cpu_possible(device->res->pm_qos.silver_cores[i])) + continue; err = dev_pm_qos_update_request( &device->res->pm_qos.pm_qos_hdls[i], latency); @@ -2299,6 +2301,8 @@ static int iris_hfi_core_init(void *device) for (i = 0; i < dev->res->pm_qos.silver_count; i++) { cpu = dev->res->pm_qos.silver_cores[i]; + if (!cpu_possible(cpu)) + continue; err = dev_pm_qos_add_request( get_cpu_device(cpu), &dev->res->pm_qos.pm_qos_hdls[i], @@ -2355,6 +2359,8 @@ static int iris_hfi_core_release(void *dev) if (device->res->pm_qos.latency_us && device->res->pm_qos.pm_qos_hdls) { for (i = 0; i < device->res->pm_qos.silver_count; i++) { + if (!cpu_possible(device->res->pm_qos.silver_cores[i])) + continue; qos_hdl = &device->res->pm_qos.pm_qos_hdls[i]; if ((qos_hdl != NULL) && dev_pm_qos_request_active(qos_hdl)) dev_pm_qos_remove_request(qos_hdl); diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index f9bb54170d..ae08d00379 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -848,7 +848,13 @@ int cvp_read_platform_resources_from_drv_data( res->pm_qos.latency_us = find_key_value(platform_data, "qcom,pm-qos-latency-us"); - res->pm_qos.silver_count = 4; + res->pm_qos.silver_count = 0; + for(i = 0; i < MAX_SILVER_CORE_NUM; i++) { + if(topology_cluster_id(i) == 0) + res->pm_qos.silver_count++; + else + break; + } for (i = 0; i < res->pm_qos.silver_count; i++) res->pm_qos.silver_cores[i] = i; res->pm_qos.off_vote_cnt = 0; From 3b5b676e7aae6b95ea3e504e12a36328ce2831c8 Mon Sep 17 00:00:00 2001 From: Naveen Ravi Date: Thu, 18 May 2023 11:08:40 -0700 Subject: [PATCH 226/317] msm: eva: enable bazel compilation for eva Enabling EVA driver DDK build. Change-Id: Ia2b7a440249dd463495eed51969e59d0608f4d37 Signed-off-by: George Shen --- Android.mk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Android.mk b/Android.mk index 214ee88bff..b74a1b3cc0 100644 --- a/Android.mk +++ b/Android.mk @@ -4,6 +4,9 @@ ifeq ($(call is-board-platform-in-list, $(TARGET_BOARD_PLATFORM)),true) DLKM_DIR := device/qcom/common/dlkm LOCAL_PATH := $(call my-dir) +# For DDK +LOCAL_MODULE_DDK_BUILD := true +LOCAL_MODULE_KO_DIRS := msm/msm-eva.ko include $(CLEAR_VARS) # For incremental compilation From 33825ea411e429b18176721db6bd7c07caf9e722 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 5 Jun 2023 17:01:56 -0700 Subject: [PATCH 227/317] msm: eva: Fix KW issue Change-Id: I93a8ff3ac20de452c2aa220a3dc4bc052880762e Signed-off-by: George Shen --- msm/eva/msm_cvp.c | 15 +++------------ msm/eva/msm_cvp_buf.c | 8 ++++++-- msm/eva/msm_cvp_common.c | 10 +++++++++- msm/eva/msm_cvp_core.c | 9 ++++++--- msm/eva/msm_cvp_core.h | 2 +- msm/eva/msm_cvp_debug.c | 7 +++++-- msm/eva/msm_cvp_dsp.c | 10 ++++++++++ 7 files changed, 40 insertions(+), 21 deletions(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 62cba335d7..a32ba467fb 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -1325,10 +1325,7 @@ static int cvp_drain_fence_sched_list(struct msm_cvp_inst *inst) if (!q) return -EINVAL; - f = list_first_entry(&q->sched_list, - struct cvp_fence_command, - list); - if (!f) + if (list_empty(&q->sched_list)) return rc; mutex_lock(&q->lock); @@ -1382,10 +1379,7 @@ static void cvp_clean_fence_queue(struct msm_cvp_inst *inst, int synx_state) mutex_lock(&q->lock); q->mode = OP_DRAINING; - f = list_first_entry(&q->wait_list, - struct cvp_fence_command, - list); - if (!f) + if (list_empty(&q->wait_list)) goto check_sched; list_for_each_entry_safe(f, d, &q->wait_list, list) { @@ -1403,10 +1397,7 @@ static void cvp_clean_fence_queue(struct msm_cvp_inst *inst, int synx_state) } check_sched: - f = list_first_entry(&q->sched_list, - struct cvp_fence_command, - list); - if (!f) { + if (list_empty(&q->sched_list)) { mutex_unlock(&q->lock); return; } diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 9001440cd6..4855a2f8a1 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1424,8 +1424,8 @@ static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, { u32 iova = 0; struct msm_cvp_smem *smem = NULL; - struct list_head *ptr = (struct list_head *)0xdead; - struct list_head *next = (struct list_head *)0xdead; + struct list_head *ptr; + struct list_head *next; struct cvp_internal_buf *pbuf; struct dma_buf *dma_buf; @@ -1439,6 +1439,10 @@ static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, return -EINVAL; mutex_lock(&inst->persistbufs.lock); + if (!inst->persistbufs.list.next) { + mutex_unlock(&inst->persistbufs.lock); + return 0; + } list_for_each_safe(ptr, next, &inst->persistbufs.list) { if (!ptr) return 0; diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 3b03d87a27..46e121522a 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -126,7 +126,12 @@ static void handle_sys_init_done(enum hal_command_response cmd, void *data) static void put_inst_helper(struct kref *kref) { - struct msm_cvp_inst *inst = container_of(kref, + struct msm_cvp_inst *inst; + + if (!kref) + return; + + inst = container_of(kref, struct msm_cvp_inst, kref); msm_cvp_destroy(inst); @@ -1190,6 +1195,9 @@ void msm_cvp_ssr_handler(struct work_struct *work) struct msm_cvp_core *core; struct cvp_hfi_device *hdev; + if (!work) + return; + core = container_of(work, struct msm_cvp_core, ssr_work); if (!core || !core->device) { dprintk(CVP_ERR, "%s: Invalid params\n", __func__); diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 2fe425e9b5..11f65b486c 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -139,7 +139,7 @@ static void __deinit_session_queue(struct msm_cvp_inst *inst) wake_up_all(&inst->session_queue.wq); } -void *msm_cvp_open(int session_type, struct task_struct *task) +struct msm_cvp_inst *msm_cvp_open(int session_type, struct task_struct *task) { struct msm_cvp_inst *inst = NULL; struct msm_cvp_core *core = NULL; @@ -428,8 +428,11 @@ int msm_cvp_destroy(struct msm_cvp_inst *inst) static void close_helper(struct kref *kref) { - struct msm_cvp_inst *inst = container_of(kref, - struct msm_cvp_inst, kref); + struct msm_cvp_inst *inst; + + if (!kref) + return; + inst = container_of(kref, struct msm_cvp_inst, kref); msm_cvp_destroy(inst); } diff --git a/msm/eva/msm_cvp_core.h b/msm/eva/msm_cvp_core.h index dd0f706dc0..aee7d60426 100644 --- a/msm/eva/msm_cvp_core.h +++ b/msm/eva/msm_cvp_core.h @@ -29,7 +29,7 @@ enum session_type { MSM_CVP_MAX_DEVICES = MSM_CVP_UNKNOWN, }; -void *msm_cvp_open(int session_type, struct task_struct *task); +struct msm_cvp_inst *msm_cvp_open(int session_type, struct task_struct *task); int msm_cvp_close(void *instance); int msm_cvp_suspend(void); int msm_cvp_poll(void *instance, struct file *filp, diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 381ed94987..20a2300862 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -477,8 +477,11 @@ static int publish_unreleased_reference(struct msm_cvp_inst *inst, static void put_inst_helper(struct kref *kref) { - struct msm_cvp_inst *inst = container_of(kref, - struct msm_cvp_inst, kref); + struct msm_cvp_inst *inst; + + if (!kref) + return; + inst = container_of(kref, struct msm_cvp_inst, kref); msm_cvp_destroy(inst); } diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 78ee7f944f..5c384cc052 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -233,6 +233,8 @@ static int delete_dsp_session(struct msm_cvp_inst *inst, mutex_lock(&buf_list->lock); ptr_dsp_buf = &buf_list->list; list_for_each_safe(ptr_dsp_buf, next_dsp_buf, &buf_list->list) { + if (!ptr_dsp_buf) + break; buf = list_entry(ptr_dsp_buf, struct cvp_internal_buf, list); if (buf) { dprintk(CVP_DSP, "fd in list 0x%x\n", buf->fd); @@ -379,6 +381,8 @@ search_again: mutex_lock(&me->fastrpc_driver_list.lock); list_for_each_safe(ptr, next, &me->fastrpc_driver_list.list) { + if (!ptr) + break; frpc_node = list_entry(ptr, struct cvp_dsp_fastrpc_driver_entry, list); @@ -991,6 +995,8 @@ static struct cvp_dsp_fastrpc_driver_entry *cvp_get_fastrpc_node_with_handle( mutex_lock(&me->fastrpc_driver_list.lock); list_for_each_safe(ptr, next, &me->fastrpc_driver_list.list) { + if (!ptr) + break; tmp_node = list_entry(ptr, struct cvp_dsp_fastrpc_driver_entry, list); if (handle == tmp_node->handle) { @@ -1189,6 +1195,8 @@ int cvp_dsp_del_sess(uint32_t handle, struct msm_cvp_inst *inst) } mutex_lock(&frpc_node->dsp_sessions.lock); list_for_each_safe(ptr, next, &frpc_node->dsp_sessions.list) { + if (!ptr) + break; sess = list_entry(ptr, struct msm_cvp_inst, dsp_list); if (sess == inst) { dprintk(CVP_DSP, "%s Find sess %pK to be deleted\n", @@ -1989,6 +1997,8 @@ static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) buf_list = &inst->cvpdspbufs; mutex_lock(&buf_list->lock); list_for_each_safe(ptr, next, &buf_list->list) { + if (!ptr) + break; buf = list_entry(ptr, struct cvp_internal_buf, list); if (!buf->smem) { From efc1db7f276a205eb3ad83abb07e116df18072cd Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 7 Jun 2023 22:13:12 -0700 Subject: [PATCH 228/317] msm: eva: fix deadlock to acquire core lock During message handling path. Remove DCVS for FD. Change-Id: Iace13914014b4305553729ac305c141433b79a8f Signed-off-by: George Shen --- msm/eva/cvp.c | 11 -- msm/eva/cvp_power.c | 291 +++++-------------------------------- msm/eva/cvp_power.h | 6 +- msm/eva/msm_cvp.c | 16 +- msm/eva/msm_cvp_dsp.c | 5 +- msm/eva/msm_cvp_internal.h | 18 +-- 6 files changed, 44 insertions(+), 303 deletions(-) diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index aa210c52ea..cde9fe25d2 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -112,16 +112,6 @@ static int read_platform_resources(struct msm_cvp_core *core, return rc; } -static void init_cycle_info(struct cvp_cycle_info *info) -{ - memset(info->sum_fps, 0, HFI_MAX_HW_THREADS*sizeof(u32)); - memset(info->hi_ctrl_lim, 0, HFI_MAX_HW_THREADS*sizeof(u32)); - memset(info->lo_ctrl_lim, 0, HFI_MAX_HW_THREADS*sizeof(u32)); - memset(info->cycle, 0, - HFI_MAX_HW_THREADS*sizeof(struct cvp_cycle_stat)); - info->conf_freq = 0; -} - static int msm_cvp_initialize_core(struct platform_device *pdev, struct msm_cvp_core *core) { @@ -147,7 +137,6 @@ static int msm_cvp_initialize_core(struct platform_device *pdev, } INIT_WORK(&core->ssr_work, msm_cvp_ssr_handler); - init_cycle_info(&core->dyn_clk); core->ssr_count = 0; return rc; diff --git a/msm/eva/cvp_power.c b/msm/eva/cvp_power.c index e9e6ce2952..0b3fc1ee98 100644 --- a/msm/eva/cvp_power.c +++ b/msm/eva/cvp_power.c @@ -46,9 +46,6 @@ static void aggregate_power_update(struct msm_cvp_core *core, unsigned long op_blocks_max[2][HFI_MAX_HW_THREADS] = {0}; unsigned long op_fw_max[2] = {0}, bw_sum[2] = {0}, op_bw_max[2] = {0}; - for (j = 0; j < HFI_MAX_HW_THREADS; j++) - core->dyn_clk.sum_fps[j] = 0; - list_for_each_entry(inst, &core->instances, list) { if (inst->state == MSM_CVP_CORE_INVALID || inst->state == MSM_CVP_CORE_UNINIT || @@ -97,13 +94,8 @@ static void aggregate_power_update(struct msm_cvp_core *core, if (inst->prop.fps[j]) dprintk(CVP_PWR, "fps %s %d ", hw_names[j], inst->prop.fps[j]); - core->dyn_clk.sum_fps[j] += inst->prop.fps[j]; } - for (j = 0; j < HFI_MAX_HW_THREADS; j++) - if (core->dyn_clk.sum_fps[j]) - dprintk(CVP_PWR, "sum_fps %s %d ", hw_names[j], - core->dyn_clk.sum_fps[j]); } for (i = 0; i < 2; i++) { @@ -140,43 +132,25 @@ static void aggregate_power_update(struct msm_cvp_core *core, * * Ensure caller acquires clk_lock! */ -static int adjust_bw_freqs(void) +static int adjust_bw_freqs(unsigned int max_bw, unsigned int min_bw) { struct msm_cvp_core *core; struct iris_hfi_device *hdev; - struct bus_info *bus = NULL; - struct clock_set *clocks; - struct clock_info *cl; struct allowed_clock_rates_table *tbl = NULL; unsigned int tbl_size; - unsigned int cvp_min_rate, cvp_max_rate, max_bw = 0, min_bw = 0; + unsigned int cvp_min_rate, cvp_max_rate; struct cvp_power_level rt_pwr = {0}, nrt_pwr = {0}; unsigned long tmp, core_sum, op_core_sum, bw_sum; - int i, rc = 0, bus_count = 0; - unsigned long ctrl_freq; + int i; core = cvp_driver->cvp_core; hdev = core->device->hfi_device_data; - clocks = &core->resources.clock_set; - cl = &clocks->clock_tbl[clocks->count - 1]; tbl = core->resources.allowed_clks_tbl; tbl_size = core->resources.allowed_clks_tbl_size; cvp_min_rate = tbl[0].clock_rate; cvp_max_rate = tbl[tbl_size - 1].clock_rate; - for (bus_count = 0; bus_count < core->resources.bus_set.count; bus_count++) { - if (!strcmp(core->resources.bus_set.bus_tbl[bus_count].name, "cvp-ddr")) { - bus = &core->resources.bus_set.bus_tbl[bus_count]; - max_bw = bus->range[1]; - min_bw = max_bw/10; - } - } - if (!bus) { - dprintk(CVP_ERR, "bus node is NULL for cvp-ddr\n"); - return -EINVAL; - } - aggregate_power_update(core, &nrt_pwr, &rt_pwr, cvp_max_rate); dprintk(CVP_PWR, "PwrUpdate nrt %u %u rt %u %u\n", nrt_pwr.core_sum, nrt_pwr.op_core_sum, @@ -213,36 +187,15 @@ static int adjust_bw_freqs(void) dprintk(CVP_PWR, "%s %lld %lld\n", __func__, core_sum, bw_sum); - if (!cl->has_scaling) { - dprintk(CVP_ERR, "Cannot scale CVP clock\n"); - return -EINVAL; - } tmp = core->curr_freq; core->curr_freq = core_sum; - core->orig_core_sum = core_sum; - rc = msm_cvp_set_clocks(core); - if (rc) { - dprintk(CVP_ERR, - "Failed to set clock rate %u %s: %d %s\n", - core_sum, cl->name, rc, __func__); - core->curr_freq = tmp; - return rc; - } - - ctrl_freq = (core->curr_freq*3)>>1; - core->dyn_clk.conf_freq = core->curr_freq; - for (i = 0; i < HFI_MAX_HW_THREADS; ++i) { - core->dyn_clk.hi_ctrl_lim[i] = core->dyn_clk.sum_fps[i] ? - ctrl_freq/core->dyn_clk.sum_fps[i] : 0; - core->dyn_clk.lo_ctrl_lim[i] = - core->dyn_clk.hi_ctrl_lim[i]; - } + core->orig_core_sum = tmp; hdev->clk_freq = core->curr_freq; - rc = msm_cvp_set_bw(bus, bw_sum); + core->bw_sum = bw_sum; - return rc; + return 0; } int msm_cvp_update_power(struct msm_cvp_inst *inst) @@ -250,6 +203,11 @@ int msm_cvp_update_power(struct msm_cvp_inst *inst) int rc = 0; struct msm_cvp_core *core; struct msm_cvp_inst *s; + struct bus_info *bus = NULL; + struct clock_set *clocks; + struct clock_info *cl; + int bus_count = 0; + unsigned int max_bw = 0, min_bw = 0; if (!inst) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); @@ -261,179 +219,43 @@ int msm_cvp_update_power(struct msm_cvp_inst *inst) return -ECONNRESET; core = inst->core; - + clocks = &core->resources.clock_set; + cl = &clocks->clock_tbl[clocks->count - 1]; + if (!cl->has_scaling) { + dprintk(CVP_ERR, "Cannot scale CVP clock\n"); + rc = -EINVAL; + goto adjust_exit; + } + for (bus_count = 0; bus_count < core->resources.bus_set.count; bus_count++) { + if (!strcmp(core->resources.bus_set.bus_tbl[bus_count].name, "cvp-ddr")) { + bus = &core->resources.bus_set.bus_tbl[bus_count]; + max_bw = bus->range[1]; + min_bw = max_bw/10; + } + } + if (!bus) { + dprintk(CVP_ERR, "bus node is NULL for cvp-ddr\n"); + rc = -EINVAL; + goto adjust_exit; + } mutex_lock(&core->clk_lock); - rc = adjust_bw_freqs(); + rc = adjust_bw_freqs(max_bw, min_bw); mutex_unlock(&core->clk_lock); - cvp_put_inst(s); + if (rc) + goto adjust_exit; - return rc; -} - - -static int cvp_readjust_clock(struct msm_cvp_core *core, - u32 avg_cycles, enum hfi_hw_thread i) -{ - int rc = 0; - struct allowed_clock_rates_table *tbl = NULL; - unsigned int tbl_size = 0; - unsigned int cvp_min_rate = 0, cvp_max_rate = 0; - unsigned long tmp = core->curr_freq; - unsigned long lo_freq = 0; - u32 j; - - tbl = core->resources.allowed_clks_tbl; - tbl_size = core->resources.allowed_clks_tbl_size; - cvp_min_rate = tbl[0].clock_rate; - cvp_max_rate = tbl[tbl_size - 1].clock_rate; - - if (!((avg_cycles > core->dyn_clk.hi_ctrl_lim[i] && - core->curr_freq != cvp_max_rate) || - (avg_cycles <= core->dyn_clk.lo_ctrl_lim[i] && - core->curr_freq != cvp_min_rate))) { - return rc; - } - - core->curr_freq = ((avg_cycles * core->dyn_clk.sum_fps[i]) << 1)/3; - dprintk(CVP_PWR, - "%s - cycles tot %u, avg %u. sum_fps %u, cur_freq %u\n", - __func__, - core->dyn_clk.cycle[i].total, - avg_cycles, - core->dyn_clk.sum_fps[i], - core->curr_freq); - - if (core->curr_freq > cvp_max_rate) { - core->curr_freq = cvp_max_rate; - lo_freq = (tbl_size > 1) ? - tbl[tbl_size - 2].clock_rate : - cvp_min_rate; - } else if (core->curr_freq <= cvp_min_rate) { - core->curr_freq = cvp_min_rate; - lo_freq = cvp_min_rate; - } else { - for (j = 1; j < tbl_size; j++) - if (core->curr_freq <= tbl[j].clock_rate) - break; - core->curr_freq = tbl[j].clock_rate; - lo_freq = tbl[j-1].clock_rate; - } - - if (core->orig_core_sum > core->curr_freq) { - dprintk(CVP_PWR, - "%s - %d - Cancel readjust, core %u, freq %u\n", - __func__, i, core->orig_core_sum, core->curr_freq); - core->curr_freq = tmp; - return rc; - } - - dprintk(CVP_PWR, - "%s:%d - %d - Readjust to %u\n", - __func__, __LINE__, i, core->curr_freq); rc = msm_cvp_set_clocks(core); if (rc) { dprintk(CVP_ERR, - "Failed to set clock rate %u: %d %s\n", - core->curr_freq, rc, __func__); - core->curr_freq = tmp; - } else { - lo_freq = (lo_freq < core->dyn_clk.conf_freq) ? - core->dyn_clk.conf_freq : lo_freq; - core->dyn_clk.hi_ctrl_lim[i] = core->dyn_clk.sum_fps[i] ? - ((core->curr_freq*3)>>1)/core->dyn_clk.sum_fps[i] : 0; - core->dyn_clk.lo_ctrl_lim[i] = - core->dyn_clk.sum_fps[i] ? - ((lo_freq*3)>>1)/core->dyn_clk.sum_fps[i] : 0; - - dprintk(CVP_PWR, - "%s - Readjust clk to %u. New lim [%d] hi %u lo %u\n", - __func__, core->curr_freq, i, - core->dyn_clk.hi_ctrl_lim[i], - core->dyn_clk.lo_ctrl_lim[i]); + "Failed to set clock rate %u %s: %d %s\n", + core->curr_freq, cl->name, rc, __func__); + core->curr_freq = core->orig_core_sum; + goto adjust_exit; } + rc = msm_cvp_set_bw(bus, core->bw_sum); - return rc; -} - -int cvp_check_clock(struct msm_cvp_inst *inst, - struct cvp_hfi_msg_session_hdr_ext *hdr) -{ - int rc = 0; - u32 i, j; - u32 hw_cycles[HFI_MAX_HW_THREADS] = {0}; - u32 fw_cycles = 0; - struct msm_cvp_core *core = inst->core; - - for (i = 0; i < HFI_MAX_HW_ACTIVATIONS_PER_FRAME; ++i) - fw_cycles += hdr->fw_cycles[i]; - - for (i = 0; i < HFI_MAX_HW_THREADS; ++i) - for (j = 0; j < HFI_MAX_HW_ACTIVATIONS_PER_FRAME; ++j) - hw_cycles[i] += hdr->hw_cycles[i][j]; - - dprintk(CVP_PWR, "%s - cycles fw %u. FDU %d MPU %d ODU %d ICA %d\n", - __func__, fw_cycles, hw_cycles[0], - hw_cycles[1], hw_cycles[2], hw_cycles[3]); - - mutex_lock(&core->clk_lock); - for (i = 0; i < HFI_MAX_HW_THREADS; ++i) { - dprintk(CVP_PWR, "%s - %d: hw_cycles %u, tens_thresh %u\n", - __func__, i, hw_cycles[i], - core->dyn_clk.hi_ctrl_lim[i]); - if (core->dyn_clk.hi_ctrl_lim[i]) { - if (core->dyn_clk.cycle[i].size < CVP_CYCLE_STAT_SIZE) - core->dyn_clk.cycle[i].size++; - else - core->dyn_clk.cycle[i].total -= - core->dyn_clk.cycle[i].busy[ - core->dyn_clk.cycle[i].idx]; - if (hw_cycles[i]) { - core->dyn_clk.cycle[i].busy[ - core->dyn_clk.cycle[i].idx] - = hw_cycles[i] + fw_cycles; - core->dyn_clk.cycle[i].total - += hw_cycles[i] + fw_cycles; - dprintk(CVP_PWR, - "%s: busy (hw + fw) cycles = %u\n", - __func__, - core->dyn_clk.cycle[i].busy[ - core->dyn_clk.cycle[i].idx]); - dprintk(CVP_PWR, "total cycles %u\n", - core->dyn_clk.cycle[i].total); - } else { - core->dyn_clk.cycle[i].busy[ - core->dyn_clk.cycle[i].idx] = - hdr->busy_cycles; - core->dyn_clk.cycle[i].total += - hdr->busy_cycles; - dprintk(CVP_PWR, - "%s - busy cycles = %u total %u\n", - __func__, - core->dyn_clk.cycle[i].busy[ - core->dyn_clk.cycle[i].idx], - core->dyn_clk.cycle[i].total); - } - - core->dyn_clk.cycle[i].idx = - (core->dyn_clk.cycle[i].idx == - CVP_CYCLE_STAT_SIZE-1) ? - 0 : core->dyn_clk.cycle[i].idx+1; - - dprintk(CVP_PWR, "%s - %d: size %u, tens_thresh %u\n", - __func__, i, core->dyn_clk.cycle[i].size, - core->dyn_clk.hi_ctrl_lim[i]); - if (core->dyn_clk.cycle[i].size == CVP_CYCLE_STAT_SIZE - && core->dyn_clk.hi_ctrl_lim[i] != 0) { - u32 avg_cycles = - core->dyn_clk.cycle[i].total>>3; - - rc = cvp_readjust_clock(core, - avg_cycles, - i); - } - } - } - mutex_unlock(&core->clk_lock); +adjust_exit: + cvp_put_inst(s); return rc; } @@ -514,36 +336,3 @@ unsigned int msm_cvp_get_hw_aggregate_cycles(enum hfi_hw_thread hwblk) return (unsigned int)cycles_sum; } -bool check_clock_required(struct msm_cvp_inst *inst, - struct eva_kmd_hfi_packet *hdr) -{ - struct cvp_hfi_msg_session_hdr_ext *ehdr = - (struct cvp_hfi_msg_session_hdr_ext *)hdr; - bool clock_check = false; - - if (!msm_cvp_dcvs_disable && - ehdr->packet_type == HFI_MSG_SESSION_CVP_FD) { - if (ehdr->size == sizeof(struct cvp_hfi_msg_session_hdr_ext) - + sizeof(struct cvp_hfi_buf_type)) { - struct msm_cvp_core *core = inst->core; - - dprintk(CVP_PWR, "busy cycle %d, total %d\n", - ehdr->busy_cycles, ehdr->total_cycles); - - if (core->dyn_clk.sum_fps[HFI_HW_FDU] || - core->dyn_clk.sum_fps[HFI_HW_MPU] || - core->dyn_clk.sum_fps[HFI_HW_OD] || - core->dyn_clk.sum_fps[HFI_HW_ICA]) { - clock_check = true; - } - } else { - dprintk(CVP_WARN, "dcvs is disabled, %d != %d + %d\n", - ehdr->size, sizeof(struct cvp_hfi_msg_session_hdr_ext), - sizeof(struct cvp_hfi_buf_type)); - } - } - - return clock_check; -} - - diff --git a/msm/eva/cvp_power.h b/msm/eva/cvp_power.h index ec438e2523..2fddafd603 100644 --- a/msm/eva/cvp_power.h +++ b/msm/eva/cvp_power.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only * - * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _CVP_POWER_H_ @@ -20,8 +20,4 @@ struct cvp_power_level { int msm_cvp_update_power(struct msm_cvp_inst *inst); unsigned int msm_cvp_get_hw_aggregate_cycles(enum hfi_hw_thread hwblk); -int cvp_check_clock(struct msm_cvp_inst *inst, - struct cvp_hfi_msg_session_hdr_ext *hdr); -bool check_clock_required(struct msm_cvp_inst *inst, - struct eva_kmd_hfi_packet *hdr); #endif diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index a32ba467fb..c41416a960 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -138,7 +138,6 @@ static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst, struct cvp_session_queue *sq; struct msm_cvp_inst *s; int rc = 0; - bool clock_check = false; if (!inst) { dprintk(CVP_ERR, "%s invalid session\n", __func__); @@ -155,11 +154,6 @@ static int msm_cvp_session_receive_hfi(struct msm_cvp_inst *inst, rc = cvp_wait_process_message(inst, sq, NULL, wait_time, out_pkt); - clock_check = check_clock_required(inst, out_pkt); - if (clock_check) - cvp_check_clock(inst, - (struct cvp_hfi_msg_session_hdr_ext *)out_pkt); - cvp_put_inst(inst); return rc; } @@ -311,7 +305,6 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, struct cvp_session_queue *sq; u32 hfi_err = HFI_ERR_NONE; struct cvp_hfi_msg_session_hdr_ext hdr; - bool clock_check = false; dprintk(CVP_SYNX, "%s %s\n", current->comm, __func__); @@ -343,10 +336,6 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, rc = cvp_wait_process_message(inst, sq, &ktid, timeout, (struct eva_kmd_hfi_packet *)&hdr); - /* Only FD support dcvs at certain FW */ - clock_check = check_clock_required(inst, - (struct eva_kmd_hfi_packet *)&hdr); - hfi_err = hdr.error_type; if (rc) { dprintk(CVP_ERR, "%s %s: cvp_wait_process_message rc %d\n", @@ -371,9 +360,6 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, exit: rc = inst->core->synx_ftbl->cvp_synx_ops(inst, CVP_OUTPUT_SYNX, fc, &synx_state); - if (clock_check) - cvp_check_clock(inst, - (struct cvp_hfi_msg_session_hdr_ext *)&hdr); return rc; } @@ -1421,7 +1407,7 @@ int cvp_clean_session_queues(struct msm_cvp_inst *inst) q = &inst->fence_cmd_queue; mutex_lock(&q->lock); - if (q->state == QUEUE_START) { + if (q->state == QUEUE_START || q->state == QUEUE_ACTIVE) { mutex_unlock(&q->lock); cvp_clean_fence_queue(inst, SYNX_STATE_SIGNALED_CANCEL); } else { diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 5c384cc052..236c79b4f6 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1107,7 +1107,7 @@ static int eva_fastrpc_dev_unmap_dma(struct fastrpc_device *frpc_device, rc = __fastrpc_driver_invoke(frpc_device, FASTRPC_DEV_UNMAP_DMA, (unsigned long)(&frpc_unmap_buf)); if (rc) { - dprintk(CVP_ERR, "%s Failed to unmap buffer 0x%x\n", + dprintk_rl(CVP_ERR, "%s Failed to unmap buffer %d\n", __func__, rc); return rc; } @@ -2015,9 +2015,6 @@ static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) rc = eva_fastrpc_dev_unmap_dma(frpc_device, buf); if (rc) { - dprintk_rl(CVP_ERR, - "%s Failed to unmap buffer 0x%x\n", - __func__, rc); cmd->ret = -1; goto fail_fastrpc_dev_unmap_dma; } diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index e81a0b3d5a..a434438451 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -212,22 +212,6 @@ struct cvp_session_queue { wait_queue_head_t wq; }; -#define CVP_CYCLE_STAT_SIZE 8 -struct cvp_cycle_stat { - u32 busy[CVP_CYCLE_STAT_SIZE]; - u32 total; - u32 idx; - u32 size; -}; - -struct cvp_cycle_info { - u32 sum_fps[HFI_MAX_HW_THREADS]; - u32 hi_ctrl_lim[HFI_MAX_HW_THREADS]; - u32 lo_ctrl_lim[HFI_MAX_HW_THREADS]; - struct cvp_cycle_stat cycle[HFI_MAX_HW_THREADS]; - unsigned long conf_freq; -}; - struct cvp_session_prop { u32 type; u32 kernel_mask; @@ -356,7 +340,7 @@ struct msm_cvp_core { bool trigger_ssr; unsigned long curr_freq; unsigned long orig_core_sum; - struct cvp_cycle_info dyn_clk; + unsigned long bw_sum; atomic64_t kernel_trans_id; struct cvp_debug_log log; }; From d9847b87142f9c3c51d548af68bd477e18376a75 Mon Sep 17 00:00:00 2001 From: Sabharsh Sidhu Date: Tue, 6 Jun 2023 16:10:33 -0700 Subject: [PATCH 229/317] msm: eva: Update HFI snapshot cmd macros Update KMD copy of HFI macros for snapshot set, release, and notify commands to align with the latest HFI Common Lib. Change-Id: I572dff24630a28da256aa8a0877badf04ee30105 Signed-off-by: Sabharsh Sidhu --- msm/eva/cvp_hfi.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/msm/eva/cvp_hfi.h b/msm/eva/cvp_hfi.h index 1f2f2b0d40..6458bf3fe1 100644 --- a/msm/eva/cvp_hfi.h +++ b/msm/eva/cvp_hfi.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef __H_CVP_HFI_H__ @@ -252,11 +253,11 @@ #define HFI_MSG_SESSION_CVP_WARP_DS_PARAMS\ (HFI_MSG_SESSION_CVP_START + 0x041) #define HFI_MSG_SESSION_CVP_SET_SNAPSHOT_BUFFERS\ - (HFI_MSG_SESSION_CVP_START + 0x042) + (HFI_MSG_SESSION_CVP_START + 0x045) #define HFI_MSG_SESSION_CVP_RELEASE_SNAPSHOT_BUFFERS\ - (HFI_MSG_SESSION_CVP_START + 0x043) + (HFI_MSG_SESSION_CVP_START + 0x046) #define HFI_MSG_EVENT_NOTIFY_SNAPSHOT_READY\ - (HFI_MSG_SESSION_CVP_START + 0x044) + (HFI_MSG_SESSION_CVP_START + 0x047) #define HFI_MSG_SESSION_CVP_FLUSH\ (HFI_MSG_SESSION_CVP_START + 0x004A) From ff26582f86f74fcb4cf7864269e6a9db7edae477 Mon Sep 17 00:00:00 2001 From: Anthony Adamo Date: Thu, 25 May 2023 14:38:13 -0700 Subject: [PATCH 230/317] msm eva: Add QMAA flags to guard compilation guard compilation of msm-eva.ko with qmaa flags. Change-Id: Iaea7270e8b268887aea364ef0ea4391c50aae84d --- Android.mk | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Android.mk b/Android.mk index b74a1b3cc0..41f3163d0f 100644 --- a/Android.mk +++ b/Android.mk @@ -1,3 +1,11 @@ +ENABLE_EVA_KERNEL := true +ifeq ($(TARGET_USES_QMAA), true) +ifneq ($(TARGET_USES_QMAA_OVERRIDE_CVP), true) +ENABLE_EVA_KERNEL := false +endif +endif + +ifeq ($(ENABLE_EVA_KERNEL), true) ifneq ($(TARGET_BOARD_PLATFORM), qssi) ifeq ($(call is-board-platform-in-list, $(TARGET_BOARD_PLATFORM)),true) @@ -54,3 +62,4 @@ include $(DLKM_DIR)/Build_external_kernelmodule.mk endif # End of check for board platform endif # End of check for target product +endif # End of enable eva kernel check \ No newline at end of file From 18d64ef8afaf8c78714962c9d4880347f4035fe1 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 15 Jun 2023 12:13:09 -0700 Subject: [PATCH 231/317] msm: eva: revert session error handling change Do it after user mode can handle it more gracefully. Change-Id: I1e42fc957f1a1fbe3f15738b3680ad169fb93f42 Signed-off-by: George Shen --- msm/eva/msm_cvp_common.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 46e121522a..2d3002c9c0 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -516,8 +516,8 @@ static void handle_session_error(enum hal_command_response cmd, void *data) struct msm_cvp_cb_cmd_done *response = data; struct cvp_hfi_device *hdev = NULL; struct msm_cvp_inst *inst = NULL; - unsigned long flags = 0; - int i; + //unsigned long flags = 0; + //int i; if (!response) { dprintk(CVP_ERR, @@ -536,18 +536,19 @@ static void handle_session_error(enum hal_command_response cmd, void *data) dprintk(CVP_ERR, "Sess error 0x%x received for inst %pK sess %x\n", response->status, inst, hash32_ptr(inst->session)); cvp_print_inst(CVP_WARN, inst); - if (inst->state != MSM_CVP_CORE_INVALID) { - change_cvp_inst_state(inst, MSM_CVP_CORE_INVALID); - if (cvp_clean_session_queues(inst)) - dprintk(CVP_WARN, "Failed to clean sess queues\n"); - for (i = 0; i < ARRAY_SIZE(inst->completions); i++) - complete(&inst->completions[i]); - spin_lock_irqsave(&inst->event_handler.lock, flags); - inst->event_handler.event = CVP_SSR_EVENT; - spin_unlock_irqrestore( - &inst->event_handler.lock, flags); - wake_up_all(&inst->event_handler.wq); - } + + //if (inst->state != MSM_CVP_CORE_INVALID) { + // change_cvp_inst_state(inst, MSM_CVP_CORE_INVALID); + // if (cvp_clean_session_queues(inst)) + // dprintk(CVP_WARN, "Failed to clean sess queues\n"); + // for (i = 0; i < ARRAY_SIZE(inst->completions); i++) + // complete(&inst->completions[i]); + // spin_lock_irqsave(&inst->event_handler.lock, flags); + // inst->event_handler.event = CVP_SSR_EVENT; + // spin_unlock_irqrestore( + // &inst->event_handler.lock, flags); + // wake_up_all(&inst->event_handler.wq); + //} cvp_put_inst(inst); } From aafc38db814837239e085af1a0d7fd20f995e605 Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 16 Jun 2023 12:11:21 -0700 Subject: [PATCH 232/317] msm: eva: Condition ready check for IRQ_MASK Core shall be powered on and WRAPPER_SPARE bit 1 shall be clear. Change-Id: Id225c44f4a245482a8b9387109211461d03042e9 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 0a0f3bcf5c..755d402334 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -4441,7 +4441,7 @@ static int __power_on_core(struct iris_hfi_device *device) static int __iris_power_on(struct iris_hfi_device *device) { int rc = 0; - + u32 reg_gdsc, reg_cbcr, spare_val; if (device->power_enabled) return 0; @@ -4484,6 +4484,36 @@ static int __iris_power_on(struct iris_hfi_device *device) goto fail_enable_core; dprintk(CVP_CORE, "Done with register set\n"); + + reg_gdsc = __read_register(device, CVP_CC_MVS1_GDSCR); + reg_cbcr = __read_register(device, CVP_CC_MVS1_CBCR); + if (!(reg_gdsc & 0x80000000) || (reg_cbcr & 0x80000000)) { + rc = -EINVAL; + dprintk(CVP_ERR, "CORE power on failed gdsc %x cbcr %x\n", + reg_gdsc, reg_cbcr); + goto fail_enable_core; + } + + reg_gdsc = __read_register(device, CVP_CC_MVS1C_GDSCR); + reg_cbcr = __read_register(device, CVP_CC_MVS1C_CBCR); + if (!(reg_gdsc & 0x80000000) || (reg_cbcr & 0x80000000)) { + rc = -EINVAL; + dprintk(CVP_ERR, "CTRL power on failed gdsc %x cbcr %x\n", + reg_gdsc, reg_cbcr); + goto fail_enable_core; + } + + spare_val = __read_register(device, CVP_AON_WRAPPER_SPARE); + if ((spare_val & 0x2) != 0) { + usleep_range(2000, 3000); + spare_val = __read_register(device, CVP_AON_WRAPPER_SPARE); + if ((spare_val & 0x2) != 0) { + dprintk(CVP_ERR, "WRAPPER_SPARE non-zero %#x\n", spare_val); + rc = -EINVAL; + goto fail_enable_core; + } + } + call_iris_op(device, interrupt_init, device); dprintk(CVP_CORE, "Done with interrupt enabling\n"); device->intr_status = 0; @@ -4878,7 +4908,6 @@ static void power_off_iris2(struct iris_hfi_device *device) static inline int __resume(struct iris_hfi_device *device) { int rc = 0; - u32 reg_gdsc, reg_cbcr; struct msm_cvp_core *core; if (!device) { @@ -4900,12 +4929,6 @@ static inline int __resume(struct iris_hfi_device *device) goto err_iris_power_on; } - reg_gdsc = __read_register(device, CVP_CC_MVS1C_GDSCR); - reg_cbcr = __read_register(device, CVP_CC_MVS1C_CBCR); - if (!(reg_gdsc & 0x80000000) || (reg_cbcr & 0x80000000)) - dprintk(CVP_ERR, "CVP power on failed gdsc %x cbcr %x\n", - reg_gdsc, reg_cbcr); - __setup_ucregion_memory_map(device); /* RUMI: set CVP_CTRL_INIT register to disable synx in FW */ From b6d08f5cab84656cd795666ef3aa6afc8fbbee27 Mon Sep 17 00:00:00 2001 From: Linux Image Build Automation Date: Tue, 20 Jun 2023 13:59:29 -0700 Subject: [PATCH 233/317] Revert "msm: eva: Avoid printing freed dma_buf name" This reverts commit 89f8cc73960045ce0f3f1673c903fb730e30ea5e. Change-Id: I63b489f8d5421059f66cfc73170977d5d049096d Signed-off-by: Linux Image Build Automation --- msm/eva/msm_cvp_buf.c | 10 +++++----- msm/eva/msm_cvp_common.c | 5 +++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 7a6615b6e9..14d805773b 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1,7 +1,6 @@ // 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 @@ -74,13 +73,13 @@ int print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, if (!atomic_read(&smem->refcount)) dprintk(tag, - " UNUSED mapping %s: 0x%llx size %d iova %#x idx %d pkt_type %s buf_idx %#x fd %d", - str, smem->dma_buf, + " UNUSED mapping %s: 0x%llx %s size %d iova %#x idx %d pkt_type %s buf_idx %#x fd %d", + str, smem->dma_buf, smem->dma_buf->name, smem->size, smem->device_addr, smem->bitmap_index, name, smem->buf_idx, smem->fd); else dprintk(tag, - "%s: %x : 0x%llx size %d flags %#x iova %#x idx %d ref %d pkt_type %s buf_idx %#x fd %d", - str, hash32_ptr(inst->session), smem->dma_buf, + "%s: %x : 0x%llx %s size %d flags %#x iova %#x idx %d ref %d pkt_type %s buf_idx %#x fd %d", + str, hash32_ptr(inst->session), smem->dma_buf, smem->dma_buf->name, smem->size, smem->flags, smem->device_addr, smem->bitmap_index, atomic_read(&smem->refcount), name, smem->buf_idx, smem->fd); @@ -1969,6 +1968,7 @@ void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) dprintk(CVP_ERR, "unmapped dsp bufs\n"); for (i = 0; i < inst->unused_dsp_bufs.nr; i++) _log_smem(snap, inst, &inst->unused_dsp_bufs.smem[i], log); + } struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index d8695bab11..31d4a73c19 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -623,9 +622,11 @@ void handle_sys_error(enum hal_command_response cmd, void *data) wake_up_all(&inst->event_handler.wq); } - if (!core->trigger_ssr) + if (!core->trigger_ssr) { + cvp_print_inst(CVP_WARN, inst); if (hfi_device->error != CVP_ERR_NOC_ERROR) msm_cvp_print_inst_bufs(inst, false); + } } /* handle the hw error before core released to get full debug info */ From 65aa4f2241c6f3510691efa9d622a799f74a48d6 Mon Sep 17 00:00:00 2001 From: Linux Image Build Automation Date: Tue, 20 Jun 2023 13:59:40 -0700 Subject: [PATCH 234/317] Revert "msm: eva: Enhance power and perf logging" This reverts commit df2c05337f7b28cd7f39eb35a0f8a1d0aa9814c9. Change-Id: Iae636316f21de9830e884824e7062ef84d535efb Signed-off-by: Linux Image Build Automation --- msm/eva/cvp_hfi.c | 12 ++---------- msm/eva/cvp_power.c | 37 ++++++++++++++++++------------------- msm/eva/msm_cvp_common.c | 6 +++--- msm/eva/msm_cvp_common.h | 1 - msm/eva/msm_cvp_core.c | 6 +++--- 5 files changed, 26 insertions(+), 36 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 4823bfd58b..0e4c376cd3 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -162,15 +162,6 @@ static int cvp_synx_recover(void) #define ROW_SIZE 32 -unsigned long long get_aon_time(void) -{ - unsigned long long val; - - asm volatile("mrs %0, cntvct_el0" : "=r" (val)); - - return val; -} - int get_hfi_version(void) { struct msm_cvp_core *core; @@ -3570,7 +3561,7 @@ static DECLARE_WORK(iris_hfi_wd_work, iris_hfi_wd_work_handler); irqreturn_t iris_hfi_isr_wd(int irq, void *dev) { struct iris_hfi_device *device = dev; - dprintk(CVP_ERR, "Got HW WDOG IRQ at %llu! \n", get_aon_time()); + dprintk(CVP_ERR, "Got HW WDOG IRQ! \n"); disable_irq_nosync(irq); queue_work(device->cvp_workq, &iris_hfi_wd_work); return IRQ_HANDLED; @@ -4919,6 +4910,7 @@ static inline int __resume(struct iris_hfi_device *device) rc = __boot_firmware(device); if (rc) { dprintk(CVP_ERR, "Failed to reset cvp core\n"); + msm_cvp_trigger_ssr(core, SSR_ERR_FATAL); goto err_reset_core; } diff --git a/msm/eva/cvp_power.c b/msm/eva/cvp_power.c index 626d3b6752..7e39db27d2 100644 --- a/msm/eva/cvp_power.c +++ b/msm/eva/cvp_power.c @@ -31,9 +31,6 @@ static bool is_subblock_profile_existed(struct msm_cvp_inst *inst) inst->prop.cycles[HFI_HW_LSR]); } -static char hw_names[HFI_MAX_HW_THREADS][8] = {{"FDU"}, {"OD"}, {"MPU"}, {"ICA"}, - {"VADL"}, {"TOF"}, {"RGE"}, {"XRA"}, - {"LSR"}}; static void aggregate_power_update(struct msm_cvp_core *core, struct cvp_power_level *nrt_pwr, struct cvp_power_level *rt_pwr, @@ -60,18 +57,17 @@ static void aggregate_power_update(struct msm_cvp_core *core, } else { i = 1; } + dprintk(CVP_PROF, "pwrUpdate fdu od mpu ica vadl tof rge xra lsr\n"); for (j = 0; j < HFI_MAX_HW_THREADS; j++) - if (inst->prop.cycles[j]) - dprintk(CVP_PWR, "pwrUpdate %s %u\n", - hw_names[j], inst->prop.cycles[j]); + dprintk(CVP_PROF, "%u ", inst->prop.cycles[j]); + dprintk(CVP_PROF, "\n"); + dprintk(CVP_PROF, "pwrUpdate fdu_o od_o ica_o mpu_o vadl_o tof_o rge_o xra_o lsr_o\n"); for (j = 0; j < HFI_MAX_HW_THREADS; j++) - if (inst->prop.op_cycles[j]) - dprintk(CVP_PWR, "pwrUpdate_OP %s %u\n", - hw_names[j], inst->prop.op_cycles[j]); + dprintk(CVP_PROF, "%u ", inst->prop.op_cycles[j]); + dprintk(CVP_PROF, "\n"); - dprintk(CVP_PWR, " fw %u fw_o %u\n", inst->prop.fw_cycles, - inst->prop.fw_op_cycles); + dprintk(CVP_PROF, " fw %u fw_o %u\n", inst->prop.fw_cycles, inst->prop.fw_op_cycles); for (j = 0; j < HFI_MAX_HW_THREADS; j++) blocks_sum[i][j] += inst->prop.cycles[j]; @@ -93,17 +89,20 @@ static void aggregate_power_update(struct msm_cvp_core *core, (op_bw_max[i] >= inst->prop.ddr_op_bw) ? op_bw_max[i] : inst->prop.ddr_op_bw; + dprintk(CVP_PWR, "%s:%d - fps fdu mpu od ica vadl tof rge xra lsf\n", + __func__, __LINE__); + for (j = 0; j < HFI_MAX_HW_THREADS; j++) { - if (inst->prop.fps[j]) - dprintk(CVP_PWR, "fps %s %d ", hw_names[j], - inst->prop.fps[j]); + dprintk(CVP_PWR, " %d ", inst->prop.fps[j]); core->dyn_clk.sum_fps[j] += inst->prop.fps[j]; } + dprintk(CVP_PWR, "\n"); + dprintk(CVP_PWR, "%s:%d - sum_fps fdu mpu od ica vadl tof rge xra lsf\n", + __func__, __LINE__); for (j = 0; j < HFI_MAX_HW_THREADS; j++) - if (core->dyn_clk.sum_fps[j]) - dprintk(CVP_PWR, "sum_fps %s %d ", hw_names[j], - core->dyn_clk.sum_fps[j]); + dprintk(CVP_PWR, " %d ", core->dyn_clk.sum_fps[j]); + dprintk(CVP_PWR, "\n"); } for (i = 0; i < 2; i++) { @@ -169,7 +168,7 @@ static int adjust_bw_freqs(void) min_bw = max_bw/10; aggregate_power_update(core, &nrt_pwr, &rt_pwr, cvp_max_rate); - dprintk(CVP_PWR, "PwrUpdate nrt %u %u rt %u %u\n", + dprintk(CVP_PROF, "PwrUpdate nrt %u %u rt %u %u\n", nrt_pwr.core_sum, nrt_pwr.op_core_sum, rt_pwr.core_sum, rt_pwr.op_core_sum); @@ -202,7 +201,7 @@ static int adjust_bw_freqs(void) bw_sum = (bw_sum > max_bw) ? max_bw : bw_sum; bw_sum = (bw_sum < min_bw) ? min_bw : bw_sum; - dprintk(CVP_PWR, "%s %lld %lld\n", __func__, + dprintk(CVP_PROF, "%s %lld %lld\n", __func__, core_sum, bw_sum); if (!cl->has_scaling) { dprintk(CVP_ERR, "Cannot scale CVP clock\n"); diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 31d4a73c19..19f7825fc5 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -625,7 +625,7 @@ void handle_sys_error(enum hal_command_response cmd, void *data) if (!core->trigger_ssr) { cvp_print_inst(CVP_WARN, inst); if (hfi_device->error != CVP_ERR_NOC_ERROR) - msm_cvp_print_inst_bufs(inst, false); + msm_cvp_print_inst_bufs(inst, false); } } @@ -1298,8 +1298,8 @@ void msm_cvp_ssr_handler(struct work_struct *work) send_again: mutex_lock(&core->lock); if (core->state == CVP_CORE_INIT_DONE) { - dprintk(CVP_WARN, "%s: ssr type %d at %llu\n", __func__, - core->ssr_type, get_aon_time()); + dprintk(CVP_WARN, "%s: ssr type %d\n", __func__, + core->ssr_type); /* * In current implementation user-initiated SSR triggers * a fatal error from hardware. However, there is no way diff --git a/msm/eva/msm_cvp_common.h b/msm/eva/msm_cvp_common.h index b9dc2e06f2..4d66055d98 100644 --- a/msm/eva/msm_cvp_common.h +++ b/msm/eva/msm_cvp_common.h @@ -33,5 +33,4 @@ int cvp_comm_set_arp_buffers(struct msm_cvp_inst *inst); int cvp_comm_release_persist_buffers(struct msm_cvp_inst *inst); int msm_cvp_noc_error_info(struct msm_cvp_core *core); int cvp_print_inst(u32 tag, struct msm_cvp_inst *inst); -unsigned long long get_aon_time(void); #endif diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 814aca34f5..3dfcef5dd4 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -325,9 +325,9 @@ wait_dsp: mutex_unlock(&inst->cvpdspbufs.lock); if (!empty) - dprintk(CVP_WARN, "Failed sess %pK DSP frame retried %d\n", - inst, - (inst->core->resources.msm_cvp_hw_rsp_timeout >> 5)); + dprintk(CVP_WARN, "Failed flush DSP frame retried %d\n", + (inst->core->resources.msm_cvp_hw_rsp_timeout >> 5) + - max_retries); max_retries = inst->core->resources.msm_cvp_hw_rsp_timeout >> 1; wait_frame: mutex_lock(&inst->frames.lock); From 6ecf8719aa36cb42d488c9d733bdcae1fb1b64e8 Mon Sep 17 00:00:00 2001 From: Linux Image Build Automation Date: Tue, 20 Jun 2023 13:59:51 -0700 Subject: [PATCH 235/317] Revert "msm: eva: Fix an issue in DSP sess create failure" This reverts commit 57b03d2f4ede9ab8cdd9b65407f985d98df0364d. Change-Id: I074cd835ee30d99f3194e49424c7f46798a05fd0 Signed-off-by: Linux Image Build Automation --- include/uapi/eva/media/msm_eva_private.h | 2 +- msm/eva/msm_cvp.c | 9 ++------- msm/eva/msm_cvp_dsp.c | 3 ++- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/include/uapi/eva/media/msm_eva_private.h b/include/uapi/eva/media/msm_eva_private.h index 4aae22dc3e..df4b04f154 100644 --- a/include/uapi/eva/media/msm_eva_private.h +++ b/include/uapi/eva/media/msm_eva_private.h @@ -180,7 +180,7 @@ struct eva_kmd_hfi_packet { #define EVA_KMD_PROP_PWR_FPS_LSR 0x30 -#define MAX_KMD_PROP_NUM_PER_PACKET 64 +#define MAX_KMD_PROP_NUM_PER_PACKET 8 #define MAX_KMD_PROP_TYPE (EVA_KMD_PROP_PWR_FPS_ICA + 1) struct eva_kmd_sys_property { diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index c57f554aa5..df2854ac3a 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -825,7 +825,7 @@ int msm_cvp_session_delete(struct msm_cvp_inst *inst) int msm_cvp_session_create(struct msm_cvp_inst *inst) { - int rc = 0, rc1 = 0; + int rc = 0; struct cvp_session_queue *sq; if (!inst || !inst->core) @@ -846,7 +846,7 @@ int msm_cvp_session_create(struct msm_cvp_inst *inst) if (rc) { dprintk(CVP_ERR, "Failed to move instance to open done state\n"); - goto fail_create; + goto fail_init; } rc = cvp_comm_set_arp_buffers(inst); @@ -861,13 +861,8 @@ int msm_cvp_session_create(struct msm_cvp_inst *inst) spin_lock(&sq->lock); sq->state = QUEUE_ACTIVE; spin_unlock(&sq->lock); - return rc; fail_init: - rc1 = msm_cvp_comm_try_state(inst, MSM_CVP_CLOSE_DONE); - if (rc1) - dprintk(CVP_ERR, "%s: close failed\n", __func__); -fail_create: return rc; } diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 6dbd93611d..7965147e76 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1549,7 +1549,7 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) rc = msm_cvp_session_create(inst); if (rc) { dprintk(CVP_ERR, "Warning: send Session Create failed\n"); - goto fail_msm_cvp_open; + goto fail_session_create; } else { dprintk(CVP_DSP, "%s DSP Session Create done\n", __func__); } @@ -1586,6 +1586,7 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) return; fail_get_session_info: +fail_session_create: msm_cvp_close(inst); fail_msm_cvp_open: /* unregister fastrpc driver */ From ea943185154f2e450bd4a70492d6b431b9738216 Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 13 Jun 2023 14:03:38 -0700 Subject: [PATCH 236/317] msm: eva: mmap firmware debug memory For user mode to save into a dump file. It helps FW debugging. Change-Id: I1c9c52d27d0dfd20e3eeb54b203416f6df095c8d Signed-off-by: George Shen --- include/uapi/eva/media/msm_eva_private.h | 2 + msm/eva/cvp_hfi.c | 4 +- msm/eva/msm_cvp.c | 23 +++- msm/eva/msm_cvp_buf.c | 138 ++++++++++++++++++----- msm/eva/msm_cvp_buf.h | 10 +- 5 files changed, 138 insertions(+), 39 deletions(-) diff --git a/include/uapi/eva/media/msm_eva_private.h b/include/uapi/eva/media/msm_eva_private.h index 4aae22dc3e..30e43b8adc 100644 --- a/include/uapi/eva/media/msm_eva_private.h +++ b/include/uapi/eva/media/msm_eva_private.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */ /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef __MSM_EVA_PRIVATE_H__ #define __MSM_EVA_PRIVATE_H__ @@ -139,6 +140,7 @@ struct eva_kmd_hfi_packet { #define EVA_KMD_PROP_SESSION_DSPMASK 6 #define EVA_KMD_PROP_SESSION_DUMPOFFSET 7 #define EVA_KMD_PROP_SESSION_DUMPSIZE 8 +#define EVA_KMD_PROP_SESSION_ERROR 9 #define EVA_KMD_PROP_PWR_FDU 0x10 #define EVA_KMD_PROP_PWR_ICA 0x11 diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 755d402334..b9b712600d 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -2531,8 +2531,8 @@ static int iris_debug_hook(void *device) dprintk(CVP_ERR, "%s Invalid device\n", __func__); return -ENODEV; } - __write_register(dev, CVP_WRAPPER_CORE_CLOCK_CONFIG, 0x11); - __write_register(dev, CVP_WRAPPER_TZ_CPU_CLOCK_CONFIG, 0x1); + //__write_register(dev, CVP_WRAPPER_CORE_CLOCK_CONFIG, 0x11); + //__write_register(dev, CVP_WRAPPER_TZ_CPU_CLOCK_CONFIG, 0x1); dprintk(CVP_ERR, "Halt Tensilica and core and axi\n"); return 0; diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index c41416a960..7da0f0866d 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -207,7 +207,7 @@ static int msm_cvp_session_process_hfi( } if (is_config_pkt) - pr_info(CVP_DBG_TAG "inst %pK config %s\n", "sess", + pr_info_ratelimited(CVP_DBG_TAG "inst %pK config %s\n", "sess", inst, cvp_hfi_defs[pkt_idx].name); if (signal == HAL_NO_RESP) { @@ -657,7 +657,7 @@ static int cvp_enqueue_pkt(struct msm_cvp_inst* inst, if (map_type == MAP_PERSIST) rc = msm_cvp_map_user_persist(inst, in_pkt, in_offset, in_buf_num); else if (map_type == UNMAP_PERSIST) - rc = msm_cvp_mark_user_persist(inst, in_pkt, in_offset, in_buf_num); + rc = msm_cvp_unmap_user_persist(inst, in_pkt, in_offset, in_buf_num); else rc = msm_cvp_map_frame(inst, in_pkt, in_offset, in_buf_num); @@ -893,7 +893,8 @@ int msm_cvp_session_start(struct msm_cvp_inst *inst, goto stop_thread; } - dprintk(CVP_SESS, "session %llx (%#x) started\n", inst, hash32_ptr(inst->session)); + pr_info_ratelimited(CVP_DBG_TAG "session %llx (%#x) started\n", + "sess", inst, hash32_ptr(inst->session)); return 0; @@ -942,8 +943,8 @@ int msm_cvp_session_stop(struct msm_cvp_inst *inst, } sq->state = QUEUE_STOP; - dprintk(CVP_SESS, "Stop session: %pK session_id = %d\n", - inst, hash32_ptr(inst->session)); + pr_info_ratelimited(CVP_DBG_TAG "Stop session: %pK session_id = %d\n", + "sess", inst, hash32_ptr(inst->session)); spin_unlock(&sq->lock); hdev = inst->core->device; @@ -1076,6 +1077,18 @@ static int msm_cvp_get_sysprop(struct msm_cvp_inst *inst, session_prop->dump_size; break; } + case EVA_KMD_PROP_SESSION_ERROR: + { + rc = dma_buf_fd(hfi->mem_addr.mem_data.dma_buf, O_RDONLY | O_CLOEXEC); + if (rc < 0) { + dprintk(CVP_WARN, "Failed get dma_buf fd %d\n", rc); + break; + } + + props->prop_data[i].data = rc; + rc = 0; + break; + } case EVA_KMD_PROP_PWR_FDU: { props->prop_data[i].data = diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 4855a2f8a1..ea2f8c238f 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1418,16 +1418,67 @@ exit: return smem; } -static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, +static int msm_cvp_unmap_user_persist_buf(struct msm_cvp_inst *inst, struct cvp_buf_type *buf, - u32 pkt_type, u32 buf_idx) + u32 pkt_type, u32 buf_idx, u32 *iova) +{ + struct msm_cvp_smem *smem = NULL; + struct list_head *ptr; + struct list_head *next; + struct cvp_internal_buf *pbuf; + struct dma_buf *dma_buf; + + if (!inst) { + dprintk(CVP_ERR, "%s: invalid params\n", __func__); + return -EINVAL; + } + + dma_buf = msm_cvp_smem_get_dma_buf(buf->fd); + if (!dma_buf) + return -EINVAL; + + mutex_lock(&inst->persistbufs.lock); + list_for_each_safe(ptr, next, &inst->persistbufs.list) { + if (!ptr) { + mutex_unlock(&inst->persistbufs.lock); + return -EINVAL; + } + pbuf = list_entry(ptr, struct cvp_internal_buf, list); + if (dma_buf == pbuf->smem->dma_buf && (pbuf->smem->flags & SMEM_PERSIST)) { + *iova = pbuf->smem->device_addr; + dprintk(CVP_MEM, + "Unmap persist fd %d, dma_buf %#llx iova %#x\n", + pbuf->fd, pbuf->smem->dma_buf, *iova); + list_del(&pbuf->list); + if (*iova) { + msm_cvp_unmap_smem(inst, pbuf->smem, "unmap user persist"); + msm_cvp_smem_put_dma_buf(pbuf->smem->dma_buf); + pbuf->smem->device_addr = 0; + } + cvp_kmem_cache_free(&cvp_driver->smem_cache, smem); + pbuf->smem = NULL; + cvp_kmem_cache_free(&cvp_driver->buf_cache, pbuf); + mutex_unlock(&inst->persistbufs.lock); + dma_buf_put(dma_buf); + return 0; + } + } + mutex_unlock(&inst->persistbufs.lock); + dma_buf_put(dma_buf); + + return -EINVAL; +} + +static int msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, + struct cvp_buf_type *buf, + u32 pkt_type, u32 buf_idx, u32 *iova) { - u32 iova = 0; struct msm_cvp_smem *smem = NULL; struct list_head *ptr; struct list_head *next; struct cvp_internal_buf *pbuf; struct dma_buf *dma_buf; + int ret; if (!inst) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); @@ -1441,24 +1492,24 @@ static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, mutex_lock(&inst->persistbufs.lock); if (!inst->persistbufs.list.next) { mutex_unlock(&inst->persistbufs.lock); - return 0; + return -EINVAL; } list_for_each_safe(ptr, next, &inst->persistbufs.list) { if (!ptr) - return 0; + return -EINVAL; pbuf = list_entry(ptr, struct cvp_internal_buf, list); if (dma_buf == pbuf->smem->dma_buf) { pbuf->size = (pbuf->size >= buf->size) ? pbuf->size : buf->size; - iova = pbuf->smem->device_addr + buf->offset; + *iova = pbuf->smem->device_addr + buf->offset; mutex_unlock(&inst->persistbufs.lock); atomic_inc(&pbuf->smem->refcount); dma_buf_put(dma_buf); dprintk(CVP_MEM, "map persist Reuse fd %d, dma_buf %#llx\n", pbuf->fd, pbuf->smem->dma_buf); - return iova; + return 0; } } mutex_unlock(&inst->persistbufs.lock); @@ -1469,7 +1520,7 @@ static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, if (!pbuf) { dprintk(CVP_ERR, "%s failed to allocate kmem obj\n", __func__); - return 0; + return -ENOMEM; } if (is_params_pkt(pkt_type)) @@ -1477,8 +1528,10 @@ static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, else smem = msm_cvp_session_get_smem(inst, buf, true, pkt_type); - if (!smem) + if (!smem) { + ret = -ENOMEM; goto exit; + } smem->pkt_type = pkt_type; smem->buf_idx = buf_idx; @@ -1495,13 +1548,13 @@ static u32 msm_cvp_map_user_persist_buf(struct msm_cvp_inst *inst, print_internal_buffer(CVP_MEM, "map persist", inst, pbuf); - iova = smem->device_addr + buf->offset; + *iova = smem->device_addr + buf->offset; - return iova; + return 0; exit: cvp_kmem_cache_free(&cvp_driver->buf_cache, pbuf); - return 0; + return ret; } static u32 msm_cvp_map_frame_buf(struct msm_cvp_inst *inst, @@ -1651,21 +1704,18 @@ void msm_cvp_unmap_frame(struct msm_cvp_inst *inst, u64 ktid) dprintk(CVP_WARN, "%s frame %llu not found!\n", __func__, ktid); } -int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst, - struct eva_kmd_hfi_packet *in_pkt, - unsigned int offset, unsigned int buf_num) -{ - dprintk(CVP_ERR, "Unexpected user persistent buffer release\n"); - return 0; -} - -int msm_cvp_map_user_persist(struct msm_cvp_inst *inst, +/* + * Unmap persistent buffer before sending RELEASE_PERSIST_BUFFERS to FW + * This packet is sent after SESSION_STOP. The assumption is FW/HW will + * NOT access any of the 3 persist buffer. + */ +int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, struct eva_kmd_hfi_packet *in_pkt, unsigned int offset, unsigned int buf_num) { struct cvp_buf_type *buf; struct cvp_hfi_cmd_session_hdr *cmd_hdr; - int i; + int i, ret; u32 iova; if (!offset || !buf_num) @@ -1679,14 +1729,48 @@ int msm_cvp_map_user_persist(struct msm_cvp_inst *inst, if (buf->fd < 0 || !buf->size) continue; - iova = msm_cvp_map_user_persist_buf(inst, buf, - cmd_hdr->packet_type, i); - if (!iova) { + ret = msm_cvp_unmap_user_persist_buf(inst, buf, + cmd_hdr->packet_type, i, &iova); + if (ret) { dprintk(CVP_ERR, - "%s: buf %d register failed.\n", + "%s: buf %d unmap failed.\n", __func__, i); - return -EINVAL; + return ret; + } + buf->fd = iova; + } + return 0; +} + +int msm_cvp_map_user_persist(struct msm_cvp_inst *inst, + struct eva_kmd_hfi_packet *in_pkt, + unsigned int offset, unsigned int buf_num) +{ + struct cvp_buf_type *buf; + struct cvp_hfi_cmd_session_hdr *cmd_hdr; + int i, ret; + u32 iova; + + if (!offset || !buf_num) + return 0; + + cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; + for (i = 0; i < buf_num; i++) { + buf = (struct cvp_buf_type *)&in_pkt->pkt_data[offset]; + offset += sizeof(*buf) >> 2; + + if (buf->fd < 0 || !buf->size) + continue; + + ret = msm_cvp_map_user_persist_buf(inst, buf, + cmd_hdr->packet_type, i, &iova); + if (ret) { + dprintk(CVP_ERR, + "%s: buf %d map failed.\n", + __func__, i); + + return ret; } buf->fd = iova; } diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index ddf15853e3..f801d721cb 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -113,11 +113,11 @@ static inline void DEINIT_DMAMAP_CACHE(struct cvp_dmamap_cache *cache) #define INPUT_FENCE_BITMASK 0x1 #define OUTPUT_FENCE_BITMASK 0x2 +/* Track source of dma_buf allocator/owner */ enum buffer_owner { - DRIVER, - FIRMWARE, - CLIENT, - DSP, + DRIVER, /* Allocated by KMD, for CPU driver */ + CLIENT, /* Allocated by Client (DSP or CPU) */ + DSP, /* Allocated by KMD, for DSP driver */ MAX_OWNER }; @@ -219,7 +219,7 @@ int msm_cvp_proc_oob(struct msm_cvp_inst* inst, struct eva_kmd_hfi_packet* in_pkt); void msm_cvp_cache_operations(struct msm_cvp_smem *smem, u32 type, u32 offset, u32 size); -int msm_cvp_mark_user_persist(struct msm_cvp_inst *inst, +int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, struct eva_kmd_hfi_packet *in_pkt, unsigned int offset, unsigned int buf_num); int msm_cvp_map_user_persist(struct msm_cvp_inst *inst, From fef6ef9ce5bad813fa1fea38ed27e9f3e281ca83 Mon Sep 17 00:00:00 2001 From: Sabharsh Sidhu Date: Tue, 20 Jun 2023 16:42:43 -0700 Subject: [PATCH 237/317] msm: eva: Enhance WarpNCC OOB santization Add WarpNCC user-space OOB pointer access checks to improve code safety in case of an under-allocated buffer. Change-Id: I51e8464b37711d8ffcc1847376e2ebfb80f035b0 Signed-off-by: Sabharsh Sidhu --- msm/eva/msm_cvp_buf.c | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index ea2f8c238f..4da8182d4e 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -178,7 +178,7 @@ void print_client_buffer(u32 tag, const char *str, dprintk(tag, "%s: %x : idx %2d fd %d off %d size %d type %d flags 0x%x" - " reserved[0] %u\n", + " reserved[0] %u\n", str, hash32_ptr(inst->session), cbuf->index, cbuf->fd, cbuf->offset, cbuf->size, cbuf->type, cbuf->flags, cbuf->reserved[0]); @@ -789,6 +789,12 @@ static int _wncc_copy_oob_from_user(struct eva_kmd_hfi_packet* in_pkt, return -EINVAL; } + if (!access_ok(&oob_buf_u->oob_type, sizeof(oob_buf_u->oob_type))) { + dprintk(CVP_ERR, + "%s: bad OOB buf pointer, oob_type inaccessible", + __func__); + return -EINVAL; + } rc = get_user(oob_type, &oob_buf_u->oob_type); if (rc) return rc; @@ -801,6 +807,13 @@ static int _wncc_copy_oob_from_user(struct eva_kmd_hfi_packet* in_pkt, wncc_oob_u = &oob_buf_u->wncc; wncc_oob_k = wncc_oob; + if (!access_ok(&wncc_oob_u->metadata_bufs_offset, + sizeof(wncc_oob_u->metadata_bufs_offset))) { + dprintk(CVP_ERR, + "%s: bad OOB buf pointer, wncc.metadata_bufs_offset inaccessible", + __func__); + return -EINVAL; + } rc = get_user(wncc_oob_k->metadata_bufs_offset, &wncc_oob_u->metadata_bufs_offset); if (rc) @@ -812,6 +825,13 @@ static int _wncc_copy_oob_from_user(struct eva_kmd_hfi_packet* in_pkt, return -EINVAL; } + if (!access_ok(&wncc_oob_u->num_layers, + sizeof(wncc_oob_u->num_layers))) { + dprintk(CVP_ERR, + "%s: bad OOB buf pointer, wncc.num_layers inaccessible", + __func__); + return -EINVAL; + } rc = get_user(wncc_oob_k->num_layers, &wncc_oob_u->num_layers); if (rc) return rc; @@ -823,6 +843,13 @@ static int _wncc_copy_oob_from_user(struct eva_kmd_hfi_packet* in_pkt, for (i = 0; i < wncc_oob_k->num_layers; i++) { + if (!access_ok(&wncc_oob_u->layers[i].num_addrs, + sizeof(wncc_oob_u->layers[i].num_addrs))) { + dprintk(CVP_ERR, + "%s: bad OOB buf pointer, wncc.layers[%u].num_addrs inaccessible", + __func__, i); + return -EINVAL; + } rc = get_user(wncc_oob_k->layers[i].num_addrs, &wncc_oob_u->layers[i].num_addrs); if (rc) @@ -837,10 +864,18 @@ static int _wncc_copy_oob_from_user(struct eva_kmd_hfi_packet* in_pkt, break; } + if (!access_ok(wncc_oob_u->layers[i].addrs, + num_addrs * sizeof(struct eva_kmd_wncc_addr)) || + !access_ok(&wncc_oob_u->layers[i].addrs[num_addrs - 1], + sizeof(struct eva_kmd_wncc_addr))) { + dprintk(CVP_ERR, + "%s: bad OOB buf pointer, wncc.layers[%u].addrs inaccessible", + __func__, i); + return -EINVAL; + } rc = copy_from_user(wncc_oob_k->layers[i].addrs, wncc_oob_u->layers[i].addrs, - wncc_oob_k->layers[i].num_addrs * - sizeof(struct eva_kmd_wncc_addr)); + num_addrs * sizeof(struct eva_kmd_wncc_addr)); if (rc) break; } From b029f87904d8db0e4f26916fa330565c09d788d0 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 22 Jun 2023 12:50:47 -0700 Subject: [PATCH 238/317] msm: eva: Avoid using wrong bus client to vote Fix a racing between power voting and SSR shutdown. Change-Id: I75c13353174a514ef175056dd98f827a987bff7a Signed-off-by: George Shen --- msm/eva/cvp_power.c | 3 +++ msm/eva/msm_cvp_buf.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/msm/eva/cvp_power.c b/msm/eva/cvp_power.c index 0b3fc1ee98..b70784dc5d 100644 --- a/msm/eva/cvp_power.c +++ b/msm/eva/cvp_power.c @@ -219,6 +219,9 @@ int msm_cvp_update_power(struct msm_cvp_inst *inst) return -ECONNRESET; core = inst->core; + if (!core || core->state == CVP_CORE_UNINIT) + return -ECONNRESET; + clocks = &core->resources.clock_set; cl = &clocks->clock_tbl[clocks->count - 1]; if (!cl->has_scaling) { diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 4da8182d4e..6485d1e309 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -290,7 +290,7 @@ int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) file = msm_cvp_fget(buf->fd, inst->task, FMODE_PATH, 1); if (file == NULL) { - dprintk(CVP_WARN, "%s fail to get file from fd\n", __func__); + dprintk(CVP_WARN, "%s fail to get file from fd %d %s\n", __func__, buf->fd, inst->proc_name); return -EINVAL; } From 6cf7b0ef632274dc9771ad26eafd785423d8c657 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 22 Jun 2023 12:50:47 -0700 Subject: [PATCH 239/317] msm: eva: Avoid using wrong bus client to vote Fix a racing between power voting and SSR shutdown. Change-Id: I5a6053393ec8aab77ccc7720cbbef98831e4c3b7 Signed-off-by: George Shen Signed-off-by: Linux Image Build Automation --- msm/eva/cvp_power.c | 3 +++ msm/eva/msm_cvp_buf.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/msm/eva/cvp_power.c b/msm/eva/cvp_power.c index 0b3fc1ee98..b70784dc5d 100644 --- a/msm/eva/cvp_power.c +++ b/msm/eva/cvp_power.c @@ -219,6 +219,9 @@ int msm_cvp_update_power(struct msm_cvp_inst *inst) return -ECONNRESET; core = inst->core; + if (!core || core->state == CVP_CORE_UNINIT) + return -ECONNRESET; + clocks = &core->resources.clock_set; cl = &clocks->clock_tbl[clocks->count - 1]; if (!cl->has_scaling) { diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 4855a2f8a1..8486b9dd11 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -290,7 +290,7 @@ int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) file = msm_cvp_fget(buf->fd, inst->task, FMODE_PATH, 1); if (file == NULL) { - dprintk(CVP_WARN, "%s fail to get file from fd\n", __func__); + dprintk(CVP_WARN, "%s fail to get file from fd %d %s\n", __func__, buf->fd, inst->proc_name); return -EINVAL; } From 1e4ff767c3a1f20a3e208d69870cfdfd2df2cf05 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 26 Jun 2023 21:39:31 -0700 Subject: [PATCH 240/317] msm: eva: Avoid double session close In case DSP session creation failed due to reaching max number of EVA sessions. There is a chance DSP may resend delete session. Blocks re-deletion attempt. Change-Id: Idf54a9eff124c60af5867b013de641c93450960f Signed-off-by: George Shen --- msm/eva/cvp_power.c | 6 +++-- msm/eva/msm_cvp_buf.c | 2 +- msm/eva/msm_cvp_common.c | 43 +++++++++++++++++++---------------- msm/eva/msm_cvp_core.c | 22 ++++++++++++------ msm/eva/msm_cvp_dsp.c | 49 ++++++++++++++++++++++++---------------- 5 files changed, 73 insertions(+), 49 deletions(-) diff --git a/msm/eva/cvp_power.c b/msm/eva/cvp_power.c index b70784dc5d..722077331c 100644 --- a/msm/eva/cvp_power.c +++ b/msm/eva/cvp_power.c @@ -219,8 +219,10 @@ int msm_cvp_update_power(struct msm_cvp_inst *inst) return -ECONNRESET; core = inst->core; - if (!core || core->state == CVP_CORE_UNINIT) - return -ECONNRESET; + if (!core || core->state == CVP_CORE_UNINIT) { + rc = -ECONNRESET; + goto adjust_exit; + } clocks = &core->resources.clock_set; cl = &clocks->clock_tbl[clocks->count - 1]; diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 6485d1e309..187be309e3 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -2190,7 +2190,7 @@ int cvp_release_arp_buffers(struct msm_cvp_inst *inst) mutex_lock(&inst->persistbufs.lock); /* Workaround for FW: release buffer means release all */ - if (inst->state <= MSM_CVP_CLOSE_DONE) { + if (inst->state > MSM_CVP_CORE_INIT_DONE && inst->state <= MSM_CVP_CLOSE_DONE) { rc = call_hfi_op(hdev, session_release_buffers, (void *)inst->session); if (!rc) { diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 2d3002c9c0..70120d1b72 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -139,8 +139,11 @@ static void put_inst_helper(struct kref *kref) void cvp_put_inst(struct msm_cvp_inst *inst) { - if (!inst) + if (!inst || (kref_read(&inst->kref) < 1)) { + dprintk(CVP_ERR, "Invalid session %llx\n", inst); + WARN_ON(true); return; + } kref_put(&inst->kref, put_inst_helper); } @@ -399,6 +402,7 @@ static void handle_session_init_done(enum hal_command_response cmd, void *data) { struct msm_cvp_cb_cmd_done *response = data; struct msm_cvp_inst *inst = NULL; + struct msm_cvp_core *core; if (!response) { dprintk(CVP_ERR, @@ -406,11 +410,13 @@ static void handle_session_init_done(enum hal_command_response cmd, void *data) return; } + core = cvp_driver->cvp_core; inst = cvp_get_inst(cvp_driver->cvp_core, response->session_id); - if (!inst) { - dprintk(CVP_WARN, "%s:Got a response for an inactive session\n", - __func__); + dprintk(CVP_WARN, "%s:Got a response for an inactive session %#x\n", + __func__, response->session_id); + list_for_each_entry(inst, &core->instances, list) + cvp_print_inst(CVP_WARN, inst); return; } @@ -579,6 +585,7 @@ void handle_sys_error(enum hal_command_response cmd, void *data) hdev = core->device; mutex_lock(&core->lock); + core->ssr_count++; if (core->state == CVP_CORE_UNINIT) { dprintk(CVP_ERR, "%s: Core %pK already moved to state %d\n", @@ -589,8 +596,8 @@ void handle_sys_error(enum hal_command_response cmd, void *data) cur_state = core->state; core->state = CVP_CORE_UNINIT; - dprintk(CVP_WARN, "SYS_ERROR received for core %pK cmd %x\n", - core, cmd); + dprintk(CVP_WARN, "SYS_ERROR from core %pK cmd %x total: %d\n", + core, cmd, core->ssr_count); mutex_lock(&core->clk_lock); hfi_device = hdev->hfi_device_data; if (hfi_device->error == CVP_ERR_NOC_ERROR) { @@ -669,6 +676,7 @@ static void handle_session_close(enum hal_command_response cmd, void *data) { struct msm_cvp_cb_cmd_done *response = data; struct msm_cvp_inst *inst; + struct msm_cvp_core *core; if (!response) { dprintk(CVP_ERR, @@ -676,10 +684,15 @@ static void handle_session_close(enum hal_command_response cmd, void *data) return; } + core = cvp_driver->cvp_core; inst = cvp_get_inst(cvp_driver->cvp_core, response->session_id); if (!inst) { - dprintk(CVP_WARN, "%s: response for an inactive session\n", - __func__); + dprintk(CVP_WARN, "%s: response for an inactive session %#x\n", + __func__, response->session_id); + + list_for_each_entry(inst, &core->instances, list) + cvp_print_inst(CVP_WARN, inst); + return; } @@ -1165,14 +1178,13 @@ int msm_cvp_noc_error_info(struct msm_cvp_core *core) return 0; last_fault_count = core->smmu_fault_count; - core->ssr_count++; dprintk(CVP_ERR, "cvp ssr count %d %d %d\n", core->ssr_count, core->resources.max_ssr_allowed, core->smmu_fault_count); hdev = core->device; call_hfi_op(hdev, noc_error_info, hdev->hfi_device_data); - if (core->ssr_count >= core->resources.max_ssr_allowed) + if (core->smmu_fault_count >= core->resources.max_ssr_allowed) BUG_ON(!core->resources.non_fatal_pagefaults); return 0; @@ -1302,15 +1314,8 @@ int msm_cvp_comm_kill_session(struct msm_cvp_inst *inst) */ if (inst->state >= MSM_CVP_OPEN_DONE && inst->state < MSM_CVP_CLOSE_DONE) { - rc = msm_comm_session_abort(inst); - if (rc) { - dprintk(CVP_ERR, - "%s: inst %pK session %x abort failed\n", - __func__, inst, hash32_ptr(inst->session)); - change_cvp_inst_state(inst, MSM_CVP_CORE_INVALID); - } else { - change_cvp_inst_state(inst, MSM_CVP_CORE_UNINIT); - } + msm_comm_session_abort(inst); + change_cvp_inst_state(inst, MSM_CVP_CORE_INVALID); } if (inst->state >= MSM_CVP_CORE_UNINIT) { diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 11f65b486c..4eeba29e40 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -176,8 +176,7 @@ struct msm_cvp_inst *msm_cvp_open(int session_type, struct task_struct *task) goto err_invalid_core; } - pr_info_ratelimited( - CVP_DBG_TAG "%s opening cvp instance: %pK type %d cnt %d\n", + pr_info(CVP_DBG_TAG "%s opening cvp instance: %pK type %d cnt %d\n", "sess", task->comm, inst, session_type, instance_count); mutex_init(&inst->sync_lock); mutex_init(&inst->lock); @@ -377,6 +376,11 @@ int msm_cvp_destroy(struct msm_cvp_inst *inst) core = inst->core; + if (inst->session_type == MSM_CVP_DSP) { + cvp_dsp_del_sess(inst->dsp_handle, inst); + inst->task = NULL; + } + /* Ensure no path has core->clk_lock and core->lock sequence */ mutex_lock(&core->lock); mutex_lock(&core->clk_lock); @@ -404,8 +408,7 @@ int msm_cvp_destroy(struct msm_cvp_inst *inst) __deinit_fence_queue(inst); core->synx_ftbl->cvp_sess_deinit_synx(inst); - pr_info_ratelimited( - CVP_DBG_TAG + pr_info(CVP_DBG_TAG "closed cvp instance: %pK session_id = %d type %d %d\n", inst->proc_name, inst, hash32_ptr(inst->session), inst->session_type, core->smem_leak_count); @@ -447,6 +450,14 @@ int msm_cvp_close(void *instance) return -EINVAL; } + pr_info(CVP_DBG_TAG + "to close instance: %pK session_id = %d type %d state %d\n", + inst->proc_name, inst, hash32_ptr(inst->session), + inst->session_type, inst->state); + + if (inst->session == 0 || inst->state == MSM_CVP_CORE_UNINIT) + return -EINVAL; + if (inst->session_type != MSM_CVP_BOOT) { msm_cvp_cleanup_instance(inst); msm_cvp_session_deinit(inst); @@ -461,9 +472,6 @@ int msm_cvp_close(void *instance) msm_cvp_comm_session_clean(inst); - if (inst->session_type == MSM_CVP_DSP) - cvp_dsp_del_sess(inst->dsp_handle, inst); - kref_put(&inst->kref, close_helper); return 0; } diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 236c79b4f6..a01cbf61a0 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -348,8 +348,9 @@ search_again: mutex_unlock(&me->fastrpc_driver_list.lock); usleep_range(5000, 10000); if (max_count-- == 0) { - dprintk(CVP_ERR, "%s timeout\n", - __func__); + dprintk(CVP_ERR, "%s timeout %d\n", + __func__, refcount); + WARN_ON(true); goto exit; } goto search_again; @@ -1516,7 +1517,7 @@ static void print_power(const struct eva_power_req *pwr_req) } } -static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) +void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) { struct cvp_dsp_apps *me = &gfa_cv; struct msm_cvp_inst *inst = NULL; @@ -1547,23 +1548,29 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) return; } frpc_node = cvp_get_fastrpc_node_with_handle(dsp2cpu_cmd->pid); - if (!frpc_node || !frpc_node->cvp_fastrpc_device) { - dprintk(CVP_WARN, "%s cannot get fastrpc node from %x\n", + if (!frpc_node) { + dprintk(CVP_WARN, "%s cannot get fastrpc node from pid %x\n", __func__, dsp2cpu_cmd->pid); goto fail_lookup; } + if (!frpc_node->cvp_fastrpc_device) { + dprintk(CVP_WARN, "%s invalid fastrpc device from pid %x\n", + __func__, dsp2cpu_cmd->pid); + goto fail_pid; + } + frpc_device = frpc_node->cvp_fastrpc_device; rc = eva_fastrpc_dev_get_pid(frpc_device, &pid); if (rc) { dprintk(CVP_ERR, "%s Failed to map buffer 0x%x\n", __func__, rc); - goto fail_lookup; + goto fail_pid; } pid_s = find_get_pid(pid); if (pid_s == NULL) { dprintk(CVP_WARN, "%s incorrect pid %x\n", __func__, pid); - goto fail_lookup; + goto fail_pid; } dprintk(CVP_DSP, "%s get pid_s 0x%x from hdl 0x%x\n", __func__, pid_s, dsp2cpu_cmd->pid); @@ -1571,7 +1578,7 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) task = get_pid_task(pid_s, PIDTYPE_TGID); if (!task) { dprintk(CVP_WARN, "%s task doesn't exist\n", __func__); - goto fail_lookup; + goto fail_pid; } inst = msm_cvp_open(MSM_CVP_DSP, task); @@ -1587,10 +1594,11 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) inst->prop.is_secure = dsp2cpu_cmd->is_secure; inst->prop.dsp_mask = dsp2cpu_cmd->dsp_access_mask; + eva_fastrpc_driver_add_sess(frpc_node, inst); rc = msm_cvp_session_create(inst); if (rc) { dprintk(CVP_ERR, "Warning: send Session Create failed\n"); - goto fail_msm_cvp_open; + goto fail_get_session_info; } else { dprintk(CVP_DSP, "%s DSP Session Create done\n", __func__); } @@ -1606,7 +1614,6 @@ static void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) cmd->session_cpu_high = (uint32_t)((inst_handle & HIGH32) >> 32); cmd->session_cpu_low = (uint32_t)(inst_handle & LOW32); - eva_fastrpc_driver_add_sess(frpc_node, inst); cvp_put_fastrpc_node(frpc_node); inst->task = task; @@ -1627,13 +1634,15 @@ fail_get_session_info: msm_cvp_close(inst); fail_msm_cvp_open: put_task_struct(task); +fail_pid: + cvp_put_fastrpc_node(frpc_node); fail_lookup: /* unregister fastrpc driver */ eva_fastrpc_driver_unregister(dsp2cpu_cmd->pid, false); cmd->ret = -1; } -static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) +void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) { struct cvp_dsp_apps *me = &gfa_cv; struct msm_cvp_inst *inst; @@ -1665,7 +1674,7 @@ static void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->session_cpu_low); if (!inst || !is_cvp_inst_valid(inst)) { - dprintk(CVP_ERR, "%s incorrect session ID\n", __func__); + dprintk(CVP_ERR, "%s incorrect session ID %llx\n", __func__, inst); cmd->ret = -1; goto dsp_fail_delete; } @@ -1703,7 +1712,7 @@ dsp_fail_delete: return; } -static void __dsp_cvp_power_req(struct cvp_dsp_cmd_msg *cmd) +void __dsp_cvp_power_req(struct cvp_dsp_cmd_msg *cmd) { struct cvp_dsp_apps *me = &gfa_cv; struct msm_cvp_inst *inst; @@ -1759,7 +1768,7 @@ dsp_fail_power_req: return; } -static void __dsp_cvp_buf_register(struct cvp_dsp_cmd_msg *cmd) +void __dsp_cvp_buf_register(struct cvp_dsp_cmd_msg *cmd) { struct cvp_dsp_apps *me = &gfa_cv; struct msm_cvp_inst *inst; @@ -1817,7 +1826,7 @@ dsp_fail_buf_reg: kfree(kmd); } -static void __dsp_cvp_buf_deregister(struct cvp_dsp_cmd_msg *cmd) +void __dsp_cvp_buf_deregister(struct cvp_dsp_cmd_msg *cmd) { struct cvp_dsp_apps *me = &gfa_cv; struct msm_cvp_inst *inst; @@ -1870,7 +1879,7 @@ fail_dsp_buf_dereg: kfree(kmd); } -static void __dsp_cvp_mem_alloc(struct cvp_dsp_cmd_msg *cmd) +void __dsp_cvp_mem_alloc(struct cvp_dsp_cmd_msg *cmd) { struct cvp_dsp_apps *me = &gfa_cv; struct msm_cvp_inst *inst; @@ -1953,7 +1962,7 @@ fail_fastrpc_node: } -static void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) +void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) { struct cvp_dsp_apps *me = &gfa_cv; struct msm_cvp_inst *inst; @@ -2041,7 +2050,7 @@ fail_fastrpc_dev_unmap_dma: cvp_put_fastrpc_node(frpc_node); } -static void __dsp_cvp_sess_start(struct cvp_dsp_cmd_msg *cmd) +void __dsp_cvp_sess_start(struct cvp_dsp_cmd_msg *cmd) { struct cvp_dsp_apps *me = &gfa_cv; struct msm_cvp_inst *inst; @@ -2063,14 +2072,14 @@ static void __dsp_cvp_sess_start(struct cvp_dsp_cmd_msg *cmd) rc = msm_cvp_session_start(inst, (struct eva_kmd_arg *)NULL); if (rc) { - dprintk(CVP_ERR, "%s Failed to start session\n", __func__); + dprintk(CVP_ERR, "%s Failed to start session %llx\n", __func__, inst); cmd->ret = -1; return; } dprintk(CVP_DSP, "%s session started\n", __func__); } -static void __dsp_cvp_sess_stop(struct cvp_dsp_cmd_msg *cmd) +void __dsp_cvp_sess_stop(struct cvp_dsp_cmd_msg *cmd) { struct cvp_dsp_apps *me = &gfa_cv; struct msm_cvp_inst *inst; From d8cc45908cd8f5f151a0423cbde9f918fa223130 Mon Sep 17 00:00:00 2001 From: Linux Image Build Automation Date: Thu, 6 Jul 2023 17:01:38 -0700 Subject: [PATCH 241/317] Revert "msm: eva: Avoid using wrong bus client to vote" This reverts commit 6cf7b0ef632274dc9771ad26eafd785423d8c657. Change-Id: I9b16709ecb39d3dc9b2cb5f59b8249095a1b3038 Signed-off-by: Linux Image Build Automation --- msm/eva/cvp_power.c | 3 --- msm/eva/msm_cvp_buf.c | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/msm/eva/cvp_power.c b/msm/eva/cvp_power.c index b70784dc5d..0b3fc1ee98 100644 --- a/msm/eva/cvp_power.c +++ b/msm/eva/cvp_power.c @@ -219,9 +219,6 @@ int msm_cvp_update_power(struct msm_cvp_inst *inst) return -ECONNRESET; core = inst->core; - if (!core || core->state == CVP_CORE_UNINIT) - return -ECONNRESET; - clocks = &core->resources.clock_set; cl = &clocks->clock_tbl[clocks->count - 1]; if (!cl->has_scaling) { diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 8486b9dd11..4855a2f8a1 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -290,7 +290,7 @@ int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) file = msm_cvp_fget(buf->fd, inst->task, FMODE_PATH, 1); if (file == NULL) { - dprintk(CVP_WARN, "%s fail to get file from fd %d %s\n", __func__, buf->fd, inst->proc_name); + dprintk(CVP_WARN, "%s fail to get file from fd\n", __func__); return -EINVAL; } From 23e1f8be284ef937d06586cb91863b9a7bed5603 Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 7 Jul 2023 13:36:16 -0700 Subject: [PATCH 242/317] msm: eva: Fix session management issue Include prematurely reaching max number of sessions and unreliable DSP session deletion. Change-Id: Ic489291c9d75964106834f84e20cf32bc334d1a7 Signed-off-by: George Shen --- msm/eva/msm_cvp_core.c | 58 +++++++++++++++++++++++++++++++++++------- msm/eva/msm_cvp_dsp.c | 32 +++++++++++++++++++++++ 2 files changed, 81 insertions(+), 9 deletions(-) diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 4eeba29e40..0922366ba2 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -289,10 +289,11 @@ check_again: static void msm_cvp_cleanup_instance(struct msm_cvp_inst *inst) { bool empty; - int max_retries; + int rc, max_retries; struct msm_cvp_frame *frame; struct cvp_session_queue *sq, *sqf; struct cvp_hfi_device *hdev; + struct msm_cvp_inst *tmp; if (!inst) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); @@ -310,16 +311,21 @@ wait_dsp: empty = list_empty(&inst->cvpdspbufs.list); if (!empty && max_retries > 0) { mutex_unlock(&inst->cvpdspbufs.lock); - usleep_range(1000, 2000); + usleep_range(2000, 3000); max_retries--; goto wait_dsp; } mutex_unlock(&inst->cvpdspbufs.lock); - if (!empty) - dprintk(CVP_WARN, "Failed sess %pK DSP frame retried %d\n", - inst, - (inst->core->resources.msm_cvp_hw_rsp_timeout >> 5)); + if (!empty) { + dprintk(CVP_WARN, "Failed sess %pK DSP frame pending\n", inst); + /* + * A session is either DSP session or CPU session, cannot have both + * DSP and frame buffers + */ + goto stop_session; + } + max_retries = inst->core->resources.msm_cvp_hw_rsp_timeout >> 1; wait_frame: mutex_lock(&inst->frames.lock); @@ -346,6 +352,32 @@ wait_frame: inst->core->synx_ftbl->cvp_dump_fence_queue(inst); } +stop_session: + tmp = cvp_get_inst_validate(inst->core, inst); + if (!tmp) { + dprintk(CVP_ERR, "%s has a invalid session %llx\n", + __func__, inst); + return; + } + if (!empty) { + /* STOP SESSION to avoid SMMU fault after releasing ARP */ + hdev = inst->core->device; + rc = call_hfi_op(hdev, session_stop, (void *)inst->session); + if (rc) { + dprintk(CVP_WARN, "%s: cannot stop session rc %d\n", + __func__, rc); + goto release_arp; + } + + /*Fail stop session, release arp later may cause smmu fault*/ + rc = wait_for_sess_signal_receipt(inst, HAL_SESSION_STOP_DONE); + if (rc) + dprintk(CVP_WARN, "%s: wait for sess_stop fail, rc %d\n", + __func__, rc); + /* Continue to release ARP anyway */ + } +release_arp: + cvp_put_inst(tmp); if (cvp_release_arp_buffers(inst)) dprintk_rl(CVP_WARN, "Failed to release persist buffers\n"); @@ -455,8 +487,16 @@ int msm_cvp_close(void *instance) inst->proc_name, inst, hash32_ptr(inst->session), inst->session_type, inst->state); - if (inst->session == 0 || inst->state == MSM_CVP_CORE_UNINIT) - return -EINVAL; + if (inst->session == 0) { + if (inst->state >= MSM_CVP_CORE_INIT_DONE && + inst->state < MSM_CVP_OPEN_DONE) { + /* Session is not created, no ARP */ + inst->state = MSM_CVP_CORE_UNINIT; + goto exit; + } + if (inst->state == MSM_CVP_CORE_UNINIT) + return -EINVAL; + } if (inst->session_type != MSM_CVP_BOOT) { msm_cvp_cleanup_instance(inst); @@ -471,7 +511,7 @@ int msm_cvp_close(void *instance) } msm_cvp_comm_session_clean(inst); - +exit: kref_put(&inst->kref, close_helper); return 0; } diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index a01cbf61a0..7d4a7e82a3 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -2054,6 +2054,7 @@ void __dsp_cvp_sess_start(struct cvp_dsp_cmd_msg *cmd) { struct cvp_dsp_apps *me = &gfa_cv; struct msm_cvp_inst *inst; + struct cvp_session_queue *sq; int rc; struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; @@ -2070,6 +2071,21 @@ void __dsp_cvp_sess_start(struct cvp_dsp_cmd_msg *cmd) dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->session_cpu_low); + if (!inst || !is_cvp_inst_valid(inst)) { + dprintk(CVP_ERR, "%s incorrect session ID %llx\n", __func__, inst); + cmd->ret = -1; + return; + } + + sq = &inst->session_queue; + spin_lock(&sq->lock); + if (sq->state == QUEUE_START) { + spin_unlock(&sq->lock); + dprintk(CVP_WARN, "DSP double started session %llx\n", inst); + return; + } + spin_unlock(&sq->lock); + rc = msm_cvp_session_start(inst, (struct eva_kmd_arg *)NULL); if (rc) { dprintk(CVP_ERR, "%s Failed to start session %llx\n", __func__, inst); @@ -2083,6 +2099,7 @@ void __dsp_cvp_sess_stop(struct cvp_dsp_cmd_msg *cmd) { struct cvp_dsp_apps *me = &gfa_cv; struct msm_cvp_inst *inst; + struct cvp_session_queue *sq; int rc; struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; @@ -2099,6 +2116,21 @@ void __dsp_cvp_sess_stop(struct cvp_dsp_cmd_msg *cmd) dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->session_cpu_low); + if (!inst || !is_cvp_inst_valid(inst)) { + dprintk(CVP_ERR, "%s incorrect session ID %llx\n", __func__, inst); + cmd->ret = -1; + return; + } + + sq = &inst->session_queue; + spin_lock(&sq->lock); + if (sq->state == QUEUE_STOP) { + spin_unlock(&sq->lock); + dprintk(CVP_WARN, "DSP double stopped session %llx\n", inst); + return; + } + spin_unlock(&sq->lock); + rc = msm_cvp_session_stop(inst, (struct eva_kmd_arg *)NULL); if (rc) { dprintk(CVP_ERR, "%s Failed to stop session\n", __func__); From 8cdf80c8acdc7a3d834a640e9056941f35dee780 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 10 Jul 2023 12:06:09 -0700 Subject: [PATCH 243/317] msm: eva: Allow up to 40 buffers in a frame MVResampling frame packet has up to 38 buffers. Without the change, kernel will complain if MV resampling number is increased above 13. Change-Id: I95a97045a312163f378be157394a4ff041b57a57 Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index f801d721cb..1b4e09c34b 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -15,7 +15,7 @@ #include #include "cvp_comm_def.h" -#define MAX_FRAME_BUFFER_NUMS 30 +#define MAX_FRAME_BUFFER_NUMS 40 #define MAX_DMABUF_NUMS 64 #define IS_CVP_BUF_VALID(buf, smem) \ ((buf->size <= smem->size) && \ From 4cae0f824e518b711aca1e364f16ac071f0332a8 Mon Sep 17 00:00:00 2001 From: Jingjing Guo Date: Tue, 11 Jul 2023 12:30:19 +0800 Subject: [PATCH 244/317] msm: eva: Modify trace related code The original trace related code is outdated. Change-Id: Idfc161cdc518868300716607fc93b0bab26c0922 Signed-off-by: Jingjing Guo --- msm/eva/msm_cvp_debug.c | 1 - msm/eva/msm_cvp_events.h | 27 +++++++++++++++++++-------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 20a2300862..293d54b428 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -11,7 +11,6 @@ #include "cvp_hfi_api.h" #include "msm_cvp_dsp.h" -#define CREATE_TRACE_POINTS #define MAX_SSR_STRING_LEN 10 int msm_cvp_debug = CVP_ERR | CVP_WARN | CVP_FW; EXPORT_SYMBOL(msm_cvp_debug); diff --git a/msm/eva/msm_cvp_events.h b/msm/eva/msm_cvp_events.h index 97d26da6b2..fe02d5f0b4 100644 --- a/msm/eva/msm_cvp_events.h +++ b/msm/eva/msm_cvp_events.h @@ -1,18 +1,26 @@ /* SPDX-License-Identifier: GPL-2.0-only * * Copyright (c) 2020, The Linux Foundation. All rights reserved. - * Copyright (c) 2021, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023, Qualcomm Innovation Center, Inc. All rights reserved. */ -#undef TRACE_SYSTEM -#define TRACE_SYSTEM msm_cvp_events +#if !defined(_MSM_CVP_EVENTS_H_) || defined(TRACE_HEADER_MULTI_READ) +#define _MSM_CVP_EVENTS_H_ -#if !defined(_TRACE_MSM_CVP_H_) || defined(TRACE_HEADER_MULTI_READ) -#define _TRACE_MSM_CVP_H #include #include -TRACE_EVENT(tracing_mark_write_cvp, +#undef TRACE_SYSTEM +#define TRACE_SYSTEM msm_cvp + +#undef TRACE_INCLUDE_FILE +#define TRACE_INCLUDE_FILE msm_cvp_events + +// Since Chrome supports to parse the event “tracing_mark_write” by default +// so we can re-use this to display your own events in Chrome +// enable command as below: +// adb shell "echo 1 > /sys/kernel/tracing/events/msm_cvp/tracing_mark_write/enable" +TRACE_EVENT(tracing_mark_write, TP_PROTO(int pid, const char *name, bool trace_begin), TP_ARGS(pid, name, trace_begin), TP_STRUCT__entry( @@ -29,9 +37,9 @@ TRACE_EVENT(tracing_mark_write_cvp, __entry->pid, __get_str(trace_name)) ) #define CVPKERNEL_ATRACE_END(name) \ - trace_tracing_mark_write_cvp(current->tgid, name, 0) + trace_tracing_mark_write(current->tgid, name, 0) #define CVPKERNEL_ATRACE_BEGIN(name) \ - trace_tracing_mark_write_cvp(current->tgid, name, 1) + trace_tracing_mark_write(current->tgid, name, 1) DECLARE_EVENT_CLASS(msm_v4l2_cvp, @@ -361,4 +369,7 @@ DEFINE_EVENT(msm_cvp_perf, msm_cvp_perf_bus_vote, #endif +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . + #include From 0deded3f88146877f2d857475b6256d31fad1f45 Mon Sep 17 00:00:00 2001 From: Sabharsh Sidhu Date: Mon, 3 Jul 2023 16:34:54 -0700 Subject: [PATCH 245/317] msm: eva: Enhance WarpNCC buffer validation Add dmabuf-based WarpNCC metadata buffer size validation to prevent fault in case of erroneous OOB buffer content. Change-Id: Iaa89e6c52d2c262d2266bdc3151b5b3feee79c5a Signed-off-by: Sabharsh Sidhu --- msm/eva/msm_cvp_buf.c | 54 +++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 17 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 187be309e3..00a307d64b 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -46,7 +46,7 @@ struct cvp_oob_pool wncc_buf_pool; static void _wncc_print_cvpwnccbufs_table(struct msm_cvp_inst* inst); static int _wncc_unmap_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, - unsigned int num_layers, unsigned int metadata_bufs_offset, + struct eva_kmd_oob_wncc *wncc_oob, struct eva_kmd_wncc_metadata** wncc_metadata); void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log); @@ -887,19 +887,26 @@ static int _wncc_copy_oob_from_user(struct eva_kmd_hfi_packet* in_pkt, } static int _wncc_map_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, - unsigned int num_layers, unsigned int metadata_bufs_offset, + struct eva_kmd_oob_wncc *wncc_oob, struct eva_kmd_wncc_metadata** wncc_metadata) { int rc = 0, i; struct cvp_buf_type* wncc_metadata_bufs; struct dma_buf* dmabuf; struct eva_buf_map map; + __u32 num_layers, metadata_bufs_offset; - if (!in_pkt || !wncc_metadata || - num_layers < 1 || num_layers > EVA_KMD_WNCC_MAX_LAYERS) { + if (!in_pkt || !wncc_metadata || !wncc_oob) { dprintk(CVP_ERR, "%s: invalid params", __func__); return -EINVAL; } + + num_layers = wncc_oob->num_layers; + metadata_bufs_offset = wncc_oob->metadata_bufs_offset; + if (num_layers < 1 || num_layers > EVA_KMD_WNCC_MAX_LAYERS) { + dprintk(CVP_ERR, "%s: invalid wncc num layers", __func__); + return -EINVAL; + } if (metadata_bufs_offset > ((sizeof(in_pkt->pkt_data) - sizeof(struct cvp_buf_type)) / sizeof(__u32))) { dprintk(CVP_ERR, "%s: invalid wncc metadata bufs offset", @@ -920,6 +927,16 @@ static int _wncc_map_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, break; } + if (dmabuf->size < wncc_oob->layers[i].num_addrs * + sizeof(struct eva_kmd_wncc_metadata)) { + dprintk(CVP_ERR, + "%s: wncc_metadata_bufs[%d] size insufficient for num addrs in oob", + __func__, i); + dma_buf_put(dmabuf); + rc = -EINVAL; + break; + } + rc = dma_buf_begin_cpu_access(dmabuf, DMA_TO_DEVICE); if (rc) { dprintk(CVP_ERR, @@ -949,26 +966,32 @@ static int _wncc_map_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, } if (rc) - _wncc_unmap_metadata_bufs(in_pkt, i, metadata_bufs_offset, - wncc_metadata); + _wncc_unmap_metadata_bufs(in_pkt, wncc_oob, wncc_metadata); return rc; } static int _wncc_unmap_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, - unsigned int num_layers, unsigned int metadata_bufs_offset, + struct eva_kmd_oob_wncc *wncc_oob, struct eva_kmd_wncc_metadata** wncc_metadata) { int rc = 0, i; struct cvp_buf_type* wncc_metadata_bufs; struct dma_buf* dmabuf; struct eva_buf_map map; + __u32 num_layers, metadata_bufs_offset; - if (!in_pkt || !wncc_metadata || - num_layers < 1 || num_layers > EVA_KMD_WNCC_MAX_LAYERS) { + if (!in_pkt || !wncc_metadata || !wncc_oob) { dprintk(CVP_ERR, "%s: invalid params", __func__); return -EINVAL; } + + num_layers = wncc_oob->num_layers; + metadata_bufs_offset = wncc_oob->metadata_bufs_offset; + if (num_layers < 1 || num_layers > EVA_KMD_WNCC_MAX_LAYERS) { + dprintk(CVP_ERR, "%s: invalid wncc num layers", __func__); + return -EINVAL; + } if (metadata_bufs_offset > ((sizeof(in_pkt->pkt_data) - sizeof(struct cvp_buf_type)) / sizeof(__u32))) { dprintk(CVP_ERR, "%s: invalid wncc metadata bufs offset", @@ -980,8 +1003,7 @@ static int _wncc_unmap_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, &in_pkt->pkt_data[metadata_bufs_offset]; for (i = 0; i < num_layers; i++) { if (!wncc_metadata[i]) { - rc = -EINVAL; - break; + continue; } dmabuf = dma_buf_get(wncc_metadata_bufs[i].fd); @@ -1116,9 +1138,9 @@ static int msm_cvp_proc_oob_wncc(struct msm_cvp_inst* inst, goto exit; } - rc = _wncc_map_metadata_bufs(in_pkt, - wncc_oob->num_layers, wncc_oob->metadata_bufs_offset, - wncc_metadata); + memset(wncc_metadata, 0, + sizeof(*wncc_metadata) * EVA_KMD_WNCC_MAX_LAYERS); + rc = _wncc_map_metadata_bufs(in_pkt, wncc_oob, wncc_metadata); if (rc) { dprintk(CVP_ERR, "%s: failed to map wncc metadata bufs", __func__); @@ -1186,9 +1208,7 @@ static int msm_cvp_proc_oob_wncc(struct msm_cvp_inst* inst, _wncc_print_metadata_buf(wncc_oob->num_layers, wncc_oob->layers[0].num_addrs, wncc_metadata); - if (_wncc_unmap_metadata_bufs(in_pkt, - wncc_oob->num_layers, wncc_oob->metadata_bufs_offset, - wncc_metadata)) { + if (_wncc_unmap_metadata_bufs(in_pkt, wncc_oob, wncc_metadata)) { dprintk(CVP_ERR, "%s: failed to unmap wncc metadata bufs", __func__); } From 65165e0b23a1bb5828ca5028d18204f6b1c19f74 Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 17 Jul 2023 18:17:39 -0700 Subject: [PATCH 246/317] msm: eva: Fix Sys Fault Reg refcount issue Avoid kernel crash due to unbalance refcount operations. Change-Id: I280682ec3352164b62ecf3469303371f2af24a7d Signed-off-by: George Shen --- msm/eva/msm_cvp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 7da0f0866d..dd4e6e1a97 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -1079,7 +1079,8 @@ static int msm_cvp_get_sysprop(struct msm_cvp_inst *inst, } case EVA_KMD_PROP_SESSION_ERROR: { - rc = dma_buf_fd(hfi->mem_addr.mem_data.dma_buf, O_RDONLY | O_CLOEXEC); + get_dma_buf(hfi->sfr.mem_data.dma_buf); + rc = dma_buf_fd(hfi->sfr.mem_data.dma_buf, O_RDONLY | O_CLOEXEC); if (rc < 0) { dprintk(CVP_WARN, "Failed get dma_buf fd %d\n", rc); break; From deb4fd788e68c0b194d339655a03dbfe95ef3e4f Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 17 Jul 2023 16:47:05 -0700 Subject: [PATCH 247/317] msm: eva: Remove unused test bus dump Avoid NoC error during smmu fault handling. Change-Id: I4b6e4314c6d95bed1c89754955f1ffc975c74d48 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index b9b712600d..eb06a0d1c2 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -5127,7 +5127,7 @@ static void __noc_error_info_iris2(struct iris_hfi_device *device) { struct msm_cvp_core *core; struct cvp_noc_log *noc_log; - u32 val = 0, regi, regii, regiii, i; + u32 val = 0, regi, regii, regiii; bool log_required = false; int rc; @@ -5251,20 +5251,6 @@ static void __noc_error_info_iris2(struct iris_hfi_device *device) __write_register(device, CVP_SS_CLK_HALT, 0); __write_register(device, CVP_SS_CLK_EN, 0x3f); __write_register(device, CVP_VPU_WRAPPER_CORE_CONFIG, 0); - - for (i = 0; i < 15; i++) { - regi = 0xC0000000 + i; - __write_register(device, CVP_SS_ARP_TEST_BUS_CONTROL, regi); - val = __read_register(device, CVP_SS_ARP_TEST_BUS_REGISTER); - noc_log->arp_test_bus[i] = val; - } - - for (i = 0; i < 512; i++) { - regi = 0x40000000 + i; - __write_register(device, CVP_DMA_TEST_BUS_CONTROL, regi); - val = __read_register(device, CVP_DMA_TEST_BUS_REGISTER); - noc_log->dma_test_bus[i] = val; - } } static int iris_hfi_noc_error_info(void *dev) From 73269ff609d24d1d8cd2d14006d98f2308af8d6d Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 18 Jul 2023 12:14:16 -0700 Subject: [PATCH 248/317] msm: eva: Remove unused dsp code Remove unnecesary warning. Change-Id: I6517a4eb22a9cbbb692d7e09a5b0edde54fc888d Signed-off-by: George Shen --- msm/eva/msm_cvp_common.c | 1 - msm/eva/msm_cvp_core.c | 2 +- msm/eva/msm_cvp_dsp.c | 70 ---------------------------------------- msm/eva/msm_cvp_dsp.h | 16 --------- 4 files changed, 1 insertion(+), 88 deletions(-) diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 70120d1b72..cc7bc563f3 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -1234,7 +1234,6 @@ void msm_cvp_ssr_handler(struct work_struct *work) if (!s) return; print_hfi_queue_info(hdev); - msm_cvp_comm_kill_session(inst); cvp_put_inst(s); } else { dprintk(CVP_WARN, "No active CVP session to abort\n"); diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 0922366ba2..838d24a2ce 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -388,7 +388,7 @@ release_arp: if (inst->core->resources.pm_qos.off_vote_cnt > 0) inst->core->resources.pm_qos.off_vote_cnt--; else - dprintk(CVP_WARN, "%s Unexpected pm_qos off vote %d\n", + dprintk(CVP_INFO, "%s Unexpected pm_qos off vote %d\n", __func__, inst->core->resources.pm_qos.off_vote_cnt); spin_unlock(&inst->core->resources.pm_qos.lock); diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 7d4a7e82a3..89b2fc97ee 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -675,76 +675,6 @@ exit: return rc; } -int cvp_dsp_register_buffer(uint32_t session_id, uint32_t buff_fd, - uint32_t buff_fd_size, uint32_t buff_size, - uint32_t buff_offset, uint32_t buff_index, - uint32_t buff_fd_iova) -{ - struct cvp_dsp_cmd_msg cmd; - int rc; - struct cvp_dsp_apps *me = &gfa_cv; - struct cvp_dsp_rsp_msg rsp; - bool retried = false; - - cmd.type = CPU2DSP_REGISTER_BUFFER; - cmd.session_id = session_id; - cmd.buff_fd = buff_fd; - cmd.buff_fd_size = buff_fd_size; - cmd.buff_size = buff_size; - cmd.buff_offset = buff_offset; - cmd.buff_index = buff_index; - cmd.buff_fd_iova = buff_fd_iova; - - dprintk(CVP_DSP, - "%s: type=0x%x, buff_fd_iova=0x%x buff_index=0x%x\n", - __func__, cmd.type, buff_fd_iova, - cmd.buff_index); - dprintk(CVP_DSP, "%s: buff_size=0x%x session_id=0x%x\n", - __func__, cmd.buff_size, cmd.session_id); - - mutex_lock(&me->tx_lock); -retry: - rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg), &rsp); - if (rc) { - dprintk(CVP_ERR, "%s send failed rc = %d\n", __func__, rc); - goto exit; - } - - if (rsp.ret == CPU2DSP_EFAIL || rsp.ret == CPU2DSP_EUNSUPPORTED) { - dprintk(CVP_WARN, "%s, DSP return err %d\n", __func__, rsp.ret); - rc = -EINVAL; - goto exit; - } - - if (rsp.ret == CPU2DSP_EUNAVAILABLE) - goto fatal_exit; - - if (rsp.ret == CPU2DSP_EFATAL) { - if (!retried) { - mutex_unlock(&me->tx_lock); - retried = true; - rc = cvp_reinit_dsp(); - mutex_lock(&me->tx_lock); - if (rc) - goto fatal_exit; - else - goto retry; - } else { - goto fatal_exit; - } - } - - goto exit; - -fatal_exit: - me->state = DSP_INVALID; - cvp_hyp_assign_from_dsp(); - rc = -ENOTSUPP; -exit: - mutex_unlock(&me->tx_lock); - return rc; -} - int cvp_dsp_deregister_buffer(uint32_t session_id, uint32_t buff_fd, uint32_t buff_fd_size, uint32_t buff_size, uint32_t buff_offset, uint32_t buff_index, diff --git a/msm/eva/msm_cvp_dsp.h b/msm/eva/msm_cvp_dsp.h index b198643c11..926caf67e0 100644 --- a/msm/eva/msm_cvp_dsp.h +++ b/msm/eva/msm_cvp_dsp.h @@ -267,22 +267,6 @@ int cvp_dsp_resume(void); */ int cvp_dsp_shutdown(void); -/* - * API to register iova buffer address with CDSP - * - * @session_id: cvp session id - * @buff_fd: buffer fd - * @buff_fd_size: total size of fd in bytes - * @buff_size: size in bytes of cvp buffer - * @buff_offset: buffer offset - * @buff_index: buffer index - * @iova_buff_addr: IOVA buffer address - */ -int cvp_dsp_register_buffer(uint32_t session_id, uint32_t buff_fd, - uint32_t buff_fd_size, uint32_t buff_size, - uint32_t buff_offset, uint32_t buff_index, - uint32_t buff_fd_iova); - /* * API to de-register iova buffer address from CDSP * From 1741a5b55c4ad4c46b97f46745f8d2f52ef7244a Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 17 Jul 2023 18:12:48 -0700 Subject: [PATCH 249/317] msm: cvp: Avoid racing in bw voting when SSR is releasing core and some clients voting for bus. Change-Id: I8575d747c17f234bbce216c346843ab07ea6b340 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 9 ++++----- msm/eva/cvp_hfi_api.h | 3 +-- msm/eva/cvp_power.c | 2 +- msm/eva/msm_cvp_clocks.c | 19 ++++++++++++++++++- msm/eva/msm_cvp_clocks.h | 4 +++- 5 files changed, 27 insertions(+), 10 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index eb06a0d1c2..9f05e71be0 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -911,7 +911,7 @@ static int __unvote_buses(struct iris_hfi_device *device) device->bus_vote.data_count = 0; iris_hfi_for_each_bus(device, bus) { - rc = msm_cvp_set_bw(bus, 0); + rc = cvp_set_bw(bus, 0); if (rc) { dprintk(CVP_ERR, "%s: Failed unvoting bus\n", __func__); @@ -952,7 +952,7 @@ no_data_count: iris_hfi_for_each_bus(device, bus) { if (bus) { - rc = msm_cvp_set_bw(bus, bus->range[1]); + rc = cvp_set_bw(bus, bus->range[1]); if (rc) dprintk(CVP_ERR, "Failed voting bus %s to ab %u\n", @@ -964,7 +964,7 @@ err_no_mem: return rc; } -static int iris_hfi_vote_buses(void *dev, struct cvp_bus_vote_data *d, int n) +static int iris_hfi_vote_buses(void *dev, struct bus_info *bus, unsigned long bw) { int rc = 0; struct iris_hfi_device *device = dev; @@ -973,11 +973,10 @@ static int iris_hfi_vote_buses(void *dev, struct cvp_bus_vote_data *d, int n) return -EINVAL; mutex_lock(&device->lock); - rc = __vote_buses(device, d, n); + rc = cvp_set_bw(bus, bw); mutex_unlock(&device->lock); return rc; - } static int __core_set_resource(struct iris_hfi_device *device, diff --git a/msm/eva/cvp_hfi_api.h b/msm/eva/cvp_hfi_api.h index f21daf5b9c..7ac9a9c3b2 100644 --- a/msm/eva/cvp_hfi_api.h +++ b/msm/eva/cvp_hfi_api.h @@ -265,8 +265,7 @@ struct cvp_hfi_device { int (*session_send)(void *sess, struct eva_kmd_hfi_packet *in_pkt); int (*session_flush)(void *sess); int (*scale_clocks)(void *dev, u32 freq); - int (*vote_bus)(void *dev, struct cvp_bus_vote_data *data, - int num_data); + int (*vote_bus)(void *dev, struct bus_info *bus, unsigned long bw); int (*get_fw_info)(void *dev, struct cvp_hal_fw_info *fw_info); int (*session_clean)(void *sess); int (*get_core_capabilities)(void *dev); diff --git a/msm/eva/cvp_power.c b/msm/eva/cvp_power.c index 722077331c..daffac2393 100644 --- a/msm/eva/cvp_power.c +++ b/msm/eva/cvp_power.c @@ -257,7 +257,7 @@ int msm_cvp_update_power(struct msm_cvp_inst *inst) core->curr_freq = core->orig_core_sum; goto adjust_exit; } - rc = msm_cvp_set_bw(bus, core->bw_sum); + rc = msm_cvp_set_bw(core, bus, core->bw_sum); adjust_exit: cvp_put_inst(s); diff --git a/msm/eva/msm_cvp_clocks.c b/msm/eva/msm_cvp_clocks.c index cf795ca44a..450ae100ac 100644 --- a/msm/eva/msm_cvp_clocks.c +++ b/msm/eva/msm_cvp_clocks.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include "msm_cvp_common.h" @@ -458,7 +459,23 @@ void msm_cvp_deinit_clocks(struct iris_hfi_device *device) } } -int msm_cvp_set_bw(struct bus_info *bus, unsigned long bw) +int msm_cvp_set_bw(struct msm_cvp_core *core, struct bus_info *bus, unsigned long bw) +{ + struct cvp_hfi_device *hdev; + int rc; + + if (!core || !core->device) { + dprintk(CVP_ERR, "%s Invalid args: %pK\n", __func__, core); + return -EINVAL; + } + + hdev = core->device; + rc = call_hfi_op(hdev, vote_bus, hdev->hfi_device_data, bus, bw); + return rc; + +} + +int cvp_set_bw(struct bus_info *bus, unsigned long bw) { int rc = 0; diff --git a/msm/eva/msm_cvp_clocks.h b/msm/eva/msm_cvp_clocks.h index 48ffea055b..c678a08555 100644 --- a/msm/eva/msm_cvp_clocks.h +++ b/msm/eva/msm_cvp_clocks.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ @@ -22,5 +23,6 @@ int msm_cvp_disable_unprepare_clk(struct iris_hfi_device *device, const char *name); int msm_cvp_init_clocks(struct iris_hfi_device *device); void msm_cvp_deinit_clocks(struct iris_hfi_device *device); -int msm_cvp_set_bw(struct bus_info *bus, unsigned long bw); +int msm_cvp_set_bw(struct msm_cvp_core *core, struct bus_info *bus, unsigned long bw); +int cvp_set_bw(struct bus_info *bus, unsigned long bw); #endif From 2c6f9ca5421c0d6e57870bf113db6fc7cbab7db7 Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 20 Jul 2023 15:38:51 -0700 Subject: [PATCH 250/317] msm: eva: Validate DSP buffer size In case clients passing larger size than the actual dma-buf size. It may avoid DSP caused SMMU fault. Change-Id: I1f87d203f65a2d18d1a35e9e0b8dec281020150b Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 00a307d64b..7f12c69680 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -304,6 +304,13 @@ int msm_cvp_map_buf_dsp(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) goto exit; } + if (dma_buf->size < buf->size) { + dprintk(CVP_ERR, "%s DSP client buffer too large %d > %d\n", + __func__, buf->size, dma_buf->size); + rc = -EINVAL; + goto exit; + } + dprintk(CVP_MEM, "dma_buf from internal %llu\n", dma_buf); cbuf = cvp_kmem_cache_zalloc(&cvp_driver->buf_cache, GFP_KERNEL); From 936925471de7c957aaf4e0c4a91a9a5ba6615a42 Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 28 Jul 2023 19:28:10 -0700 Subject: [PATCH 251/317] msm: eva: Enhanced check to avoid kernel panic Avoid delete non-existing session and power on check before register write. Change-Id: I0b7d5045d68fd18e5a9a041d3ad3e37f4dac16ad Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 39 +++++++++++++++++++++++++++++++-------- msm/eva/msm_cvp.c | 2 +- msm/eva/msm_cvp_common.c | 3 +-- msm/eva/msm_cvp_core.c | 11 +++++++---- 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 9f05e71be0..08a7e640dd 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -112,6 +112,7 @@ static int __reset_control_assert_name(struct iris_hfi_device *device, const cha static int __reset_control_deassert_name(struct iris_hfi_device *device, const char *name); static int __reset_control_acquire(struct iris_hfi_device *device, const char *name); static int __reset_control_release(struct iris_hfi_device *device, const char *name); +static bool __is_ctl_power_on(struct iris_hfi_device *device); static struct iris_hfi_vpu_ops iris2_ops = { @@ -444,16 +445,15 @@ static int __write_queue(struct cvp_iface_q_info *qinfo, u8 *packet, cmd_pkt = (struct cvp_hfi_cmd_session_hdr *)packet; - if (cmd_pkt->size >= sizeof(struct cvp_hfi_cmd_session_hdr)) - dprintk(CVP_CMD, "%s: " - "pkt_type %08x sess_id %08x trans_id %u ktid %llu\n", + if (cmd_pkt->size >= sizeof(struct cvp_hfi_cmd_session_hdr)) + dprintk(CVP_CMD, "%s: pkt_type %08x sess_id %08x trans_id %u ktid %llu\n", __func__, cmd_pkt->packet_type, cmd_pkt->session_id, cmd_pkt->client_data.transaction_id, cmd_pkt->client_data.kdata & (FENCE_BIT - 1)); - else - dprintk(CVP_CMD, "%s: " - "pkt_type %08x", __func__, cmd_pkt->packet_type); + else if (cmd_pkt->size >= 12) + dprintk(CVP_CMD, "%s: pkt_type %08x sess_id %08x\n", __func__, + cmd_pkt->packet_type, cmd_pkt->session_id); if (msm_cvp_debug & CVP_PKT) { dprintk(CVP_PKT, "%s: %pK\n", __func__, qinfo); @@ -810,6 +810,21 @@ static int __read_register(struct iris_hfi_device *device, u32 reg) return rc; } +static bool __is_ctl_power_on(struct iris_hfi_device *device) +{ + u32 reg; + + reg = __read_register(device, CVP_CC_MVS1C_GDSCR); + if (!(reg & 0x80000000)) + return false; + + reg = __read_register(device, CVP_CC_MVS1C_CBCR); + if (reg & 0x80000000) + return false; + + return true; +} + static int __set_registers(struct iris_hfi_device *device) { struct msm_cvp_core *core; @@ -1409,6 +1424,8 @@ static int __iface_cmdq_write(struct iris_hfi_device *device, void *pkt) if (!rc && needs_interrupt) { /* Consumer of cmdq prefers that we raise an interrupt */ rc = 0; + if (!__is_ctl_power_on(device)) + dprintk(CVP_ERR, "%s power off, don't access reg\n", __func__); __write_register(device, CVP_CPU_CS_H2ASOFTINT, 1); } @@ -1442,8 +1459,11 @@ static int __iface_msgq_read(struct iris_hfi_device *device, void *pkt) } if (!__read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) { - if (tx_req_is_set) + if (tx_req_is_set) { + if (!__is_ctl_power_on(device)) + dprintk(CVP_ERR, "%s power off, don't access reg\n", __func__); __write_register(device, CVP_CPU_CS_H2ASOFTINT, 1); + } rc = 0; } else rc = -ENODATA; @@ -1473,8 +1493,11 @@ static int __iface_dbgq_read(struct iris_hfi_device *device, void *pkt) } if (!__read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) { - if (tx_req_is_set) + if (tx_req_is_set) { + if (!__is_ctl_power_on(device)) + dprintk(CVP_ERR, "%s power off, don't access reg\n", __func__); __write_register(device, CVP_CPU_CS_H2ASOFTINT, 1); + } rc = 0; } else rc = -ENODATA; diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index dd4e6e1a97..7048485948 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -988,7 +988,7 @@ int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst) sq->state = QUEUE_STOP; - dprintk(CVP_SESS, "Stop session queue: %pK session_id = %d\n", + dprintk(CVP_SESS, "Stop session queue: %pK session_id = %#x\n", inst, hash32_ptr(inst->session)); spin_unlock(&sq->lock); diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index cc7bc563f3..b9c2dd0592 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -196,8 +196,7 @@ struct msm_cvp_inst *cvp_get_inst_validate(struct msm_cvp_core *core, s = cvp_get_inst(core, session_id); if (!s) { - dprintk(CVP_ERR, "%s session doesn't exit\n", - __builtin_return_address(0)); + WARN(true, "%s session doesn't exit\n", __func__); return NULL; } diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 838d24a2ce..969268bc75 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -286,7 +286,7 @@ check_again: } } -static void msm_cvp_cleanup_instance(struct msm_cvp_inst *inst) +static int msm_cvp_cleanup_instance(struct msm_cvp_inst *inst) { bool empty; int rc, max_retries; @@ -297,7 +297,7 @@ static void msm_cvp_cleanup_instance(struct msm_cvp_inst *inst) if (!inst) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); - return; + return -EINVAL; } sqf = &inst->session_queue_fence; @@ -357,7 +357,7 @@ stop_session: if (!tmp) { dprintk(CVP_ERR, "%s has a invalid session %llx\n", __func__, inst); - return; + return -EINVAL; } if (!empty) { /* STOP SESSION to avoid SMMU fault after releasing ARP */ @@ -395,6 +395,7 @@ release_arp: hdev = inst->core->device; call_hfi_op(hdev, pm_qos_update, hdev->hfi_device_data); } + return 0; } int msm_cvp_destroy(struct msm_cvp_inst *inst) @@ -499,7 +500,9 @@ int msm_cvp_close(void *instance) } if (inst->session_type != MSM_CVP_BOOT) { - msm_cvp_cleanup_instance(inst); + rc = msm_cvp_cleanup_instance(inst); + if (rc) + return -EINVAL; msm_cvp_session_deinit(inst); } From b293b5b7130b19cbe194ac9bbff2d962e94d7058 Mon Sep 17 00:00:00 2001 From: George Shen Date: Sun, 23 Jul 2023 13:51:40 -0700 Subject: [PATCH 252/317] msm: eva: Rename hfi related devices To avoid confusion in code reading and prepare for future compatibility changes. Change-Id: I43d61e18d2e2d75d1fd46ceb2e763511329ee32d Signed-off-by: George Shen --- msm/eva/cvp.c | 10 +-- msm/eva/cvp_core_hfi.c | 27 ++++---- msm/eva/cvp_core_hfi.h | 10 +-- msm/eva/cvp_hfi.c | 80 ++++++++++----------- msm/eva/cvp_hfi_api.h | 8 +-- msm/eva/cvp_power.c | 2 +- msm/eva/cvp_smem.c | 16 ++--- msm/eva/msm_cvp.c | 47 ++++++------- msm/eva/msm_cvp_buf.c | 14 ++-- msm/eva/msm_cvp_clocks.c | 18 ++--- msm/eva/msm_cvp_common.c | 134 ++++++++++++++++++------------------ msm/eva/msm_cvp_core.c | 10 +-- msm/eva/msm_cvp_debug.c | 38 +++++----- msm/eva/msm_cvp_dsp.c | 34 ++++----- msm/eva/msm_cvp_internal.h | 2 +- msm/eva/msm_cvp_res_parse.c | 4 +- 16 files changed, 228 insertions(+), 226 deletions(-) diff --git a/msm/eva/cvp.c b/msm/eva/cvp.c index cde9fe25d2..4dee1a6766 100644 --- a/msm/eva/cvp.c +++ b/msm/eva/cvp.c @@ -379,13 +379,13 @@ static int msm_probe_cvp_device(struct platform_device *pdev) /* VM manager shall be started before HFI init */ vm_manager.vm_ops->vm_start(core); - core->device = cvp_hfi_initialize(core->hfi_type, + core->dev_ops = cvp_hfi_initialize(core->hfi_type, &core->resources, &cvp_handle_cmd_response); - if (IS_ERR_OR_NULL(core->device)) { + if (IS_ERR_OR_NULL(core->dev_ops)) { mutex_lock(&cvp_driver->lock); mutex_unlock(&cvp_driver->lock); - rc = PTR_ERR(core->device) ?: -EBADHANDLE; + rc = PTR_ERR(core->dev_ops) ?: -EBADHANDLE; if (rc != -EPROBE_DEFER) dprintk(CVP_ERR, "Failed to create HFI device\n"); else @@ -435,7 +435,7 @@ static int msm_probe_cvp_device(struct platform_device *pdev) return rc; err_fail_sub_device_probe: - cvp_hfi_deinitialize(core->hfi_type, core->device); + cvp_hfi_deinitialize(core->hfi_type, core->dev_ops); debugfs_remove_recursive(cvp_driver->debugfs_root); err_hfi_initialize: err_cores_exceeded: @@ -510,7 +510,7 @@ static int msm_cvp_remove(struct platform_device *pdev) return -EINVAL; } - cvp_hfi_deinitialize(core->hfi_type, core->device); + cvp_hfi_deinitialize(core->hfi_type, core->dev_ops); msm_cvp_free_platform_resources(&core->resources); sysfs_remove_group(&pdev->dev.kobj, &msm_cvp_core_attr_group); dev_set_drvdata(&pdev->dev, NULL); diff --git a/msm/eva/cvp_core_hfi.c b/msm/eva/cvp_core_hfi.c index 3ebbf2f987..3bba81f90a 100644 --- a/msm/eva/cvp_core_hfi.c +++ b/msm/eva/cvp_core_hfi.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -8,20 +9,20 @@ #include "cvp_hfi_api.h" #include "cvp_core_hfi.h" -struct cvp_hfi_device *cvp_hfi_initialize(enum msm_cvp_hfi_type hfi_type, +struct cvp_hfi_ops *cvp_hfi_initialize(enum msm_cvp_hfi_type hfi_type, struct msm_cvp_platform_resources *res, hfi_cmd_response_callback callback) { - struct cvp_hfi_device *hdev = NULL; + struct cvp_hfi_ops *ops_tbl = NULL; int rc = 0; - hdev = kzalloc(sizeof(struct cvp_hfi_device), GFP_KERNEL); - if (!hdev) { - dprintk(CVP_ERR, "%s: failed to allocate hdev\n", __func__); + ops_tbl = kzalloc(sizeof(struct cvp_hfi_ops), GFP_KERNEL); + if (!ops_tbl) { + dprintk(CVP_ERR, "%s: failed to allocate ops_tbl\n", __func__); return NULL; } - rc = cvp_iris_hfi_initialize(hdev, res, callback); + rc = cvp_iris_hfi_initialize(ops_tbl, res, callback); if (rc) { if (rc != -EPROBE_DEFER) @@ -30,23 +31,23 @@ struct cvp_hfi_device *cvp_hfi_initialize(enum msm_cvp_hfi_type hfi_type, goto err_hfi_init; } - return hdev; + return ops_tbl; err_hfi_init: - kfree(hdev); + kfree(ops_tbl); return ERR_PTR(rc); } void cvp_hfi_deinitialize(enum msm_cvp_hfi_type hfi_type, - struct cvp_hfi_device *hdev) + struct cvp_hfi_ops *ops_tbl) { - if (!hdev) { - dprintk(CVP_ERR, "%s invalid device %pK", __func__, hdev); + if (!ops_tbl) { + dprintk(CVP_ERR, "%s invalid device %pK", __func__, ops_tbl); return; } - cvp_iris_hfi_delete_device(hdev->hfi_device_data); + cvp_iris_hfi_delete_device(ops_tbl->hfi_device_data); - kfree(hdev); + kfree(ops_tbl); } diff --git a/msm/eva/cvp_core_hfi.h b/msm/eva/cvp_core_hfi.h index d44cb54271..2f417062d1 100644 --- a/msm/eva/cvp_core_hfi.h +++ b/msm/eva/cvp_core_hfi.h @@ -196,8 +196,8 @@ struct cvp_iface_q_info { iris_hfi_for_each_thing_reverse(__device, __sinfo, subcache) #define call_iris_op(d, op, args...) \ - (((d) && (d)->vpu_ops && (d)->vpu_ops->op) ? \ - ((d)->vpu_ops->op(args)):0) + (((d) && (d)->hal_ops && (d)->hal_ops->op) ? \ + ((d)->hal_ops->op(args)):0) struct cvp_hal_data { u32 irq; @@ -226,7 +226,7 @@ enum reset_state { struct iris_hfi_device; -struct iris_hfi_vpu_ops { +struct cvp_hal_ops { void (*interrupt_init)(struct iris_hfi_device *ptr); void (*setup_dsp_uc_memmap)(struct iris_hfi_device *device); void (*clock_config_on_enable)(struct iris_hfi_device *device); @@ -276,7 +276,7 @@ struct iris_hfi_device { struct pm_qos_request qos; unsigned int skip_pc_count; struct msm_cvp_capability *sys_init_capabilities; - struct iris_hfi_vpu_ops *vpu_ops; + struct cvp_hal_ops *hal_ops; }; irqreturn_t cvp_hfi_isr(int irq, void *dev); @@ -284,7 +284,7 @@ irqreturn_t iris_hfi_core_work_handler(int irq, void *data); irqreturn_t iris_hfi_isr_wd(int irq, void *dev); void cvp_iris_hfi_delete_device(void *device); -int cvp_iris_hfi_initialize(struct cvp_hfi_device *hdev, +int cvp_iris_hfi_initialize(struct cvp_hfi_ops *hdev, struct msm_cvp_platform_resources *res, hfi_cmd_response_callback callback); diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 08a7e640dd..3fb6d500d9 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -115,7 +115,7 @@ static int __reset_control_release(struct iris_hfi_device *device, const char *n static bool __is_ctl_power_on(struct iris_hfi_device *device); -static struct iris_hfi_vpu_ops iris2_ops = { +static struct cvp_hal_ops hal_ops = { .interrupt_init = interrupt_init_iris2, .setup_dsp_uc_memmap = setup_dsp_uc_memmap_vpu5, .clock_config_on_enable = clock_config_on_enable_vpu5, @@ -179,7 +179,7 @@ int get_hfi_version(void) struct iris_hfi_device *hfi; core = cvp_driver->cvp_core; - hfi = (struct iris_hfi_device *)core->device->hfi_device_data; + hfi = (struct iris_hfi_device *)core->dev_ops->hfi_device_data; return hfi->version; } @@ -192,7 +192,7 @@ unsigned int get_msg_size(struct cvp_hfi_msg_session_hdr *hdr) core = cvp_driver->cvp_core; if (core) - device = core->device->hfi_device_data; + device = core->dev_ops->hfi_device_data; else return 0; @@ -2994,7 +2994,7 @@ static void iris_hfi_pm_handler(struct work_struct *work) core = cvp_driver->cvp_core; if (core) - device = core->device->hfi_device_data; + device = core->dev_ops->hfi_device_data; else return; @@ -3492,7 +3492,7 @@ irqreturn_t iris_hfi_core_work_handler(int irq, void *data) core = cvp_driver->cvp_core; if (core) - device = core->device->hfi_device_data; + device = core->dev_ops->hfi_device_data; else return IRQ_HANDLED; @@ -3572,7 +3572,7 @@ static void iris_hfi_wd_work_handler(struct work_struct *work) enum hal_command_response cmd = HAL_SYS_WATCHDOG_TIMEOUT; core = cvp_driver->cvp_core; if (core) - device = core->device->hfi_device_data; + device = core->dev_ops->hfi_device_data; else return; if (msm_cvp_hw_wd_recovery) { @@ -5318,7 +5318,7 @@ static int __initialize_packetization(struct iris_hfi_device *device) void __init_cvp_ops(struct iris_hfi_device *device) { - device->vpu_ops = &iris2_ops; + device->hal_ops = &hal_ops; } static struct iris_hfi_device *__add_device(struct msm_cvp_platform_resources *res, @@ -5413,7 +5413,7 @@ void cvp_iris_hfi_delete_device(void *device) core = cvp_driver->cvp_core; if (core) - dev = core->device->hfi_device_data; + dev = core->dev_ops->hfi_device_data; if (!dev) return; @@ -5450,55 +5450,55 @@ static int iris_hfi_validate_session(void *sess, const char *func) return rc; } -static void iris_init_hfi_callbacks(struct cvp_hfi_device *hdev) +static void iris_init_hfi_callbacks(struct cvp_hfi_ops *ops_tbl) { - hdev->core_init = iris_hfi_core_init; - hdev->core_release = iris_hfi_core_release; - hdev->core_trigger_ssr = iris_hfi_core_trigger_ssr; - hdev->session_init = iris_hfi_session_init; - hdev->session_end = iris_hfi_session_end; - hdev->session_start = iris_hfi_session_start; - hdev->session_stop = iris_hfi_session_stop; - hdev->session_abort = iris_hfi_session_abort; - hdev->session_clean = iris_hfi_session_clean; - hdev->session_set_buffers = iris_hfi_session_set_buffers; - hdev->session_release_buffers = iris_hfi_session_release_buffers; - hdev->session_send = iris_hfi_session_send; - hdev->session_flush = iris_hfi_session_flush; - hdev->scale_clocks = iris_hfi_scale_clocks; - hdev->vote_bus = iris_hfi_vote_buses; - hdev->get_fw_info = iris_hfi_get_fw_info; - hdev->get_core_capabilities = iris_hfi_get_core_capabilities; - hdev->suspend = iris_hfi_suspend; - hdev->resume = iris_hfi_resume; - hdev->flush_debug_queue = iris_hfi_flush_debug_queue; - hdev->noc_error_info = iris_hfi_noc_error_info; - hdev->validate_session = iris_hfi_validate_session; - hdev->pm_qos_update = iris_pm_qos_update; - hdev->debug_hook = iris_debug_hook; + ops_tbl->core_init = iris_hfi_core_init; + ops_tbl->core_release = iris_hfi_core_release; + ops_tbl->core_trigger_ssr = iris_hfi_core_trigger_ssr; + ops_tbl->session_init = iris_hfi_session_init; + ops_tbl->session_end = iris_hfi_session_end; + ops_tbl->session_start = iris_hfi_session_start; + ops_tbl->session_stop = iris_hfi_session_stop; + ops_tbl->session_abort = iris_hfi_session_abort; + ops_tbl->session_clean = iris_hfi_session_clean; + ops_tbl->session_set_buffers = iris_hfi_session_set_buffers; + ops_tbl->session_release_buffers = iris_hfi_session_release_buffers; + ops_tbl->session_send = iris_hfi_session_send; + ops_tbl->session_flush = iris_hfi_session_flush; + ops_tbl->scale_clocks = iris_hfi_scale_clocks; + ops_tbl->vote_bus = iris_hfi_vote_buses; + ops_tbl->get_fw_info = iris_hfi_get_fw_info; + ops_tbl->get_core_capabilities = iris_hfi_get_core_capabilities; + ops_tbl->suspend = iris_hfi_suspend; + ops_tbl->resume = iris_hfi_resume; + ops_tbl->flush_debug_queue = iris_hfi_flush_debug_queue; + ops_tbl->noc_error_info = iris_hfi_noc_error_info; + ops_tbl->validate_session = iris_hfi_validate_session; + ops_tbl->pm_qos_update = iris_pm_qos_update; + ops_tbl->debug_hook = iris_debug_hook; } -int cvp_iris_hfi_initialize(struct cvp_hfi_device *hdev, +int cvp_iris_hfi_initialize(struct cvp_hfi_ops *ops_tbl, struct msm_cvp_platform_resources *res, hfi_cmd_response_callback callback) { int rc = 0; - if (!hdev || !res || !callback) { + if (!ops_tbl || !res || !callback) { dprintk(CVP_ERR, "Invalid params: %pK %pK %pK\n", - hdev, res, callback); + ops_tbl, res, callback); rc = -EINVAL; goto err_iris_hfi_init; } - hdev->hfi_device_data = __get_device(res, callback); + ops_tbl->hfi_device_data = __get_device(res, callback); - if (IS_ERR_OR_NULL(hdev->hfi_device_data)) { - rc = PTR_ERR(hdev->hfi_device_data) ?: -EINVAL; + if (IS_ERR_OR_NULL(ops_tbl->hfi_device_data)) { + rc = PTR_ERR(ops_tbl->hfi_device_data) ?: -EINVAL; goto err_iris_hfi_init; } - iris_init_hfi_callbacks(hdev); + iris_init_hfi_callbacks(ops_tbl); err_iris_hfi_init: return rc; diff --git a/msm/eva/cvp_hfi_api.h b/msm/eva/cvp_hfi_api.h index 7ac9a9c3b2..e15f9d671d 100644 --- a/msm/eva/cvp_hfi_api.h +++ b/msm/eva/cvp_hfi_api.h @@ -249,7 +249,7 @@ struct msm_cvp_hfi_defs { bool force_kernel_fence; }; -struct cvp_hfi_device { +struct cvp_hfi_ops { void *hfi_device_data; /*Add function pointers for all the hfi functions below*/ int (*core_init)(void *device); @@ -297,11 +297,11 @@ enum cvp_status hfi_process_session_init_done_prop_read( struct cvp_hfi_msg_sys_session_init_done_packet *pkt, struct cvp_hal_session_init_done *session_init_done); -struct cvp_hfi_device *cvp_hfi_initialize(enum msm_cvp_hfi_type hfi_type, +struct cvp_hfi_ops *cvp_hfi_initialize(enum msm_cvp_hfi_type hfi_type, struct msm_cvp_platform_resources *res, hfi_cmd_response_callback callback); void cvp_hfi_deinitialize(enum msm_cvp_hfi_type hfi_type, - struct cvp_hfi_device *hdev); + struct cvp_hfi_ops *hdev); int get_pkt_index(struct cvp_hal_session_cmd_pkt *hdr); int get_pkt_fenceoverride(struct cvp_hal_session_cmd_pkt* hdr); @@ -313,5 +313,5 @@ unsigned int get_msg_errorcode(void *msg); int get_msg_opconfigs(void *msg, unsigned int *session_id, unsigned int *error_type, unsigned int *config_id); extern const struct msm_cvp_hfi_defs cvp_hfi_defs[MAX_PKT_IDX]; -void print_hfi_queue_info(struct cvp_hfi_device *hdev); +void print_hfi_queue_info(struct cvp_hfi_ops *hdev); #endif /*__CVP_HFI_API_H__ */ diff --git a/msm/eva/cvp_power.c b/msm/eva/cvp_power.c index daffac2393..a0e74c729f 100644 --- a/msm/eva/cvp_power.c +++ b/msm/eva/cvp_power.c @@ -145,7 +145,7 @@ static int adjust_bw_freqs(unsigned int max_bw, unsigned int min_bw) core = cvp_driver->cvp_core; - hdev = core->device->hfi_device_data; + hdev = core->dev_ops->hfi_device_data; tbl = core->resources.allowed_clks_tbl; tbl_size = core->resources.allowed_clks_tbl_size; cvp_min_rate = tbl[0].clock_rate; diff --git a/msm/eva/cvp_smem.c b/msm/eva/cvp_smem.c index 1dcf884ec6..66b9b5979a 100644 --- a/msm/eva/cvp_smem.c +++ b/msm/eva/cvp_smem.c @@ -574,16 +574,16 @@ int msm_cvp_map_ipcc_regs(u32 *iova) { struct context_bank_info *cb; struct msm_cvp_core *core; - struct cvp_hfi_device *hfi_ops; + struct cvp_hfi_ops *ops_tbl; struct iris_hfi_device *dev = NULL; phys_addr_t paddr; u32 size; core = cvp_driver->cvp_core; if (core) { - hfi_ops = core->device; - if (hfi_ops) - dev = hfi_ops->hfi_device_data; + ops_tbl = core->dev_ops; + if (ops_tbl) + dev = ops_tbl->hfi_device_data; } if (!dev) @@ -612,15 +612,15 @@ int msm_cvp_unmap_ipcc_regs(u32 iova) { struct context_bank_info *cb; struct msm_cvp_core *core; - struct cvp_hfi_device *hfi_ops; + struct cvp_hfi_ops *ops_tbl; struct iris_hfi_device *dev = NULL; u32 size; core = cvp_driver->cvp_core; if (core) { - hfi_ops = core->device; - if (hfi_ops) - dev = hfi_ops->hfi_device_data; + ops_tbl = core->dev_ops; + if (ops_tbl) + dev = ops_tbl->hfi_device_data; } if (!dev) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 7048485948..dbbc9ade26 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -95,8 +95,9 @@ static int cvp_wait_process_message(struct msm_cvp_inst *inst, if (wait_event_timeout(sq->wq, cvp_msg_pending(sq, &msg, ktid), timeout) == 0) { dprintk(CVP_WARN, "session queue wait timeout\n"); - if (inst && inst->core && inst->core->device && inst->state != MSM_CVP_CORE_INVALID) - print_hfi_queue_info(inst->core->device); + if (inst && inst->core && inst->core->dev_ops && + inst->state != MSM_CVP_CORE_INVALID) + print_hfi_queue_info(inst->core->dev_ops); rc = -ETIMEDOUT; goto exit; } @@ -301,7 +302,7 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, unsigned long timeout; u64 ktid; int synx_state = SYNX_STATE_SIGNALED_SUCCESS; - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; struct cvp_session_queue *sq; u32 hfi_err = HFI_ERR_NONE; struct cvp_hfi_msg_session_hdr_ext hdr; @@ -311,7 +312,7 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, if (!inst || !inst->core) return -EINVAL; - hdev = inst->core->device; + ops_tbl = inst->core->dev_ops; sq = &inst->session_queue_fence; ktid = pkt->client_data.kdata; @@ -322,7 +323,7 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, goto exit; } - rc = call_hfi_op(hdev, session_send, (void *)inst->session, + rc = call_hfi_op(ops_tbl, session_send, (void *)inst->session, (struct eva_kmd_hfi_packet *)pkt); if (rc) { dprintk(CVP_ERR, "%s %s: Failed in call_hfi_op %d, %x\n", @@ -405,7 +406,7 @@ static int cvp_fence_thread(void *data) dprintk(CVP_SYNX, "Enter %s\n", current->comm); inst = (struct msm_cvp_inst *)data; - if (!inst || !inst->core || !inst->core->device) { + if (!inst || !inst->core || !inst->core->dev_ops) { dprintk(CVP_ERR, "%s invalid inst %pK\n", current->comm, inst); rc = -EINVAL; goto exit; @@ -634,12 +635,12 @@ static int cvp_enqueue_pkt(struct msm_cvp_inst* inst, unsigned int in_offset, unsigned int in_buf_num) { - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; struct cvp_hfi_cmd_session_hdr *cmd_hdr; int pkt_type, rc = 0; enum buf_map_type map_type; - hdev = inst->core->device; + ops_tbl = inst->core->dev_ops; pkt_type = in_pkt->pkt_data[1]; map_type = cvp_find_map_type(pkt_type); @@ -666,7 +667,7 @@ static int cvp_enqueue_pkt(struct msm_cvp_inst* inst, rc = cvp_populate_fences(in_pkt, in_offset, in_buf_num, inst); if (rc == 0) { - rc = call_hfi_op(hdev, session_send, (void*)inst->session, + rc = call_hfi_op(ops_tbl, session_send, (void *)inst->session, in_pkt); if (rc) { dprintk(CVP_ERR,"%s: Failed in call_hfi_op %d, %x\n", @@ -838,7 +839,7 @@ int msm_cvp_session_start(struct msm_cvp_inst *inst, struct eva_kmd_arg *arg) { struct cvp_session_queue *sq; - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; int rc; enum queue_state old_state; @@ -860,13 +861,13 @@ int msm_cvp_session_start(struct msm_cvp_inst *inst, sq->state = QUEUE_START; spin_unlock(&sq->lock); - hdev = inst->core->device; + ops_tbl = inst->core->dev_ops; if (inst->prop.type == HFI_SESSION_FD || inst->prop.type == HFI_SESSION_DMM) { spin_lock(&inst->core->resources.pm_qos.lock); inst->core->resources.pm_qos.off_vote_cnt++; spin_unlock(&inst->core->resources.pm_qos.lock); - call_hfi_op(hdev, pm_qos_update, hdev->hfi_device_data); + call_hfi_op(ops_tbl, pm_qos_update, ops_tbl->hfi_device_data); } /* * cvp_fence_thread_start will increment reference to instance. @@ -878,7 +879,7 @@ int msm_cvp_session_start(struct msm_cvp_inst *inst, goto restore_state; /* Send SESSION_START command */ - rc = call_hfi_op(hdev, session_start, (void *)inst->session); + rc = call_hfi_op(ops_tbl, session_start, (void *)inst->session); if (rc) { dprintk(CVP_WARN, "%s: session start failed rc %d\n", __func__, rc); @@ -914,7 +915,7 @@ int msm_cvp_session_stop(struct msm_cvp_inst *inst, struct cvp_session_queue *sq; struct eva_kmd_session_control *sc = NULL; struct msm_cvp_inst *s; - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; int rc; if (!inst || !inst->core) { @@ -947,9 +948,9 @@ int msm_cvp_session_stop(struct msm_cvp_inst *inst, "sess", inst, hash32_ptr(inst->session)); spin_unlock(&sq->lock); - hdev = inst->core->device; + ops_tbl = inst->core->dev_ops; /* Send SESSION_STOP command */ - rc = call_hfi_op(hdev, session_stop, (void *)inst->session); + rc = call_hfi_op(ops_tbl, session_stop, (void *)inst->session); if (rc) { dprintk(CVP_WARN, "%s: session stop failed rc %d\n", __func__, rc); @@ -1037,18 +1038,18 @@ static int msm_cvp_get_sysprop(struct msm_cvp_inst *inst, struct eva_kmd_arg *arg) { struct eva_kmd_sys_properties *props = &arg->data.sys_properties; - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; struct iris_hfi_device *hfi; struct cvp_session_prop *session_prop; int i, rc = 0; - if (!inst || !inst->core || !inst->core->device) { + if (!inst || !inst->core || !inst->core->dev_ops) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); return -EINVAL; } - hdev = inst->core->device; - hfi = hdev->hfi_device_data; + ops_tbl = inst->core->dev_ops; + hfi = ops_tbl->hfi_device_data; if (props->prop_num > MAX_KMD_PROP_NUM_PER_PACKET) { dprintk(CVP_ERR, "Too many properties %d to get\n", @@ -1452,7 +1453,7 @@ static int cvp_flush_all(struct msm_cvp_inst *inst) int rc = 0; struct msm_cvp_inst *s; struct cvp_fence_queue *q; - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; if (!inst || !inst->core) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); @@ -1466,7 +1467,7 @@ static int cvp_flush_all(struct msm_cvp_inst *inst) dprintk(CVP_SESS, "session %llx (%#x)flush all starts\n", inst, hash32_ptr(inst->session)); q = &inst->fence_cmd_queue; - hdev = inst->core->device; + ops_tbl = inst->core->dev_ops; cvp_clean_fence_queue(inst, SYNX_STATE_SIGNALED_CANCEL); @@ -1474,7 +1475,7 @@ static int cvp_flush_all(struct msm_cvp_inst *inst) __func__, hash32_ptr(inst->session)); /* Send flush to FW */ - rc = call_hfi_op(hdev, session_flush, (void *)inst->session); + rc = call_hfi_op(ops_tbl, session_flush, (void *)inst->session); if (rc) { dprintk(CVP_WARN, "%s: continue flush without fw. rc %d\n", __func__, rc); diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 7f12c69680..36a196be56 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -2195,7 +2195,7 @@ int cvp_release_arp_buffers(struct msm_cvp_inst *inst) struct cvp_internal_buf *buf; int rc = 0; struct msm_cvp_core *core; - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; if (!inst) { dprintk(CVP_ERR, "Invalid instance pointer = %pK\n", inst); @@ -2207,9 +2207,9 @@ int cvp_release_arp_buffers(struct msm_cvp_inst *inst) dprintk(CVP_ERR, "Invalid core pointer = %pK\n", core); return -EINVAL; } - hdev = core->device; - if (!hdev) { - dprintk(CVP_ERR, "Invalid device pointer = %pK\n", hdev); + ops_tbl = core->dev_ops; + if (!ops_tbl) { + dprintk(CVP_ERR, "Invalid device pointer = %pK\n", ops_tbl); return -EINVAL; } @@ -2218,7 +2218,7 @@ int cvp_release_arp_buffers(struct msm_cvp_inst *inst) mutex_lock(&inst->persistbufs.lock); /* Workaround for FW: release buffer means release all */ if (inst->state > MSM_CVP_CORE_INIT_DONE && inst->state <= MSM_CVP_CLOSE_DONE) { - rc = call_hfi_op(hdev, session_release_buffers, + rc = call_hfi_op(ops_tbl, session_release_buffers, (void *)inst->session); if (!rc) { mutex_unlock(&inst->persistbufs.lock); @@ -2370,7 +2370,7 @@ int cvp_release_dsp_buffers(struct msm_cvp_inst *inst, int msm_cvp_register_buffer(struct msm_cvp_inst *inst, struct eva_kmd_buffer *buf) { - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; struct cvp_hal_session *session; struct msm_cvp_inst *s; int rc = 0; @@ -2390,7 +2390,7 @@ int msm_cvp_register_buffer(struct msm_cvp_inst *inst, rc = -EINVAL; goto exit; } - hdev = inst->core->device; + ops_tbl = inst->core->dev_ops; print_client_buffer(CVP_HFI, "register", inst, buf); if (buf->index) diff --git a/msm/eva/msm_cvp_clocks.c b/msm/eva/msm_cvp_clocks.c index 450ae100ac..d2586ed756 100644 --- a/msm/eva/msm_cvp_clocks.c +++ b/msm/eva/msm_cvp_clocks.c @@ -81,17 +81,17 @@ int msm_cvp_mmrm_notifier_cb( int msm_cvp_set_clocks(struct msm_cvp_core *core) { - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; int rc; - if (!core || !core->device) { + if (!core || !core->dev_ops) { dprintk(CVP_ERR, "%s Invalid args: %pK\n", __func__, core); return -EINVAL; } - hdev = core->device; - rc = call_hfi_op(hdev, scale_clocks, - hdev->hfi_device_data, core->curr_freq); + ops_tbl = core->dev_ops; + rc = call_hfi_op(ops_tbl, scale_clocks, + ops_tbl->hfi_device_data, core->curr_freq); return rc; } @@ -461,16 +461,16 @@ void msm_cvp_deinit_clocks(struct iris_hfi_device *device) int msm_cvp_set_bw(struct msm_cvp_core *core, struct bus_info *bus, unsigned long bw) { - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; int rc; - if (!core || !core->device) { + if (!core || !core->dev_ops) { dprintk(CVP_ERR, "%s Invalid args: %pK\n", __func__, core); return -EINVAL; } - hdev = core->device; - rc = call_hfi_op(hdev, vote_bus, hdev->hfi_device_data, bus, bw); + ops_tbl = core->dev_ops; + rc = call_hfi_op(ops_tbl, vote_bus, ops_tbl->hfi_device_data, bus, bw); return rc; } diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index b9c2dd0592..9a16e89b31 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -64,12 +64,12 @@ static void dump_hfi_queue(struct iris_hfi_device *device) mutex_unlock(&device->lock); } -void print_hfi_queue_info(struct cvp_hfi_device *hdev) +void print_hfi_queue_info(struct cvp_hfi_ops *ops_tbl) { - if(hdev && hdev->hfi_device_data){ - call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data); - dump_hfi_queue(hdev->hfi_device_data); - } + if (ops_tbl && ops_tbl->hfi_device_data) { + call_hfi_op(ops_tbl, flush_debug_queue, ops_tbl->hfi_device_data); + dump_hfi_queue(ops_tbl->hfi_device_data); + } } static void handle_sys_init_done(enum hal_command_response cmd, void *data) @@ -191,7 +191,7 @@ struct msm_cvp_inst *cvp_get_inst_validate(struct msm_cvp_core *core, void *session_id) { int rc = 0; - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; struct msm_cvp_inst *s; s = cvp_get_inst(core, session_id); @@ -200,8 +200,8 @@ struct msm_cvp_inst *cvp_get_inst_validate(struct msm_cvp_core *core, return NULL; } - hdev = s->core->device; - rc = call_hfi_op(hdev, validate_session, s->session, __func__); + ops_tbl = s->core->dev_ops; + rc = call_hfi_op(ops_tbl, validate_session, s->session, __func__); if (rc) { cvp_put_inst(s); s = NULL; @@ -350,13 +350,13 @@ int wait_for_sess_signal_receipt(struct msm_cvp_inst *inst, enum hal_command_response cmd) { int rc = 0; - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; if (!IS_HAL_SESSION_CMD(cmd)) { dprintk(CVP_ERR, "Invalid inst cmd response: %d\n", cmd); return -EINVAL; } - hdev = (struct cvp_hfi_device *)(inst->core->device); + ops_tbl = (struct cvp_hfi_ops *)(inst->core->dev_ops); rc = wait_for_completion_timeout( &inst->completions[SESSION_MSG_INDEX(cmd)], msecs_to_jiffies( @@ -365,7 +365,7 @@ int wait_for_sess_signal_receipt(struct msm_cvp_inst *inst, dprintk(CVP_WARN, "Wait interrupted or timed out: %d\n", SESSION_MSG_INDEX(cmd)); if (inst->state != MSM_CVP_CORE_INVALID) - print_hfi_queue_info(hdev); + print_hfi_queue_info(ops_tbl); rc = -ETIMEDOUT; } else if (inst->state == MSM_CVP_CORE_INVALID) { rc = -ECONNRESET; @@ -519,7 +519,7 @@ static void handle_session_ctrl(enum hal_command_response cmd, void *data) static void handle_session_error(enum hal_command_response cmd, void *data) { struct msm_cvp_cb_cmd_done *response = data; - struct cvp_hfi_device *hdev = NULL; + struct cvp_hfi_ops *ops_tbl = NULL; struct msm_cvp_inst *inst = NULL; //unsigned long flags = 0; //int i; @@ -537,7 +537,7 @@ static void handle_session_error(enum hal_command_response cmd, void *data) return; } - hdev = inst->core->device; + ops_tbl = inst->core->dev_ops; dprintk(CVP_ERR, "Sess error 0x%x received for inst %pK sess %x\n", response->status, inst, hash32_ptr(inst->session)); cvp_print_inst(CVP_WARN, inst); @@ -562,7 +562,7 @@ void handle_sys_error(enum hal_command_response cmd, void *data) { struct msm_cvp_cb_cmd_done *response = data; struct msm_cvp_core *core = NULL; - struct cvp_hfi_device *hdev = NULL; + struct cvp_hfi_ops *ops_tbl = NULL; struct iris_hfi_device *hfi_device; struct msm_cvp_inst *inst = NULL; int i, rc = 0; @@ -581,7 +581,7 @@ void handle_sys_error(enum hal_command_response cmd, void *data) "Got SYS_ERR but unable to identify core\n"); return; } - hdev = core->device; + ops_tbl = core->dev_ops; mutex_lock(&core->lock); core->ssr_count++; @@ -598,12 +598,12 @@ void handle_sys_error(enum hal_command_response cmd, void *data) dprintk(CVP_WARN, "SYS_ERROR from core %pK cmd %x total: %d\n", core, cmd, core->ssr_count); mutex_lock(&core->clk_lock); - hfi_device = hdev->hfi_device_data; + hfi_device = ops_tbl->hfi_device_data; if (hfi_device->error == CVP_ERR_NOC_ERROR) { dprintk(CVP_WARN, "Got NOC error"); msm_cvp_noc_error_info(core); } - call_hfi_op(hdev, flush_debug_queue, hdev->hfi_device_data); + call_hfi_op(ops_tbl, flush_debug_queue, ops_tbl->hfi_device_data); list_for_each_entry(inst, &core->instances, list) { cvp_print_inst(CVP_WARN, inst); if (inst->state != MSM_CVP_CORE_INVALID) { @@ -628,7 +628,7 @@ void handle_sys_error(enum hal_command_response cmd, void *data) msm_cvp_handle_hw_error(core); dprintk(CVP_CORE, "Calling core_release\n"); - rc = call_hfi_op(hdev, core_release, hdev->hfi_device_data); + rc = call_hfi_op(ops_tbl, core_release, ops_tbl->hfi_device_data); if (rc) { dprintk(CVP_ERR, "core_release failed\n"); core->state = cur_state; @@ -646,9 +646,9 @@ void handle_sys_error(enum hal_command_response cmd, void *data) void msm_cvp_comm_session_clean(struct msm_cvp_inst *inst) { int rc = 0; - struct cvp_hfi_device *hdev = NULL; + struct cvp_hfi_ops *ops_tbl = NULL; - if (!inst || !inst->core || !inst->core->device) { + if (!inst || !inst->core || !inst->core->dev_ops) { dprintk(CVP_ERR, "%s invalid params\n", __func__); return; } @@ -658,10 +658,10 @@ void msm_cvp_comm_session_clean(struct msm_cvp_inst *inst) return; } - hdev = inst->core->device; + ops_tbl = inst->core->dev_ops; mutex_lock(&inst->lock); dprintk(CVP_SESS, "%s: inst %pK\n", __func__, inst); - rc = call_hfi_op(hdev, session_clean, + rc = call_hfi_op(ops_tbl, session_clean, (void *)inst->session); if (rc) { dprintk(CVP_ERR, @@ -772,16 +772,16 @@ static inline enum msm_cvp_thermal_level msm_comm_cvp_thermal_level(int level) static int msm_comm_session_abort(struct msm_cvp_inst *inst) { int rc = 0, abort_completion = 0; - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; - if (!inst || !inst->core || !inst->core->device) { + if (!inst || !inst->core || !inst->core->dev_ops) { dprintk(CVP_ERR, "%s invalid params\n", __func__); return -EINVAL; } - hdev = inst->core->device; - print_hfi_queue_info(hdev); + ops_tbl = inst->core->dev_ops; + print_hfi_queue_info(ops_tbl); if (1) return 0; @@ -790,7 +790,7 @@ static int msm_comm_session_abort(struct msm_cvp_inst *inst) dprintk(CVP_WARN, "%s: inst %pK session %x\n", __func__, inst, hash32_ptr(inst->session)); - rc = call_hfi_op(hdev, session_abort, (void *)inst->session); + rc = call_hfi_op(ops_tbl, session_abort, (void *)inst->session); if (rc) { dprintk(CVP_ERR, "%s session_abort failed rc: %d\n", __func__, rc); @@ -803,7 +803,7 @@ static int msm_comm_session_abort(struct msm_cvp_inst *inst) if (!rc) { dprintk(CVP_ERR, "%s: inst %pK session %x abort timed out\n", __func__, inst, hash32_ptr(inst->session)); - print_hfi_queue_info(hdev); + print_hfi_queue_info(ops_tbl); msm_cvp_comm_generate_sys_error(inst); rc = -EBUSY; } else { @@ -821,7 +821,7 @@ void msm_cvp_comm_handle_thermal_event(void) int msm_cvp_comm_check_core_init(struct msm_cvp_core *core) { int rc = 0; - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; mutex_lock(&core->lock); if (core->state >= CVP_CORE_INIT_DONE) { @@ -836,8 +836,8 @@ int msm_cvp_comm_check_core_init(struct msm_cvp_core *core) if (!rc) { dprintk(CVP_ERR, "%s: Wait interrupted or timed out: %d\n", __func__, SYS_MSG_INDEX(HAL_SYS_INIT_DONE)); - hdev = core->device; - print_hfi_queue_info(hdev); + ops_tbl = core->dev_ops; + print_hfi_queue_info(ops_tbl); rc = -EIO; goto exit; } else { @@ -867,14 +867,14 @@ static int msm_comm_init_core_done(struct msm_cvp_inst *inst) static int msm_comm_init_core(struct msm_cvp_inst *inst) { int rc = 0; - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; struct msm_cvp_core *core; - if (!inst || !inst->core || !inst->core->device) + if (!inst || !inst->core || !inst->core->dev_ops) return -EINVAL; core = inst->core; - hdev = core->device; + ops_tbl = core->dev_ops; mutex_lock(&core->lock); if (core->state >= CVP_CORE_INIT) { dprintk(CVP_CORE, "CVP core: is already in state: %d\n", @@ -897,7 +897,7 @@ static int msm_comm_init_core(struct msm_cvp_inst *inst) __func__); } dprintk(CVP_CORE, "%s: core %pK\n", __func__, core); - rc = call_hfi_op(hdev, core_init, hdev->hfi_device_data); + rc = call_hfi_op(ops_tbl, core_init, ops_tbl->hfi_device_data); if (rc) { dprintk(CVP_ERR, "Failed to init core\n"); goto fail_core_init; @@ -923,15 +923,15 @@ fail_cap_alloc: int msm_cvp_deinit_core(struct msm_cvp_inst *inst) { struct msm_cvp_core *core; - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; - if (!inst || !inst->core || !inst->core->device) { + if (!inst || !inst->core || !inst->core->dev_ops) { dprintk(CVP_ERR, "%s invalid parameters\n", __func__); return -EINVAL; } core = inst->core; - hdev = core->device; + ops_tbl = core->dev_ops; mutex_lock(&core->lock); change_cvp_inst_state(inst, MSM_CVP_CORE_UNINIT); @@ -959,13 +959,13 @@ static int msm_comm_session_init(int flipped_state, struct msm_cvp_inst *inst) { int rc = 0; - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; - if (!inst || !inst->core || !inst->core->device) { + if (!inst || !inst->core || !inst->core->dev_ops) { dprintk(CVP_ERR, "%s invalid parameters\n", __func__); return -EINVAL; } - hdev = inst->core->device; + ops_tbl = inst->core->dev_ops; if (IS_ALREADY_IN_STATE(flipped_state, MSM_CVP_OPEN)) { dprintk(CVP_INFO, "inst: %pK is already in state: %d\n", @@ -974,13 +974,13 @@ static int msm_comm_session_init(int flipped_state, } dprintk(CVP_SESS, "%s: inst %pK\n", __func__, inst); - rc = call_hfi_op(hdev, session_init, hdev->hfi_device_data, + rc = call_hfi_op(ops_tbl, session_init, ops_tbl->hfi_device_data, inst, &inst->session); if (rc || !inst->session) { dprintk(CVP_ERR, "Failed to call session init for: %pK, %pK, %d\n", - inst->core->device, inst, inst->session_type); + inst->core->dev_ops, inst, inst->session_type); rc = -EINVAL; goto exit; } @@ -994,9 +994,9 @@ static int msm_comm_session_close(int flipped_state, struct msm_cvp_inst *inst) { int rc = 0; - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; - if (!inst || !inst->core || !inst->core->device) { + if (!inst || !inst->core || !inst->core->dev_ops) { dprintk(CVP_ERR, "%s invalid params\n", __func__); return -EINVAL; } @@ -1006,9 +1006,9 @@ static int msm_comm_session_close(int flipped_state, inst, inst->state); goto exit; } - hdev = inst->core->device; + ops_tbl = inst->core->dev_ops; dprintk(CVP_SESS, "%s: inst %pK\n", __func__, inst); - rc = call_hfi_op(hdev, session_end, (void *) inst->session); + rc = call_hfi_op(ops_tbl, session_end, (void *) inst->session); if (rc) { dprintk(CVP_ERR, "Failed to send close\n"); @@ -1021,7 +1021,7 @@ exit: int msm_cvp_comm_suspend(void) { - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; struct msm_cvp_core *core; int rc = 0; @@ -1032,13 +1032,13 @@ int msm_cvp_comm_suspend(void) return -EINVAL; } - hdev = (struct cvp_hfi_device *)core->device; - if (!hdev) { + ops_tbl = (struct cvp_hfi_ops *)core->dev_ops; + if (!ops_tbl) { dprintk(CVP_ERR, "%s Invalid device handle\n", __func__); return -EINVAL; } - rc = call_hfi_op(hdev, suspend, hdev->hfi_device_data); + rc = call_hfi_op(ops_tbl, suspend, ops_tbl->hfi_device_data); return rc; } @@ -1163,10 +1163,10 @@ int msm_cvp_comm_try_state(struct msm_cvp_inst *inst, int state) int msm_cvp_noc_error_info(struct msm_cvp_core *core) { - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; static u32 last_fault_count = 0; - if (!core || !core->device) { + if (!core || !core->dev_ops) { dprintk(CVP_WARN, "%s: Invalid parameters: %pK\n", __func__, core); return -EINVAL; @@ -1180,8 +1180,8 @@ int msm_cvp_noc_error_info(struct msm_cvp_core *core) dprintk(CVP_ERR, "cvp ssr count %d %d %d\n", core->ssr_count, core->resources.max_ssr_allowed, core->smmu_fault_count); - hdev = core->device; - call_hfi_op(hdev, noc_error_info, hdev->hfi_device_data); + ops_tbl = core->dev_ops; + call_hfi_op(ops_tbl, noc_error_info, ops_tbl->hfi_device_data); if (core->smmu_fault_count >= core->resources.max_ssr_allowed) BUG_ON(!core->resources.non_fatal_pagefaults); @@ -1205,17 +1205,17 @@ void msm_cvp_ssr_handler(struct work_struct *work) { int rc; struct msm_cvp_core *core; - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; if (!work) return; core = container_of(work, struct msm_cvp_core, ssr_work); - if (!core || !core->device) { + if (!core || !core->dev_ops) { dprintk(CVP_ERR, "%s: Invalid params\n", __func__); return; } - hdev = core->device; + ops_tbl = core->dev_ops; if (core->ssr_type == SSR_SESSION_ABORT) { struct msm_cvp_inst *inst = NULL, *s; @@ -1232,7 +1232,7 @@ void msm_cvp_ssr_handler(struct work_struct *work) s = cvp_get_inst_validate(inst->core, inst); if (!s) return; - print_hfi_queue_info(hdev); + print_hfi_queue_info(ops_tbl); cvp_put_inst(s); } else { dprintk(CVP_WARN, "No active CVP session to abort\n"); @@ -1253,8 +1253,8 @@ send_again: * user SSR as non-fatal. */ core->trigger_ssr = true; - rc = call_hfi_op(hdev, core_trigger_ssr, - hdev->hfi_device_data, core->ssr_type); + rc = call_hfi_op(ops_tbl, core_trigger_ssr, + ops_tbl->hfi_device_data, core->ssr_type); if (rc) { if (rc == -EAGAIN) { core->trigger_ssr = false; @@ -1295,7 +1295,7 @@ int msm_cvp_comm_kill_session(struct msm_cvp_inst *inst) int rc = 0; unsigned long flags = 0; - if (!inst || !inst->core || !inst->core->device) { + if (!inst || !inst->core || !inst->core->dev_ops) { dprintk(CVP_ERR, "%s: invalid input parameters\n", __func__); return -EINVAL; } else if (!inst->session) { @@ -1329,24 +1329,24 @@ int msm_cvp_comm_kill_session(struct msm_cvp_inst *inst) static int set_internal_buf_on_fw(struct msm_cvp_inst *inst, struct msm_cvp_smem *handle) { - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; int rc = 0; u32 iova; u32 size; - if (!inst || !inst->core || !inst->core->device || !handle) { + if (!inst || !inst->core || !inst->core->dev_ops || !handle) { dprintk(CVP_ERR, "%s - invalid params\n", __func__); return -EINVAL; } - hdev = inst->core->device; + ops_tbl = inst->core->dev_ops; iova = handle->device_addr; size = handle->size; dprintk(CVP_SESS, "%s: allocated ARP buffer : %x\n", __func__, iova); - rc = call_hfi_op(hdev, session_set_buffers, + rc = call_hfi_op(ops_tbl, session_set_buffers, (void *) inst->session, iova, size); if (rc) { dprintk(CVP_ERR, "cvp_session_set_buffers failed\n"); @@ -1361,7 +1361,7 @@ int cvp_comm_set_arp_buffers(struct msm_cvp_inst *inst) int rc = 0; struct cvp_internal_buf *buf; - if (!inst || !inst->core || !inst->core->device) { + if (!inst || !inst->core || !inst->core->dev_ops) { dprintk(CVP_ERR, "%s invalid parameters\n", __func__); return -EINVAL; } diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 969268bc75..c0c96207b4 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -292,7 +292,7 @@ static int msm_cvp_cleanup_instance(struct msm_cvp_inst *inst) int rc, max_retries; struct msm_cvp_frame *frame; struct cvp_session_queue *sq, *sqf; - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; struct msm_cvp_inst *tmp; if (!inst) { @@ -361,8 +361,8 @@ stop_session: } if (!empty) { /* STOP SESSION to avoid SMMU fault after releasing ARP */ - hdev = inst->core->device; - rc = call_hfi_op(hdev, session_stop, (void *)inst->session); + ops_tbl = inst->core->dev_ops; + rc = call_hfi_op(ops_tbl, session_stop, (void *)inst->session); if (rc) { dprintk(CVP_WARN, "%s: cannot stop session rc %d\n", __func__, rc); @@ -392,8 +392,8 @@ release_arp: __func__, inst->core->resources.pm_qos.off_vote_cnt); spin_unlock(&inst->core->resources.pm_qos.lock); - hdev = inst->core->device; - call_hfi_op(hdev, pm_qos_update, hdev->hfi_device_data); + ops_tbl = inst->core->dev_ops; + call_hfi_op(ops_tbl, pm_qos_update, ops_tbl->hfi_device_data); } return 0; } diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 293d54b428..a7f29cf9af 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -69,13 +69,13 @@ static ssize_t core_info_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct msm_cvp_core *core = file->private_data; - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; struct cvp_hal_fw_info fw_info = { {0} }; char *dbuf, *cur, *end; int i = 0, rc = 0; ssize_t len = 0; - if (!core || !core->device) { + if (!core || !core->dev_ops) { dprintk(CVP_ERR, "Invalid params, core: %pK\n", core); return 0; } @@ -87,13 +87,13 @@ static ssize_t core_info_read(struct file *file, char __user *buf, } cur = dbuf; end = cur + MAX_DBG_BUF_SIZE; - hdev = core->device; + ops_tbl = core->dev_ops; cur += write_str(cur, end - cur, "===============================\n"); cur += write_str(cur, end - cur, "CORE %d: %pK\n", 0, core); cur += write_str(cur, end - cur, "===============================\n"); cur += write_str(cur, end - cur, "Core state: %d\n", core->state); - rc = call_hfi_op(hdev, get_fw_info, hdev->hfi_device_data, &fw_info); + rc = call_hfi_op(ops_tbl, get_fw_info, ops_tbl->hfi_device_data, &fw_info); if (rc) { dprintk(CVP_WARN, "Failed to read FW info\n"); goto err_fw_info; @@ -177,18 +177,18 @@ static const struct file_operations ssr_fops = { static int cvp_power_get(void *data, u64 *val) { - struct cvp_hfi_device *hfi_ops; + struct cvp_hfi_ops *ops_tbl; struct msm_cvp_core *core; struct iris_hfi_device *hfi_device; core = cvp_driver->cvp_core; if (!core) return 0; - hfi_ops = core->device; - if (!hfi_ops) + ops_tbl = core->dev_ops; + if (!ops_tbl) return 0; - hfi_device = hfi_ops->hfi_device_data; + hfi_device = ops_tbl->hfi_device_data; if (!hfi_device) return 0; @@ -201,7 +201,7 @@ static int cvp_power_get(void *data, u64 *val) static int cvp_power_set(void *data, u64 val) { - struct cvp_hfi_device *hfi_ops; + struct cvp_hfi_ops *ops_tbl; struct msm_cvp_core *core; struct iris_hfi_device *hfi_device; int rc = 0; @@ -210,11 +210,11 @@ static int cvp_power_set(void *data, u64 val) if (!core) return -EINVAL; - hfi_ops = core->device; - if (!hfi_ops) + ops_tbl = core->dev_ops; + if (!ops_tbl) return -EINVAL; - hfi_device = hfi_ops->hfi_device_data; + hfi_device = ops_tbl->hfi_device_data; if (!hfi_device) return -EINVAL; @@ -230,7 +230,7 @@ static int cvp_power_set(void *data, u64 val) return -EINVAL; if (val > 0) { - rc = call_hfi_op(hfi_ops, resume, hfi_ops->hfi_device_data); + rc = call_hfi_op(ops_tbl, resume, ops_tbl->hfi_device_data); if (rc) dprintk(CVP_ERR, "debugfs fail to power on cvp\n"); } @@ -284,20 +284,20 @@ failed_create_dir: static int _clk_rate_set(void *data, u64 val) { struct msm_cvp_core *core; - struct cvp_hfi_device *dev; + struct cvp_hfi_ops *ops_tbl; struct allowed_clock_rates_table *tbl = NULL; unsigned int tbl_size, i; core = cvp_driver->cvp_core; - dev = core->device; + ops_tbl = core->dev_ops; tbl = core->resources.allowed_clks_tbl; tbl_size = core->resources.allowed_clks_tbl_size; if (val == 0) { - struct iris_hfi_device *hdev = dev->hfi_device_data; + struct iris_hfi_device *hdev = ops_tbl->hfi_device_data; msm_cvp_clock_voting = 0; - call_hfi_op(dev, scale_clocks, hdev, hdev->clk_freq); + call_hfi_op(ops_tbl, scale_clocks, hdev, hdev->clk_freq); return 0; } @@ -313,7 +313,7 @@ static int _clk_rate_set(void *data, u64 val) dprintk(CVP_WARN, "Override cvp_clk_rate with %d\n", msm_cvp_clock_voting); - call_hfi_op(dev, scale_clocks, dev->hfi_device_data, + call_hfi_op(ops_tbl, scale_clocks, ops_tbl->hfi_device_data, msm_cvp_clock_voting); return 0; @@ -325,7 +325,7 @@ static int _clk_rate_get(void *data, u64 *val) struct iris_hfi_device *hdev; core = cvp_driver->cvp_core; - hdev = core->device->hfi_device_data; + hdev = core->dev_ops->hfi_device_data; if (msm_cvp_clock_voting) *val = msm_cvp_clock_voting; else diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 89b2fc97ee..fc8c9d2f73 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -222,7 +222,7 @@ static int delete_dsp_session(struct msm_cvp_inst *inst, struct list_head *ptr_dsp_buf = NULL, *next_dsp_buf = NULL; struct cvp_internal_buf *buf = NULL; struct task_struct *task = NULL; - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; int rc; if (!inst) @@ -280,8 +280,8 @@ static int delete_dsp_session(struct msm_cvp_inst *inst, inst->core->resources.pm_qos.off_vote_cnt); spin_unlock(&inst->core->resources.pm_qos.lock); - hdev = inst->core->device; - call_hfi_op(hdev, pm_qos_update, hdev->hfi_device_data); + ops_tbl = inst->core->dev_ops; + call_hfi_op(ops_tbl, pm_qos_update, ops_tbl->hfi_device_data); rc = msm_cvp_close(inst); if (rc) @@ -833,8 +833,8 @@ static int __reinit_dsp(void) struct iris_hfi_device *device; core = cvp_driver->cvp_core; - if (core && core->device) - device = core->device->hfi_device_data; + if (core && core->dev_ops) + device = core->dev_ops->hfi_device_data; else return -EINVAL; @@ -1306,8 +1306,8 @@ void cvp_dsp_send_hfi_queue(void) int rc; core = cvp_driver->cvp_core; - if (core && core->device) - device = core->device->hfi_device_data; + if (core && core->dev_ops) + device = core->dev_ops->hfi_device_data; else return; @@ -1458,7 +1458,7 @@ void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; struct pid *pid_s = NULL; struct task_struct *task = NULL; - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; struct fastrpc_device *frpc_device; cmd->ret = 0; @@ -1555,8 +1555,8 @@ void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) spin_lock(&inst->core->resources.pm_qos.lock); inst->core->resources.pm_qos.off_vote_cnt++; spin_unlock(&inst->core->resources.pm_qos.lock); - hdev = inst->core->device; - call_hfi_op(hdev, pm_qos_update, hdev->hfi_device_data); + ops_tbl = inst->core->dev_ops; + call_hfi_op(ops_tbl, pm_qos_update, ops_tbl->hfi_device_data); return; @@ -1580,7 +1580,7 @@ void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; struct cvp_dsp_fastrpc_driver_entry *frpc_node = NULL; struct task_struct *task = NULL; - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; cmd->ret = 0; @@ -1620,8 +1620,8 @@ void __dsp_cvp_sess_delete(struct cvp_dsp_cmd_msg *cmd) inst->core->resources.pm_qos.off_vote_cnt); spin_unlock(&inst->core->resources.pm_qos.lock); - hdev = inst->core->device; - call_hfi_op(hdev, pm_qos_update, hdev->hfi_device_data); + ops_tbl = inst->core->dev_ops; + call_hfi_op(ops_tbl, pm_qos_update, ops_tbl->hfi_device_data); rc = msm_cvp_close(inst); if (rc) { @@ -2075,7 +2075,7 @@ static int cvp_dsp_thread(void *data) int rc = 0, old_state; struct cvp_dsp_apps *me = &gfa_cv; struct cvp_dsp_cmd_msg cmd; - struct cvp_hfi_device *hdev; + struct cvp_hfi_ops *ops_tbl; struct msm_cvp_core *core; core = cvp_driver->cvp_core; @@ -2085,8 +2085,8 @@ static int cvp_dsp_thread(void *data) goto exit; } - hdev = (struct cvp_hfi_device *)core->device; - if (!hdev) { + ops_tbl = (struct cvp_hfi_ops *)core->dev_ops; + if (!ops_tbl) { dprintk(CVP_ERR, "%s Invalid device handle\n", __func__); rc = -EINVAL; goto exit; @@ -2129,7 +2129,7 @@ wait_dsp: mutex_lock(&me->tx_lock); old_state = me->state; me->state = DSP_READY; - rc = call_hfi_op(hdev, resume, hdev->hfi_device_data); + rc = call_hfi_op(ops_tbl, resume, ops_tbl->hfi_device_data); if (rc) { dprintk(CVP_WARN, "%s Failed to resume cvp\n", __func__); diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index a434438451..bb7d539436 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -320,7 +320,7 @@ struct msm_cvp_core { struct cdev cdev; struct class *class; struct device *dev; - struct cvp_hfi_device *device; + struct cvp_hfi_ops *dev_ops; struct msm_cvp_platform_data *platform_data; struct msm_cvp_synx_ops *synx_ftbl; struct list_head instances; diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index ae08d00379..b9abc9e392 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -1061,10 +1061,10 @@ int msm_cvp_smmu_fault_handler(struct iommu_domain *domain, cvp_print_inst(CVP_ERR, inst); msm_cvp_print_inst_bufs(inst, log); } - hdev = core->device->hfi_device_data; + hdev = core->dev_ops->hfi_device_data; if (hdev) { hdev->error = CVP_ERR_NOC_ERROR; - call_hfi_op(core->device, debug_hook, hdev); + call_hfi_op(core->dev_ops, debug_hook, hdev); } mutex_unlock(&core->lock); /* From acc49d12ac05c80f3a344af52cfb59f7400447f9 Mon Sep 17 00:00:00 2001 From: Jingjing Guo Date: Fri, 28 Jul 2023 09:53:23 +0800 Subject: [PATCH 253/317] msm: eva: Fix print error The order of MPU and OD is wrong, which will cause confusion when logcat to debug. Change-Id: Iff298350bde322a03dda28e78a3737996d5a2965 Signed-off-by: Jingjing Guo --- msm/eva/cvp_power.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/cvp_power.c b/msm/eva/cvp_power.c index a0e74c729f..385b70351f 100644 --- a/msm/eva/cvp_power.c +++ b/msm/eva/cvp_power.c @@ -31,7 +31,7 @@ static bool is_subblock_profile_existed(struct msm_cvp_inst *inst) inst->prop.cycles[HFI_HW_LSR]); } -static char hw_names[HFI_MAX_HW_THREADS][8] = {{"FDU"}, {"OD"}, {"MPU"}, {"ICA"}, +static char hw_names[HFI_MAX_HW_THREADS][8] = {{"FDU"}, {"MPU"}, {"OD"}, {"ICA"}, {"VADL"}, {"TOF"}, {"RGE"}, {"XRA"}, {"LSR"}}; static void aggregate_power_update(struct msm_cvp_core *core, From 1028da124c7b4ab631a04db3a00e359970a760ac Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 31 Jul 2023 21:29:57 -0700 Subject: [PATCH 254/317] msm: eva: Reduce HFI processing timeout to 1s From original 2s. It enables CPU and DSP communication timeout to 1.5s. Change-Id: I33cba756e95cd2cc535927960610c1dab26d4242 Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 8 ----- msm/eva/msm_cvp_dsp.c | 70 -------------------------------------- msm/eva/msm_cvp_dsp.h | 19 ++--------- msm/eva/msm_cvp_platform.c | 3 +- 4 files changed, 4 insertions(+), 96 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 36a196be56..5f439abd99 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1998,14 +1998,6 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) list_for_each_entry_safe(cbuf, dummy, &inst->cvpdspbufs.list, list) { print_internal_buffer(CVP_MEM, "remove dspbufs", inst, cbuf); if (cbuf->ownership == CLIENT) { - rc = cvp_dsp_deregister_buffer(hash32_ptr(session), - cbuf->fd, cbuf->smem->dma_buf->size, cbuf->size, - cbuf->offset, cbuf->index, - (uint32_t)cbuf->smem->device_addr); - if (rc) - dprintk(CVP_ERR, - "%s: failed dsp deregistration fd=%d rc=%d", - __func__, cbuf->fd, rc); msm_cvp_unmap_smem(inst, cbuf->smem, "unmap dsp"); msm_cvp_smem_put_dma_buf(cbuf->smem->dma_buf); } else if (cbuf->ownership == DSP) { diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index fc8c9d2f73..07ed6327dc 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -675,76 +675,6 @@ exit: return rc; } -int cvp_dsp_deregister_buffer(uint32_t session_id, uint32_t buff_fd, - uint32_t buff_fd_size, uint32_t buff_size, - uint32_t buff_offset, uint32_t buff_index, - uint32_t buff_fd_iova) -{ - struct cvp_dsp_cmd_msg cmd; - int rc; - struct cvp_dsp_apps *me = &gfa_cv; - struct cvp_dsp_rsp_msg rsp; - bool retried = false; - - cmd.type = CPU2DSP_DEREGISTER_BUFFER; - cmd.session_id = session_id; - cmd.buff_fd = buff_fd; - cmd.buff_fd_size = buff_fd_size; - cmd.buff_size = buff_size; - cmd.buff_offset = buff_offset; - cmd.buff_index = buff_index; - cmd.buff_fd_iova = buff_fd_iova; - - dprintk(CVP_DSP, - "%s: type=0x%x, buff_fd_iova=0x%x buff_index=0x%x\n", - __func__, cmd.type, buff_fd_iova, - cmd.buff_index); - dprintk(CVP_DSP, "%s: buff_size=0x%x session_id=0x%x\n", - __func__, cmd.buff_size, cmd.session_id); - - mutex_lock(&me->tx_lock); -retry: - rc = cvp_dsp_send_cmd_sync(&cmd, sizeof(struct cvp_dsp_cmd_msg), &rsp); - if (rc) { - dprintk(CVP_ERR, "%s send failed rc = %d\n", __func__, rc); - goto exit; - } - - if (rsp.ret == CPU2DSP_EFAIL || rsp.ret == CPU2DSP_EUNSUPPORTED) { - dprintk(CVP_WARN, "%s, DSP return err %d\n", __func__, rsp.ret); - rc = -EINVAL; - goto exit; - } - - if (rsp.ret == CPU2DSP_EUNAVAILABLE) - goto fatal_exit; - - if (rsp.ret == CPU2DSP_EFATAL) { - if (!retried) { - mutex_unlock(&me->tx_lock); - retried = true; - rc = cvp_reinit_dsp(); - mutex_lock(&me->tx_lock); - if (rc) - goto fatal_exit; - else - goto retry; - } else { - goto fatal_exit; - } - } - - goto exit; - -fatal_exit: - me->state = DSP_INVALID; - cvp_hyp_assign_from_dsp(); - rc = -ENOTSUPP; -exit: - mutex_unlock(&me->tx_lock); - return rc; -} - static const struct rpmsg_device_id cvp_dsp_rpmsg_match[] = { { CVP_APPS_DSP_GLINK_GUID }, { }, diff --git a/msm/eva/msm_cvp_dsp.h b/msm/eva/msm_cvp_dsp.h index 926caf67e0..6773d2025c 100644 --- a/msm/eva/msm_cvp_dsp.h +++ b/msm/eva/msm_cvp_dsp.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef MSM_CVP_DSP_H @@ -48,7 +49,7 @@ struct fastrpc_driver { #define DSP_VM_NUM 2 #define CVP_DSP_MAX_RESERVED 5 #define CVP_DSP2CPU_RESERVED 8 -#define CVP_DSP_RESPONSE_TIMEOUT 300 +#define CVP_DSP_RESPONSE_TIMEOUT 600 #define CVP_INVALID_RPMSG_TYPE 0xBADDFACE #define MAX_FRAME_BUF_NUM 16 @@ -267,22 +268,6 @@ int cvp_dsp_resume(void); */ int cvp_dsp_shutdown(void); -/* - * API to de-register iova buffer address from CDSP - * - * @session_id: cvp session id - * @buff_fd: buffer fd - * @buff_fd_size: total size of fd in bytes - * @buff_size: size in bytes of cvp buffer - * @buff_offset: buffer offset - * @buff_index: buffer index - * @iova_buff_addr: IOVA buffer address - */ -int cvp_dsp_deregister_buffer(uint32_t session_id, uint32_t buff_fd, - uint32_t buff_fd_size, uint32_t buff_size, - uint32_t buff_offset, uint32_t buff_index, - uint32_t buff_fd_iova); - int cvp_dsp_fastrpc_unmap(uint32_t handle, struct cvp_internal_buf *buf); int cvp_dsp_del_sess(uint32_t handle, struct msm_cvp_inst *inst); diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 0cfa12a35d..7b9fe5b07d 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -235,7 +236,7 @@ static struct msm_cvp_common_data sm8650_common_data[] = { }, { .key = "qcom,hw-resp-timeout", - .value = 2000, + .value = 1000, }, { .key = "qcom,dsp-resp-timeout", From 96b871c93661f532f3213aad19b34ad994d3a82f Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 28 Jul 2023 19:28:10 -0700 Subject: [PATCH 255/317] msm: eva: Enhanced check to avoid kernel panic Avoid delete non-existing session and power on check before register write. Change-Id: I474fe959503622320774d659444c131bfcb3e840 Signed-off-by: George Shen Signed-off-by: Linux Image Build Automation --- msm/eva/cvp_hfi.c | 39 +++++++++++++++++++++++++++++++-------- msm/eva/msm_cvp.c | 2 +- msm/eva/msm_cvp_common.c | 3 +-- msm/eva/msm_cvp_core.c | 11 +++++++---- 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 9f05e71be0..08a7e640dd 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -112,6 +112,7 @@ static int __reset_control_assert_name(struct iris_hfi_device *device, const cha static int __reset_control_deassert_name(struct iris_hfi_device *device, const char *name); static int __reset_control_acquire(struct iris_hfi_device *device, const char *name); static int __reset_control_release(struct iris_hfi_device *device, const char *name); +static bool __is_ctl_power_on(struct iris_hfi_device *device); static struct iris_hfi_vpu_ops iris2_ops = { @@ -444,16 +445,15 @@ static int __write_queue(struct cvp_iface_q_info *qinfo, u8 *packet, cmd_pkt = (struct cvp_hfi_cmd_session_hdr *)packet; - if (cmd_pkt->size >= sizeof(struct cvp_hfi_cmd_session_hdr)) - dprintk(CVP_CMD, "%s: " - "pkt_type %08x sess_id %08x trans_id %u ktid %llu\n", + if (cmd_pkt->size >= sizeof(struct cvp_hfi_cmd_session_hdr)) + dprintk(CVP_CMD, "%s: pkt_type %08x sess_id %08x trans_id %u ktid %llu\n", __func__, cmd_pkt->packet_type, cmd_pkt->session_id, cmd_pkt->client_data.transaction_id, cmd_pkt->client_data.kdata & (FENCE_BIT - 1)); - else - dprintk(CVP_CMD, "%s: " - "pkt_type %08x", __func__, cmd_pkt->packet_type); + else if (cmd_pkt->size >= 12) + dprintk(CVP_CMD, "%s: pkt_type %08x sess_id %08x\n", __func__, + cmd_pkt->packet_type, cmd_pkt->session_id); if (msm_cvp_debug & CVP_PKT) { dprintk(CVP_PKT, "%s: %pK\n", __func__, qinfo); @@ -810,6 +810,21 @@ static int __read_register(struct iris_hfi_device *device, u32 reg) return rc; } +static bool __is_ctl_power_on(struct iris_hfi_device *device) +{ + u32 reg; + + reg = __read_register(device, CVP_CC_MVS1C_GDSCR); + if (!(reg & 0x80000000)) + return false; + + reg = __read_register(device, CVP_CC_MVS1C_CBCR); + if (reg & 0x80000000) + return false; + + return true; +} + static int __set_registers(struct iris_hfi_device *device) { struct msm_cvp_core *core; @@ -1409,6 +1424,8 @@ static int __iface_cmdq_write(struct iris_hfi_device *device, void *pkt) if (!rc && needs_interrupt) { /* Consumer of cmdq prefers that we raise an interrupt */ rc = 0; + if (!__is_ctl_power_on(device)) + dprintk(CVP_ERR, "%s power off, don't access reg\n", __func__); __write_register(device, CVP_CPU_CS_H2ASOFTINT, 1); } @@ -1442,8 +1459,11 @@ static int __iface_msgq_read(struct iris_hfi_device *device, void *pkt) } if (!__read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) { - if (tx_req_is_set) + if (tx_req_is_set) { + if (!__is_ctl_power_on(device)) + dprintk(CVP_ERR, "%s power off, don't access reg\n", __func__); __write_register(device, CVP_CPU_CS_H2ASOFTINT, 1); + } rc = 0; } else rc = -ENODATA; @@ -1473,8 +1493,11 @@ static int __iface_dbgq_read(struct iris_hfi_device *device, void *pkt) } if (!__read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) { - if (tx_req_is_set) + if (tx_req_is_set) { + if (!__is_ctl_power_on(device)) + dprintk(CVP_ERR, "%s power off, don't access reg\n", __func__); __write_register(device, CVP_CPU_CS_H2ASOFTINT, 1); + } rc = 0; } else rc = -ENODATA; diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index dd4e6e1a97..7048485948 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -988,7 +988,7 @@ int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst) sq->state = QUEUE_STOP; - dprintk(CVP_SESS, "Stop session queue: %pK session_id = %d\n", + dprintk(CVP_SESS, "Stop session queue: %pK session_id = %#x\n", inst, hash32_ptr(inst->session)); spin_unlock(&sq->lock); diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index cc7bc563f3..b9c2dd0592 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -196,8 +196,7 @@ struct msm_cvp_inst *cvp_get_inst_validate(struct msm_cvp_core *core, s = cvp_get_inst(core, session_id); if (!s) { - dprintk(CVP_ERR, "%s session doesn't exit\n", - __builtin_return_address(0)); + WARN(true, "%s session doesn't exit\n", __func__); return NULL; } diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 838d24a2ce..969268bc75 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -286,7 +286,7 @@ check_again: } } -static void msm_cvp_cleanup_instance(struct msm_cvp_inst *inst) +static int msm_cvp_cleanup_instance(struct msm_cvp_inst *inst) { bool empty; int rc, max_retries; @@ -297,7 +297,7 @@ static void msm_cvp_cleanup_instance(struct msm_cvp_inst *inst) if (!inst) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); - return; + return -EINVAL; } sqf = &inst->session_queue_fence; @@ -357,7 +357,7 @@ stop_session: if (!tmp) { dprintk(CVP_ERR, "%s has a invalid session %llx\n", __func__, inst); - return; + return -EINVAL; } if (!empty) { /* STOP SESSION to avoid SMMU fault after releasing ARP */ @@ -395,6 +395,7 @@ release_arp: hdev = inst->core->device; call_hfi_op(hdev, pm_qos_update, hdev->hfi_device_data); } + return 0; } int msm_cvp_destroy(struct msm_cvp_inst *inst) @@ -499,7 +500,9 @@ int msm_cvp_close(void *instance) } if (inst->session_type != MSM_CVP_BOOT) { - msm_cvp_cleanup_instance(inst); + rc = msm_cvp_cleanup_instance(inst); + if (rc) + return -EINVAL; msm_cvp_session_deinit(inst); } From f79b5db5ae76b6ef59383bf369871741997c1745 Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 16 Aug 2023 11:36:49 -0700 Subject: [PATCH 256/317] msm: eva: Reduce session creation delay by one milisecond at least. Change-Id: Ia32840d2a47533aa81ff3b31af5404b1636b546b Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 3fb6d500d9..790d692ee0 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1166,7 +1166,7 @@ static const char boot_states[0x40][32] = { static inline int __boot_firmware(struct iris_hfi_device *device) { int rc = 0, loop = 10; - u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 500; + u32 ctrl_init_val = 0, ctrl_status = 0, count = 0, max_tries = 5000; u32 reg_gdsc; /* @@ -1206,8 +1206,8 @@ skip_core_power_check: break; } - /* Reduce to 500, 1000 on silicon */ - usleep_range(500, 1000); + /* Reduce to 50, 100 on silicon */ + usleep_range(50, 100); count++; } @@ -4392,7 +4392,7 @@ static int __power_on_controller(struct iris_hfi_device *device) if (rc) dprintk(CVP_ERR, "%s: assert cvp_core_reset failed\n", __func__); /* wait for deassert */ - usleep_range(1000, 1050); + usleep_range(300, 400); rc = call_iris_op(device, reset_control_deassert_name, device, "cvp_axi_reset"); if (rc) From c0cf3ec7db629c01f3d02c4507e5d9110895f7f5 Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 18 Aug 2023 14:16:36 -0700 Subject: [PATCH 257/317] msm: eva: Enable FW cachelog By default. Change-Id: I4d7eaaf3dda5cd19db5f11922d740a94577152cb Signed-off-by: George Shen --- msm/eva/msm_cvp_debug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index a7f29cf9af..5eea8602ab 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -18,7 +18,7 @@ EXPORT_SYMBOL(msm_cvp_debug); int msm_cvp_debug_out = CVP_OUT_PRINTK; EXPORT_SYMBOL(msm_cvp_debug_out); -int msm_cvp_fw_debug = 0x18; +int msm_cvp_fw_debug = 0x10018; int msm_cvp_fw_debug_mode = 1; int msm_cvp_fw_low_power_mode = 1; bool msm_cvp_fw_coverage = !true; From 8adf2c6b698dc777cdb57b1f0426bb93ef036d93 Mon Sep 17 00:00:00 2001 From: George Shen Date: Sun, 20 Aug 2023 10:51:41 -0700 Subject: [PATCH 258/317] msm: eva: Map dsp hfi queue using dma alloc api Use dma_alloc_coherent to allocate 4MB dsp hfi queues and map them in non-io-coherent way. Change-Id: I6d8adb58ebcddae569259862a83e3aeffa3d2304 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 4 ++-- msm/eva/cvp_smem.c | 3 +++ msm/eva/msm_cvp_buf.c | 4 ++-- msm/eva/msm_cvp_buf.h | 2 +- msm/eva/msm_cvp_res_parse.c | 9 ++++----- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 790d692ee0..2e3e017873 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1581,10 +1581,10 @@ static int __interface_dsp_queues_init(struct iris_hfi_device *dev) dprintk(CVP_ERR, "%s: failed dma allocation\n", __func__); goto fail_dma_alloc; } - cb = msm_cvp_smem_get_context_bank(dev->res, 0); + cb = msm_cvp_smem_get_context_bank(dev->res, SMEM_CDSP); if (!cb) { dprintk(CVP_ERR, - "%s: failed to get context bank\n", __func__); + "%s: failed to get DSP context bank\n", __func__); goto fail_dma_map; } iova = dma_map_single_attrs(cb->dev, phys_to_virt(dma_handle), diff --git a/msm/eva/cvp_smem.c b/msm/eva/cvp_smem.c index 66b9b5979a..30d415a796 100644 --- a/msm/eva/cvp_smem.c +++ b/msm/eva/cvp_smem.c @@ -542,6 +542,7 @@ struct context_bank_info *msm_cvp_smem_get_context_bank( char *secure_nonpixel_cb = "cvp_sec_nonpixel"; char *secure_pixel_cb = "cvp_sec_pixel"; char *camera_cb = "cvp_camera"; + char *dsp_cb = "cvp_dsp"; bool is_secure = (flags & SMEM_SECURE) ? true : false; if (flags & SMEM_PIXEL) @@ -551,6 +552,8 @@ struct context_bank_info *msm_cvp_smem_get_context_bank( else if (flags & SMEM_CAMERA) /* Secure Camera pixel buffer */ search_str = camera_cb; + else if (flags & SMEM_CDSP) + search_str = dsp_cb; else search_str = non_secure_cb; diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 5f439abd99..9f667e7a60 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -153,7 +153,7 @@ static void _log_buf(struct inst_snapshot *snapshot, enum smem_prop prop, if (!logging) return; if (snapshot) { - if (prop == SMEM_ADSP && snapshot->dsp_index < MAX_ENTRIES) { + if (prop == SMEM_CDSP && snapshot->dsp_index < MAX_ENTRIES) { index = snapshot->dsp_index; buf = &snapshot->dsp_buf_log[index]; snapshot->dsp_index++; @@ -2090,7 +2090,7 @@ void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) mutex_lock(&inst->cvpdspbufs.lock); dprintk(CVP_ERR, "dsp buffer list:\n"); list_for_each_entry(buf, &inst->cvpdspbufs.list, list) - _log_buf(snap, SMEM_ADSP, inst, buf, log); + _log_buf(snap, SMEM_CDSP, inst, buf, log); mutex_unlock(&inst->cvpdspbufs.lock); mutex_lock(&inst->cvpwnccbufs.lock); diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index 1b4e09c34b..6e12e7bce6 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -35,7 +35,7 @@ enum smem_prop { SMEM_UNCACHED = 0x1, SMEM_CACHED = 0x2, SMEM_SECURE = 0x4, - SMEM_ADSP = 0x8, + SMEM_CDSP = 0x8, SMEM_NON_PIXEL = 0x10, SMEM_PIXEL = 0x20, SMEM_CAMERA = 0x40, diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index b9abc9e392..946641559d 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -1095,9 +1095,6 @@ static int msm_cvp_populate_context_bank(struct device *dev, return -ENOMEM; } - INIT_LIST_HEAD(&cb->list); - list_add_tail(&cb->list, &core->resources.context_banks); - rc = of_property_read_string(np, "label", &cb->name); if (rc) { dprintk(CVP_CORE, @@ -1105,6 +1102,9 @@ static int msm_cvp_populate_context_bank(struct device *dev, rc = 0; } + INIT_LIST_HEAD(&cb->list); + list_add_tail(&cb->list, &core->resources.context_banks); + dprintk(CVP_CORE, "%s: context bank has name %s\n", __func__, cb->name); if (!strcmp(cb->name, "cvp_camera")) { cb->is_secure = true; @@ -1121,10 +1121,9 @@ static int msm_cvp_populate_context_bank(struct device *dev, rc = of_property_read_u32_array(np, "qcom,iommu-dma-addr-pool", (u32 *)&cb->addr_range, 2); if (rc) { - dprintk(CVP_ERR, + dprintk(CVP_CORE, "Could not read addr pool for context bank : %s %d\n", cb->name, rc); - goto err_setup_cb; } cb->is_secure = of_property_read_bool(np, "qcom,iommu-vmid"); From cb0859e124680bd721b1ddaac7ca9621bfcec13c Mon Sep 17 00:00:00 2001 From: Linux Image Build Automation Date: Wed, 23 Aug 2023 16:26:04 -0700 Subject: [PATCH 259/317] Revert "msm: eva: Enhanced check to avoid kernel panic" This reverts commit 96b871c93661f532f3213aad19b34ad994d3a82f. Change-Id: I82ad94c59b723245fb306903d8fc841371c27f1a Signed-off-by: Linux Image Build Automation --- msm/eva/cvp_hfi.c | 39 ++++++++------------------------------- msm/eva/msm_cvp.c | 2 +- msm/eva/msm_cvp_common.c | 3 ++- msm/eva/msm_cvp_core.c | 11 ++++------- 4 files changed, 15 insertions(+), 40 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 08a7e640dd..9f05e71be0 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -112,7 +112,6 @@ static int __reset_control_assert_name(struct iris_hfi_device *device, const cha static int __reset_control_deassert_name(struct iris_hfi_device *device, const char *name); static int __reset_control_acquire(struct iris_hfi_device *device, const char *name); static int __reset_control_release(struct iris_hfi_device *device, const char *name); -static bool __is_ctl_power_on(struct iris_hfi_device *device); static struct iris_hfi_vpu_ops iris2_ops = { @@ -445,15 +444,16 @@ static int __write_queue(struct cvp_iface_q_info *qinfo, u8 *packet, cmd_pkt = (struct cvp_hfi_cmd_session_hdr *)packet; - if (cmd_pkt->size >= sizeof(struct cvp_hfi_cmd_session_hdr)) - dprintk(CVP_CMD, "%s: pkt_type %08x sess_id %08x trans_id %u ktid %llu\n", + if (cmd_pkt->size >= sizeof(struct cvp_hfi_cmd_session_hdr)) + dprintk(CVP_CMD, "%s: " + "pkt_type %08x sess_id %08x trans_id %u ktid %llu\n", __func__, cmd_pkt->packet_type, cmd_pkt->session_id, cmd_pkt->client_data.transaction_id, cmd_pkt->client_data.kdata & (FENCE_BIT - 1)); - else if (cmd_pkt->size >= 12) - dprintk(CVP_CMD, "%s: pkt_type %08x sess_id %08x\n", __func__, - cmd_pkt->packet_type, cmd_pkt->session_id); + else + dprintk(CVP_CMD, "%s: " + "pkt_type %08x", __func__, cmd_pkt->packet_type); if (msm_cvp_debug & CVP_PKT) { dprintk(CVP_PKT, "%s: %pK\n", __func__, qinfo); @@ -810,21 +810,6 @@ static int __read_register(struct iris_hfi_device *device, u32 reg) return rc; } -static bool __is_ctl_power_on(struct iris_hfi_device *device) -{ - u32 reg; - - reg = __read_register(device, CVP_CC_MVS1C_GDSCR); - if (!(reg & 0x80000000)) - return false; - - reg = __read_register(device, CVP_CC_MVS1C_CBCR); - if (reg & 0x80000000) - return false; - - return true; -} - static int __set_registers(struct iris_hfi_device *device) { struct msm_cvp_core *core; @@ -1424,8 +1409,6 @@ static int __iface_cmdq_write(struct iris_hfi_device *device, void *pkt) if (!rc && needs_interrupt) { /* Consumer of cmdq prefers that we raise an interrupt */ rc = 0; - if (!__is_ctl_power_on(device)) - dprintk(CVP_ERR, "%s power off, don't access reg\n", __func__); __write_register(device, CVP_CPU_CS_H2ASOFTINT, 1); } @@ -1459,11 +1442,8 @@ static int __iface_msgq_read(struct iris_hfi_device *device, void *pkt) } if (!__read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) { - if (tx_req_is_set) { - if (!__is_ctl_power_on(device)) - dprintk(CVP_ERR, "%s power off, don't access reg\n", __func__); + if (tx_req_is_set) __write_register(device, CVP_CPU_CS_H2ASOFTINT, 1); - } rc = 0; } else rc = -ENODATA; @@ -1493,11 +1473,8 @@ static int __iface_dbgq_read(struct iris_hfi_device *device, void *pkt) } if (!__read_queue(q_info, (u8 *)pkt, &tx_req_is_set)) { - if (tx_req_is_set) { - if (!__is_ctl_power_on(device)) - dprintk(CVP_ERR, "%s power off, don't access reg\n", __func__); + if (tx_req_is_set) __write_register(device, CVP_CPU_CS_H2ASOFTINT, 1); - } rc = 0; } else rc = -ENODATA; diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 7048485948..dd4e6e1a97 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -988,7 +988,7 @@ int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst) sq->state = QUEUE_STOP; - dprintk(CVP_SESS, "Stop session queue: %pK session_id = %#x\n", + dprintk(CVP_SESS, "Stop session queue: %pK session_id = %d\n", inst, hash32_ptr(inst->session)); spin_unlock(&sq->lock); diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index b9c2dd0592..cc7bc563f3 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -196,7 +196,8 @@ struct msm_cvp_inst *cvp_get_inst_validate(struct msm_cvp_core *core, s = cvp_get_inst(core, session_id); if (!s) { - WARN(true, "%s session doesn't exit\n", __func__); + dprintk(CVP_ERR, "%s session doesn't exit\n", + __builtin_return_address(0)); return NULL; } diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 969268bc75..838d24a2ce 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -286,7 +286,7 @@ check_again: } } -static int msm_cvp_cleanup_instance(struct msm_cvp_inst *inst) +static void msm_cvp_cleanup_instance(struct msm_cvp_inst *inst) { bool empty; int rc, max_retries; @@ -297,7 +297,7 @@ static int msm_cvp_cleanup_instance(struct msm_cvp_inst *inst) if (!inst) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); - return -EINVAL; + return; } sqf = &inst->session_queue_fence; @@ -357,7 +357,7 @@ stop_session: if (!tmp) { dprintk(CVP_ERR, "%s has a invalid session %llx\n", __func__, inst); - return -EINVAL; + return; } if (!empty) { /* STOP SESSION to avoid SMMU fault after releasing ARP */ @@ -395,7 +395,6 @@ release_arp: hdev = inst->core->device; call_hfi_op(hdev, pm_qos_update, hdev->hfi_device_data); } - return 0; } int msm_cvp_destroy(struct msm_cvp_inst *inst) @@ -500,9 +499,7 @@ int msm_cvp_close(void *instance) } if (inst->session_type != MSM_CVP_BOOT) { - rc = msm_cvp_cleanup_instance(inst); - if (rc) - return -EINVAL; + msm_cvp_cleanup_instance(inst); msm_cvp_session_deinit(inst); } From f448885aa10a30ca7122315da5cf29f011cac0f7 Mon Sep 17 00:00:00 2001 From: George Shen Date: Fri, 25 Aug 2023 11:23:28 -0700 Subject: [PATCH 260/317] msm: eva: restore 2s HW comm timeout Increase dsp timeout from 0.6s to 1s. Change-Id: If5b556fa52fed897945bf62611c01e9abce1cbec Signed-off-by: George Shen --- msm/eva/msm_cvp_dsp.h | 2 +- msm/eva/msm_cvp_platform.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/eva/msm_cvp_dsp.h b/msm/eva/msm_cvp_dsp.h index 6773d2025c..96631b71e1 100644 --- a/msm/eva/msm_cvp_dsp.h +++ b/msm/eva/msm_cvp_dsp.h @@ -49,7 +49,7 @@ struct fastrpc_driver { #define DSP_VM_NUM 2 #define CVP_DSP_MAX_RESERVED 5 #define CVP_DSP2CPU_RESERVED 8 -#define CVP_DSP_RESPONSE_TIMEOUT 600 +#define CVP_DSP_RESPONSE_TIMEOUT 1000 #define CVP_INVALID_RPMSG_TYPE 0xBADDFACE #define MAX_FRAME_BUF_NUM 16 diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 7b9fe5b07d..718b31b9d8 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -236,7 +236,7 @@ static struct msm_cvp_common_data sm8650_common_data[] = { }, { .key = "qcom,hw-resp-timeout", - .value = 1000, + .value = 2000, }, { .key = "qcom,dsp-resp-timeout", From c888aaadf03c3e93264e85c6a74a3b26f97ba238 Mon Sep 17 00:00:00 2001 From: George Shen Date: Sun, 20 Aug 2023 10:51:41 -0700 Subject: [PATCH 261/317] msm: eva: Map dsp hfi queue using dma alloc api Use dma_alloc_coherent to allocate 4MB dsp hfi queues and map them in non-io-coherent way. Change-Id: I6d8adb58ebcddae569259862a83e3aeffa3d2304 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 4 ++-- msm/eva/cvp_smem.c | 3 +++ msm/eva/msm_cvp_buf.c | 4 ++-- msm/eva/msm_cvp_buf.h | 2 +- msm/eva/msm_cvp_res_parse.c | 9 ++++----- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 3fb6d500d9..ee4829e98e 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1581,10 +1581,10 @@ static int __interface_dsp_queues_init(struct iris_hfi_device *dev) dprintk(CVP_ERR, "%s: failed dma allocation\n", __func__); goto fail_dma_alloc; } - cb = msm_cvp_smem_get_context_bank(dev->res, 0); + cb = msm_cvp_smem_get_context_bank(dev->res, SMEM_CDSP); if (!cb) { dprintk(CVP_ERR, - "%s: failed to get context bank\n", __func__); + "%s: failed to get DSP context bank\n", __func__); goto fail_dma_map; } iova = dma_map_single_attrs(cb->dev, phys_to_virt(dma_handle), diff --git a/msm/eva/cvp_smem.c b/msm/eva/cvp_smem.c index 66b9b5979a..30d415a796 100644 --- a/msm/eva/cvp_smem.c +++ b/msm/eva/cvp_smem.c @@ -542,6 +542,7 @@ struct context_bank_info *msm_cvp_smem_get_context_bank( char *secure_nonpixel_cb = "cvp_sec_nonpixel"; char *secure_pixel_cb = "cvp_sec_pixel"; char *camera_cb = "cvp_camera"; + char *dsp_cb = "cvp_dsp"; bool is_secure = (flags & SMEM_SECURE) ? true : false; if (flags & SMEM_PIXEL) @@ -551,6 +552,8 @@ struct context_bank_info *msm_cvp_smem_get_context_bank( else if (flags & SMEM_CAMERA) /* Secure Camera pixel buffer */ search_str = camera_cb; + else if (flags & SMEM_CDSP) + search_str = dsp_cb; else search_str = non_secure_cb; diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 5f439abd99..9f667e7a60 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -153,7 +153,7 @@ static void _log_buf(struct inst_snapshot *snapshot, enum smem_prop prop, if (!logging) return; if (snapshot) { - if (prop == SMEM_ADSP && snapshot->dsp_index < MAX_ENTRIES) { + if (prop == SMEM_CDSP && snapshot->dsp_index < MAX_ENTRIES) { index = snapshot->dsp_index; buf = &snapshot->dsp_buf_log[index]; snapshot->dsp_index++; @@ -2090,7 +2090,7 @@ void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) mutex_lock(&inst->cvpdspbufs.lock); dprintk(CVP_ERR, "dsp buffer list:\n"); list_for_each_entry(buf, &inst->cvpdspbufs.list, list) - _log_buf(snap, SMEM_ADSP, inst, buf, log); + _log_buf(snap, SMEM_CDSP, inst, buf, log); mutex_unlock(&inst->cvpdspbufs.lock); mutex_lock(&inst->cvpwnccbufs.lock); diff --git a/msm/eva/msm_cvp_buf.h b/msm/eva/msm_cvp_buf.h index 1b4e09c34b..6e12e7bce6 100644 --- a/msm/eva/msm_cvp_buf.h +++ b/msm/eva/msm_cvp_buf.h @@ -35,7 +35,7 @@ enum smem_prop { SMEM_UNCACHED = 0x1, SMEM_CACHED = 0x2, SMEM_SECURE = 0x4, - SMEM_ADSP = 0x8, + SMEM_CDSP = 0x8, SMEM_NON_PIXEL = 0x10, SMEM_PIXEL = 0x20, SMEM_CAMERA = 0x40, diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index b9abc9e392..946641559d 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -1095,9 +1095,6 @@ static int msm_cvp_populate_context_bank(struct device *dev, return -ENOMEM; } - INIT_LIST_HEAD(&cb->list); - list_add_tail(&cb->list, &core->resources.context_banks); - rc = of_property_read_string(np, "label", &cb->name); if (rc) { dprintk(CVP_CORE, @@ -1105,6 +1102,9 @@ static int msm_cvp_populate_context_bank(struct device *dev, rc = 0; } + INIT_LIST_HEAD(&cb->list); + list_add_tail(&cb->list, &core->resources.context_banks); + dprintk(CVP_CORE, "%s: context bank has name %s\n", __func__, cb->name); if (!strcmp(cb->name, "cvp_camera")) { cb->is_secure = true; @@ -1121,10 +1121,9 @@ static int msm_cvp_populate_context_bank(struct device *dev, rc = of_property_read_u32_array(np, "qcom,iommu-dma-addr-pool", (u32 *)&cb->addr_range, 2); if (rc) { - dprintk(CVP_ERR, + dprintk(CVP_CORE, "Could not read addr pool for context bank : %s %d\n", cb->name, rc); - goto err_setup_cb; } cb->is_secure = of_property_read_bool(np, "qcom,iommu-vmid"); From f2cbbfd0517a84200cc1f9fa5f9bbc16ec3103e7 Mon Sep 17 00:00:00 2001 From: Gopireddy Arunteja Reddy Date: Tue, 29 Aug 2023 23:52:59 +0530 Subject: [PATCH 262/317] msm: eva: Added platform data for cliffs Cliffs common and platform data structures are added. Change-Id: I16156da7f1a801fca74fc5e2daff3d317031aaaa Signed-off-by: Gopireddy Arunteja Reddy --- msm/eva/msm_cvp_platform.c | 58 +++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 718b31b9d8..064018a1bc 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -252,6 +252,49 @@ static struct msm_cvp_common_data sm8650_common_data[] = { } }; +static struct msm_cvp_common_data sm7650_common_data[] = { + { + .key = "qcom,pm-qos-latency-us", + .value = 50, + }, + { + .key = "qcom,sw-power-collapse", + .value = 1, + }, + { + .key = "qcom,domain-attr-non-fatal-faults", + .value = 0, + }, + { + .key = "qcom,max-secure-instances", + .value = 2, + }, + { + .key = "qcom,max-ssr-allowed", + .value = 1, + }, + { + .key = "qcom,power-collapse-delay", + .value = 3000, + }, + { + .key = "qcom,hw-resp-timeout", + .value = 2000, + }, + { + .key = "qcom,dsp-resp-timeout", + .value = 1000, + }, + { + .key = "qcom,debug-timeout", + .value = 0, + }, + { + .key = "qcom,dsp-enabled", + .value = 1, + } +}; + /* Default UBWC config for LPDDR5 */ static struct msm_cvp_ubwc_config_data kona_ubwc_data[] = { UBWC_CONFIG(1, 1, 1, 0, 0, 0, 8, 32, 16, 0, 0), @@ -316,6 +359,16 @@ static struct msm_cvp_platform_data sm8650_data = { .vm_id = 1, }; +static struct msm_cvp_platform_data sm7650_data = { + .common_data = sm7650_common_data, + .common_data_length = ARRAY_SIZE(sm7650_common_data), + .sku_version = 0, + .vpu_ver = VPU_VERSION_5, + .ubwc_config = kona_ubwc_data, /*Reuse Kona setting*/ + .noc_qos = &waipio_noc_qos, /*Reuse Waipio setting*/ + .vm_id = 1, +}; + static const struct of_device_id msm_cvp_dt_match[] = { { .compatible = "qcom,waipio-cvp", @@ -333,7 +386,10 @@ static const struct of_device_id msm_cvp_dt_match[] = { .compatible = "qcom,pineapple-cvp", .data = &sm8650_data, }, - + { + .compatible = "qcom,cliffs-cvp", + .data = &sm7650_data, + }, {}, }; From 536a3ed7545047c355490382ecc5e1a40ae6d6f7 Mon Sep 17 00:00:00 2001 From: Palak Joshi Date: Mon, 4 Sep 2023 13:15:33 +0530 Subject: [PATCH 263/317] msm: eva: Clean up in case of SSR Instead of returning from validate session failure with SSR, doing other required clean up. Change-Id: I5a2baa7039bc4e23758c541af31648d58a58823c Signed-off-by: Palak Joshi --- msm/eva/msm_cvp.c | 2 +- msm/eva/msm_cvp_core.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index dbbc9ade26..57431984bf 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -944,7 +944,7 @@ int msm_cvp_session_stop(struct msm_cvp_inst *inst, } sq->state = QUEUE_STOP; - pr_info_ratelimited(CVP_DBG_TAG "Stop session: %pK session_id = %d\n", + pr_info_ratelimited(CVP_DBG_TAG "Stop session: %pK session_id = %#x\n", "sess", inst, hash32_ptr(inst->session)); spin_unlock(&sq->lock); diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index c0c96207b4..31321b9a99 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -357,7 +357,7 @@ stop_session: if (!tmp) { dprintk(CVP_ERR, "%s has a invalid session %llx\n", __func__, inst); - return -EINVAL; + goto exit; } if (!empty) { /* STOP SESSION to avoid SMMU fault after releasing ARP */ @@ -378,6 +378,7 @@ stop_session: } release_arp: cvp_put_inst(tmp); +exit: if (cvp_release_arp_buffers(inst)) dprintk_rl(CVP_WARN, "Failed to release persist buffers\n"); From 4db4b2a5fa40747a14600495052c8f1eb8b2b4dc Mon Sep 17 00:00:00 2001 From: George Shen Date: Wed, 13 Sep 2023 16:02:20 -0700 Subject: [PATCH 264/317] msm: eva: Add missing QOS setting Fix wrong QoS setting for RGE and GCE. Change-Id: Ibd156b4133c9027ec7ab7c383c86f81ef9d744e3 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 12 +++++++++++- msm/eva/cvp_hfi_io.h | 10 ++++++++++ msm/eva/msm_cvp_internal.h | 1 + msm/eva/msm_cvp_platform.c | 12 +++++++++++- 4 files changed, 33 insertions(+), 2 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 2e3e017873..220a8bd45a 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -868,12 +868,22 @@ static int __set_registers(struct iris_hfi_device *device) pdata->noc_qos->dangerlut_low); __write_register(device, CVP_NOC_RGE_SAFELUT_LOW, pdata->noc_qos->safelut_low); + __write_register(device, CVP_NOC_GCE_PRIORITYLUT_LOW, + pdata->noc_qos->prioritylut_low); + __write_register(device, CVP_NOC_GCE_PRIORITYLUT_HIGH, + pdata->noc_qos->prioritylut_high); + __write_register(device, CVP_NOC_GCE_URGENCY_LOW, + pdata->noc_qos->urgency_low); + __write_register(device, CVP_NOC_GCE_DANGERLUT_LOW, + pdata->noc_qos->dangerlut_low); + __write_register(device, CVP_NOC_GCE_SAFELUT_LOW, + pdata->noc_qos->safelut_low); __write_register(device, CVP_NOC_CDM_PRIORITYLUT_LOW, pdata->noc_qos->prioritylut_low); __write_register(device, CVP_NOC_CDM_PRIORITYLUT_HIGH, pdata->noc_qos->prioritylut_high); __write_register(device, CVP_NOC_CDM_URGENCY_LOW, - pdata->noc_qos->urgency_low); + pdata->noc_qos->urgency_low_ro); __write_register(device, CVP_NOC_CDM_DANGERLUT_LOW, pdata->noc_qos->dangerlut_low); __write_register(device, CVP_NOC_CDM_SAFELUT_LOW, diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index 46322c5b83..eb686c5248 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -254,6 +254,16 @@ (CVP_NOC_CORE_BASE_OFFS + 0x3040) #define CVP_NOC_RGE_SAFELUT_LOW \ (CVP_NOC_CORE_BASE_OFFS + 0x3048) +#define CVP_NOC_GCE_PRIORITYLUT_LOW \ + (CVP_NOC_CORE_BASE_OFFS + 0x3430) +#define CVP_NOC_GCE_PRIORITYLUT_HIGH \ + (CVP_NOC_CORE_BASE_OFFS + 0x3434) +#define CVP_NOC_GCE_URGENCY_LOW \ + (CVP_NOC_CORE_BASE_OFFS + 0x3438) +#define CVP_NOC_GCE_DANGERLUT_LOW \ + (CVP_NOC_CORE_BASE_OFFS + 0x3440) +#define CVP_NOC_GCE_SAFELUT_LOW \ + (CVP_NOC_CORE_BASE_OFFS + 0x3448) #define CVP_NOC_CDM_PRIORITYLUT_LOW \ (CVP_NOC_CORE_BASE_OFFS + 0x3830) #define CVP_NOC_CDM_PRIORITYLUT_HIGH \ diff --git a/msm/eva/msm_cvp_internal.h b/msm/eva/msm_cvp_internal.h index bb7d539436..c33fb653ed 100644 --- a/msm/eva/msm_cvp_internal.h +++ b/msm/eva/msm_cvp_internal.h @@ -115,6 +115,7 @@ struct msm_cvp_qos_setting { u32 prioritylut_low; u32 prioritylut_high; u32 urgency_low; + u32 urgency_low_ro; u32 dangerlut_low; u32 safelut_low; }; diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 064018a1bc..01eadebca1 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -309,6 +309,16 @@ static struct msm_cvp_qos_setting waipio_noc_qos = { .safelut_low = 0xffff, }; +static struct msm_cvp_qos_setting lanai_noc_qos = { + .axi_qos = 0x99, + .prioritylut_low = 0x33333333, + .prioritylut_high = 0x33333333, + .urgency_low = 0x1033, + .urgency_low_ro = 0x1003, + .dangerlut_low = 0x0, + .safelut_low = 0xffff, +}; + static struct msm_cvp_platform_data default_data = { .common_data = default_common_data, .common_data_length = ARRAY_SIZE(default_common_data), @@ -355,7 +365,7 @@ static struct msm_cvp_platform_data sm8650_data = { .sku_version = 0, .vpu_ver = VPU_VERSION_5, .ubwc_config = kona_ubwc_data, /*Reuse Kona setting*/ - .noc_qos = &waipio_noc_qos, /*Reuse Waipio setting*/ + .noc_qos = &lanai_noc_qos, .vm_id = 1, }; From c82996e90f5a6b1275e134b4668dd42a1480a821 Mon Sep 17 00:00:00 2001 From: Jingyu Su Date: Thu, 7 Sep 2023 12:22:29 -0700 Subject: [PATCH 265/317] msm: eva: Extract DSP buffer info from debug queue Extracts DSP buffer information for log printing upon SMMU faults Change-Id: I36b1900ea84a85cdfdb2dec8ad62b67a5ff57119 Signed-off-by: Jingyu Su --- eva_module_build.bzl | 1 + msm/eva/cvp_core_hfi.h | 8 +++++++ msm/eva/msm_cvp_buf.c | 48 +++++++++++++++++++++++++++++++++++++++++- msm/eva/msm_cvp_dsp.h | 37 ++++++++++++++++++++++++++++++++ 4 files changed, 93 insertions(+), 1 deletion(-) diff --git a/eva_module_build.bzl b/eva_module_build.bzl index 73410a8fa3..465995b23d 100644 --- a/eva_module_build.bzl +++ b/eva_module_build.bzl @@ -101,6 +101,7 @@ def define_target_variant_modules(target, variant, registry, modules, config_opt name = rule_name, srcs = module_srcs, out = "{}.ko".format(module.name), + copts = ["-Wno-format"], deps = headers + _get_kernel_build_module_deps(module, options, formatter), local_defines = options.keys(), ) diff --git a/msm/eva/cvp_core_hfi.h b/msm/eva/cvp_core_hfi.h index 2f417062d1..840e360a64 100644 --- a/msm/eva/cvp_core_hfi.h +++ b/msm/eva/cvp_core_hfi.h @@ -224,6 +224,14 @@ enum reset_state { DEASSERT, }; +/* Indices of hfi queues in hfi queue arrays (iface_queues & dsp_iface_queues) */ +enum hfi_queue_idx { + CMD_Q, /* Command queue */ + MSG_Q, /* Message queue */ + DEBUG_Q, /* Debug queue */ + MAX_Q +}; + struct iris_hfi_device; struct cvp_hal_ops { diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 9f667e7a60..52629ca743 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -2036,6 +2036,40 @@ int msm_cvp_session_deinit_buffers(struct msm_cvp_inst *inst) return rc; } +void msm_cvp_populate_dsp_buf_info(struct cvp_internal_buf *buf, + struct cvp_hal_session *session, + u32 session_id, + struct msm_cvp_core *core) +{ + struct cvp_hfi_ops *dev_ops = (struct cvp_hfi_ops *) core->dev_ops; + struct iris_hfi_device *cvp_device = (struct iris_hfi_device *) dev_ops->hfi_device_data; + struct cvp_iface_q_info dsp_debugQ_info = cvp_device->dsp_iface_queues[DEBUG_Q]; + struct cvp_dsp_trace_buf *trace_buf; + struct cvp_dsp_trace *dsp_debug_trace; + + dsp_debug_trace = (struct cvp_dsp_trace *) dsp_debugQ_info.q_array.align_virtual_addr; + + if (!dsp_debug_trace) { + dprintk(CVP_ERR, "dsp trace is NULL\n"); + return; + } + for (int session_idx = 0; session_idx < EVA_TRACE_MAX_SESSION_NUM; session_idx++) { + if (dsp_debug_trace->sessions[session_idx].session_id == session_id) { + u32 buf_cnt = dsp_debug_trace->sessions[session_idx].buf_cnt; + + for (int buf_idx = 0; buf_idx < buf_cnt; buf_idx++) { + trace_buf = &dsp_debug_trace->sessions[session_idx].buf[buf_idx]; + if (buf->smem->device_addr == trace_buf->iova) { + buf->smem->buf_idx = trace_buf->buf_idx; + buf->smem->pkt_type = trace_buf->pkt_type; + buf->smem->fd = trace_buf->fd; + return; + } + } + } + } +} + #define MAX_NUM_FRAMES_DUMP 4 void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) { @@ -2045,6 +2079,13 @@ void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) struct inst_snapshot *snap = NULL; int i = 0, c = 0; + // DSP trace related variables + struct cvp_hal_session *session; + u32 session_id; + + session = (struct cvp_hal_session *)inst->session; + session_id = hash32_ptr(session); + core = cvp_driver->cvp_core; if (log && core->log.snapshot_index < 16) { snap = &core->log.snapshot[core->log.snapshot_index]; @@ -2088,9 +2129,14 @@ void msm_cvp_print_inst_bufs(struct msm_cvp_inst *inst, bool log) mutex_unlock(&inst->frames.lock); mutex_lock(&inst->cvpdspbufs.lock); + dprintk(CVP_ERR, "dsp buffer list:\n"); - list_for_each_entry(buf, &inst->cvpdspbufs.list, list) + list_for_each_entry(buf, &inst->cvpdspbufs.list, list) { + // Populate DSP buffer info from debug queue to kernel instance + msm_cvp_populate_dsp_buf_info(buf, session, session_id, core); + // Log print buffer info _log_buf(snap, SMEM_CDSP, inst, buf, log); + } mutex_unlock(&inst->cvpdspbufs.lock); mutex_lock(&inst->cvpwnccbufs.lock); diff --git a/msm/eva/msm_cvp_dsp.h b/msm/eva/msm_cvp_dsp.h index 96631b71e1..c49e0be556 100644 --- a/msm/eva/msm_cvp_dsp.h +++ b/msm/eva/msm_cvp_dsp.h @@ -249,6 +249,43 @@ struct cvp_dsp_apps { struct driver_name cvp_fastrpc_name[MAX_FASTRPC_DRIVER_NUM]; }; +#define EVA_TRACE_MAX_SESSION_NUM 16 +#define EVA_TRACE_MAX_INSTANCE_NUM 6 +#define EVA_TRACE_MAX_BUF_NUM 256 + +#define CONFIG_SIZE_IN_BYTES 2048 +#define CONFIG_SIZE_IN_WORDS (CONFIG_SIZE_IN_BYTES >> 2) + +// iova is eva_dsp_buf->iova +// pkt_type is frame packet type using the buffer +// buf_idx is the index of the buffer in a frame packet +// transaction_id is the transaction id of frame packet +struct cvp_dsp_trace_buf { + u32 iova; + u32 pkt_type; + u32 buf_idx; + u32 transaction_id; + u32 fd; +}; + +// Saving config packet for each intance +struct cvp_dsp_trace_instance { + u32 feature_type; + u32 config_pkt[CONFIG_SIZE_IN_WORDS]; +}; + +struct cvp_dsp_trace_session { + u32 session_id; + u32 buf_cnt; + u32 inst_cnt; + struct cvp_dsp_trace_instance instance[EVA_TRACE_MAX_INSTANCE_NUM]; + struct cvp_dsp_trace_buf buf[EVA_TRACE_MAX_BUF_NUM]; +}; + +struct cvp_dsp_trace { + struct cvp_dsp_trace_session sessions[EVA_TRACE_MAX_SESSION_NUM]; +}; + extern struct cvp_dsp_apps gfa_cv; /* * API for CVP driver to suspend CVP session during From ed194e2329694c1fb460f2b3b41397495db814a3 Mon Sep 17 00:00:00 2001 From: Gopireddy Arunteja Reddy Date: Wed, 13 Sep 2023 16:07:37 +0530 Subject: [PATCH 266/317] msm: eva: To resolve race condition in EVA state while DSP probing The change helps in proper DSP initialization. Change-Id: I5a9b65b4617ed364186ee79872b0f5596d926131 Signed-off-by: Gopireddy Arunteja Reddy --- msm/eva/msm_cvp_dsp.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 07ed6327dc..c41b541c24 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1264,8 +1264,15 @@ void cvp_dsp_send_hfi_queue(void) goto exit; } - if (me->state != DSP_PROBED && me->state != DSP_INACTIVE) + if (me->state != DSP_PROBED && me->state != DSP_INACTIVE) { + dprintk(CVP_DSP, + "%s: Either DSP is not probed or is not in proper state. me->state = %d\n", + __func__, me->state); goto exit; + } + dprintk(CVP_DSP, + "%s: DSP probe Successful, going ahead with hyp_assign, me->state = %d\n", + __func__, me->state); rc = cvp_hyp_assign_to_dsp(addr, size); if (rc) { @@ -2191,7 +2198,13 @@ int cvp_dsp_device_init(void) goto register_bail; } snprintf(tname, sizeof(tname), "cvp-dsp-thread"); - me->state = DSP_UNINIT; + mutex_lock(&me->tx_lock); + + if (me->state == DSP_INVALID) + me->state = DSP_UNINIT; + + mutex_unlock(&me->tx_lock); + me->dsp_thread = kthread_run(cvp_dsp_thread, me, tname); if (!me->dsp_thread) { dprintk(CVP_ERR, "%s create %s fail", __func__, tname); From 4b2e1595657d18860fd90bc1ccf5aace031db59a Mon Sep 17 00:00:00 2001 From: Gopireddy Arunteja Reddy Date: Mon, 25 Sep 2023 16:33:34 +0530 Subject: [PATCH 267/317] msm: eva: Reading FW ELF naming from device tree This change helps to read firmware elf name from device tree. Change-Id: Idc5779063d386ceb0ed8435090a4a70c9651f19d Signed-off-by: Gopireddy Arunteja Reddy --- msm/eva/msm_cvp_res_parse.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index 946641559d..f3cfbfd104 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -326,6 +326,14 @@ err_qdss_addr_tbl: return rc; } +static int msm_cvp_load_fw_name(struct msm_cvp_platform_resources *res) +{ + struct platform_device *pdev = res->pdev; + + return of_property_read_string_index(pdev->dev.of_node, + "cvp,firmware-name", 0, &res->fw_name); +} + static int msm_cvp_load_subcache_info(struct msm_cvp_platform_resources *res) { int rc = 0, num_subcaches = 0, c; @@ -830,10 +838,6 @@ int cvp_read_platform_resources_from_drv_data( res->sku_version = platform_data->sku_version; - res->fw_name = "evass"; - - dprintk(CVP_CORE, "Firmware filename: %s\n", res->fw_name); - res->dsp_enabled = find_key_value(platform_data, "qcom,dsp-enabled"); @@ -912,6 +916,12 @@ int cvp_read_platform_resources_from_dt( dprintk(CVP_CORE, "%s: res->irq_wd:%d \n", __func__, res->irq_wd); + + rc = msm_cvp_load_fw_name(res); + dprintk(CVP_CORE, "Firmware filename: %s\n", res->fw_name); + if (rc) + dprintk(CVP_WARN, "Failed to load fw name info: %d\n", rc); + rc = msm_cvp_load_subcache_info(res); if (rc) dprintk(CVP_WARN, "Failed to load subcache info: %d\n", rc); From e1502aacbdc9c2e1dbf902dc3c5aaf572788ecc4 Mon Sep 17 00:00:00 2001 From: VIVEK VARDHAN JOSHI Date: Sat, 23 Sep 2023 07:32:11 +0530 Subject: [PATCH 268/317] msm: eva: Handling mutex lock in case of failure Returning false if mutex lock is not successful in cvp_fence-wait function instead of sleep. Change-Id: Ieddfb6e16c72d571646a39a63c073a1b9912b3bc Signed-off-by: VIVEK VARDHAN JOSHI --- msm/eva/msm_cvp.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 57431984bf..43ae87f923 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -272,7 +272,8 @@ static bool cvp_fence_wait(struct cvp_fence_queue *q, return false; *fence = NULL; - mutex_lock(&q->lock); + if (!mutex_trylock(&q->lock)) + return false; *state = q->state; if (*state != QUEUE_START) { mutex_unlock(&q->lock); @@ -422,8 +423,10 @@ wait: if (state != QUEUE_START) goto exit; - if (!f) + if (!f) { + usleep_range(100, 200); goto wait; + } pkt = f->pkt; synx = (u32 *)f->synx; From d2c57a156bbca8b93b3d6b218c7f586783c8f45e Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 5 Oct 2023 15:25:57 -0700 Subject: [PATCH 269/317] msm: eva: Add delay after resetting xo clk Wait 200us to 300us. Change-Id: Ia3d83b18a8b1c8fe351ab9fcd7a0ec3ed1b9822a Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 220a8bd45a..e6aa8dacd6 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -4767,8 +4767,8 @@ static int __power_off_controller(struct iris_hfi_device *device) /* de-assert EVA_NoC reset */ __write_register(device, CVP_AON_WRAPPER_CVP_NOC_CORE_SW_RESET, 0x0); - /* de-assert EVA video_cc XO reset and enable video_cc XO clock after 80us */ - usleep_range(80, 100); + /* de-assert EVA video_cc XO reset and enable video_cc XO clock after 125us */ + usleep_range(200, 300); rc = call_iris_op(device, reset_control_deassert_name, device, "cvp_xo_reset"); if (rc) dprintk(CVP_ERR, "%s: de-assert cvp_xo_reset failed\n", __func__); From 59387891a24acd7f4b7521b4b9d7c035b7c4f60c Mon Sep 17 00:00:00 2001 From: Vivek Vardhan Joshi Date: Tue, 10 Oct 2023 10:12:17 -0700 Subject: [PATCH 270/317] Revert "msm: eva: Handling mutex lock in case of failure" This reverts commit e1502aacbdc9c2e1dbf902dc3c5aaf572788ecc4. Reason for revert: Causing CVP session close failure Change-Id: I79f22e6ee694f46d9a9de51d1b51f42d67bad828 Signed-off-by: VIVEK VARDHAN JOSHI --- msm/eva/msm_cvp.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 43ae87f923..57431984bf 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -272,8 +272,7 @@ static bool cvp_fence_wait(struct cvp_fence_queue *q, return false; *fence = NULL; - if (!mutex_trylock(&q->lock)) - return false; + mutex_lock(&q->lock); *state = q->state; if (*state != QUEUE_START) { mutex_unlock(&q->lock); @@ -423,10 +422,8 @@ wait: if (state != QUEUE_START) goto exit; - if (!f) { - usleep_range(100, 200); + if (!f) goto wait; - } pkt = f->pkt; synx = (u32 *)f->synx; From e4d6b997a0b6409a41d07b7200ebfe72d39aceeb Mon Sep 17 00:00:00 2001 From: Aditya Shubham Date: Fri, 22 Sep 2023 10:20:24 +0530 Subject: [PATCH 271/317] msm: eva: fixes for integer over-flow Adding checks for offset and buf_num. Change-Id: Icb75ec99947712c8fa636ade58234be78af8d458 Signed-off-by: Aditya Shubham --- msm/eva/msm_cvp.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/msm/eva/msm_cvp.h b/msm/eva/msm_cvp.h index 4f78e5327e..470525a5b6 100644 --- a/msm/eva/msm_cvp.h +++ b/msm/eva/msm_cvp.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2018-2021 The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef _MSM_CVP_H_ @@ -22,11 +23,15 @@ static inline bool is_buf_param_valid(u32 buf_num, u32 offset) if (buf_num > max_buf_num) return false; - + if ((offset > U32_MAX/sizeof(u32)) || + (offset*sizeof(u32) > U32_MAX - buf_num * sizeof(struct cvp_buf_type))) + return false; if ((offset * sizeof(u32) + buf_num * sizeof(struct cvp_buf_type)) > sizeof(struct eva_kmd_hfi_packet)) return false; + + return true; } From 636d3499d6ab3d54345324b6fc0bf7f50b915b17 Mon Sep 17 00:00:00 2001 From: VIVEK VARDHAN JOSHI Date: Fri, 13 Oct 2023 16:13:05 +0530 Subject: [PATCH 272/317] msm: eva: Handling mutex lock in case of failure Retrying the mutex lock, if it is not successful in cvp_fence-wait function instead returning false. Change-Id: I8dfb24b92eef50218d4d9a73f76c5533352a31fc Signed-off-by: VIVEK VARDHAN JOSHI --- msm/eva/msm_cvp.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 57431984bf..5b2b624060 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -272,7 +272,9 @@ static bool cvp_fence_wait(struct cvp_fence_queue *q, return false; *fence = NULL; - mutex_lock(&q->lock); + + while (!mutex_trylock(&q->lock)) + usleep_range(100, 200); *state = q->state; if (*state != QUEUE_START) { mutex_unlock(&q->lock); @@ -422,8 +424,10 @@ wait: if (state != QUEUE_START) goto exit; - if (!f) + if (!f) { + usleep_range(100, 200); goto wait; + } pkt = f->pkt; synx = (u32 *)f->synx; From d7dfd9368d380cf5394d06169612cc0097b4c037 Mon Sep 17 00:00:00 2001 From: Gopireddy Arunteja Reddy Date: Fri, 20 Oct 2023 01:03:30 +0530 Subject: [PATCH 273/317] msm: eva: Prevent defects found from static analysis tool Added fixes for out-of-bounds read, uninitialized variable use, resource leak issues. Change-Id: I6c59ff53d9f1d9cf5362bea0a3f1fe5d9a8008aa Signed-off-by: Gopireddy Arunteja Reddy --- msm/eva/msm_cvp.c | 4 ++-- msm/eva/msm_cvp_buf.c | 10 ++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 57431984bf..349cb8a80f 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -534,14 +534,14 @@ static int cvp_populate_fences( struct eva_kmd_hfi_packet *in_pkt, { dprintk(CVP_ERR, "%s: invalid params", __func__); rc = -EINVAL; - goto exit; + goto free_exit; } } else { dprintk(CVP_ERR, "%s: invalid params", __func__); rc = -EINVAL; - goto exit; + goto free_exit; } soc_fence: diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 52629ca743..e05464eb29 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -902,6 +902,7 @@ static int _wncc_map_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, struct dma_buf* dmabuf; struct eva_buf_map map; __u32 num_layers, metadata_bufs_offset; + _buf_map_set_vaddr(&map, (void *)0xdeadbeaf); if (!in_pkt || !wncc_metadata || !wncc_oob) { dprintk(CVP_ERR, "%s: invalid params", __func__); @@ -915,7 +916,7 @@ static int _wncc_map_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, return -EINVAL; } if (metadata_bufs_offset > ((sizeof(in_pkt->pkt_data) - - sizeof(struct cvp_buf_type)) / sizeof(__u32))) { + - num_layers * sizeof(struct cvp_buf_type)) / sizeof(__u32))) { dprintk(CVP_ERR, "%s: invalid wncc metadata bufs offset", __func__); return -EINVAL; @@ -1000,7 +1001,7 @@ static int _wncc_unmap_metadata_bufs(struct eva_kmd_hfi_packet* in_pkt, return -EINVAL; } if (metadata_bufs_offset > ((sizeof(in_pkt->pkt_data) - - sizeof(struct cvp_buf_type)) / sizeof(__u32))) { + - num_layers * sizeof(struct cvp_buf_type)) / sizeof(__u32))) { dprintk(CVP_ERR, "%s: invalid wncc metadata bufs offset", __func__); return -EINVAL; @@ -2196,7 +2197,7 @@ struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, buf->smem = cvp_kmem_cache_zalloc(&cvp_driver->smem_cache, GFP_KERNEL); if (!buf->smem) { dprintk(CVP_ERR, "%s Out of memory\n", __func__); - goto fail_kzalloc; + goto err_no_smem; } buf->smem->flags = smem_flags; @@ -2206,7 +2207,6 @@ struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, dprintk(CVP_ERR, "Failed to allocate ARP memory\n"); goto err_no_mem; } - buf->smem->pkt_type = buf->smem->buf_idx = 0; buf->smem->pkt_type = buf->smem->buf_idx = 0; atomic_inc(&buf->smem->refcount); @@ -2220,6 +2220,8 @@ struct cvp_internal_buf *cvp_allocate_arp_bufs(struct msm_cvp_inst *inst, return buf; err_no_mem: + cvp_kmem_cache_free(&cvp_driver->smem_cache, buf->smem); +err_no_smem: cvp_kmem_cache_free(&cvp_driver->buf_cache, buf); fail_kzalloc: return NULL; From 5ea6a34323ea1eabdc8c29f091fcbe47c4f41f8b Mon Sep 17 00:00:00 2001 From: George Shen Date: Thu, 5 Oct 2023 15:25:57 -0700 Subject: [PATCH 274/317] msm: eva: Add delay after resetting xo clk Wait 200us to 300us. Change-Id: Ia3d83b18a8b1c8fe351ab9fcd7a0ec3ed1b9822a Signed-off-by: George Shen (cherry picked from commit d2c57a156bbca8b93b3d6b218c7f586783c8f45e) --- msm/eva/cvp_hfi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 220a8bd45a..e6aa8dacd6 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -4767,8 +4767,8 @@ static int __power_off_controller(struct iris_hfi_device *device) /* de-assert EVA_NoC reset */ __write_register(device, CVP_AON_WRAPPER_CVP_NOC_CORE_SW_RESET, 0x0); - /* de-assert EVA video_cc XO reset and enable video_cc XO clock after 80us */ - usleep_range(80, 100); + /* de-assert EVA video_cc XO reset and enable video_cc XO clock after 125us */ + usleep_range(200, 300); rc = call_iris_op(device, reset_control_deassert_name, device, "cvp_xo_reset"); if (rc) dprintk(CVP_ERR, "%s: de-assert cvp_xo_reset failed\n", __func__); From 65910f26812b316ec72d042e5270f2fc5758694e Mon Sep 17 00:00:00 2001 From: Palak Joshi Date: Mon, 9 Oct 2023 12:53:54 +0530 Subject: [PATCH 275/317] msm: eva: Added QOS registers settings Changes made to accommodate difference in QOS & NOC base registers offsets between pineapple and cliffs. Change-Id: If8c631480d1f09bac21de52d0f27f0c29cdf594e Signed-off-by: Palak Joshi --- msm/eva/cvp_hfi.c | 181 ++++++++++++++++++++++++------------ msm/eva/cvp_hfi_io.h | 34 +++---- msm/eva/msm_cvp_platform.c | 52 ++++++++++- msm/eva/msm_cvp_res_parse.c | 13 +++ msm/eva/msm_cvp_resources.h | 6 ++ 5 files changed, 208 insertions(+), 78 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index e6aa8dacd6..591ec02536 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -858,50 +858,94 @@ static int __set_registers(struct iris_hfi_device *device) __write_register(device, CVP_CPU_CS_AXI4_QOS, pdata->noc_qos->axi_qos); - __write_register(device, CVP_NOC_RGE_PRIORITYLUT_LOW, - pdata->noc_qos->prioritylut_low); - __write_register(device, CVP_NOC_RGE_PRIORITYLUT_HIGH, - pdata->noc_qos->prioritylut_high); - __write_register(device, CVP_NOC_RGE_URGENCY_LOW, - pdata->noc_qos->urgency_low); - __write_register(device, CVP_NOC_RGE_DANGERLUT_LOW, - pdata->noc_qos->dangerlut_low); - __write_register(device, CVP_NOC_RGE_SAFELUT_LOW, - pdata->noc_qos->safelut_low); - __write_register(device, CVP_NOC_GCE_PRIORITYLUT_LOW, - pdata->noc_qos->prioritylut_low); - __write_register(device, CVP_NOC_GCE_PRIORITYLUT_HIGH, - pdata->noc_qos->prioritylut_high); - __write_register(device, CVP_NOC_GCE_URGENCY_LOW, - pdata->noc_qos->urgency_low); - __write_register(device, CVP_NOC_GCE_DANGERLUT_LOW, - pdata->noc_qos->dangerlut_low); - __write_register(device, CVP_NOC_GCE_SAFELUT_LOW, - pdata->noc_qos->safelut_low); - __write_register(device, CVP_NOC_CDM_PRIORITYLUT_LOW, - pdata->noc_qos->prioritylut_low); - __write_register(device, CVP_NOC_CDM_PRIORITYLUT_HIGH, - pdata->noc_qos->prioritylut_high); - __write_register(device, CVP_NOC_CDM_URGENCY_LOW, - pdata->noc_qos->urgency_low_ro); - __write_register(device, CVP_NOC_CDM_DANGERLUT_LOW, - pdata->noc_qos->dangerlut_low); - __write_register(device, CVP_NOC_CDM_SAFELUT_LOW, - pdata->noc_qos->safelut_low); + __write_register(device, + CVP_NOC_RGE_PRIORITYLUT_LOW + + device->res->qos_noc_rge_niu_offset, + pdata->noc_qos->prioritylut_low); + __write_register(device, + CVP_NOC_RGE_PRIORITYLUT_HIGH + + device->res->qos_noc_rge_niu_offset, + pdata->noc_qos->prioritylut_high); + __write_register(device, + CVP_NOC_RGE_URGENCY_LOW + + device->res->qos_noc_rge_niu_offset, + pdata->noc_qos->urgency_low); + __write_register(device, + CVP_NOC_RGE_DANGERLUT_LOW + + device->res->qos_noc_rge_niu_offset, + pdata->noc_qos->dangerlut_low); + __write_register(device, + CVP_NOC_RGE_SAFELUT_LOW + + device->res->qos_noc_rge_niu_offset, + pdata->noc_qos->safelut_low); + __write_register(device, + CVP_NOC_GCE_PRIORITYLUT_LOW + + device->res->qos_noc_gce_vadl_tof_niu_offset, + pdata->noc_qos->prioritylut_low); + __write_register(device, + CVP_NOC_GCE_PRIORITYLUT_HIGH + + device->res->qos_noc_gce_vadl_tof_niu_offset, + pdata->noc_qos->prioritylut_high); + __write_register(device, + CVP_NOC_GCE_URGENCY_LOW + + device->res->qos_noc_gce_vadl_tof_niu_offset, + pdata->noc_qos->urgency_low); + __write_register(device, + CVP_NOC_GCE_DANGERLUT_LOW + + device->res->qos_noc_gce_vadl_tof_niu_offset, + pdata->noc_qos->dangerlut_low); + __write_register(device, + CVP_NOC_GCE_SAFELUT_LOW + + device->res->qos_noc_gce_vadl_tof_niu_offset, + pdata->noc_qos->safelut_low); + + __write_register(device, + CVP_NOC_CDM_PRIORITYLUT_LOW + + device->res->qos_noc_cdm_niu_offset, + pdata->noc_qos->prioritylut_low); + __write_register(device, + CVP_NOC_CDM_PRIORITYLUT_HIGH + + device->res->qos_noc_cdm_niu_offset, + pdata->noc_qos->prioritylut_high); + __write_register(device, + CVP_NOC_CDM_URGENCY_LOW + + device->res->qos_noc_cdm_niu_offset, + pdata->noc_qos->urgency_low_ro); + __write_register(device, + CVP_NOC_CDM_DANGERLUT_LOW + + device->res->qos_noc_cdm_niu_offset, + pdata->noc_qos->dangerlut_low); + __write_register(device, + CVP_NOC_CDM_SAFELUT_LOW + + device->res->qos_noc_cdm_niu_offset, + pdata->noc_qos->safelut_low); /* Below registers write moved from FW to SW to enable UBWC */ - __write_register(device, CVP_NOC_RGE_NIU_DECCTL_LOW, - 0x1); - __write_register(device, CVP_NOC_RGE_NIU_ENCCTL_LOW, - 0x1); - __write_register(device, CVP_NOC_GCE_VADL_TOF_NIU_DECCTL_LOW, - 0x1); - __write_register(device, CVP_NOC_GCE_VADL_TOF_NIU_ENCCTL_LOW, - 0x1); - __write_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS, - 0x3); - __write_register(device, CVP_NOC_MAIN_SIDEBANDMANAGER_FAULTINEN0_LOW, - 0x1); + __write_register(device, + CVP_NOC_RGE_NIU_DECCTL_LOW + + device->res->qos_noc_rge_niu_offset, + 0x1); + __write_register(device, + CVP_NOC_RGE_NIU_ENCCTL_LOW + + device->res->qos_noc_rge_niu_offset, + 0x1); + __write_register(device, + CVP_NOC_GCE_VADL_TOF_NIU_DECCTL_LOW + + device->res->qos_noc_gce_vadl_tof_niu_offset, + 0x1); + __write_register(device, + CVP_NOC_GCE_VADL_TOF_NIU_ENCCTL_LOW + + device->res->qos_noc_gce_vadl_tof_niu_offset, + 0x1); + + __write_register(device, + CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS + + device->res->noc_core_err_offset, + 0x3); + __write_register(device, + CVP_NOC_MAIN_SIDEBANDMANAGER_FAULTINEN0_LOW + + device->res->noc_main_sidebandmanager_offset, + 0x1); call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); return 0; @@ -4633,11 +4677,14 @@ static void __print_sidebandmanager_regs(struct iris_hfi_device *device) goto exit; } main_sbm_ln0_low = __read_register(device, - CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_LOW); + CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_LOW + + device->res->noc_main_sidebandmanager_offset); main_sbm_ln0_high = __read_register(device, - CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_HIGH); + CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_HIGH + + device->res->noc_main_sidebandmanager_offset); main_sbm_ln1_high = __read_register(device, - CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN1_HIGH); + CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN1_HIGH + + device->res->noc_main_sidebandmanager_offset); call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); exit: @@ -5231,47 +5278,61 @@ static void __noc_error_info_iris2(struct iris_hfi_device *device) return; } - val = __read_register(device, CVP_NOC_CORE_ERR_SWID_LOW_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_SWID_LOW_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_swid_low, "CVP_NOC__CORE_ERL_MAIN_SWID_LOW", val); - val = __read_register(device, CVP_NOC_CORE_ERR_SWID_HIGH_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_SWID_HIGH_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_swid_high, "CVP_NOC_CORE_ERL_MAIN_SWID_HIGH", val); - val = __read_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_mainctl_low, "CVP_NOC_CORE_ERL_MAIN_MAINCTL_LOW", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_errvld_low, "CVP_NOC_CORE_ERL_MAIN_ERRVLD_LOW", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_errclr_low, "CVP_NOC_CORE_ERL_MAIN_ERRCLR_LOW", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_errlog0_low, "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_LOW", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_errlog0_high, "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_HIGH", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_errlog1_low, "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_LOW", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_errlog1_high, "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_HIGH", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_errlog2_low, "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_LOW", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_errlog2_high, "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_HIGH", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS); - __err_log(log_required, &noc_log->err_core_errlog3_low, + val = __read_register(device, + CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS + device->res->noc_core_err_offset); + __err_log(log_required, &noc_log->err_core_errlog3_low, "CORE ERRLOG3_LOW, below details", val); __print_reg_details(val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_errlog3_high, "CVP_NOC_CORE_ERL_MAIN_ERRLOG3_HIGH", val); - __write_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS, 0x1); + __write_register(device, + CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS + device->res->noc_core_err_offset, 0x1); call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); #define CVP_SS_CLK_HALT 0x8 #define CVP_SS_CLK_EN 0xC diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index eb686c5248..5691c4ecf2 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -207,39 +207,39 @@ #define CVP_NOC_GCE_VADL_TOF_NIU_ENCCTL_LOW \ (CVP_NOC_CORE_BASE_OFFS + 0x3588) #define CVP_NOC_MAIN_SIDEBANDMANAGER_FAULTINEN0_LOW \ - (CVP_NOC_CORE_BASE_OFFS + 0x7040) + (CVP_NOC_CORE_BASE_OFFS + 0x0240) #define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_LOW \ - (CVP_NOC_CORE_BASE_OFFS + 0x7100) + (CVP_NOC_CORE_BASE_OFFS + 0x0300) #define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_HIGH \ - (CVP_NOC_CORE_BASE_OFFS + 0x7104) + (CVP_NOC_CORE_BASE_OFFS + 0x0304) #define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN1_HIGH \ - (CVP_NOC_CORE_BASE_OFFS + 0x710C) + (CVP_NOC_CORE_BASE_OFFS + 0x030C) #define CVP_NOC_CORE_ERR_SWID_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA000) + (CVP_NOC_CORE_BASE_OFFS + 0x0000) #define CVP_NOC_CORE_ERR_SWID_HIGH_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA004) + (CVP_NOC_CORE_BASE_OFFS + 0x0004) #define CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA008) + (CVP_NOC_CORE_BASE_OFFS + 0x0008) #define CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA010) + (CVP_NOC_CORE_BASE_OFFS + 0x0010) #define CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA018) + (CVP_NOC_CORE_BASE_OFFS + 0x0018) #define CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA020) + (CVP_NOC_CORE_BASE_OFFS + 0x0020) #define CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA024) + (CVP_NOC_CORE_BASE_OFFS + 0x0024) #define CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA028) + (CVP_NOC_CORE_BASE_OFFS + 0x0028) #define CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA02C) + (CVP_NOC_CORE_BASE_OFFS + 0x002C) #define CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA030) + (CVP_NOC_CORE_BASE_OFFS + 0x0030) #define CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA034) + (CVP_NOC_CORE_BASE_OFFS + 0x0034) #define CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA038) + (CVP_NOC_CORE_BASE_OFFS + 0x0038) #define CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA03C) + (CVP_NOC_CORE_BASE_OFFS + 0x003C) #define CVP_NOC_RCG_VNOC_NOC_CLK_FORCECLOCKON_LOW \ (CVP_NOC_CORE_BASE_OFFS + 0x2018) diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 01eadebca1..8345e41cbd 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -249,6 +249,26 @@ static struct msm_cvp_common_data sm8650_common_data[] = { { .key = "qcom,dsp-enabled", .value = 1, + }, + { + .key = "qcom,qos_noc_rge_niu_offset", + .value = 0x0, + }, + { + .key = "qcom,qos_noc_gce_vadl_tof_niu_offset", + .value = 0x0, + }, + { + .key = "qcom,qos_noc_cdm_niu_offset", + .value = 0x0, + }, + { + .key = "qcom,noc_core_err_offset", + .value = 0xA000, + }, + { + .key = "qcom,noc_main_sidebandmanager_offset", + .value = 0x6E00, } }; @@ -292,6 +312,26 @@ static struct msm_cvp_common_data sm7650_common_data[] = { { .key = "qcom,dsp-enabled", .value = 1, + }, + { + .key = "qcom,qos_noc_rge_niu_offset", + .value = 0x200, + }, + { + .key = "qcom,qos_noc_gce_vadl_tof_niu_offset", + .value = 0xE00, + }, + { + .key = "qcom,qos_noc_cdm_niu_offset", + .value = 0x1A00, + }, + { + .key = "qcom,noc_core_err_offset", + .value = 0x0, + }, + { + .key = "qcom,noc_main_sidebandmanager_offset", + .value = 0x0, } }; @@ -319,6 +359,16 @@ static struct msm_cvp_qos_setting lanai_noc_qos = { .safelut_low = 0xffff, }; +static struct msm_cvp_qos_setting palawan_noc_qos = { + .axi_qos = 0x99, + .prioritylut_low = 0x33333333, + .prioritylut_high = 0x33333333, + .urgency_low = 0x1003, + .urgency_low_ro = 0x1003, + .dangerlut_low = 0x0, + .safelut_low = 0xffff, +}; + static struct msm_cvp_platform_data default_data = { .common_data = default_common_data, .common_data_length = ARRAY_SIZE(default_common_data), @@ -375,7 +425,7 @@ static struct msm_cvp_platform_data sm7650_data = { .sku_version = 0, .vpu_ver = VPU_VERSION_5, .ubwc_config = kona_ubwc_data, /*Reuse Kona setting*/ - .noc_qos = &waipio_noc_qos, /*Reuse Waipio setting*/ + .noc_qos = &palawan_noc_qos, .vm_id = 1, }; diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index f3cfbfd104..0b7e5ceac0 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -878,6 +878,19 @@ int cvp_read_platform_resources_from_drv_data( res->non_fatal_pagefaults = find_key_value(platform_data, "qcom,domain-attr-non-fatal-faults"); + //Address offsets for QOS setting. + //There are diff between lanai and palawan for QOS register addresses + res->qos_noc_rge_niu_offset = find_key_value(platform_data, + "qcom,qos_noc_rge_niu_offset"); + res->qos_noc_gce_vadl_tof_niu_offset = find_key_value(platform_data, + "qcom,qos_noc_gce_vadl_tof_niu_offset"); + res->qos_noc_cdm_niu_offset = find_key_value(platform_data, + "qcom,qos_noc_cdm_niu_offset"); + res->noc_core_err_offset = find_key_value(platform_data, + "qcom,noc_core_err_offset"); + res->noc_main_sidebandmanager_offset = find_key_value(platform_data, + "qcom,noc_main_sidebandmanager_offset"); + res->vpu_ver = platform_data->vpu_ver; res->ubwc_config = platform_data->ubwc_config; res->fatal_ssr = false; diff --git a/msm/eva/msm_cvp_resources.h b/msm/eva/msm_cvp_resources.h index d1e823eb2c..906654aba0 100644 --- a/msm/eva/msm_cvp_resources.h +++ b/msm/eva/msm_cvp_resources.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef __MSM_CVP_RESOURCES_H__ @@ -214,6 +215,11 @@ struct msm_cvp_platform_resources { uint32_t vpu_ver; uint32_t fw_cycles; struct msm_cvp_ubwc_config_data *ubwc_config; + uint32_t qos_noc_rge_niu_offset; + uint32_t qos_noc_gce_vadl_tof_niu_offset; + uint32_t qos_noc_cdm_niu_offset; + uint32_t noc_core_err_offset; + uint32_t noc_main_sidebandmanager_offset; }; static inline bool is_iommu_present(struct msm_cvp_platform_resources *res) From 34cfa712698a46a3fd4f0a9d1c52fbb7f0a7bda7 Mon Sep 17 00:00:00 2001 From: Palak Joshi Date: Mon, 9 Oct 2023 12:53:54 +0530 Subject: [PATCH 276/317] msm: eva: Added QOS registers settings Changes made to accommodate difference in QOS & NOC base registers offsets between pineapple and cliffs. Change-Id: If8c631480d1f09bac21de52d0f27f0c29cdf594e Signed-off-by: Palak Joshi (cherry picked from commit 65910f26812b316ec72d042e5270f2fc5758694e) --- msm/eva/cvp_hfi.c | 181 ++++++++++++++++++++++++------------ msm/eva/cvp_hfi_io.h | 34 +++---- msm/eva/msm_cvp_platform.c | 52 ++++++++++- msm/eva/msm_cvp_res_parse.c | 13 +++ msm/eva/msm_cvp_resources.h | 6 ++ 5 files changed, 208 insertions(+), 78 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index e6aa8dacd6..591ec02536 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -858,50 +858,94 @@ static int __set_registers(struct iris_hfi_device *device) __write_register(device, CVP_CPU_CS_AXI4_QOS, pdata->noc_qos->axi_qos); - __write_register(device, CVP_NOC_RGE_PRIORITYLUT_LOW, - pdata->noc_qos->prioritylut_low); - __write_register(device, CVP_NOC_RGE_PRIORITYLUT_HIGH, - pdata->noc_qos->prioritylut_high); - __write_register(device, CVP_NOC_RGE_URGENCY_LOW, - pdata->noc_qos->urgency_low); - __write_register(device, CVP_NOC_RGE_DANGERLUT_LOW, - pdata->noc_qos->dangerlut_low); - __write_register(device, CVP_NOC_RGE_SAFELUT_LOW, - pdata->noc_qos->safelut_low); - __write_register(device, CVP_NOC_GCE_PRIORITYLUT_LOW, - pdata->noc_qos->prioritylut_low); - __write_register(device, CVP_NOC_GCE_PRIORITYLUT_HIGH, - pdata->noc_qos->prioritylut_high); - __write_register(device, CVP_NOC_GCE_URGENCY_LOW, - pdata->noc_qos->urgency_low); - __write_register(device, CVP_NOC_GCE_DANGERLUT_LOW, - pdata->noc_qos->dangerlut_low); - __write_register(device, CVP_NOC_GCE_SAFELUT_LOW, - pdata->noc_qos->safelut_low); - __write_register(device, CVP_NOC_CDM_PRIORITYLUT_LOW, - pdata->noc_qos->prioritylut_low); - __write_register(device, CVP_NOC_CDM_PRIORITYLUT_HIGH, - pdata->noc_qos->prioritylut_high); - __write_register(device, CVP_NOC_CDM_URGENCY_LOW, - pdata->noc_qos->urgency_low_ro); - __write_register(device, CVP_NOC_CDM_DANGERLUT_LOW, - pdata->noc_qos->dangerlut_low); - __write_register(device, CVP_NOC_CDM_SAFELUT_LOW, - pdata->noc_qos->safelut_low); + __write_register(device, + CVP_NOC_RGE_PRIORITYLUT_LOW + + device->res->qos_noc_rge_niu_offset, + pdata->noc_qos->prioritylut_low); + __write_register(device, + CVP_NOC_RGE_PRIORITYLUT_HIGH + + device->res->qos_noc_rge_niu_offset, + pdata->noc_qos->prioritylut_high); + __write_register(device, + CVP_NOC_RGE_URGENCY_LOW + + device->res->qos_noc_rge_niu_offset, + pdata->noc_qos->urgency_low); + __write_register(device, + CVP_NOC_RGE_DANGERLUT_LOW + + device->res->qos_noc_rge_niu_offset, + pdata->noc_qos->dangerlut_low); + __write_register(device, + CVP_NOC_RGE_SAFELUT_LOW + + device->res->qos_noc_rge_niu_offset, + pdata->noc_qos->safelut_low); + __write_register(device, + CVP_NOC_GCE_PRIORITYLUT_LOW + + device->res->qos_noc_gce_vadl_tof_niu_offset, + pdata->noc_qos->prioritylut_low); + __write_register(device, + CVP_NOC_GCE_PRIORITYLUT_HIGH + + device->res->qos_noc_gce_vadl_tof_niu_offset, + pdata->noc_qos->prioritylut_high); + __write_register(device, + CVP_NOC_GCE_URGENCY_LOW + + device->res->qos_noc_gce_vadl_tof_niu_offset, + pdata->noc_qos->urgency_low); + __write_register(device, + CVP_NOC_GCE_DANGERLUT_LOW + + device->res->qos_noc_gce_vadl_tof_niu_offset, + pdata->noc_qos->dangerlut_low); + __write_register(device, + CVP_NOC_GCE_SAFELUT_LOW + + device->res->qos_noc_gce_vadl_tof_niu_offset, + pdata->noc_qos->safelut_low); + + __write_register(device, + CVP_NOC_CDM_PRIORITYLUT_LOW + + device->res->qos_noc_cdm_niu_offset, + pdata->noc_qos->prioritylut_low); + __write_register(device, + CVP_NOC_CDM_PRIORITYLUT_HIGH + + device->res->qos_noc_cdm_niu_offset, + pdata->noc_qos->prioritylut_high); + __write_register(device, + CVP_NOC_CDM_URGENCY_LOW + + device->res->qos_noc_cdm_niu_offset, + pdata->noc_qos->urgency_low_ro); + __write_register(device, + CVP_NOC_CDM_DANGERLUT_LOW + + device->res->qos_noc_cdm_niu_offset, + pdata->noc_qos->dangerlut_low); + __write_register(device, + CVP_NOC_CDM_SAFELUT_LOW + + device->res->qos_noc_cdm_niu_offset, + pdata->noc_qos->safelut_low); /* Below registers write moved from FW to SW to enable UBWC */ - __write_register(device, CVP_NOC_RGE_NIU_DECCTL_LOW, - 0x1); - __write_register(device, CVP_NOC_RGE_NIU_ENCCTL_LOW, - 0x1); - __write_register(device, CVP_NOC_GCE_VADL_TOF_NIU_DECCTL_LOW, - 0x1); - __write_register(device, CVP_NOC_GCE_VADL_TOF_NIU_ENCCTL_LOW, - 0x1); - __write_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS, - 0x3); - __write_register(device, CVP_NOC_MAIN_SIDEBANDMANAGER_FAULTINEN0_LOW, - 0x1); + __write_register(device, + CVP_NOC_RGE_NIU_DECCTL_LOW + + device->res->qos_noc_rge_niu_offset, + 0x1); + __write_register(device, + CVP_NOC_RGE_NIU_ENCCTL_LOW + + device->res->qos_noc_rge_niu_offset, + 0x1); + __write_register(device, + CVP_NOC_GCE_VADL_TOF_NIU_DECCTL_LOW + + device->res->qos_noc_gce_vadl_tof_niu_offset, + 0x1); + __write_register(device, + CVP_NOC_GCE_VADL_TOF_NIU_ENCCTL_LOW + + device->res->qos_noc_gce_vadl_tof_niu_offset, + 0x1); + + __write_register(device, + CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS + + device->res->noc_core_err_offset, + 0x3); + __write_register(device, + CVP_NOC_MAIN_SIDEBANDMANAGER_FAULTINEN0_LOW + + device->res->noc_main_sidebandmanager_offset, + 0x1); call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); return 0; @@ -4633,11 +4677,14 @@ static void __print_sidebandmanager_regs(struct iris_hfi_device *device) goto exit; } main_sbm_ln0_low = __read_register(device, - CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_LOW); + CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_LOW + + device->res->noc_main_sidebandmanager_offset); main_sbm_ln0_high = __read_register(device, - CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_HIGH); + CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_HIGH + + device->res->noc_main_sidebandmanager_offset); main_sbm_ln1_high = __read_register(device, - CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN1_HIGH); + CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN1_HIGH + + device->res->noc_main_sidebandmanager_offset); call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); exit: @@ -5231,47 +5278,61 @@ static void __noc_error_info_iris2(struct iris_hfi_device *device) return; } - val = __read_register(device, CVP_NOC_CORE_ERR_SWID_LOW_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_SWID_LOW_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_swid_low, "CVP_NOC__CORE_ERL_MAIN_SWID_LOW", val); - val = __read_register(device, CVP_NOC_CORE_ERR_SWID_HIGH_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_SWID_HIGH_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_swid_high, "CVP_NOC_CORE_ERL_MAIN_SWID_HIGH", val); - val = __read_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_mainctl_low, "CVP_NOC_CORE_ERL_MAIN_MAINCTL_LOW", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_errvld_low, "CVP_NOC_CORE_ERL_MAIN_ERRVLD_LOW", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_errclr_low, "CVP_NOC_CORE_ERL_MAIN_ERRCLR_LOW", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_errlog0_low, "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_LOW", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_errlog0_high, "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_HIGH", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_errlog1_low, "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_LOW", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_errlog1_high, "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_HIGH", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_errlog2_low, "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_LOW", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_errlog2_high, "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_HIGH", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS); - __err_log(log_required, &noc_log->err_core_errlog3_low, + val = __read_register(device, + CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS + device->res->noc_core_err_offset); + __err_log(log_required, &noc_log->err_core_errlog3_low, "CORE ERRLOG3_LOW, below details", val); __print_reg_details(val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS); + val = __read_register(device, + CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS + device->res->noc_core_err_offset); __err_log(log_required, &noc_log->err_core_errlog3_high, "CVP_NOC_CORE_ERL_MAIN_ERRLOG3_HIGH", val); - __write_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS, 0x1); + __write_register(device, + CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS + device->res->noc_core_err_offset, 0x1); call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); #define CVP_SS_CLK_HALT 0x8 #define CVP_SS_CLK_EN 0xC diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index eb686c5248..5691c4ecf2 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -207,39 +207,39 @@ #define CVP_NOC_GCE_VADL_TOF_NIU_ENCCTL_LOW \ (CVP_NOC_CORE_BASE_OFFS + 0x3588) #define CVP_NOC_MAIN_SIDEBANDMANAGER_FAULTINEN0_LOW \ - (CVP_NOC_CORE_BASE_OFFS + 0x7040) + (CVP_NOC_CORE_BASE_OFFS + 0x0240) #define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_LOW \ - (CVP_NOC_CORE_BASE_OFFS + 0x7100) + (CVP_NOC_CORE_BASE_OFFS + 0x0300) #define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN0_HIGH \ - (CVP_NOC_CORE_BASE_OFFS + 0x7104) + (CVP_NOC_CORE_BASE_OFFS + 0x0304) #define CVP_NOC_MAIN_SIDEBANDMANAGER_SENSELN1_HIGH \ - (CVP_NOC_CORE_BASE_OFFS + 0x710C) + (CVP_NOC_CORE_BASE_OFFS + 0x030C) #define CVP_NOC_CORE_ERR_SWID_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA000) + (CVP_NOC_CORE_BASE_OFFS + 0x0000) #define CVP_NOC_CORE_ERR_SWID_HIGH_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA004) + (CVP_NOC_CORE_BASE_OFFS + 0x0004) #define CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA008) + (CVP_NOC_CORE_BASE_OFFS + 0x0008) #define CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA010) + (CVP_NOC_CORE_BASE_OFFS + 0x0010) #define CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA018) + (CVP_NOC_CORE_BASE_OFFS + 0x0018) #define CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA020) + (CVP_NOC_CORE_BASE_OFFS + 0x0020) #define CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA024) + (CVP_NOC_CORE_BASE_OFFS + 0x0024) #define CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA028) + (CVP_NOC_CORE_BASE_OFFS + 0x0028) #define CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA02C) + (CVP_NOC_CORE_BASE_OFFS + 0x002C) #define CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA030) + (CVP_NOC_CORE_BASE_OFFS + 0x0030) #define CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA034) + (CVP_NOC_CORE_BASE_OFFS + 0x0034) #define CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA038) + (CVP_NOC_CORE_BASE_OFFS + 0x0038) #define CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS \ - (CVP_NOC_CORE_BASE_OFFS + 0xA03C) + (CVP_NOC_CORE_BASE_OFFS + 0x003C) #define CVP_NOC_RCG_VNOC_NOC_CLK_FORCECLOCKON_LOW \ (CVP_NOC_CORE_BASE_OFFS + 0x2018) diff --git a/msm/eva/msm_cvp_platform.c b/msm/eva/msm_cvp_platform.c index 01eadebca1..8345e41cbd 100644 --- a/msm/eva/msm_cvp_platform.c +++ b/msm/eva/msm_cvp_platform.c @@ -249,6 +249,26 @@ static struct msm_cvp_common_data sm8650_common_data[] = { { .key = "qcom,dsp-enabled", .value = 1, + }, + { + .key = "qcom,qos_noc_rge_niu_offset", + .value = 0x0, + }, + { + .key = "qcom,qos_noc_gce_vadl_tof_niu_offset", + .value = 0x0, + }, + { + .key = "qcom,qos_noc_cdm_niu_offset", + .value = 0x0, + }, + { + .key = "qcom,noc_core_err_offset", + .value = 0xA000, + }, + { + .key = "qcom,noc_main_sidebandmanager_offset", + .value = 0x6E00, } }; @@ -292,6 +312,26 @@ static struct msm_cvp_common_data sm7650_common_data[] = { { .key = "qcom,dsp-enabled", .value = 1, + }, + { + .key = "qcom,qos_noc_rge_niu_offset", + .value = 0x200, + }, + { + .key = "qcom,qos_noc_gce_vadl_tof_niu_offset", + .value = 0xE00, + }, + { + .key = "qcom,qos_noc_cdm_niu_offset", + .value = 0x1A00, + }, + { + .key = "qcom,noc_core_err_offset", + .value = 0x0, + }, + { + .key = "qcom,noc_main_sidebandmanager_offset", + .value = 0x0, } }; @@ -319,6 +359,16 @@ static struct msm_cvp_qos_setting lanai_noc_qos = { .safelut_low = 0xffff, }; +static struct msm_cvp_qos_setting palawan_noc_qos = { + .axi_qos = 0x99, + .prioritylut_low = 0x33333333, + .prioritylut_high = 0x33333333, + .urgency_low = 0x1003, + .urgency_low_ro = 0x1003, + .dangerlut_low = 0x0, + .safelut_low = 0xffff, +}; + static struct msm_cvp_platform_data default_data = { .common_data = default_common_data, .common_data_length = ARRAY_SIZE(default_common_data), @@ -375,7 +425,7 @@ static struct msm_cvp_platform_data sm7650_data = { .sku_version = 0, .vpu_ver = VPU_VERSION_5, .ubwc_config = kona_ubwc_data, /*Reuse Kona setting*/ - .noc_qos = &waipio_noc_qos, /*Reuse Waipio setting*/ + .noc_qos = &palawan_noc_qos, .vm_id = 1, }; diff --git a/msm/eva/msm_cvp_res_parse.c b/msm/eva/msm_cvp_res_parse.c index f3cfbfd104..0b7e5ceac0 100644 --- a/msm/eva/msm_cvp_res_parse.c +++ b/msm/eva/msm_cvp_res_parse.c @@ -878,6 +878,19 @@ int cvp_read_platform_resources_from_drv_data( res->non_fatal_pagefaults = find_key_value(platform_data, "qcom,domain-attr-non-fatal-faults"); + //Address offsets for QOS setting. + //There are diff between lanai and palawan for QOS register addresses + res->qos_noc_rge_niu_offset = find_key_value(platform_data, + "qcom,qos_noc_rge_niu_offset"); + res->qos_noc_gce_vadl_tof_niu_offset = find_key_value(platform_data, + "qcom,qos_noc_gce_vadl_tof_niu_offset"); + res->qos_noc_cdm_niu_offset = find_key_value(platform_data, + "qcom,qos_noc_cdm_niu_offset"); + res->noc_core_err_offset = find_key_value(platform_data, + "qcom,noc_core_err_offset"); + res->noc_main_sidebandmanager_offset = find_key_value(platform_data, + "qcom,noc_main_sidebandmanager_offset"); + res->vpu_ver = platform_data->vpu_ver; res->ubwc_config = platform_data->ubwc_config; res->fatal_ssr = false; diff --git a/msm/eva/msm_cvp_resources.h b/msm/eva/msm_cvp_resources.h index d1e823eb2c..906654aba0 100644 --- a/msm/eva/msm_cvp_resources.h +++ b/msm/eva/msm_cvp_resources.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #ifndef __MSM_CVP_RESOURCES_H__ @@ -214,6 +215,11 @@ struct msm_cvp_platform_resources { uint32_t vpu_ver; uint32_t fw_cycles; struct msm_cvp_ubwc_config_data *ubwc_config; + uint32_t qos_noc_rge_niu_offset; + uint32_t qos_noc_gce_vadl_tof_niu_offset; + uint32_t qos_noc_cdm_niu_offset; + uint32_t noc_core_err_offset; + uint32_t noc_main_sidebandmanager_offset; }; static inline bool is_iommu_present(struct msm_cvp_platform_resources *res) From 7761c7c52dfde068c162f176e81e35d2d74719b9 Mon Sep 17 00:00:00 2001 From: Palak Joshi Date: Wed, 18 Oct 2023 15:32:59 +0530 Subject: [PATCH 277/317] msm: eva: Increasing wait time to acquire xo reset Waiting for 1sec to acquire xo reset else BUG_ON. Change-Id: I26bcc27d02b4104f36b1bcdac97cb784c1daca44 Signed-off-by: Palak Joshi --- msm/eva/cvp_hfi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index e6aa8dacd6..a681ef2e1c 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -3731,7 +3731,7 @@ static int __reset_control_acquire(struct iris_hfi_device *device, struct reset_info *rcinfo = NULL; int rc = 0; bool found = false; - int max_retries = 10; + int max_retries = 1000; iris_hfi_for_each_reset_clock(device, rcinfo) { if (strcmp(rcinfo->name, name)) @@ -3743,15 +3743,15 @@ acquire_again: rc = reset_control_acquire(rcinfo->rst); if (rc) { if (rc == -EBUSY) { - usleep_range(500, 1000); + usleep_range(1000, 1500); max_retries--; if (max_retries) { goto acquire_again; } else { dprintk(CVP_ERR, "%s acquire %s -EBUSY\n", - __func__, rcinfo->name); - rc = -EINVAL; + __func__, rcinfo->name); + BUG_ON(1); } } else { dprintk(CVP_ERR, From 3454357c09a50c9b786e563ce41dca8d6f8ed42b Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 10 Oct 2023 14:48:56 -0700 Subject: [PATCH 278/317] msm: eva: Revert to 80us before XO de-assert Revert back 200us sleep to 80us before XO de-assert. Change-Id: I8446aa2eb5cfac32fdc5fc971ddd37b999623bf8 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index e6aa8dacd6..220a8bd45a 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -4767,8 +4767,8 @@ static int __power_off_controller(struct iris_hfi_device *device) /* de-assert EVA_NoC reset */ __write_register(device, CVP_AON_WRAPPER_CVP_NOC_CORE_SW_RESET, 0x0); - /* de-assert EVA video_cc XO reset and enable video_cc XO clock after 125us */ - usleep_range(200, 300); + /* de-assert EVA video_cc XO reset and enable video_cc XO clock after 80us */ + usleep_range(80, 100); rc = call_iris_op(device, reset_control_deassert_name, device, "cvp_xo_reset"); if (rc) dprintk(CVP_ERR, "%s: de-assert cvp_xo_reset failed\n", __func__); From dc5c927020b3c3736b1843e1c35a0e83a20dab3f Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 24 Oct 2023 15:47:32 -0700 Subject: [PATCH 279/317] msm: eva: Add QDENY and QACTIVE checks During CPU NoC LPI sequence. Print more debugging registers in case LPI QACCEPT is not set after 20ms. It indicates a pending transaction lingering around. Adding dump for NOC registers. Change-Id: Ied58e52e30572074be77b4d51a03fb4194d78caa Signed-off-by: George Shen --- msm/eva/cvp_core_hfi.h | 1 + msm/eva/cvp_hfi.c | 213 ++++++++++++++++++++++++++++++++------- msm/eva/cvp_hfi_io.h | 2 + msm/eva/msm_cvp.c | 7 ++ msm/eva/msm_cvp_common.c | 1 + 5 files changed, 189 insertions(+), 35 deletions(-) diff --git a/msm/eva/cvp_core_hfi.h b/msm/eva/cvp_core_hfi.h index 840e360a64..7ee1235782 100644 --- a/msm/eva/cvp_core_hfi.h +++ b/msm/eva/cvp_core_hfi.h @@ -298,4 +298,5 @@ int cvp_iris_hfi_initialize(struct cvp_hfi_ops *hdev, int load_cvp_fw_impl(struct iris_hfi_device *device); int unload_cvp_fw_impl(struct iris_hfi_device *device); +void cvp_dump_csr(struct iris_hfi_device *dev); #endif diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 591ec02536..f7160dd742 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -115,6 +115,9 @@ static int __reset_control_release(struct iris_hfi_device *device, const char *n static bool __is_ctl_power_on(struct iris_hfi_device *device); +static void __print_sidebandmanager_regs(struct iris_hfi_device *device); +static void dump_noc_reg(struct iris_hfi_device *device); + static struct cvp_hal_ops hal_ops = { .interrupt_init = interrupt_init_iris2, .setup_dsp_uc_memmap = setup_dsp_uc_memmap_vpu5, @@ -1329,7 +1332,7 @@ static int iris_hfi_suspend(void *dev) return rc; } -static void cvp_dump_csr(struct iris_hfi_device *dev) +void cvp_dump_csr(struct iris_hfi_device *dev) { u32 reg; @@ -1355,6 +1358,9 @@ static void cvp_dump_csr(struct iris_hfi_device *dev) dprintk(CVP_ERR, "CVP_WRAPPER_CPU_CLOCK_CONFIG: %x\n", reg); reg = __read_register(dev, CVP_WRAPPER_CORE_CLOCK_CONFIG); dprintk(CVP_ERR, "CVP_WRAPPER_CORE_CLOCK_CONFIG: %x\n", reg); + + dump_noc_reg(dev); + dev->reg_dumped = true; } @@ -3632,6 +3638,7 @@ static void iris_hfi_wd_work_handler(struct work_struct *work) if (msm_cvp_hw_wd_recovery) { dprintk(CVP_ERR, "Cleaning up as HW WD recovery is enable %d\n", msm_cvp_hw_wd_recovery); + __print_sidebandmanager_regs(device); response.device_id = 0; handle_sys_error(cmd, (void *) &response); enable_irq(device->cvp_hal_data->irq_wd); @@ -4550,6 +4557,10 @@ static int __iris_power_on(struct iris_hfi_device *device) /*Do not access registers before this point!*/ device->power_enabled = true; + /* Thomas input to debug CPU NoC hang */ + __write_register(device, CVP_NOC_SBM_FAULTINEN0_LOW, 0x1); + __write_register(device, CVP_NOC_ERR_MAINCTL_LOW_OFFS, 0x3); + /* * Re-program all of the registers that get reset as a result of * regulator_disable() and _enable() @@ -4643,7 +4654,7 @@ err_tzbsp_suspend: static void __print_sidebandmanager_regs(struct iris_hfi_device *device) { - u32 sbm_ln0_low, axi_cbcr; + u32 sbm_ln0_low, axi_cbcr, val; u32 main_sbm_ln0_low = 0xdeadbeef, main_sbm_ln0_high = 0xdeadbeef; u32 main_sbm_ln1_high = 0xdeadbeef, cpu_cs_x2rpmh; int rc; @@ -4671,6 +4682,39 @@ static void __print_sidebandmanager_regs(struct iris_hfi_device *device) goto exit; } + /* Added by Thomas to debug CPU NoC hang */ + val = __read_register(device, CVP_NOC_ERR_ERRVLD_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRVLD_LOW %#x\n", val); + + val = __read_register(device, CVP_NOC_SBM_FAULTINSTATUS0_LOW); + dprintk(CVP_ERR, "CVP_NOC_SBM_FAULTINSTATUS0_LOW %#x\n", val); + + val = __read_register(device, CVP_NOC_ERR_ERRLOG0_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG0_LOW %#x\n", val); + + val = __read_register(device, CVP_NOC_ERR_ERRLOG0_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG0_HIGH %#x\n", val); + + val = __read_register(device, CVP_NOC_ERR_ERRLOG1_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG1_LOW %#x\n", val); + + val = __read_register(device, CVP_NOC_ERR_ERRLOG1_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG1_HIGH %#x\n", val); + + val = __read_register(device, CVP_NOC_ERR_ERRLOG2_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG2_LOW %#x\n", val); + + val = __read_register(device, CVP_NOC_ERR_ERRLOG2_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG2_HIGH %#x\n", val); + + val = __read_register(device, CVP_NOC_ERR_ERRLOG3_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG3_LOW %#x\n", val); + + val = __read_register(device, CVP_NOC_ERR_ERRLOG3_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG3_HIGH %#x\n", val); + + /* end of addition */ + rc = call_iris_op(device, reset_control_acquire_name, device, "cvp_xo_reset"); if (rc) { dprintk(CVP_WARN, "%s Fail acquire xo_reset\n", __func__); @@ -4696,10 +4740,50 @@ exit: cpu_cs_x2rpmh); } +static void __enter_cpu_noc_lpi(struct iris_hfi_device *device) +{ + u32 lpi_status, count = 0, max_count = 2000; + + /* New addition to put CPU/Tensilica to low power */ + count = 0; + __write_register(device, CVP_WRAPPER_CPU_NOC_LPI_CONTROL, 0x1); + while (count < max_count) { + lpi_status = __read_register(device, CVP_WRAPPER_CPU_NOC_LPI_STATUS); + if ((lpi_status & BIT(1)) || ((lpi_status & BIT(2)) && (!(lpi_status & BIT(0))))) { + /* + * If QDENY == true, or + * If QACTIVE == true && QACCEPT == false + * Try again + */ + __write_register(device, CVP_WRAPPER_CPU_NOC_LPI_CONTROL, 0x0); + usleep_range(10, 20); + __write_register(device, CVP_WRAPPER_CPU_NOC_LPI_CONTROL, 0x1); + usleep_range(1000, 1200); + count++; + } else { + break; + } + } + + dprintk(CVP_PWR, + "%s, CPU Noc: lpi_status %x (count %d)\n", __func__, lpi_status, count); + if (count == max_count) { + u32 pc_ready, wfi_status; + + wfi_status = __read_register(device, CVP_WRAPPER_CPU_STATUS); + pc_ready = __read_register(device, CVP_CTRL_STATUS); + + dprintk(CVP_WARN, + "%s, CPU NOC not in qaccept status %x %x %x\n", + __func__, lpi_status, wfi_status, pc_ready); + + __print_sidebandmanager_regs(device); + } +} + static int __power_off_controller(struct iris_hfi_device *device) { - u32 lpi_status, reg_status = 0, count = 0, max_count = 1000; - u32 sbm_ln0_low; + u32 lpi_status, count = 0, max_count = 1000; int rc; u32 spare_val, spare_status; @@ -4708,37 +4792,7 @@ static int __power_off_controller(struct iris_hfi_device *device) __write_register(device, CVP_CPU_CS_X2RPMh, 0x3); /* HPG 6.2.2 Step 2, noc to low power */ - - /* New addition to put CPU/Tensilica to low power */ - reg_status = 0; - count = 0; - __write_register(device, CVP_WRAPPER_CPU_NOC_LPI_CONTROL, 0x1); - while (!reg_status && count < max_count) { - lpi_status = - __read_register(device, - CVP_WRAPPER_CPU_NOC_LPI_STATUS); - reg_status = lpi_status & BIT(0); - /* Wait for CPU noc lpi status to be set */ - usleep_range(50, 100); - count++; - } - sbm_ln0_low = __read_register(device, CVP_NOC_SBM_SENSELN0_LOW); - dprintk(CVP_PWR, - "CPU Noc: lpi_status %x noc_status %x (count %d) 0x%x\n", - lpi_status, reg_status, count, sbm_ln0_low); - if (count == max_count) { - u32 pc_ready, wfi_status; - - wfi_status = __read_register(device, CVP_WRAPPER_CPU_STATUS); - pc_ready = __read_register(device, CVP_CTRL_STATUS); - - dprintk(CVP_WARN, - "CPU NOC not in qaccept status %x %x %x %x\n", - reg_status, lpi_status, wfi_status, pc_ready); - - __print_sidebandmanager_regs(device); - } - + __enter_cpu_noc_lpi(device); /* HPG 6.2.2 Step 3, debug bridge to low power BYPASSED */ @@ -5113,6 +5167,9 @@ static void __unload_fw(struct iris_hfi_device *device) if (device->state != IRIS_STATE_DEINIT) flush_workqueue(device->iris_pm_workq); + /* New addition to put CPU/Tensilica to low power */ + __enter_cpu_noc_lpi(device); + unload_cvp_fw_impl(device); __interface_queues_release(device); call_iris_op(device, power_off, device); @@ -5575,3 +5632,89 @@ err_iris_hfi_init: return rc; } +static void dump_noc_reg(struct iris_hfi_device *device) +{ + u32 val = 0, config; + int i; + struct regulator_info *rinfo; + int rc = 0; + + if (msm_cvp_fw_low_power_mode) { + iris_hfi_for_each_regulator(device, rinfo) { + if (strcmp(rinfo->name, "cvp-core")) + continue; + rc = __acquire_regulator(rinfo, device); + if (rc) + dprintk(CVP_WARN, + "%s, Failed to acquire regulator control: %s\n", + __func__, rinfo->name); + } + } + val = __read_register(device, CVP_CC_MVS1_GDSCR); + dprintk(CVP_ERR, "%s, CVP_CC_MVS1_GDSCR: 0x%x", __func__, val); + config = __read_register(device, CVP_WRAPPER_CORE_CLOCK_CONFIG); + dprintk(CVP_ERR, "%s, CVP_WRAPPER_CORE_CLOCK_CONFIG: 0x%x", __func__, config); + if (config) { + dprintk(CVP_PWR, + "core clock config not enabled, enable it to access core\n"); + __write_register(device, CVP_WRAPPER_CORE_CLOCK_CONFIG, 0); + } + i = call_iris_op(device, reset_control_acquire_name, device, "cvp_xo_reset"); + if (i) { + dprintk(CVP_WARN, "%s Fail acquire xo_reset\n", __func__); + return; + } + + val = __read_register(device, CVP_NOC_RGE_NIU_DECCTL_LOW); + dprintk(CVP_ERR, "CVP_NOC_RGE_NIU_DECCTL_LOW: 0x%x", val); + val = __read_register(device, CVP_NOC_RGE_NIU_ENCCTL_LOW); + dprintk(CVP_ERR, "CVP_NOC_RGE_NIU_ENCCTL_LOW: 0x%x", val); + val = __read_register(device, CVP_NOC_GCE_VADL_TOF_NIU_DECCTL_LOW); + dprintk(CVP_ERR, "CVP_NOC_GCE_VADL_TOF_NIU_DECCTL_LOW: 0x%x", val); + val = __read_register(device, CVP_NOC_GCE_VADL_TOF_NIU_ENCCTL_LOW); + dprintk(CVP_ERR, "CVP_NOC_GCE_VADL_TOF_NIU_ENCCTL_LOW: 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS: 0x%x", val); + val = __read_register(device, CVP_NOC_MAIN_SIDEBANDMANAGER_FAULTINEN0_LOW); + dprintk(CVP_ERR, "CVP_NOC_MAIN_SIDEBANDMANAGER_FAULTINEN0_LOW: 0x%x", val); + + dprintk(CVP_ERR, "Dumping Core NoC registers\n"); + val = __read_register(device, CVP_NOC_CORE_ERR_SWID_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC__CORE_ERL_MAIN_SWID_LOW: 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_SWID_HIGH_OFFS); + dprintk(CVP_ERR, "CVVP_NOC_CORE_ERL_MAIN_SWID_HIGH 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_MAINCTL_LOW 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRVLD_LOW 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRCLR_LOW 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_LOW 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_HIGH 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_LOW 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_HIGH 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_LOW 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_HIGH 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS); + dprintk(CVP_ERR, "CORE ERRLOG3_LOW 0x%x, below details", val); + __print_reg_details(val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG3_HIGH 0x%x", val); + __write_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS, 0x1); + + call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); + if (msm_cvp_fw_low_power_mode) { + iris_hfi_for_each_regulator(device, rinfo) { + if (strcmp(rinfo->name, "cvp-core")) + continue; + rc = __hand_off_regulator(rinfo); + } + } + __write_register(device, CVP_WRAPPER_CORE_CLOCK_CONFIG, config); +} diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index 5691c4ecf2..80957d055f 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -195,6 +195,8 @@ #define CVP_NOC_ERR_ERRLOG2_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0x34) #define CVP_NOC_ERR_ERRLOG3_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x38) #define CVP_NOC_ERR_ERRLOG3_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0x3C) +#define CVP_NOC_SBM_FAULTINEN0_LOW (CVP_NOC_BASE_OFFS + 0x240) +#define CVP_NOC_SBM_FAULTINSTATUS0_LOW (CVP_NOC_BASE_OFFS + 0x248) #define CVP_NOC_SBM_SENSELN0_LOW (CVP_NOC_BASE_OFFS + 0x300) #define CVP_NOC_CORE_BASE_OFFS 0x00010000 diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 5b2b624060..6439babfb6 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -308,6 +308,7 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, struct cvp_session_queue *sq; u32 hfi_err = HFI_ERR_NONE; struct cvp_hfi_msg_session_hdr_ext hdr; + struct iris_hfi_device *device; dprintk(CVP_SYNX, "%s %s\n", current->comm, __func__); @@ -354,6 +355,12 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, dprintk(CVP_INFO, "%s %s: cvp_wait_process_msg non-fatal %d\n", current->comm, __func__, hfi_err); synx_state = SYNX_STATE_SIGNALED_SUCCESS; + } else if (hfi_err == HFI_ERR_SESSION_HW_HANG_DETECTED) { + dprintk(CVP_ERR, "%s %s: cvp_wait_process_message hfi HW hang err %d\n", + current->comm, __func__, hfi_err); + synx_state = SYNX_STATE_SIGNALED_CANCEL; + device = ops_tbl->hfi_device_data; + cvp_dump_csr(device); } else if (hfi_err != HFI_ERR_NONE) { dprintk(CVP_ERR, "%s %s: cvp_wait_process_message hfi err %d\n", current->comm, __func__, hfi_err); diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 9a16e89b31..19eea69e87 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -542,6 +542,7 @@ static void handle_session_error(enum hal_command_response cmd, void *data) response->status, inst, hash32_ptr(inst->session)); cvp_print_inst(CVP_WARN, inst); + print_hfi_queue_info(ops_tbl); //if (inst->state != MSM_CVP_CORE_INVALID) { // change_cvp_inst_state(inst, MSM_CVP_CORE_INVALID); // if (cvp_clean_session_queues(inst)) From 1635c2920e702cb887142f708f4a2a2101ee5249 Mon Sep 17 00:00:00 2001 From: Palak Joshi Date: Fri, 10 Nov 2023 12:47:32 +0530 Subject: [PATCH 280/317] msm: eva: Added required offset for NOC registers Added required offset for NOC registers while dumping. Change-Id: I77964a045cc15480ec27316318f6d39e31196225 Signed-off-by: Palak Joshi --- msm/eva/cvp_hfi.c | 60 +++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 6d4fb68ecf..3007839693 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -5665,48 +5665,68 @@ static void dump_noc_reg(struct iris_hfi_device *device) return; } - val = __read_register(device, CVP_NOC_RGE_NIU_DECCTL_LOW); + val = __read_register(device, CVP_NOC_RGE_NIU_DECCTL_LOW + + device->res->qos_noc_rge_niu_offset); dprintk(CVP_ERR, "CVP_NOC_RGE_NIU_DECCTL_LOW: 0x%x", val); - val = __read_register(device, CVP_NOC_RGE_NIU_ENCCTL_LOW); + val = __read_register(device, CVP_NOC_RGE_NIU_ENCCTL_LOW + + device->res->qos_noc_rge_niu_offset); dprintk(CVP_ERR, "CVP_NOC_RGE_NIU_ENCCTL_LOW: 0x%x", val); - val = __read_register(device, CVP_NOC_GCE_VADL_TOF_NIU_DECCTL_LOW); + val = __read_register(device, CVP_NOC_GCE_VADL_TOF_NIU_DECCTL_LOW + + device->res->qos_noc_gce_vadl_tof_niu_offset); dprintk(CVP_ERR, "CVP_NOC_GCE_VADL_TOF_NIU_DECCTL_LOW: 0x%x", val); - val = __read_register(device, CVP_NOC_GCE_VADL_TOF_NIU_ENCCTL_LOW); + val = __read_register(device, CVP_NOC_GCE_VADL_TOF_NIU_ENCCTL_LOW + + device->res->qos_noc_gce_vadl_tof_niu_offset); dprintk(CVP_ERR, "CVP_NOC_GCE_VADL_TOF_NIU_ENCCTL_LOW: 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS: 0x%x", val); - val = __read_register(device, CVP_NOC_MAIN_SIDEBANDMANAGER_FAULTINEN0_LOW); + val = __read_register(device, CVP_NOC_MAIN_SIDEBANDMANAGER_FAULTINEN0_LOW + + device->res->noc_main_sidebandmanager_offset); dprintk(CVP_ERR, "CVP_NOC_MAIN_SIDEBANDMANAGER_FAULTINEN0_LOW: 0x%x", val); dprintk(CVP_ERR, "Dumping Core NoC registers\n"); - val = __read_register(device, CVP_NOC_CORE_ERR_SWID_LOW_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_SWID_LOW_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC__CORE_ERL_MAIN_SWID_LOW: 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_SWID_HIGH_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_SWID_HIGH_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVVP_NOC_CORE_ERL_MAIN_SWID_HIGH 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_MAINCTL_LOW 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRVLD_LOW 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRCLR_LOW 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_LOW 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_HIGH 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_LOW 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_HIGH 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_LOW 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_HIGH 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CORE ERRLOG3_LOW 0x%x, below details", val); __print_reg_details(val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG3_HIGH 0x%x", val); - __write_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS, 0x1); + __write_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS + + device->res->noc_core_err_offset, 0x1); call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); if (msm_cvp_fw_low_power_mode) { From a0ed71291f67a2260bf162cb3c6f68ca55e84217 Mon Sep 17 00:00:00 2001 From: Aniruddh Sharma Date: Fri, 3 Nov 2023 19:56:00 +0530 Subject: [PATCH 281/317] msm: eva: Acquire XO_RESET before GDSC access Acquire XO_RESET before turning on/off the controller/core gdscs. This is to enasure that XO_RESET can not be asserted by video while EVA is turning on/off the gdsc. Make sure to acquire XO_RESET before set operation on gdsc as well. Wait at least 90ms for acquiring the XO_RESET. Change-Id: I851297b1b6b48a903fbd5ce6d680e4d8727ebcc0 Signed-off-by: Aniruddh Sharma --- msm/eva/cvp_hfi.c | 57 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 3007839693..863630f9f9 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -330,6 +330,15 @@ static int __acquire_regulator(struct regulator_info *rinfo, int rc = 0; if (rinfo->has_hw_power_collapse) { + /*Acquire XO_RESET to avoid race condition with video*/ + rc = call_iris_op(device, reset_control_acquire_name, device, "cvp_xo_reset"); + if (rc) { + dprintk(CVP_ERR, + "XO_RESET could not be acquired: skip acquiring the regulator %s from FW\n", + rinfo->name); + return -EINVAL; + } + rc = regulator_set_mode(rinfo->regulator, REGULATOR_MODE_NORMAL); if (rc) { @@ -348,6 +357,8 @@ static int __acquire_regulator(struct regulator_info *rinfo, rinfo->name); } + /*Release XO_RESET after regulator is enabled.*/ + call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); } if (!regulator_is_enabled(rinfo->regulator)) { @@ -359,13 +370,26 @@ static int __acquire_regulator(struct regulator_info *rinfo, return rc; } -static int __hand_off_regulator(struct regulator_info *rinfo) +static int __hand_off_regulator(struct iris_hfi_device *device, struct regulator_info *rinfo) { int rc = 0; if (rinfo->has_hw_power_collapse) { + /*Acquire XO_RESET to avoid race condition with video*/ + rc = call_iris_op(device, reset_control_acquire_name, device, "cvp_xo_reset"); + if (rc) { + dprintk(CVP_ERR, + "XO_RESET could not be acquired: skip hand off the regulator %s to FW\n", + rinfo->name); + return -EINVAL; + } + rc = regulator_set_mode(rinfo->regulator, REGULATOR_MODE_FAST); + + /*Release XO_RESET after regulator is enabled.*/ + call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); + if (rc) { dprintk(CVP_WARN, "Failed to hand off regulator control: %s\n", @@ -386,7 +410,7 @@ static int __hand_off_regulators(struct iris_hfi_device *device) int rc = 0, c = 0; iris_hfi_for_each_regulator(device, rinfo) { - rc = __hand_off_regulator(rinfo); + rc = __hand_off_regulator(device, rinfo); /* * If one regulator hand off failed, driver should take * the control for other regulators back. @@ -4099,7 +4123,20 @@ static int __disable_regulator_impl(struct regulator_info *rinfo, goto disable_regulator_failed; } + /*Acquire XO_RESET to avoid race condition with video*/ + rc = call_iris_op(device, reset_control_acquire_name, device, "cvp_xo_reset"); + if (rc) { + dprintk(CVP_ERR, + "XO_RESET could not be acquired: skip disabling the regulator %s\n", + rinfo->name); + return -EINVAL; + } + rc = regulator_disable(rinfo->regulator); + + /*Release XO_RESET after regulator is enabled.*/ + call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); + if (rc) { dprintk(CVP_WARN, "Failed to disable %s: %d\n", @@ -4158,7 +4195,21 @@ static int __enable_regulator(struct iris_hfi_device *device, iris_hfi_for_each_regulator(device, rinfo) { if (strcmp(rinfo->name, name)) continue; + + /*Acquire XO_RESET to avoid race condition with video*/ + rc = call_iris_op(device, reset_control_acquire_name, device, "cvp_xo_reset"); + if (rc) { + dprintk(CVP_ERR, + "XO_RESET could not be acquired: skip enabling the regulator %s\n", + rinfo->name); + return -EINVAL; + } + rc = regulator_enable(rinfo->regulator); + + /*Release XO_RESET after regulator is enabled.*/ + call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); + if (rc) { dprintk(CVP_ERR, "Failed to enable %s: %d\n", rinfo->name, rc); @@ -5733,7 +5784,7 @@ static void dump_noc_reg(struct iris_hfi_device *device) iris_hfi_for_each_regulator(device, rinfo) { if (strcmp(rinfo->name, "cvp-core")) continue; - rc = __hand_off_regulator(rinfo); + rc = __hand_off_regulator(device, rinfo); } } __write_register(device, CVP_WRAPPER_CORE_CLOCK_CONFIG, config); From dfd982cf5edd7f6fc62975829ff960df3c861e41 Mon Sep 17 00:00:00 2001 From: Gopireddy Arunteja Reddy Date: Thu, 23 Nov 2023 17:23:19 +0530 Subject: [PATCH 282/317] msm: eva: Releasing DSP buffers based on ref count Added fixes to release DSP buffers only if the ref count is zero and checking the fd is also matching or not while freeing the DSP buffers. Change-Id: I8d3475a0c50c7240142420d02a0444f718f883c2 Signed-off-by: Gopireddy Arunteja Reddy --- msm/eva/msm_cvp_buf.c | 7 ++++--- msm/eva/msm_cvp_core.c | 1 + msm/eva/msm_cvp_dsp.c | 12 +++++++----- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index e05464eb29..c18a5c372d 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -2394,9 +2394,10 @@ int cvp_release_dsp_buffers(struct msm_cvp_inst *inst, "%s: %x : fd %x %s size %d", __func__, hash32_ptr(inst->session), buf->fd, smem->dma_buf->name, buf->size); - atomic_dec(&smem->refcount); - msm_cvp_smem_free(smem); - cvp_kmem_cache_free(&cvp_driver->smem_cache, smem); + if (atomic_dec_and_test(&smem->refcount)) { + msm_cvp_smem_free(smem); + cvp_kmem_cache_free(&cvp_driver->smem_cache, smem); + } } else { dprintk(CVP_ERR, "%s: wrong owner %d %x : fd %x %s size %d", diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 31321b9a99..74d03c21a4 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -453,6 +453,7 @@ int msm_cvp_destroy(struct msm_cvp_inst *inst) core->smem_leak_count += atomic_read(&inst->smem_count); } kfree(inst); + inst = NULL; dprintk(CVP_SESS, "sys-stat: nr_insts %d msgs %d, frames %d, bufs %d, smems %d\n", atomic_read(&nr_insts), diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index c41b541c24..8876e4a382 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1485,9 +1485,9 @@ void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) inst->task = task; dprintk(CVP_DSP, - "%s CREATE_SESS id 0x%x, cpu_low 0x%x, cpu_high 0x%x\n", + "%s CREATE_SESS id 0x%x, cpu_low 0x%x, cpu_high 0x%x, inst %pK, inst->session %pK\n", __func__, cmd->session_id, cmd->session_cpu_low, - cmd->session_cpu_high); + cmd->session_cpu_high, inst, inst->session); spin_lock(&inst->core->resources.pm_qos.lock); inst->core->resources.pm_qos.off_vote_cnt++; @@ -1811,8 +1811,9 @@ void __dsp_cvp_mem_alloc(struct cvp_dsp_cmd_msg *cmd) cmd->sbuf.iova = buf->smem->device_addr; cmd->sbuf.v_dsp_addr = v_dsp_addr; dprintk(CVP_DSP, "%s: size %d, iova 0x%x, v_dsp_addr 0x%llx\n", - __func__, cmd->sbuf.size, cmd->sbuf.iova, - cmd->sbuf.v_dsp_addr); + __func__, cmd->sbuf.size, cmd->sbuf.iova, cmd->sbuf.v_dsp_addr); + dprintk(CVP_DSP, "%s: DSP2CPU_session_id 0x%x, smem_fd 0x%x, smem_refcount %d\n", + __func__, dsp2cpu_cmd->session_id, buf->smem->fd, buf->smem->refcount); cvp_put_fastrpc_node(frpc_node); return; @@ -1883,7 +1884,8 @@ void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) } /* Verify with device addr */ - if (buf->smem->device_addr == dsp2cpu_cmd->sbuf.iova) { + if ((buf->smem->device_addr == dsp2cpu_cmd->sbuf.iova) && + (buf->fd == dsp2cpu_cmd->sbuf.fd)) { dprintk(CVP_DSP, "%s find device addr 0x%x\n", __func__, buf->smem->device_addr); dprintk(CVP_DSP, "fd in list 0x%x, fd from dsp 0x%x\n", From 9e0f4d0dd60d112af7edd0aeee96af784711359a Mon Sep 17 00:00:00 2001 From: George Shen Date: Mon, 20 Nov 2023 14:14:18 -0800 Subject: [PATCH 283/317] msm: eva: Add line break When printing buffer info for smmu fault debugging. Change-Id: Icf23db20e69e9c54e0405a4ea58e0a3dc0dce59d Signed-off-by: George Shen --- msm/eva/msm_cvp_buf.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index e05464eb29..f6a21c2610 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -74,12 +74,12 @@ int print_smem(u32 tag, const char *str, struct msm_cvp_inst *inst, if (!atomic_read(&smem->refcount)) dprintk(tag, - " UNUSED mapping %s: 0x%llx size %d iova %#x idx %d pkt_type %s buf_idx %#x fd %d", + " UNUSED mapping %s: 0x%llx size %d iova %#x idx %d pkt_type %s buf_idx %#x fd %d\n", str, smem->dma_buf, smem->size, smem->device_addr, smem->bitmap_index, name, smem->buf_idx, smem->fd); else dprintk(tag, - "%s: %x : 0x%llx size %d flags %#x iova %#x idx %d ref %d pkt_type %s buf_idx %#x fd %d", + "%s: %x : 0x%llx size %d flags %#x iova %#x idx %d ref %d pkt_type %s buf_idx %#x fd %d\n", str, hash32_ptr(inst->session), smem->dma_buf, smem->size, smem->flags, smem->device_addr, smem->bitmap_index, atomic_read(&smem->refcount), @@ -96,13 +96,13 @@ static void print_internal_buffer(u32 tag, const char *str, if (cbuf->smem->dma_buf) { dprintk(tag, - "%s: %x : fd %d off %d 0x%llx %s size %d iova %#x", + "%s: %x : fd %d off %d 0x%llx %s size %d iova %#x\n", str, hash32_ptr(inst->session), cbuf->fd, cbuf->offset, cbuf->smem->dma_buf, cbuf->smem->dma_buf->name, cbuf->size, cbuf->smem->device_addr); } else { dprintk(tag, - "%s: %x : idx %2d fd %d off %d size %d iova %#x", + "%s: %x : idx %2d fd %d off %d size %d iova %#x\n", str, hash32_ptr(inst->session), cbuf->index, cbuf->fd, cbuf->offset, cbuf->size, cbuf->smem->device_addr); } @@ -177,8 +177,7 @@ void print_client_buffer(u32 tag, const char *str, return; dprintk(tag, - "%s: %x : idx %2d fd %d off %d size %d type %d flags 0x%x" - " reserved[0] %u\n", + "%s: %x : idx %2d fd %d off %d size %d type %d flags 0x%x reserved[0] %u\n", str, hash32_ptr(inst->session), cbuf->index, cbuf->fd, cbuf->offset, cbuf->size, cbuf->type, cbuf->flags, cbuf->reserved[0]); From 8c95544429046d9018dd00a6882a3c7ed3fc998c Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 24 Oct 2023 15:47:32 -0700 Subject: [PATCH 284/317] msm: eva: Add QDENY and QACTIVE checks During CPU NoC LPI sequence. Print more debugging registers in case LPI QACCEPT is not set after 20ms. It indicates a pending transaction lingering around. Adding dump for NOC registers. Change-Id: Ied58e52e30572074be77b4d51a03fb4194d78caa Signed-off-by: George Shen --- msm/eva/cvp_core_hfi.h | 1 + msm/eva/cvp_hfi.c | 213 ++++++++++++++++++++++++++++++++------- msm/eva/cvp_hfi_io.h | 2 + msm/eva/msm_cvp.c | 7 ++ msm/eva/msm_cvp_common.c | 1 + 5 files changed, 189 insertions(+), 35 deletions(-) diff --git a/msm/eva/cvp_core_hfi.h b/msm/eva/cvp_core_hfi.h index 840e360a64..7ee1235782 100644 --- a/msm/eva/cvp_core_hfi.h +++ b/msm/eva/cvp_core_hfi.h @@ -298,4 +298,5 @@ int cvp_iris_hfi_initialize(struct cvp_hfi_ops *hdev, int load_cvp_fw_impl(struct iris_hfi_device *device); int unload_cvp_fw_impl(struct iris_hfi_device *device); +void cvp_dump_csr(struct iris_hfi_device *dev); #endif diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 591ec02536..f7160dd742 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -115,6 +115,9 @@ static int __reset_control_release(struct iris_hfi_device *device, const char *n static bool __is_ctl_power_on(struct iris_hfi_device *device); +static void __print_sidebandmanager_regs(struct iris_hfi_device *device); +static void dump_noc_reg(struct iris_hfi_device *device); + static struct cvp_hal_ops hal_ops = { .interrupt_init = interrupt_init_iris2, .setup_dsp_uc_memmap = setup_dsp_uc_memmap_vpu5, @@ -1329,7 +1332,7 @@ static int iris_hfi_suspend(void *dev) return rc; } -static void cvp_dump_csr(struct iris_hfi_device *dev) +void cvp_dump_csr(struct iris_hfi_device *dev) { u32 reg; @@ -1355,6 +1358,9 @@ static void cvp_dump_csr(struct iris_hfi_device *dev) dprintk(CVP_ERR, "CVP_WRAPPER_CPU_CLOCK_CONFIG: %x\n", reg); reg = __read_register(dev, CVP_WRAPPER_CORE_CLOCK_CONFIG); dprintk(CVP_ERR, "CVP_WRAPPER_CORE_CLOCK_CONFIG: %x\n", reg); + + dump_noc_reg(dev); + dev->reg_dumped = true; } @@ -3632,6 +3638,7 @@ static void iris_hfi_wd_work_handler(struct work_struct *work) if (msm_cvp_hw_wd_recovery) { dprintk(CVP_ERR, "Cleaning up as HW WD recovery is enable %d\n", msm_cvp_hw_wd_recovery); + __print_sidebandmanager_regs(device); response.device_id = 0; handle_sys_error(cmd, (void *) &response); enable_irq(device->cvp_hal_data->irq_wd); @@ -4550,6 +4557,10 @@ static int __iris_power_on(struct iris_hfi_device *device) /*Do not access registers before this point!*/ device->power_enabled = true; + /* Thomas input to debug CPU NoC hang */ + __write_register(device, CVP_NOC_SBM_FAULTINEN0_LOW, 0x1); + __write_register(device, CVP_NOC_ERR_MAINCTL_LOW_OFFS, 0x3); + /* * Re-program all of the registers that get reset as a result of * regulator_disable() and _enable() @@ -4643,7 +4654,7 @@ err_tzbsp_suspend: static void __print_sidebandmanager_regs(struct iris_hfi_device *device) { - u32 sbm_ln0_low, axi_cbcr; + u32 sbm_ln0_low, axi_cbcr, val; u32 main_sbm_ln0_low = 0xdeadbeef, main_sbm_ln0_high = 0xdeadbeef; u32 main_sbm_ln1_high = 0xdeadbeef, cpu_cs_x2rpmh; int rc; @@ -4671,6 +4682,39 @@ static void __print_sidebandmanager_regs(struct iris_hfi_device *device) goto exit; } + /* Added by Thomas to debug CPU NoC hang */ + val = __read_register(device, CVP_NOC_ERR_ERRVLD_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRVLD_LOW %#x\n", val); + + val = __read_register(device, CVP_NOC_SBM_FAULTINSTATUS0_LOW); + dprintk(CVP_ERR, "CVP_NOC_SBM_FAULTINSTATUS0_LOW %#x\n", val); + + val = __read_register(device, CVP_NOC_ERR_ERRLOG0_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG0_LOW %#x\n", val); + + val = __read_register(device, CVP_NOC_ERR_ERRLOG0_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG0_HIGH %#x\n", val); + + val = __read_register(device, CVP_NOC_ERR_ERRLOG1_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG1_LOW %#x\n", val); + + val = __read_register(device, CVP_NOC_ERR_ERRLOG1_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG1_HIGH %#x\n", val); + + val = __read_register(device, CVP_NOC_ERR_ERRLOG2_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG2_LOW %#x\n", val); + + val = __read_register(device, CVP_NOC_ERR_ERRLOG2_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG2_HIGH %#x\n", val); + + val = __read_register(device, CVP_NOC_ERR_ERRLOG3_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG3_LOW %#x\n", val); + + val = __read_register(device, CVP_NOC_ERR_ERRLOG3_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_ERL_MAIN_ERRLOG3_HIGH %#x\n", val); + + /* end of addition */ + rc = call_iris_op(device, reset_control_acquire_name, device, "cvp_xo_reset"); if (rc) { dprintk(CVP_WARN, "%s Fail acquire xo_reset\n", __func__); @@ -4696,10 +4740,50 @@ exit: cpu_cs_x2rpmh); } +static void __enter_cpu_noc_lpi(struct iris_hfi_device *device) +{ + u32 lpi_status, count = 0, max_count = 2000; + + /* New addition to put CPU/Tensilica to low power */ + count = 0; + __write_register(device, CVP_WRAPPER_CPU_NOC_LPI_CONTROL, 0x1); + while (count < max_count) { + lpi_status = __read_register(device, CVP_WRAPPER_CPU_NOC_LPI_STATUS); + if ((lpi_status & BIT(1)) || ((lpi_status & BIT(2)) && (!(lpi_status & BIT(0))))) { + /* + * If QDENY == true, or + * If QACTIVE == true && QACCEPT == false + * Try again + */ + __write_register(device, CVP_WRAPPER_CPU_NOC_LPI_CONTROL, 0x0); + usleep_range(10, 20); + __write_register(device, CVP_WRAPPER_CPU_NOC_LPI_CONTROL, 0x1); + usleep_range(1000, 1200); + count++; + } else { + break; + } + } + + dprintk(CVP_PWR, + "%s, CPU Noc: lpi_status %x (count %d)\n", __func__, lpi_status, count); + if (count == max_count) { + u32 pc_ready, wfi_status; + + wfi_status = __read_register(device, CVP_WRAPPER_CPU_STATUS); + pc_ready = __read_register(device, CVP_CTRL_STATUS); + + dprintk(CVP_WARN, + "%s, CPU NOC not in qaccept status %x %x %x\n", + __func__, lpi_status, wfi_status, pc_ready); + + __print_sidebandmanager_regs(device); + } +} + static int __power_off_controller(struct iris_hfi_device *device) { - u32 lpi_status, reg_status = 0, count = 0, max_count = 1000; - u32 sbm_ln0_low; + u32 lpi_status, count = 0, max_count = 1000; int rc; u32 spare_val, spare_status; @@ -4708,37 +4792,7 @@ static int __power_off_controller(struct iris_hfi_device *device) __write_register(device, CVP_CPU_CS_X2RPMh, 0x3); /* HPG 6.2.2 Step 2, noc to low power */ - - /* New addition to put CPU/Tensilica to low power */ - reg_status = 0; - count = 0; - __write_register(device, CVP_WRAPPER_CPU_NOC_LPI_CONTROL, 0x1); - while (!reg_status && count < max_count) { - lpi_status = - __read_register(device, - CVP_WRAPPER_CPU_NOC_LPI_STATUS); - reg_status = lpi_status & BIT(0); - /* Wait for CPU noc lpi status to be set */ - usleep_range(50, 100); - count++; - } - sbm_ln0_low = __read_register(device, CVP_NOC_SBM_SENSELN0_LOW); - dprintk(CVP_PWR, - "CPU Noc: lpi_status %x noc_status %x (count %d) 0x%x\n", - lpi_status, reg_status, count, sbm_ln0_low); - if (count == max_count) { - u32 pc_ready, wfi_status; - - wfi_status = __read_register(device, CVP_WRAPPER_CPU_STATUS); - pc_ready = __read_register(device, CVP_CTRL_STATUS); - - dprintk(CVP_WARN, - "CPU NOC not in qaccept status %x %x %x %x\n", - reg_status, lpi_status, wfi_status, pc_ready); - - __print_sidebandmanager_regs(device); - } - + __enter_cpu_noc_lpi(device); /* HPG 6.2.2 Step 3, debug bridge to low power BYPASSED */ @@ -5113,6 +5167,9 @@ static void __unload_fw(struct iris_hfi_device *device) if (device->state != IRIS_STATE_DEINIT) flush_workqueue(device->iris_pm_workq); + /* New addition to put CPU/Tensilica to low power */ + __enter_cpu_noc_lpi(device); + unload_cvp_fw_impl(device); __interface_queues_release(device); call_iris_op(device, power_off, device); @@ -5575,3 +5632,89 @@ err_iris_hfi_init: return rc; } +static void dump_noc_reg(struct iris_hfi_device *device) +{ + u32 val = 0, config; + int i; + struct regulator_info *rinfo; + int rc = 0; + + if (msm_cvp_fw_low_power_mode) { + iris_hfi_for_each_regulator(device, rinfo) { + if (strcmp(rinfo->name, "cvp-core")) + continue; + rc = __acquire_regulator(rinfo, device); + if (rc) + dprintk(CVP_WARN, + "%s, Failed to acquire regulator control: %s\n", + __func__, rinfo->name); + } + } + val = __read_register(device, CVP_CC_MVS1_GDSCR); + dprintk(CVP_ERR, "%s, CVP_CC_MVS1_GDSCR: 0x%x", __func__, val); + config = __read_register(device, CVP_WRAPPER_CORE_CLOCK_CONFIG); + dprintk(CVP_ERR, "%s, CVP_WRAPPER_CORE_CLOCK_CONFIG: 0x%x", __func__, config); + if (config) { + dprintk(CVP_PWR, + "core clock config not enabled, enable it to access core\n"); + __write_register(device, CVP_WRAPPER_CORE_CLOCK_CONFIG, 0); + } + i = call_iris_op(device, reset_control_acquire_name, device, "cvp_xo_reset"); + if (i) { + dprintk(CVP_WARN, "%s Fail acquire xo_reset\n", __func__); + return; + } + + val = __read_register(device, CVP_NOC_RGE_NIU_DECCTL_LOW); + dprintk(CVP_ERR, "CVP_NOC_RGE_NIU_DECCTL_LOW: 0x%x", val); + val = __read_register(device, CVP_NOC_RGE_NIU_ENCCTL_LOW); + dprintk(CVP_ERR, "CVP_NOC_RGE_NIU_ENCCTL_LOW: 0x%x", val); + val = __read_register(device, CVP_NOC_GCE_VADL_TOF_NIU_DECCTL_LOW); + dprintk(CVP_ERR, "CVP_NOC_GCE_VADL_TOF_NIU_DECCTL_LOW: 0x%x", val); + val = __read_register(device, CVP_NOC_GCE_VADL_TOF_NIU_ENCCTL_LOW); + dprintk(CVP_ERR, "CVP_NOC_GCE_VADL_TOF_NIU_ENCCTL_LOW: 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS: 0x%x", val); + val = __read_register(device, CVP_NOC_MAIN_SIDEBANDMANAGER_FAULTINEN0_LOW); + dprintk(CVP_ERR, "CVP_NOC_MAIN_SIDEBANDMANAGER_FAULTINEN0_LOW: 0x%x", val); + + dprintk(CVP_ERR, "Dumping Core NoC registers\n"); + val = __read_register(device, CVP_NOC_CORE_ERR_SWID_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC__CORE_ERL_MAIN_SWID_LOW: 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_SWID_HIGH_OFFS); + dprintk(CVP_ERR, "CVVP_NOC_CORE_ERL_MAIN_SWID_HIGH 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_MAINCTL_LOW 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRVLD_LOW 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRCLR_LOW 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_LOW 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_HIGH 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_LOW 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_HIGH 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_LOW 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_HIGH 0x%x", val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS); + dprintk(CVP_ERR, "CORE ERRLOG3_LOW 0x%x, below details", val); + __print_reg_details(val); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS); + dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG3_HIGH 0x%x", val); + __write_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS, 0x1); + + call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); + if (msm_cvp_fw_low_power_mode) { + iris_hfi_for_each_regulator(device, rinfo) { + if (strcmp(rinfo->name, "cvp-core")) + continue; + rc = __hand_off_regulator(rinfo); + } + } + __write_register(device, CVP_WRAPPER_CORE_CLOCK_CONFIG, config); +} diff --git a/msm/eva/cvp_hfi_io.h b/msm/eva/cvp_hfi_io.h index 5691c4ecf2..80957d055f 100644 --- a/msm/eva/cvp_hfi_io.h +++ b/msm/eva/cvp_hfi_io.h @@ -195,6 +195,8 @@ #define CVP_NOC_ERR_ERRLOG2_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0x34) #define CVP_NOC_ERR_ERRLOG3_LOW_OFFS (CVP_NOC_BASE_OFFS + 0x38) #define CVP_NOC_ERR_ERRLOG3_HIGH_OFFS (CVP_NOC_BASE_OFFS + 0x3C) +#define CVP_NOC_SBM_FAULTINEN0_LOW (CVP_NOC_BASE_OFFS + 0x240) +#define CVP_NOC_SBM_FAULTINSTATUS0_LOW (CVP_NOC_BASE_OFFS + 0x248) #define CVP_NOC_SBM_SENSELN0_LOW (CVP_NOC_BASE_OFFS + 0x300) #define CVP_NOC_CORE_BASE_OFFS 0x00010000 diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 5b2b624060..6439babfb6 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -308,6 +308,7 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, struct cvp_session_queue *sq; u32 hfi_err = HFI_ERR_NONE; struct cvp_hfi_msg_session_hdr_ext hdr; + struct iris_hfi_device *device; dprintk(CVP_SYNX, "%s %s\n", current->comm, __func__); @@ -354,6 +355,12 @@ static int cvp_fence_proc(struct msm_cvp_inst *inst, dprintk(CVP_INFO, "%s %s: cvp_wait_process_msg non-fatal %d\n", current->comm, __func__, hfi_err); synx_state = SYNX_STATE_SIGNALED_SUCCESS; + } else if (hfi_err == HFI_ERR_SESSION_HW_HANG_DETECTED) { + dprintk(CVP_ERR, "%s %s: cvp_wait_process_message hfi HW hang err %d\n", + current->comm, __func__, hfi_err); + synx_state = SYNX_STATE_SIGNALED_CANCEL; + device = ops_tbl->hfi_device_data; + cvp_dump_csr(device); } else if (hfi_err != HFI_ERR_NONE) { dprintk(CVP_ERR, "%s %s: cvp_wait_process_message hfi err %d\n", current->comm, __func__, hfi_err); diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 9a16e89b31..19eea69e87 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -542,6 +542,7 @@ static void handle_session_error(enum hal_command_response cmd, void *data) response->status, inst, hash32_ptr(inst->session)); cvp_print_inst(CVP_WARN, inst); + print_hfi_queue_info(ops_tbl); //if (inst->state != MSM_CVP_CORE_INVALID) { // change_cvp_inst_state(inst, MSM_CVP_CORE_INVALID); // if (cvp_clean_session_queues(inst)) From 6a1fbb254350e77700935e39399e5c177312f7bf Mon Sep 17 00:00:00 2001 From: Palak Joshi Date: Wed, 18 Oct 2023 15:32:59 +0530 Subject: [PATCH 285/317] msm: eva: Increasing wait time to acquire xo reset Waiting for 1sec to acquire xo reset else BUG_ON. Change-Id: I26bcc27d02b4104f36b1bcdac97cb784c1daca44 Signed-off-by: Palak Joshi --- msm/eva/cvp_hfi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index f7160dd742..e7d5a26b57 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -3782,7 +3782,7 @@ static int __reset_control_acquire(struct iris_hfi_device *device, struct reset_info *rcinfo = NULL; int rc = 0; bool found = false; - int max_retries = 10; + int max_retries = 1000; iris_hfi_for_each_reset_clock(device, rcinfo) { if (strcmp(rcinfo->name, name)) @@ -3794,15 +3794,15 @@ acquire_again: rc = reset_control_acquire(rcinfo->rst); if (rc) { if (rc == -EBUSY) { - usleep_range(500, 1000); + usleep_range(1000, 1500); max_retries--; if (max_retries) { goto acquire_again; } else { dprintk(CVP_ERR, "%s acquire %s -EBUSY\n", - __func__, rcinfo->name); - rc = -EINVAL; + __func__, rcinfo->name); + BUG_ON(1); } } else { dprintk(CVP_ERR, From c9a9b87bcb28080df8ead2374a10310cf91c1864 Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 10 Oct 2023 14:48:56 -0700 Subject: [PATCH 286/317] msm: eva: Revert to 80us before XO de-assert Revert back 200us sleep to 80us before XO de-assert. Change-Id: I8446aa2eb5cfac32fdc5fc971ddd37b999623bf8 Signed-off-by: George Shen --- msm/eva/cvp_hfi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index e7d5a26b57..6d4fb68ecf 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -4868,8 +4868,8 @@ static int __power_off_controller(struct iris_hfi_device *device) /* de-assert EVA_NoC reset */ __write_register(device, CVP_AON_WRAPPER_CVP_NOC_CORE_SW_RESET, 0x0); - /* de-assert EVA video_cc XO reset and enable video_cc XO clock after 125us */ - usleep_range(200, 300); + /* de-assert EVA video_cc XO reset and enable video_cc XO clock after 80us */ + usleep_range(80, 100); rc = call_iris_op(device, reset_control_deassert_name, device, "cvp_xo_reset"); if (rc) dprintk(CVP_ERR, "%s: de-assert cvp_xo_reset failed\n", __func__); From d94fadce9cb82268396584ab00e7ebb8a82e9434 Mon Sep 17 00:00:00 2001 From: Aniruddh Sharma Date: Fri, 3 Nov 2023 19:56:00 +0530 Subject: [PATCH 287/317] msm: eva: Acquire XO_RESET before GDSC access Acquire XO_RESET before turning on/off the controller/core gdscs. This is to enasure that XO_RESET can not be asserted by video while EVA is turning on/off the gdsc. Make sure to acquire XO_RESET before set operation on gdsc as well. Wait at least 90ms for acquiring the XO_RESET. Change-Id: I851297b1b6b48a903fbd5ce6d680e4d8727ebcc0 Signed-off-by: Aniruddh Sharma --- msm/eva/cvp_hfi.c | 57 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 54 insertions(+), 3 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 6d4fb68ecf..1a16f9260c 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -330,6 +330,15 @@ static int __acquire_regulator(struct regulator_info *rinfo, int rc = 0; if (rinfo->has_hw_power_collapse) { + /*Acquire XO_RESET to avoid race condition with video*/ + rc = call_iris_op(device, reset_control_acquire_name, device, "cvp_xo_reset"); + if (rc) { + dprintk(CVP_ERR, + "XO_RESET could not be acquired: skip acquiring the regulator %s from FW\n", + rinfo->name); + return -EINVAL; + } + rc = regulator_set_mode(rinfo->regulator, REGULATOR_MODE_NORMAL); if (rc) { @@ -348,6 +357,8 @@ static int __acquire_regulator(struct regulator_info *rinfo, rinfo->name); } + /*Release XO_RESET after regulator is enabled.*/ + call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); } if (!regulator_is_enabled(rinfo->regulator)) { @@ -359,13 +370,26 @@ static int __acquire_regulator(struct regulator_info *rinfo, return rc; } -static int __hand_off_regulator(struct regulator_info *rinfo) +static int __hand_off_regulator(struct iris_hfi_device *device, struct regulator_info *rinfo) { int rc = 0; if (rinfo->has_hw_power_collapse) { + /*Acquire XO_RESET to avoid race condition with video*/ + rc = call_iris_op(device, reset_control_acquire_name, device, "cvp_xo_reset"); + if (rc) { + dprintk(CVP_ERR, + "XO_RESET could not be acquired: skip hand off the regulator %s to FW\n", + rinfo->name); + return -EINVAL; + } + rc = regulator_set_mode(rinfo->regulator, REGULATOR_MODE_FAST); + + /*Release XO_RESET after regulator is enabled.*/ + call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); + if (rc) { dprintk(CVP_WARN, "Failed to hand off regulator control: %s\n", @@ -386,7 +410,7 @@ static int __hand_off_regulators(struct iris_hfi_device *device) int rc = 0, c = 0; iris_hfi_for_each_regulator(device, rinfo) { - rc = __hand_off_regulator(rinfo); + rc = __hand_off_regulator(device, rinfo); /* * If one regulator hand off failed, driver should take * the control for other regulators back. @@ -4099,7 +4123,20 @@ static int __disable_regulator_impl(struct regulator_info *rinfo, goto disable_regulator_failed; } + /*Acquire XO_RESET to avoid race condition with video*/ + rc = call_iris_op(device, reset_control_acquire_name, device, "cvp_xo_reset"); + if (rc) { + dprintk(CVP_ERR, + "XO_RESET could not be acquired: skip disabling the regulator %s\n", + rinfo->name); + return -EINVAL; + } + rc = regulator_disable(rinfo->regulator); + + /*Release XO_RESET after regulator is enabled.*/ + call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); + if (rc) { dprintk(CVP_WARN, "Failed to disable %s: %d\n", @@ -4158,7 +4195,21 @@ static int __enable_regulator(struct iris_hfi_device *device, iris_hfi_for_each_regulator(device, rinfo) { if (strcmp(rinfo->name, name)) continue; + + /*Acquire XO_RESET to avoid race condition with video*/ + rc = call_iris_op(device, reset_control_acquire_name, device, "cvp_xo_reset"); + if (rc) { + dprintk(CVP_ERR, + "XO_RESET could not be acquired: skip enabling the regulator %s\n", + rinfo->name); + return -EINVAL; + } + rc = regulator_enable(rinfo->regulator); + + /*Release XO_RESET after regulator is enabled.*/ + call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); + if (rc) { dprintk(CVP_ERR, "Failed to enable %s: %d\n", rinfo->name, rc); @@ -5713,7 +5764,7 @@ static void dump_noc_reg(struct iris_hfi_device *device) iris_hfi_for_each_regulator(device, rinfo) { if (strcmp(rinfo->name, "cvp-core")) continue; - rc = __hand_off_regulator(rinfo); + rc = __hand_off_regulator(device, rinfo); } } __write_register(device, CVP_WRAPPER_CORE_CLOCK_CONFIG, config); From 65550f09bbb41ba7784c75f4aeb8a93dde3b9ce7 Mon Sep 17 00:00:00 2001 From: Palak Joshi Date: Fri, 10 Nov 2023 12:47:32 +0530 Subject: [PATCH 288/317] msm: eva: Added required offset for NOC registers Added required offset for NOC registers while dumping. Change-Id: I77964a045cc15480ec27316318f6d39e31196225 Signed-off-by: Palak Joshi --- msm/eva/cvp_hfi.c | 60 +++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 20 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 1a16f9260c..863630f9f9 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -5716,48 +5716,68 @@ static void dump_noc_reg(struct iris_hfi_device *device) return; } - val = __read_register(device, CVP_NOC_RGE_NIU_DECCTL_LOW); + val = __read_register(device, CVP_NOC_RGE_NIU_DECCTL_LOW + + device->res->qos_noc_rge_niu_offset); dprintk(CVP_ERR, "CVP_NOC_RGE_NIU_DECCTL_LOW: 0x%x", val); - val = __read_register(device, CVP_NOC_RGE_NIU_ENCCTL_LOW); + val = __read_register(device, CVP_NOC_RGE_NIU_ENCCTL_LOW + + device->res->qos_noc_rge_niu_offset); dprintk(CVP_ERR, "CVP_NOC_RGE_NIU_ENCCTL_LOW: 0x%x", val); - val = __read_register(device, CVP_NOC_GCE_VADL_TOF_NIU_DECCTL_LOW); + val = __read_register(device, CVP_NOC_GCE_VADL_TOF_NIU_DECCTL_LOW + + device->res->qos_noc_gce_vadl_tof_niu_offset); dprintk(CVP_ERR, "CVP_NOC_GCE_VADL_TOF_NIU_DECCTL_LOW: 0x%x", val); - val = __read_register(device, CVP_NOC_GCE_VADL_TOF_NIU_ENCCTL_LOW); + val = __read_register(device, CVP_NOC_GCE_VADL_TOF_NIU_ENCCTL_LOW + + device->res->qos_noc_gce_vadl_tof_niu_offset); dprintk(CVP_ERR, "CVP_NOC_GCE_VADL_TOF_NIU_ENCCTL_LOW: 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS: 0x%x", val); - val = __read_register(device, CVP_NOC_MAIN_SIDEBANDMANAGER_FAULTINEN0_LOW); + val = __read_register(device, CVP_NOC_MAIN_SIDEBANDMANAGER_FAULTINEN0_LOW + + device->res->noc_main_sidebandmanager_offset); dprintk(CVP_ERR, "CVP_NOC_MAIN_SIDEBANDMANAGER_FAULTINEN0_LOW: 0x%x", val); dprintk(CVP_ERR, "Dumping Core NoC registers\n"); - val = __read_register(device, CVP_NOC_CORE_ERR_SWID_LOW_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_SWID_LOW_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC__CORE_ERL_MAIN_SWID_LOW: 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_SWID_HIGH_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_SWID_HIGH_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVVP_NOC_CORE_ERL_MAIN_SWID_HIGH 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_MAINCTL_LOW_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_MAINCTL_LOW 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRVLD_LOW_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRVLD_LOW 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRCLR_LOW 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_LOW_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_LOW 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG0_HIGH_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG0_HIGH 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_LOW_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_LOW 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG1_HIGH_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG1_HIGH 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_LOW_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_LOW 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG2_HIGH_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG2_HIGH 0x%x", val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_LOW_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CORE ERRLOG3_LOW 0x%x, below details", val); __print_reg_details(val); - val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS); + val = __read_register(device, CVP_NOC_CORE_ERR_ERRLOG3_HIGH_OFFS + + device->res->noc_core_err_offset); dprintk(CVP_ERR, "CVP_NOC_CORE_ERL_MAIN_ERRLOG3_HIGH 0x%x", val); - __write_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS, 0x1); + __write_register(device, CVP_NOC_CORE_ERR_ERRCLR_LOW_OFFS + + device->res->noc_core_err_offset, 0x1); call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); if (msm_cvp_fw_low_power_mode) { From b32d3554440f8a082ac5fd44dae23453b1035bc5 Mon Sep 17 00:00:00 2001 From: Gopireddy Arunteja Reddy Date: Thu, 23 Nov 2023 17:23:19 +0530 Subject: [PATCH 289/317] msm: eva: Releasing DSP buffers based on ref count Added fixes to release DSP buffers only if the ref count is zero and checking the fd is also matching or not while freeing the DSP buffers. Change-Id: I8d3475a0c50c7240142420d02a0444f718f883c2 Signed-off-by: Gopireddy Arunteja Reddy --- msm/eva/msm_cvp_buf.c | 7 ++++--- msm/eva/msm_cvp_core.c | 1 + msm/eva/msm_cvp_dsp.c | 12 +++++++----- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 52629ca743..bb198384fc 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -2392,9 +2392,10 @@ int cvp_release_dsp_buffers(struct msm_cvp_inst *inst, "%s: %x : fd %x %s size %d", __func__, hash32_ptr(inst->session), buf->fd, smem->dma_buf->name, buf->size); - atomic_dec(&smem->refcount); - msm_cvp_smem_free(smem); - cvp_kmem_cache_free(&cvp_driver->smem_cache, smem); + if (atomic_dec_and_test(&smem->refcount)) { + msm_cvp_smem_free(smem); + cvp_kmem_cache_free(&cvp_driver->smem_cache, smem); + } } else { dprintk(CVP_ERR, "%s: wrong owner %d %x : fd %x %s size %d", diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 31321b9a99..74d03c21a4 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -453,6 +453,7 @@ int msm_cvp_destroy(struct msm_cvp_inst *inst) core->smem_leak_count += atomic_read(&inst->smem_count); } kfree(inst); + inst = NULL; dprintk(CVP_SESS, "sys-stat: nr_insts %d msgs %d, frames %d, bufs %d, smems %d\n", atomic_read(&nr_insts), diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index c41b541c24..8876e4a382 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1485,9 +1485,9 @@ void __dsp_cvp_sess_create(struct cvp_dsp_cmd_msg *cmd) inst->task = task; dprintk(CVP_DSP, - "%s CREATE_SESS id 0x%x, cpu_low 0x%x, cpu_high 0x%x\n", + "%s CREATE_SESS id 0x%x, cpu_low 0x%x, cpu_high 0x%x, inst %pK, inst->session %pK\n", __func__, cmd->session_id, cmd->session_cpu_low, - cmd->session_cpu_high); + cmd->session_cpu_high, inst, inst->session); spin_lock(&inst->core->resources.pm_qos.lock); inst->core->resources.pm_qos.off_vote_cnt++; @@ -1811,8 +1811,9 @@ void __dsp_cvp_mem_alloc(struct cvp_dsp_cmd_msg *cmd) cmd->sbuf.iova = buf->smem->device_addr; cmd->sbuf.v_dsp_addr = v_dsp_addr; dprintk(CVP_DSP, "%s: size %d, iova 0x%x, v_dsp_addr 0x%llx\n", - __func__, cmd->sbuf.size, cmd->sbuf.iova, - cmd->sbuf.v_dsp_addr); + __func__, cmd->sbuf.size, cmd->sbuf.iova, cmd->sbuf.v_dsp_addr); + dprintk(CVP_DSP, "%s: DSP2CPU_session_id 0x%x, smem_fd 0x%x, smem_refcount %d\n", + __func__, dsp2cpu_cmd->session_id, buf->smem->fd, buf->smem->refcount); cvp_put_fastrpc_node(frpc_node); return; @@ -1883,7 +1884,8 @@ void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) } /* Verify with device addr */ - if (buf->smem->device_addr == dsp2cpu_cmd->sbuf.iova) { + if ((buf->smem->device_addr == dsp2cpu_cmd->sbuf.iova) && + (buf->fd == dsp2cpu_cmd->sbuf.fd)) { dprintk(CVP_DSP, "%s find device addr 0x%x\n", __func__, buf->smem->device_addr); dprintk(CVP_DSP, "fd in list 0x%x, fd from dsp 0x%x\n", From d5fa449f167e6a231ca0838331d4321f61a94031 Mon Sep 17 00:00:00 2001 From: Palak Joshi Date: Sat, 25 Nov 2023 19:40:35 +0530 Subject: [PATCH 290/317] msm: eva: Acquire XO_RESET before accessing INTR_STATUS register Acquire XO_RESET before accessing INTER_STATUS and H2ASOFTINT. Reducing sleep time to acquire XO_RESET. Change-Id: Iffbe5e8ec0ff920a31805b80f8a64a890776669f Signed-off-by: Palak Joshi --- msm/eva/cvp_hfi.c | 45 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 863630f9f9..cec6d9e967 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1368,10 +1368,10 @@ void cvp_dump_csr(struct iris_hfi_device *dev) dprintk(CVP_ERR, "CVP_WRAPPER_CPU_STATUS: %x\n", reg); reg = __read_register(dev, CVP_CPU_CS_SCIACMDARG0); dprintk(CVP_ERR, "CVP_CPU_CS_SCIACMDARG0: %x\n", reg); - reg = __read_register(dev, CVP_WRAPPER_INTR_STATUS); - dprintk(CVP_ERR, "CVP_WRAPPER_INTR_STATUS: %x\n", reg); - reg = __read_register(dev, CVP_CPU_CS_H2ASOFTINT); - dprintk(CVP_ERR, "CVP_CPU_CS_H2ASOFTINT: %x\n", reg); + //reg = __read_register(dev, CVP_WRAPPER_INTR_STATUS); + //dprintk(CVP_ERR, "CVP_WRAPPER_INTR_STATUS: %x\n", reg); + //reg = __read_register(dev, CVP_CPU_CS_H2ASOFTINT); + //dprintk(CVP_ERR, "CVP_CPU_CS_H2ASOFTINT: %x\n", reg); reg = __read_register(dev, CVP_CPU_CS_A2HSOFTINT); dprintk(CVP_ERR, "CVP_CPU_CS_A2HSOFTINT: %x\n", reg); reg = __read_register(dev, CVP_CC_MVS1C_GDSCR); @@ -1504,13 +1504,20 @@ static int __iface_cmdq_write(struct iris_hfi_device *device, void *pkt) { bool needs_interrupt = false; int rc = __iface_cmdq_write_relaxed(device, pkt, &needs_interrupt); + int i = 0; if (!rc && needs_interrupt) { /* Consumer of cmdq prefers that we raise an interrupt */ rc = 0; if (!__is_ctl_power_on(device)) dprintk(CVP_ERR, "%s power off, don't access reg\n", __func__); + i = call_iris_op(device, reset_control_acquire_name, device, "cvp_xo_reset"); + if (i) { + dprintk(CVP_WARN, "%s Fail acquire xo_reset at %d\n", __func__, __LINE__); + return -EINVAL; + } __write_register(device, CVP_CPU_CS_H2ASOFTINT, 1); + call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); } return rc; @@ -1521,6 +1528,7 @@ static int __iface_msgq_read(struct iris_hfi_device *device, void *pkt) u32 tx_req_is_set = 0; int rc = 0; struct cvp_iface_q_info *q_info; + int i = 0; if (!pkt) { dprintk(CVP_ERR, "Invalid Params\n"); @@ -1546,7 +1554,15 @@ static int __iface_msgq_read(struct iris_hfi_device *device, void *pkt) if (tx_req_is_set) { if (!__is_ctl_power_on(device)) dprintk(CVP_ERR, "%s power off, don't access reg\n", __func__); + i = call_iris_op(device, reset_control_acquire_name, device, + "cvp_xo_reset"); + if (i) { + dprintk(CVP_WARN, "%s Fail acquire xo_reset at %d\n", + __func__, __LINE__); + return -EINVAL; + } __write_register(device, CVP_CPU_CS_H2ASOFTINT, 1); + call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); } rc = 0; } else @@ -1561,6 +1577,7 @@ static int __iface_dbgq_read(struct iris_hfi_device *device, void *pkt) u32 tx_req_is_set = 0; int rc = 0; struct cvp_iface_q_info *q_info; + int i = 0; if (!pkt) { dprintk(CVP_ERR, "Invalid Params\n"); @@ -1580,7 +1597,15 @@ static int __iface_dbgq_read(struct iris_hfi_device *device, void *pkt) if (tx_req_is_set) { if (!__is_ctl_power_on(device)) dprintk(CVP_ERR, "%s power off, don't access reg\n", __func__); + i = call_iris_op(device, reset_control_acquire_name, device, + "cvp_xo_reset"); + if (i) { + dprintk(CVP_WARN, "%s Fail acquire xo_reset at %d\n", + __func__, __LINE__); + return -EINVAL; + } __write_register(device, CVP_CPU_CS_H2ASOFTINT, 1); + call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); } rc = 0; } else @@ -2513,13 +2538,21 @@ static int iris_hfi_core_release(void *dev) static void __core_clear_interrupt(struct iris_hfi_device *device) { u32 intr_status = 0, mask = 0; + int i = 0; if (!device) { dprintk(CVP_ERR, "%s: NULL device\n", __func__); return; } + i = call_iris_op(device, reset_control_acquire_name, device, "cvp_xo_reset"); + if (i) { + dprintk(CVP_WARN, "%s Fail acquire xo_reset at %d\n", __func__, __LINE__); + return; + } intr_status = __read_register(device, CVP_WRAPPER_INTR_STATUS); + call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); + mask = (CVP_WRAPPER_INTR_MASK_A2HCPU_BMSK | CVP_FATAL_INTR_BMSK); if (intr_status & mask) { @@ -3806,7 +3839,7 @@ static int __reset_control_acquire(struct iris_hfi_device *device, struct reset_info *rcinfo = NULL; int rc = 0; bool found = false; - int max_retries = 1000; + int max_retries = 10000; iris_hfi_for_each_reset_clock(device, rcinfo) { if (strcmp(rcinfo->name, name)) @@ -3818,7 +3851,7 @@ acquire_again: rc = reset_control_acquire(rcinfo->rst); if (rc) { if (rc == -EBUSY) { - usleep_range(1000, 1500); + usleep_range(100, 150); max_retries--; if (max_retries) { goto acquire_again; From 439638488c85ff1ee6354a7259683187ecb6b1d0 Mon Sep 17 00:00:00 2001 From: Palak Joshi Date: Wed, 22 Nov 2023 18:57:58 +0530 Subject: [PATCH 291/317] msm: eva: BUG_ON in case Tensillica noc is not in LPI If we are not getting QACCEPT from NOC LPI status for ~2s then will crash the target. No need to go further and unload the FW. Change-Id: I29b30ca2e4c0a98ce180df094bc8d12cf20735bf Signed-off-by: Palak Joshi --- msm/eva/cvp_hfi.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index cec6d9e967..4b46e4304a 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -4862,6 +4862,8 @@ static void __enter_cpu_noc_lpi(struct iris_hfi_device *device) __func__, lpi_status, wfi_status, pc_ready); __print_sidebandmanager_regs(device); + dprintk(CVP_ERR, "%s, crashing the target\n", __func__); + BUG_ON(1); } } From b8ec2ffd59bca0243c18d274e506c7d330ce0339 Mon Sep 17 00:00:00 2001 From: Pranay Varma Kopanati Date: Mon, 4 Dec 2023 19:50:30 +0530 Subject: [PATCH 292/317] msm: eva: Removing EVA compilation for volcano target Disabling EVA compilation. Change-Id: I2fb06bdda88bd8ee234f265f934055cdcf391a31 Signed-off-by: Pranay Varma Kopanati --- Android.mk | 4 +++- eva_kernel_board.mk | 4 +++- eva_kernel_product.mk | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Android.mk b/Android.mk index 41f3163d0f..0bad2821f0 100644 --- a/Android.mk +++ b/Android.mk @@ -4,7 +4,9 @@ ifneq ($(TARGET_USES_QMAA_OVERRIDE_CVP), true) ENABLE_EVA_KERNEL := false endif endif - +ifeq ($(call is-board-platform-in-list,volcano),true) +ENABLE_EVA_KERNEL := false +endif ifeq ($(ENABLE_EVA_KERNEL), true) ifneq ($(TARGET_BOARD_PLATFORM), qssi) ifeq ($(call is-board-platform-in-list, $(TARGET_BOARD_PLATFORM)),true) diff --git a/eva_kernel_board.mk b/eva_kernel_board.mk index 86dcf02f47..e9dc36caba 100644 --- a/eva_kernel_board.mk +++ b/eva_kernel_board.mk @@ -6,7 +6,9 @@ ifneq ($(TARGET_USES_QMAA_OVERRIDE_CVP), true) ENABLE_EVA_KERNEL := false endif endif - +ifeq ($(TARGET_BOARD_PLATFORM),volcano) +ENABLE_EVA_KERNEL := false +endif ifeq ($(ENABLE_EVA_KERNEL), true) ifneq ($(TARGET_BOARD_AUTO),true) ifeq ($(call is-board-platform-in-list,$(TARGET_BOARD_PLATFORM)),true) diff --git a/eva_kernel_product.mk b/eva_kernel_product.mk index 61b6e04681..1cdc231897 100644 --- a/eva_kernel_product.mk +++ b/eva_kernel_product.mk @@ -4,7 +4,9 @@ ifneq ($(TARGET_USES_QMAA_OVERRIDE_CVP), true) ENABLE_EVA_KERNEL := false endif endif - +ifeq ($(TARGET_BOARD_PLATFORM),volcano) +ENABLE_EVA_KERNEL := false +endif ifeq ($(ENABLE_EVA_KERNEL), true) PRODUCT_PACKAGES += msm-eva.ko endif From 4768eac7b07eafedfe8088f4d949ad1a908baa89 Mon Sep 17 00:00:00 2001 From: Aniruddh Sharma Date: Mon, 11 Dec 2023 17:52:36 +0530 Subject: [PATCH 293/317] msm: eva: Added the check for valid session pointer Checking if session pointer is 0xdeadbeef or not. Change-Id: I49a7675a9123b39d107f10a3666d9f9e31982259 Signed-off-by: Aniruddh Sharma --- msm/eva/cvp_hfi.c | 4 ++-- msm/eva/hfi_packetization.c | 3 ++- msm/eva/msm_cvp.c | 2 +- msm/eva/msm_cvp_common.c | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 4b46e4304a..85a5185690 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -2640,7 +2640,7 @@ static int iris_hfi_session_clean(void *session) struct cvp_hal_session *sess_close; struct iris_hfi_device *device; - if (!session) { + if (!session || session == (void *)0xdeadbeef) { dprintk(CVP_ERR, "Invalid Params %s\n", __func__); return -EINVAL; } @@ -2945,7 +2945,7 @@ static int iris_hfi_session_release_buffers(void *sess) struct cvp_hal_session *session = sess; struct iris_hfi_device *device; - if (!session || !session->device) { + if (!session || session == (void *)0xdeadbeef || !session->device) { dprintk(CVP_ERR, "Invalid Params\n"); return -EINVAL; } diff --git a/msm/eva/hfi_packetization.c b/msm/eva/hfi_packetization.c index bebacc315f..b119d1982c 100644 --- a/msm/eva/hfi_packetization.c +++ b/msm/eva/hfi_packetization.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include "hfi_packetization.h" @@ -325,7 +326,7 @@ int cvp_create_pkt_cmd_session_release_buffers( { struct cvp_session_release_buffers_packet *pkt; - if (!cmd || !session) + if (!cmd || !session || session == (void *)0xdeadbeef) return -EINVAL; pkt = (struct cvp_session_release_buffers_packet *)cmd; diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 64743a2d31..87b6de6c89 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -1626,7 +1626,7 @@ int msm_cvp_session_deinit(struct msm_cvp_inst *inst) inst, hash32_ptr(inst->session)); session = (struct cvp_hal_session *)inst->session; - if (!session) + if (!session || session == (void *)0xdeadbeef) return rc; rc = msm_cvp_comm_try_state(inst, MSM_CVP_CLOSE_DONE); diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 19eea69e87..00e1faeb39 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -653,7 +653,7 @@ void msm_cvp_comm_session_clean(struct msm_cvp_inst *inst) dprintk(CVP_ERR, "%s invalid params\n", __func__); return; } - if (!inst->session) { + if (!inst->session || inst->session == (void *)0xdeadbeef) { dprintk(CVP_SESS, "%s: inst %pK session already cleaned\n", __func__, inst); return; @@ -1299,7 +1299,7 @@ int msm_cvp_comm_kill_session(struct msm_cvp_inst *inst) if (!inst || !inst->core || !inst->core->dev_ops) { dprintk(CVP_ERR, "%s: invalid input parameters\n", __func__); return -EINVAL; - } else if (!inst->session) { + } else if (!inst->session || inst->session == (void *)0xdeadbeef) { dprintk(CVP_ERR, "%s: no session to kill for inst %pK\n", __func__, inst); return 0; From 43452023a2b209044ae18a1ffdf74de909dc2c56 Mon Sep 17 00:00:00 2001 From: George Shen Date: Tue, 5 Dec 2023 23:10:25 -0800 Subject: [PATCH 294/317] msm: eva: Use error checked property num When copying sys property set/read commands from user to kernel, the error checked property number could be re-written by user. It invalidated the earlier check and may cause out-of-boundary write. Change-Id: Ia219eb7f922aaef23741641fdc52d93f13a22278 Signed-off-by: George Shen --- msm/eva/msm_cvp_ioctl.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/msm/eva/msm_cvp_ioctl.c b/msm/eva/msm_cvp_ioctl.c index 437b4bc6cf..bddf1d60ca 100644 --- a/msm/eva/msm_cvp_ioctl.c +++ b/msm/eva/msm_cvp_ioctl.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -63,14 +64,14 @@ static int _get_fence_pkt_hdr_from_user(struct eva_kmd_arg __user *up, /* Size is in unit of u32 */ static int _copy_pkt_from_user(struct eva_kmd_arg *kp, struct eva_kmd_arg __user *up, - unsigned int size) + unsigned int start, unsigned int size) { struct eva_kmd_hfi_packet *k, *u; int i; k = &kp->data.hfi_pkt; u = &up->data.hfi_pkt; - for (i = 0; i < size; i++) + for (i = start; i < size; i++) if (get_user(k->pkt_data[i], &u->pkt_data[i])) return -EFAULT; @@ -164,13 +165,13 @@ static int _copy_sysprop_from_user(struct eva_kmd_arg *kp, if (get_user(k->prop_num, &u->prop_num)) return -EFAULT; - if (k->prop_num < 1 || k->prop_num > 32) { + if (k->prop_num < 1 || k->prop_num > MAX_KMD_PROP_NUM_PER_PACKET) { dprintk(CVP_ERR, "Num of prop out of range %d\n", k->prop_num); return -EFAULT; } - return _copy_pkt_from_user(kp, up, - (k->prop_num*((sizeof(struct eva_kmd_sys_property)>>2)+1))); + return _copy_pkt_from_user(kp, up, 1, + (k->prop_num * (sizeof(struct eva_kmd_sys_property) >> 2))); } static int _copy_pkt_to_user(struct eva_kmd_arg *kp, @@ -376,7 +377,7 @@ static int convert_from_user(struct eva_kmd_arg *kp, return -EFAULT; } - rc = _copy_pkt_from_user(kp, up, (pkt_hdr.size >> 2)); + rc = _copy_pkt_from_user(kp, up, 0, (pkt_hdr.size >> 2)); break; } case EVA_KMD_SEND_FENCE_CMD_PKT: From 0054914baaf2f0add868a28e9a2e8fbcfa020ca8 Mon Sep 17 00:00:00 2001 From: Palak Joshi Date: Sat, 25 Nov 2023 19:40:35 +0530 Subject: [PATCH 295/317] msm: eva: Acquire XO_RESET before accessing INTR_STATUS register Acquire XO_RESET before accessing INTER_STATUS and H2ASOFTINT. Reducing sleep time to acquire XO_RESET. Change-Id: Iffbe5e8ec0ff920a31805b80f8a64a890776669f Signed-off-by: Palak Joshi (cherry picked from commit d5fa449f167e6a231ca0838331d4321f61a94031) --- msm/eva/cvp_hfi.c | 45 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 863630f9f9..cec6d9e967 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1368,10 +1368,10 @@ void cvp_dump_csr(struct iris_hfi_device *dev) dprintk(CVP_ERR, "CVP_WRAPPER_CPU_STATUS: %x\n", reg); reg = __read_register(dev, CVP_CPU_CS_SCIACMDARG0); dprintk(CVP_ERR, "CVP_CPU_CS_SCIACMDARG0: %x\n", reg); - reg = __read_register(dev, CVP_WRAPPER_INTR_STATUS); - dprintk(CVP_ERR, "CVP_WRAPPER_INTR_STATUS: %x\n", reg); - reg = __read_register(dev, CVP_CPU_CS_H2ASOFTINT); - dprintk(CVP_ERR, "CVP_CPU_CS_H2ASOFTINT: %x\n", reg); + //reg = __read_register(dev, CVP_WRAPPER_INTR_STATUS); + //dprintk(CVP_ERR, "CVP_WRAPPER_INTR_STATUS: %x\n", reg); + //reg = __read_register(dev, CVP_CPU_CS_H2ASOFTINT); + //dprintk(CVP_ERR, "CVP_CPU_CS_H2ASOFTINT: %x\n", reg); reg = __read_register(dev, CVP_CPU_CS_A2HSOFTINT); dprintk(CVP_ERR, "CVP_CPU_CS_A2HSOFTINT: %x\n", reg); reg = __read_register(dev, CVP_CC_MVS1C_GDSCR); @@ -1504,13 +1504,20 @@ static int __iface_cmdq_write(struct iris_hfi_device *device, void *pkt) { bool needs_interrupt = false; int rc = __iface_cmdq_write_relaxed(device, pkt, &needs_interrupt); + int i = 0; if (!rc && needs_interrupt) { /* Consumer of cmdq prefers that we raise an interrupt */ rc = 0; if (!__is_ctl_power_on(device)) dprintk(CVP_ERR, "%s power off, don't access reg\n", __func__); + i = call_iris_op(device, reset_control_acquire_name, device, "cvp_xo_reset"); + if (i) { + dprintk(CVP_WARN, "%s Fail acquire xo_reset at %d\n", __func__, __LINE__); + return -EINVAL; + } __write_register(device, CVP_CPU_CS_H2ASOFTINT, 1); + call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); } return rc; @@ -1521,6 +1528,7 @@ static int __iface_msgq_read(struct iris_hfi_device *device, void *pkt) u32 tx_req_is_set = 0; int rc = 0; struct cvp_iface_q_info *q_info; + int i = 0; if (!pkt) { dprintk(CVP_ERR, "Invalid Params\n"); @@ -1546,7 +1554,15 @@ static int __iface_msgq_read(struct iris_hfi_device *device, void *pkt) if (tx_req_is_set) { if (!__is_ctl_power_on(device)) dprintk(CVP_ERR, "%s power off, don't access reg\n", __func__); + i = call_iris_op(device, reset_control_acquire_name, device, + "cvp_xo_reset"); + if (i) { + dprintk(CVP_WARN, "%s Fail acquire xo_reset at %d\n", + __func__, __LINE__); + return -EINVAL; + } __write_register(device, CVP_CPU_CS_H2ASOFTINT, 1); + call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); } rc = 0; } else @@ -1561,6 +1577,7 @@ static int __iface_dbgq_read(struct iris_hfi_device *device, void *pkt) u32 tx_req_is_set = 0; int rc = 0; struct cvp_iface_q_info *q_info; + int i = 0; if (!pkt) { dprintk(CVP_ERR, "Invalid Params\n"); @@ -1580,7 +1597,15 @@ static int __iface_dbgq_read(struct iris_hfi_device *device, void *pkt) if (tx_req_is_set) { if (!__is_ctl_power_on(device)) dprintk(CVP_ERR, "%s power off, don't access reg\n", __func__); + i = call_iris_op(device, reset_control_acquire_name, device, + "cvp_xo_reset"); + if (i) { + dprintk(CVP_WARN, "%s Fail acquire xo_reset at %d\n", + __func__, __LINE__); + return -EINVAL; + } __write_register(device, CVP_CPU_CS_H2ASOFTINT, 1); + call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); } rc = 0; } else @@ -2513,13 +2538,21 @@ static int iris_hfi_core_release(void *dev) static void __core_clear_interrupt(struct iris_hfi_device *device) { u32 intr_status = 0, mask = 0; + int i = 0; if (!device) { dprintk(CVP_ERR, "%s: NULL device\n", __func__); return; } + i = call_iris_op(device, reset_control_acquire_name, device, "cvp_xo_reset"); + if (i) { + dprintk(CVP_WARN, "%s Fail acquire xo_reset at %d\n", __func__, __LINE__); + return; + } intr_status = __read_register(device, CVP_WRAPPER_INTR_STATUS); + call_iris_op(device, reset_control_release_name, device, "cvp_xo_reset"); + mask = (CVP_WRAPPER_INTR_MASK_A2HCPU_BMSK | CVP_FATAL_INTR_BMSK); if (intr_status & mask) { @@ -3806,7 +3839,7 @@ static int __reset_control_acquire(struct iris_hfi_device *device, struct reset_info *rcinfo = NULL; int rc = 0; bool found = false; - int max_retries = 1000; + int max_retries = 10000; iris_hfi_for_each_reset_clock(device, rcinfo) { if (strcmp(rcinfo->name, name)) @@ -3818,7 +3851,7 @@ acquire_again: rc = reset_control_acquire(rcinfo->rst); if (rc) { if (rc == -EBUSY) { - usleep_range(1000, 1500); + usleep_range(100, 150); max_retries--; if (max_retries) { goto acquire_again; From ff164c8cbf5ca35156c37bff4a45c31f5ebf3f1d Mon Sep 17 00:00:00 2001 From: Aniruddh Sharma Date: Mon, 11 Dec 2023 17:52:36 +0530 Subject: [PATCH 296/317] msm: eva: Added the check for valid session pointer Checking if session pointer is 0xdeadbeef or not. Change-Id: I49a7675a9123b39d107f10a3666d9f9e31982259 Signed-off-by: Aniruddh Sharma (cherry picked from commit 4768eac7b07eafedfe8088f4d949ad1a908baa89) --- msm/eva/cvp_hfi.c | 4 ++-- msm/eva/hfi_packetization.c | 3 ++- msm/eva/msm_cvp.c | 2 +- msm/eva/msm_cvp_common.c | 4 ++-- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 863630f9f9..0ddce151d4 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -2607,7 +2607,7 @@ static int iris_hfi_session_clean(void *session) struct cvp_hal_session *sess_close; struct iris_hfi_device *device; - if (!session) { + if (!session || session == (void *)0xdeadbeef) { dprintk(CVP_ERR, "Invalid Params %s\n", __func__); return -EINVAL; } @@ -2912,7 +2912,7 @@ static int iris_hfi_session_release_buffers(void *sess) struct cvp_hal_session *session = sess; struct iris_hfi_device *device; - if (!session || !session->device) { + if (!session || session == (void *)0xdeadbeef || !session->device) { dprintk(CVP_ERR, "Invalid Params\n"); return -EINVAL; } diff --git a/msm/eva/hfi_packetization.c b/msm/eva/hfi_packetization.c index bebacc315f..b119d1982c 100644 --- a/msm/eva/hfi_packetization.c +++ b/msm/eva/hfi_packetization.c @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. */ #include "hfi_packetization.h" @@ -325,7 +326,7 @@ int cvp_create_pkt_cmd_session_release_buffers( { struct cvp_session_release_buffers_packet *pkt; - if (!cmd || !session) + if (!cmd || !session || session == (void *)0xdeadbeef) return -EINVAL; pkt = (struct cvp_session_release_buffers_packet *)cmd; diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 64743a2d31..87b6de6c89 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -1626,7 +1626,7 @@ int msm_cvp_session_deinit(struct msm_cvp_inst *inst) inst, hash32_ptr(inst->session)); session = (struct cvp_hal_session *)inst->session; - if (!session) + if (!session || session == (void *)0xdeadbeef) return rc; rc = msm_cvp_comm_try_state(inst, MSM_CVP_CLOSE_DONE); diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 19eea69e87..00e1faeb39 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -653,7 +653,7 @@ void msm_cvp_comm_session_clean(struct msm_cvp_inst *inst) dprintk(CVP_ERR, "%s invalid params\n", __func__); return; } - if (!inst->session) { + if (!inst->session || inst->session == (void *)0xdeadbeef) { dprintk(CVP_SESS, "%s: inst %pK session already cleaned\n", __func__, inst); return; @@ -1299,7 +1299,7 @@ int msm_cvp_comm_kill_session(struct msm_cvp_inst *inst) if (!inst || !inst->core || !inst->core->dev_ops) { dprintk(CVP_ERR, "%s: invalid input parameters\n", __func__); return -EINVAL; - } else if (!inst->session) { + } else if (!inst->session || inst->session == (void *)0xdeadbeef) { dprintk(CVP_ERR, "%s: no session to kill for inst %pK\n", __func__, inst); return 0; From b1164ed158209f169492023e768921356fc889be Mon Sep 17 00:00:00 2001 From: Aniruddh Sharma Date: Tue, 19 Dec 2023 12:31:58 +0530 Subject: [PATCH 297/317] msm: eva: Changing WARN to dprintk to avoid excessive loging WARN prints the callstack along with other module information. Because of more logs, IPI WDOG could not be handlled in time and lead to WDOG bark. Change-Id: I087be6e21287c0f232255c202789b752dcd7f0d5 Signed-off-by: Aniruddh Sharma --- msm/eva/msm_cvp_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 00e1faeb39..7782cb5eb9 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -196,7 +196,7 @@ struct msm_cvp_inst *cvp_get_inst_validate(struct msm_cvp_core *core, s = cvp_get_inst(core, session_id); if (!s) { - WARN(true, "%s session doesn't exit\n", __func__); + dprintk(CVP_WARN, "%s session doesn't exit\n", __func__); return NULL; } From b8005190c6ad533e26364ce5026992965824c2dd Mon Sep 17 00:00:00 2001 From: Gopireddy Arunteja Reddy Date: Thu, 4 Jan 2024 13:28:49 +0530 Subject: [PATCH 298/317] msm: eva: Removing the bug on from noc_lpi No need of BUG_ON when NOC is not in a QACCEPT state, removed that during power off controller in this change Change-Id: If68d61009e498f596c0e457976da17d2d3679e3b Signed-off-by: Gopireddy Arunteja Reddy --- msm/eva/cvp_hfi.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 85a5185690..a9164c0ed4 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -4862,8 +4862,6 @@ static void __enter_cpu_noc_lpi(struct iris_hfi_device *device) __func__, lpi_status, wfi_status, pc_ready); __print_sidebandmanager_regs(device); - dprintk(CVP_ERR, "%s, crashing the target\n", __func__); - BUG_ON(1); } } From 40c203ce8194498db8075f252ad0ef1e42fd23e8 Mon Sep 17 00:00:00 2001 From: Gopireddy Arunteja Reddy Date: Tue, 9 Jan 2024 14:59:36 +0530 Subject: [PATCH 299/317] msm: eva: Removing the bug on from noc_lpi No need of BUG_ON when NOC is not in a QACCEPT state, removed that during power off controller in this change. Change-Id: If68d61009e498f596c0e457976da17d2d3679e3b Signed-off-by: Gopireddy Arunteja Reddy --- msm/eva/cvp_hfi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 85a5185690..83ee08868a 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -4862,8 +4862,6 @@ static void __enter_cpu_noc_lpi(struct iris_hfi_device *device) __func__, lpi_status, wfi_status, pc_ready); __print_sidebandmanager_regs(device); - dprintk(CVP_ERR, "%s, crashing the target\n", __func__); - BUG_ON(1); } } From 0671810ca16820751715378a97ebc797dff18a89 Mon Sep 17 00:00:00 2001 From: Aniruddh Sharma Date: Wed, 27 Dec 2023 18:49:07 +0530 Subject: [PATCH 300/317] msm: eva: Fix for use after free Two threads may enter into race condition if the complete function is not protected by mutex lock. Change-Id: I1634ef203aa842eda2239a51f3f6bb1b90c43971 Signed-off-by: Aniruddh Sharma --- msm/eva/msm_cvp_buf.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index 0224742b3a..f3a7876d9e 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -652,14 +652,12 @@ int msm_cvp_unmap_buf_wncc(struct msm_cvp_inst *inst, NUM_WNCC_BUFS : inst->unused_wncc_bufs.nr; inst->unused_wncc_bufs.ktid = ++idx % NUM_WNCC_BUFS; } - mutex_unlock(&inst->cvpwnccbufs.lock); if (cbuf->smem->device_addr) { msm_cvp_unmap_smem(inst, cbuf->smem, "unmap wncc"); msm_cvp_smem_put_dma_buf(cbuf->smem->dma_buf); } - mutex_lock(&inst->cvpwnccbufs.lock); list_del(&cbuf->list); inst->cvpwnccbufs_table[buf_idx].fd = 0; inst->cvpwnccbufs_table[buf_idx].iova = 0; From 702fbcc6f1531a3ec1a2dcf986cae1fe4600f9d6 Mon Sep 17 00:00:00 2001 From: Gopireddy Arunteja Reddy Date: Fri, 12 Jan 2024 11:48:55 +0530 Subject: [PATCH 301/317] msm: eva: memset the cvp_dsp_cmd_msg structure to 0 memset cvp_dsp_cmd_msg structure to 0 after dsp thread wakes up by rpmsg callback. This avoids a corner case where hlos driver sends the previous cmd results even if current cmd fails. Change-Id: I672c4a2a1f0f0cb231fe9eebfc5f2ed86372cbe1 Signed-off-by: Aniruddh Sharma Signed-off-by: Gopireddy Arunteja Reddy --- msm/eva/msm_cvp_dsp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 8876e4a382..c5a605c117 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include #include @@ -2046,6 +2046,8 @@ wait_dsp: goto wait_dsp; } + /* Set the cmd to 0 to avoid sending previous session values in case the command fails*/ + memset(&cmd, 0, sizeof(struct cvp_dsp_cmd_msg)); cmd.type = me->pending_dsp2cpu_cmd.type; if (rc == -ERESTARTSYS) { From f18cfb94f1b2a72f64b618ddec72d1c88f77b957 Mon Sep 17 00:00:00 2001 From: Palak Joshi Date: Fri, 20 Oct 2023 10:11:12 +0530 Subject: [PATCH 302/317] msm: eva: Added required register dump in case of sys error Waiting for SYS_ERROR from FW. Change-Id: I3e25e2bdbe2d1464ef70e29298ea69567f07f340 Signed-off-by: Palak Joshi --- msm/eva/cvp_hfi.c | 19 ------------------- msm/eva/msm_cvp_common.c | 2 +- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 83ee08868a..30dbb33827 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -3496,29 +3496,11 @@ static int __response_handler(struct iris_hfi_device *device) } if (device->intr_status & CVP_FATAL_INTR_BMSK) { - struct cvp_hfi_sfr_struct *vsfr = (struct cvp_hfi_sfr_struct *) - device->sfr.align_virtual_addr; - struct msm_cvp_cb_info info = { - .response_type = HAL_SYS_WATCHDOG_TIMEOUT, - .response.cmd = { - .device_id = 0, - } - }; - - if (vsfr) - dprintk(CVP_ERR, "SFR Message from FW: %s\n", - vsfr->rg_data); if (device->intr_status & CVP_WRAPPER_INTR_MASK_CPU_NOC_BMSK) dprintk(CVP_ERR, "Received Xtensa NOC error\n"); if (device->intr_status & CVP_WRAPPER_INTR_MASK_CORE_NOC_BMSK) dprintk(CVP_ERR, "Received CVP core NOC error\n"); - - if (device->intr_status & CVP_WRAPPER_INTR_MASK_A2HWD_BMSK) - dprintk(CVP_ERR, "Received CVP watchdog timeout\n"); - - packets[packet_count++] = info; - goto exit; } /* Bleed the msg queue dry of packets */ @@ -3594,7 +3576,6 @@ static int __response_handler(struct iris_hfi_device *device) } } -exit: __flush_debug_queue(device, raw_packet); return packet_count; } diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 7782cb5eb9..05f5d64562 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -600,11 +600,11 @@ void handle_sys_error(enum hal_command_response cmd, void *data) core, cmd, core->ssr_count); mutex_lock(&core->clk_lock); hfi_device = ops_tbl->hfi_device_data; + call_hfi_op(ops_tbl, flush_debug_queue, ops_tbl->hfi_device_data); if (hfi_device->error == CVP_ERR_NOC_ERROR) { dprintk(CVP_WARN, "Got NOC error"); msm_cvp_noc_error_info(core); } - call_hfi_op(ops_tbl, flush_debug_queue, ops_tbl->hfi_device_data); list_for_each_entry(inst, &core->instances, list) { cvp_print_inst(CVP_WARN, inst); if (inst->state != MSM_CVP_CORE_INVALID) { From acbceeae6b804608904d472ad1575ab282151c82 Mon Sep 17 00:00:00 2001 From: Gopireddy Arunteja Reddy Date: Fri, 12 Jan 2024 11:48:55 +0530 Subject: [PATCH 303/317] msm: eva: memset the cvp_dsp_cmd_msg structure to 0 memset cvp_dsp_cmd_msg structure to 0 after dsp thread wakes up by rpmsg callback. This avoids a corner case where hlos driver sends the previous cmd results even if current cmd fails. Change-Id: I672c4a2a1f0f0cb231fe9eebfc5f2ed86372cbe1 Signed-off-by: Aniruddh Sharma Signed-off-by: Gopireddy Arunteja Reddy (cherry picked from commit 702fbcc6f1531a3ec1a2dcf986cae1fe4600f9d6) --- msm/eva/msm_cvp_dsp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index 8876e4a382..c5a605c117 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include #include @@ -2046,6 +2046,8 @@ wait_dsp: goto wait_dsp; } + /* Set the cmd to 0 to avoid sending previous session values in case the command fails*/ + memset(&cmd, 0, sizeof(struct cvp_dsp_cmd_msg)); cmd.type = me->pending_dsp2cpu_cmd.type; if (rc == -ERESTARTSYS) { From fdaf5495d3a6cc95fe505b80a8353d2df9125132 Mon Sep 17 00:00:00 2001 From: Palak Joshi Date: Fri, 20 Oct 2023 10:11:12 +0530 Subject: [PATCH 304/317] msm: eva: Added required register dump in case of sys error Waiting for SYS_ERROR from FW. Change-Id: I3e25e2bdbe2d1464ef70e29298ea69567f07f340 Signed-off-by: Palak Joshi (cherry picked from commit f18cfb94f1b2a72f64b618ddec72d1c88f77b957) --- msm/eva/cvp_hfi.c | 19 ------------------- msm/eva/msm_cvp_common.c | 2 +- 2 files changed, 1 insertion(+), 20 deletions(-) diff --git a/msm/eva/cvp_hfi.c b/msm/eva/cvp_hfi.c index 83ee08868a..30dbb33827 100644 --- a/msm/eva/cvp_hfi.c +++ b/msm/eva/cvp_hfi.c @@ -3496,29 +3496,11 @@ static int __response_handler(struct iris_hfi_device *device) } if (device->intr_status & CVP_FATAL_INTR_BMSK) { - struct cvp_hfi_sfr_struct *vsfr = (struct cvp_hfi_sfr_struct *) - device->sfr.align_virtual_addr; - struct msm_cvp_cb_info info = { - .response_type = HAL_SYS_WATCHDOG_TIMEOUT, - .response.cmd = { - .device_id = 0, - } - }; - - if (vsfr) - dprintk(CVP_ERR, "SFR Message from FW: %s\n", - vsfr->rg_data); if (device->intr_status & CVP_WRAPPER_INTR_MASK_CPU_NOC_BMSK) dprintk(CVP_ERR, "Received Xtensa NOC error\n"); if (device->intr_status & CVP_WRAPPER_INTR_MASK_CORE_NOC_BMSK) dprintk(CVP_ERR, "Received CVP core NOC error\n"); - - if (device->intr_status & CVP_WRAPPER_INTR_MASK_A2HWD_BMSK) - dprintk(CVP_ERR, "Received CVP watchdog timeout\n"); - - packets[packet_count++] = info; - goto exit; } /* Bleed the msg queue dry of packets */ @@ -3594,7 +3576,6 @@ static int __response_handler(struct iris_hfi_device *device) } } -exit: __flush_debug_queue(device, raw_packet); return packet_count; } diff --git a/msm/eva/msm_cvp_common.c b/msm/eva/msm_cvp_common.c index 7782cb5eb9..05f5d64562 100644 --- a/msm/eva/msm_cvp_common.c +++ b/msm/eva/msm_cvp_common.c @@ -600,11 +600,11 @@ void handle_sys_error(enum hal_command_response cmd, void *data) core, cmd, core->ssr_count); mutex_lock(&core->clk_lock); hfi_device = ops_tbl->hfi_device_data; + call_hfi_op(ops_tbl, flush_debug_queue, ops_tbl->hfi_device_data); if (hfi_device->error == CVP_ERR_NOC_ERROR) { dprintk(CVP_WARN, "Got NOC error"); msm_cvp_noc_error_info(core); } - call_hfi_op(ops_tbl, flush_debug_queue, ops_tbl->hfi_device_data); list_for_each_entry(inst, &core->instances, list) { cvp_print_inst(CVP_WARN, inst); if (inst->state != MSM_CVP_CORE_INVALID) { From 41a759aae2a770a29393b3a67fa0e31f8efe5865 Mon Sep 17 00:00:00 2001 From: Palak Joshi Date: Mon, 5 Feb 2024 11:37:15 +0530 Subject: [PATCH 305/317] msm: eva: Changing FW debug mask Removed default cachelog debug mask from FW debug mask. Change-Id: I98ff39ef09d46aca0596c9aafb20d9681bf6942d Signed-off-by: Palak Joshi --- msm/eva/msm_cvp_debug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 5eea8602ab..e00cd1635a 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -18,7 +18,7 @@ EXPORT_SYMBOL(msm_cvp_debug); int msm_cvp_debug_out = CVP_OUT_PRINTK; EXPORT_SYMBOL(msm_cvp_debug_out); -int msm_cvp_fw_debug = 0x10018; +int msm_cvp_fw_debug = 0x18; int msm_cvp_fw_debug_mode = 1; int msm_cvp_fw_low_power_mode = 1; bool msm_cvp_fw_coverage = !true; From 703e7c751c05f4a9406feedeec9096d02970488e Mon Sep 17 00:00:00 2001 From: Palak Joshi Date: Mon, 5 Feb 2024 11:37:15 +0530 Subject: [PATCH 306/317] msm: eva: Changing FW debug mask Removed default cachelog debug mask from FW debug mask. Change-Id: I98ff39ef09d46aca0596c9aafb20d9681bf6942d Signed-off-by: Palak Joshi (cherry picked from commit 41a759aae2a770a29393b3a67fa0e31f8efe5865) --- msm/eva/msm_cvp_debug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/eva/msm_cvp_debug.c b/msm/eva/msm_cvp_debug.c index 5eea8602ab..e00cd1635a 100644 --- a/msm/eva/msm_cvp_debug.c +++ b/msm/eva/msm_cvp_debug.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -18,7 +18,7 @@ EXPORT_SYMBOL(msm_cvp_debug); int msm_cvp_debug_out = CVP_OUT_PRINTK; EXPORT_SYMBOL(msm_cvp_debug_out); -int msm_cvp_fw_debug = 0x10018; +int msm_cvp_fw_debug = 0x18; int msm_cvp_fw_debug_mode = 1; int msm_cvp_fw_low_power_mode = 1; bool msm_cvp_fw_coverage = !true; From 86537770ec88769bc86671be16f64735ac88c9fc Mon Sep 17 00:00:00 2001 From: Jingyu Su Date: Mon, 12 Feb 2024 16:52:55 -0800 Subject: [PATCH 307/317] msm: eva: Fix _copy_pkt_from_user start # of words are omitted in sysprop Change-Id: Iddb83fc02658bda816c52b76d121a82ba2a87241 Signed-off-by: Jingyu Su --- msm/eva/msm_cvp_ioctl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/eva/msm_cvp_ioctl.c b/msm/eva/msm_cvp_ioctl.c index bddf1d60ca..75009fef52 100644 --- a/msm/eva/msm_cvp_ioctl.c +++ b/msm/eva/msm_cvp_ioctl.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -71,7 +71,7 @@ static int _copy_pkt_from_user(struct eva_kmd_arg *kp, k = &kp->data.hfi_pkt; u = &up->data.hfi_pkt; - for (i = start; i < size; i++) + for (i = start; i < start + size; i++) if (get_user(k->pkt_data[i], &u->pkt_data[i])) return -EFAULT; From 20bfba635c23c9a23106f59526421d9d3ba9faeb Mon Sep 17 00:00:00 2001 From: Aniruddh Sharma Date: Wed, 13 Dec 2023 10:22:58 +0530 Subject: [PATCH 308/317] msm: eva: Session queue state check before calling stop session To avoid calling stop session twice, we need to check the state before calling the stop session. Failing this will result in incorrect cmd sequence error(0x1026) from FW. Change-Id: I01c8325881952e5152799c62daebd622933667b2 Signed-off-by: Aniruddh Sharma --- msm/eva/msm_cvp.c | 30 +++++++++++++++++++++++++++--- msm/eva/msm_cvp_core.c | 17 ++++++++++++++++- msm/eva/msm_cvp_dsp.c | 27 +++++++++------------------ 3 files changed, 52 insertions(+), 22 deletions(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index 87b6de6c89..f30b6e929a 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -927,7 +927,8 @@ int msm_cvp_session_stop(struct msm_cvp_inst *inst, struct eva_kmd_session_control *sc = NULL; struct msm_cvp_inst *s; struct cvp_hfi_ops *ops_tbl; - int rc; + int rc = 0; + int curr_sq_state = -1; if (!inst || !inst->core) { dprintk(CVP_ERR, "%s: invalid params\n", __func__); @@ -942,8 +943,27 @@ int msm_cvp_session_stop(struct msm_cvp_inst *inst, return -ECONNRESET; sq = &inst->session_queue; + curr_sq_state = sq->state; spin_lock(&sq->lock); + if (sq->state != QUEUE_START) { + spin_unlock(&sq->lock); + dprintk(CVP_ERR, + "%s: Stop not allowed - curr state %d, inst %llx, sess %llx, %s type %d\n", + __func__, sq->state, inst, inst->session, inst->proc_name, + inst->session_type); + rc = -EINVAL; + return rc; + } + + if (sq->state == QUEUE_STOP) { + spin_unlock(&sq->lock); + dprintk(CVP_WARN, + "%s: Double stop session - inst %llx, sess %llx, %s of type %d\n", + __func__, inst, inst->session, inst->proc_name, inst->session_type); + return rc; + } + if (sq->msg_count) { dprintk(CVP_ERR, "session stop incorrect: queue not empty%d\n", sq->msg_count); @@ -965,6 +985,9 @@ int msm_cvp_session_stop(struct msm_cvp_inst *inst, if (rc) { dprintk(CVP_WARN, "%s: session stop failed rc %d\n", __func__, rc); + spin_lock(&sq->lock); + sq->state = curr_sq_state; + spin_unlock(&sq->lock); goto stop_thread; } @@ -973,6 +996,9 @@ int msm_cvp_session_stop(struct msm_cvp_inst *inst, if (rc) { dprintk(CVP_WARN, "%s: wait for signal failed, rc %d\n", __func__, rc); + spin_lock(&sq->lock); + sq->state = curr_sq_state; + spin_unlock(&sq->lock); goto stop_thread; } @@ -998,8 +1024,6 @@ int msm_cvp_session_queue_stop(struct msm_cvp_inst *inst) return 0; } - sq->state = QUEUE_STOP; - dprintk(CVP_SESS, "Stop session queue: %pK session_id = %#x\n", inst, hash32_ptr(inst->session)); spin_unlock(&sq->lock); diff --git a/msm/eva/msm_cvp_core.c b/msm/eva/msm_cvp_core.c index 74d03c21a4..5a8d3039d5 100644 --- a/msm/eva/msm_cvp_core.c +++ b/msm/eva/msm_cvp_core.c @@ -359,6 +359,16 @@ stop_session: __func__, inst); goto exit; } + spin_lock(&sq->lock); + if (sq->state == QUEUE_STOP) { + spin_unlock(&sq->lock); + dprintk(CVP_WARN, + "%s: Double stop session - inst %llx, sess %llx, %s of type %d\n", + __func__, inst, inst->session, inst->proc_name, inst->session_type); + goto release_arp; + } + spin_unlock(&sq->lock); + if (!empty) { /* STOP SESSION to avoid SMMU fault after releasing ARP */ ops_tbl = inst->core->dev_ops; @@ -371,9 +381,14 @@ stop_session: /*Fail stop session, release arp later may cause smmu fault*/ rc = wait_for_sess_signal_receipt(inst, HAL_SESSION_STOP_DONE); - if (rc) + if (rc) { dprintk(CVP_WARN, "%s: wait for sess_stop fail, rc %d\n", __func__, rc); + } else { + spin_lock(&sq->lock); + sq->state = QUEUE_STOP; + spin_unlock(&sq->lock); + } /* Continue to release ARP anyway */ } release_arp: diff --git a/msm/eva/msm_cvp_dsp.c b/msm/eva/msm_cvp_dsp.c index c5a605c117..a3300ca886 100644 --- a/msm/eva/msm_cvp_dsp.c +++ b/msm/eva/msm_cvp_dsp.c @@ -1846,11 +1846,12 @@ void __dsp_cvp_mem_free(struct cvp_dsp_cmd_msg *cmd) cmd->ret = 0; dprintk(CVP_DSP, - "%s sess id 0x%x, low 0x%x, high 0x%x, hnl 0x%x\n", + "%s sess 0x%x, low 0x%x, high 0x%x, hnl 0x%x, iova 0x%x, fd 0x%x\n", __func__, dsp2cpu_cmd->session_id, dsp2cpu_cmd->session_cpu_low, dsp2cpu_cmd->session_cpu_high, - dsp2cpu_cmd->pid); + dsp2cpu_cmd->pid, dsp2cpu_cmd->sbuf.iova, + dsp2cpu_cmd->sbuf.fd); inst = (struct msm_cvp_inst *)get_inst_from_dsp( dsp2cpu_cmd->session_cpu_high, @@ -1968,19 +1969,11 @@ void __dsp_cvp_sess_stop(struct cvp_dsp_cmd_msg *cmd) { struct cvp_dsp_apps *me = &gfa_cv; struct msm_cvp_inst *inst; - struct cvp_session_queue *sq; int rc; struct cvp_dsp2cpu_cmd *dsp2cpu_cmd = &me->pending_dsp2cpu_cmd; cmd->ret = 0; - dprintk(CVP_DSP, - "%s sess id 0x%x, low 0x%x, high 0x%x, pid 0x%x\n", - __func__, dsp2cpu_cmd->session_id, - dsp2cpu_cmd->session_cpu_low, - dsp2cpu_cmd->session_cpu_high, - dsp2cpu_cmd->pid); - inst = (struct msm_cvp_inst *)get_inst_from_dsp( dsp2cpu_cmd->session_cpu_high, dsp2cpu_cmd->session_cpu_low); @@ -1991,14 +1984,12 @@ void __dsp_cvp_sess_stop(struct cvp_dsp_cmd_msg *cmd) return; } - sq = &inst->session_queue; - spin_lock(&sq->lock); - if (sq->state == QUEUE_STOP) { - spin_unlock(&sq->lock); - dprintk(CVP_WARN, "DSP double stopped session %llx\n", inst); - return; - } - spin_unlock(&sq->lock); + dprintk(CVP_DSP, + "%s sess id 0x%x low 0x%x high 0x%x, pid 0x%x, inst_kref_refcount 0x%x\n", + __func__, dsp2cpu_cmd->session_id, + dsp2cpu_cmd->session_cpu_low, + dsp2cpu_cmd->session_cpu_high, + dsp2cpu_cmd->pid, kref_read(&inst->kref)); rc = msm_cvp_session_stop(inst, (struct eva_kmd_arg *)NULL); if (rc) { From 5d54dbf3f5071daecf9998282d78252d86fc2dfb Mon Sep 17 00:00:00 2001 From: Gopireddy Arunteja Reddy Date: Wed, 21 Feb 2024 20:13:37 +0530 Subject: [PATCH 309/317] msm: eva: debug change to print the dbuf Printing attach and dbuf, to check if the same IOVA is being allocated again or not. Printing debug info while calling dma_buf_unmap_attachment. Change-Id: Iae4eeb0393ca93496cc5feb6216e2d1da5212ed9 Signed-off-by: Gopireddy Arunteja Reddy --- msm/eva/cvp_smem.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/msm/eva/cvp_smem.c b/msm/eva/cvp_smem.c index 30d415a796..c398db56cf 100644 --- a/msm/eva/cvp_smem.c +++ b/msm/eva/cvp_smem.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -88,6 +88,8 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, u32 align, dprintk(CVP_ERR, "Failed to attach dmabuf\n"); goto mem_buf_attach_failed; } + dprintk(CVP_MEM, "%s: CB dev: %s, attach dev: %s, attach: 0x%lx, dbuf: 0x%lx", + __func__, dev_name(cb->dev), dev_name(attach->dev), attach, dbuf); /* * Get the scatterlist for the given attachment @@ -130,6 +132,9 @@ static int msm_dma_get_device_address(struct dma_buf *dbuf, u32 align, mapping_info->attach = attach; mapping_info->buf = dbuf; mapping_info->cb_info = (void *)cb; + + dprintk(CVP_MEM, "%s: sg-table: 0x%lx, dbuf: 0x%lx, table->sgl->dma_address: 0x%lx", + __func__, table, dbuf, table->sgl->dma_address); } else { dprintk(CVP_MEM, "iommu not present, use phys mem addr\n"); } @@ -148,6 +153,10 @@ static int msm_dma_put_device_address(u32 flags, struct cvp_dma_mapping_info *mapping_info) { int rc = 0; + struct dma_buf_attachment *attach = NULL; + struct sg_table *table = NULL; + struct context_bank_info *cb = NULL; + struct dma_buf *dbuf = NULL; if (!mapping_info) { dprintk(CVP_WARN, "Invalid mapping_info\n"); @@ -161,6 +170,15 @@ static int msm_dma_put_device_address(u32 flags, return -EINVAL; } + attach = mapping_info->attach; + table = mapping_info->table; + cb = (struct context_bank_info *) mapping_info->cb_info; + dbuf = mapping_info->buf; + dprintk(CVP_MEM, "%s: CB dev_name: %s, attach dev_name: %s, attach: 0x%lx, dbuf: 0x%lx", + __func__, dev_name(cb->dev), dev_name(attach->dev), attach, dbuf); + dprintk(CVP_MEM, "%s: sg-table: 0x%lx, table->sgl->dma_address: 0x%lx", + __func__, table, dbuf, table->sgl->dma_address); + dma_buf_unmap_attachment(mapping_info->attach, mapping_info->table, DMA_BIDIRECTIONAL); dma_buf_detach(mapping_info->buf, mapping_info->attach); From edd1ef24688e296591db54fac0f81f2ff42c6071 Mon Sep 17 00:00:00 2001 From: Gopireddy Arunteja Reddy Date: Tue, 23 Apr 2024 19:43:53 +0530 Subject: [PATCH 310/317] msm: eva: overflow issue in vm msq receiver function OOB write in VM message Q receiver function. Change-Id: I99d8b5f792c10cfb05387520e3e995f43d02ee29 Signed-off-by: Gopireddy Arunteja Reddy --- msm/eva/vm/cvp_vm_msgq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msm/eva/vm/cvp_vm_msgq.c b/msm/eva/vm/cvp_vm_msgq.c index 907b58cf4c..1671439bdd 100644 --- a/msm/eva/vm/cvp_vm_msgq.c +++ b/msm/eva/vm/cvp_vm_msgq.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only * * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -37,7 +38,7 @@ static int cvp_msgq_receiver(void *data) while (true) { rc = gh_msgq_recv(msgq_drv->config.handle, msg_ptr, - GH_MSGQ_MAX_MSG_SIZE_BYTES, &size, 0); + sizeof(*msg_ptr), &size, 0); if (rc != 0 ) { dprintk(CVP_ERR, From e1a1fe3d65bb91ebdf204360962b1d55d87929ef Mon Sep 17 00:00:00 2001 From: Gopireddy Arunteja Reddy Date: Tue, 23 Apr 2024 19:43:53 +0530 Subject: [PATCH 311/317] msm: eva: overflow issue in vm msq receiver function OOB write in VM message Q receiver function. Change-Id: I99d8b5f792c10cfb05387520e3e995f43d02ee29 Signed-off-by: Gopireddy Arunteja Reddy (cherry picked from commit edd1ef24688e296591db54fac0f81f2ff42c6071) --- msm/eva/vm/cvp_vm_msgq.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msm/eva/vm/cvp_vm_msgq.c b/msm/eva/vm/cvp_vm_msgq.c index 907b58cf4c..1671439bdd 100644 --- a/msm/eva/vm/cvp_vm_msgq.c +++ b/msm/eva/vm/cvp_vm_msgq.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only * * Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023-2024 Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -37,7 +38,7 @@ static int cvp_msgq_receiver(void *data) while (true) { rc = gh_msgq_recv(msgq_drv->config.handle, msg_ptr, - GH_MSGQ_MAX_MSG_SIZE_BYTES, &size, 0); + sizeof(*msg_ptr), &size, 0); if (rc != 0 ) { dprintk(CVP_ERR, From 3bc875b30c06fa6e3cadd8413ae4e4e24c28ff96 Mon Sep 17 00:00:00 2001 From: Palak Joshi Date: Fri, 17 May 2024 13:29:06 +0530 Subject: [PATCH 312/317] msm: eva: Added check for valid buffer offset Check total number of kernel fences if its in limit or not. Change-Id: Ibeaeca085bea9942dcab0fa2ad574c717d2cc104 Signed-off-by: Palak Joshi --- msm/eva/msm_cvp.c | 20 +++++++++++++++++++- msm/eva/msm_cvp_buf.c | 14 +++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index f30b6e929a..b4afdeaf29 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved. */ #include "msm_cvp.h" @@ -493,8 +493,18 @@ static int cvp_populate_fences( struct eva_kmd_hfi_packet *in_pkt, enum op_mode mode; struct cvp_buf_type *buf; bool override; + unsigned int total_fence_count = 0; int rc = 0; + cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; + if (!offset || !num) + return 0; + + if (offset < (sizeof(struct cvp_hfi_cmd_session_hdr)/sizeof(u32))) { + dprintk(CVP_ERR, "%s: Incorrect offset in cmd %d\n", __func__, offset); + rc = -EINVAL; + goto exit; + } override = get_pkt_fenceoverride((struct cvp_hal_session_cmd_pkt*)in_pkt); @@ -585,7 +595,15 @@ kernel_fence: f->num_fences++; buf->fence_type &= ~INPUT_FENCE_BITMASK; buf->input_handle = 0; + total_fence_count++; } + if (buf->output_handle) + total_fence_count++; + } + if (total_fence_count > MAX_HFI_FENCE_SIZE) { + dprintk(CVP_ERR, "Invalid total_fence_count %d\n", total_fence_count); + rc = -EINVAL; + goto free_exit; } f->output_index = f->num_fences; diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index f3a7876d9e..288b408904 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1,7 +1,7 @@ // 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. + * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -1781,6 +1781,10 @@ int msm_cvp_unmap_user_persist(struct msm_cvp_inst *inst, if (!offset || !buf_num) return 0; + if (offset < (sizeof(struct cvp_hfi_cmd_session_hdr)/sizeof(u32))) { + dprintk(CVP_ERR, "%s: Incorrect offset in cmd %d\n", __func__, offset); + return -EINVAL; + } cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; for (i = 0; i < buf_num; i++) { buf = (struct cvp_buf_type *)&in_pkt->pkt_data[offset]; @@ -1815,6 +1819,10 @@ int msm_cvp_map_user_persist(struct msm_cvp_inst *inst, if (!offset || !buf_num) return 0; + if (offset < (sizeof(struct cvp_hfi_cmd_session_hdr)/sizeof(u32))) { + dprintk(CVP_ERR, "%s: Incorrect offset in cmd %d\n", __func__, offset); + return -EINVAL; + } cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; for (i = 0; i < buf_num; i++) { buf = (struct cvp_buf_type *)&in_pkt->pkt_data[offset]; @@ -1857,6 +1865,10 @@ int msm_cvp_map_frame(struct msm_cvp_inst *inst, if (!offset || !buf_num) return 0; + if (offset < (sizeof(struct cvp_hfi_cmd_session_hdr)/sizeof(u32))) { + dprintk(CVP_ERR, "%s: Incorrect offset in cmd %d\n", __func__, offset); + return -EINVAL; + } cmd_hdr = (struct cvp_hfi_cmd_session_hdr *)in_pkt; ktid = atomic64_inc_return(&inst->core->kernel_trans_id); ktid &= (FENCE_BIT - 1); From 00a07388b1638319559aab80672d308d54cd59dc Mon Sep 17 00:00:00 2001 From: Gopireddy Arunteja Reddy Date: Fri, 10 May 2024 14:31:06 +0530 Subject: [PATCH 313/317] msm: eva: UAF issue in mapping wncc buffers Adding wncc buf only if the wncc buf count doesn't exceed the 'EVA_KMD_WNCC_MAX_SRC_BUFS'. Change-Id: I33a98868b90bd3819a47f533eb115543b19186ac Signed-off-by: Gopireddy Arunteja Reddy --- msm/eva/msm_cvp_buf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/eva/msm_cvp_buf.c b/msm/eva/msm_cvp_buf.c index f3a7876d9e..f494e662d9 100644 --- a/msm/eva/msm_cvp_buf.c +++ b/msm/eva/msm_cvp_buf.c @@ -1,7 +1,7 @@ // 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. + * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -536,11 +536,11 @@ int msm_cvp_map_buf_wncc(struct msm_cvp_inst *inst, } } - list_add_tail(&cbuf->list, &inst->cvpwnccbufs.list); for (i = 0; i < EVA_KMD_WNCC_MAX_SRC_BUFS; i++) { if (inst->cvpwnccbufs_table[i].iova == 0) { + list_add_tail(&cbuf->list, &inst->cvpwnccbufs.list); inst->cvpwnccbufs_num++; inst->cvpwnccbufs_table[i].fd = buf->fd; inst->cvpwnccbufs_table[i].iova = smem->device_addr; From 9be225ebfdbcee6553f5b727266081416ae5930f Mon Sep 17 00:00:00 2001 From: Gopireddy Arunteja Reddy Date: Fri, 10 May 2024 13:00:52 +0530 Subject: [PATCH 314/317] msm: eva: Resource leak in get_sys_prop Calling dma_buf_put to decrement the f_count in error scenario. Change-Id: I9c9db10bad46b38330c9221f57457ddd6a80c029 Signed-off-by: Gopireddy Arunteja Reddy --- msm/eva/msm_cvp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/msm/eva/msm_cvp.c b/msm/eva/msm_cvp.c index f30b6e929a..d2bb3c98de 100644 --- a/msm/eva/msm_cvp.c +++ b/msm/eva/msm_cvp.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved. */ #include "msm_cvp.h" @@ -1119,6 +1119,7 @@ static int msm_cvp_get_sysprop(struct msm_cvp_inst *inst, rc = dma_buf_fd(hfi->sfr.mem_data.dma_buf, O_RDONLY | O_CLOEXEC); if (rc < 0) { dprintk(CVP_WARN, "Failed get dma_buf fd %d\n", rc); + dma_buf_put(hfi->sfr.mem_data.dma_buf); break; } From 12119c6299de371dd71afce0aa4860fe52d80281 Mon Sep 17 00:00:00 2001 From: Gopireddy Arunteja Reddy Date: Sun, 26 May 2024 23:13:07 +0530 Subject: [PATCH 315/317] msm: eva: OOB write fix due to integer underflow If FW send a pkt->size which is less than the sizeof packet structure then pkt->size - sizeof() would result into an integer underflow. Due to this the subsequent check would be by passed and we will start write to an OOB memory. Change-Id: I8d33602a707a4bab07c5db53abe252bd480bfb84 Signed-off-by: Gopireddy Arunteja Reddy --- msm/eva/hfi_response_handler.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/msm/eva/hfi_response_handler.c b/msm/eva/hfi_response_handler.c index 0cb9559f63..89f7b2b68d 100644 --- a/msm/eva/hfi_response_handler.c +++ b/msm/eva/hfi_response_handler.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -624,7 +624,7 @@ static void hfi_process_sys_get_prop_image_version( int req_bytes; req_bytes = pkt->size - sizeof(*pkt); - if (req_bytes < version_string_size || + if (req_bytes < (signed int)version_string_size || !pkt->rg_property_data[1] || pkt->num_properties > 1) { dprintk(CVP_ERR, "%s: bad_pkt: %d\n", __func__, req_bytes); From 9ab52a824ab6738c19d15b85bfb86f23daf40312 Mon Sep 17 00:00:00 2001 From: Pranay Varma Kopanati Date: Sun, 12 May 2024 14:41:32 +0530 Subject: [PATCH 316/317] msm: eva: Adding kref count for cvp_get_inst_from_id Adding count for instance Change-Id: I1de6e3d4371f1b473907390afafa11e41806671b Signed-off-by: Pranay Varma Kopanati --- msm/eva/hfi_response_handler.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/msm/eva/hfi_response_handler.c b/msm/eva/hfi_response_handler.c index 0cb9559f63..f5d153e238 100644 --- a/msm/eva/hfi_response_handler.c +++ b/msm/eva/hfi_response_handler.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -487,7 +487,7 @@ retry: } } - inst = match ? inst : NULL; + inst = match && kref_get_unless_zero(&inst->kref) ? inst : NULL; mutex_unlock(&core->lock); } else { if (core->state == CVP_CORE_UNINIT) @@ -546,6 +546,7 @@ static int hfi_process_session_dump_notify(u32 device_id, info->response_type = HAL_SESSION_DUMP_NOTIFY; info->response.cmd = cmd_done; + cvp_put_inst(inst); return 0; } @@ -584,7 +585,7 @@ static int hfi_process_session_cvp_msg(u32 device_id, sess_msg = cvp_kmem_cache_zalloc(&cvp_driver->msg_cache, GFP_KERNEL); if (sess_msg == NULL) { dprintk(CVP_ERR, "%s runs out msg cache memory\n", __func__); - return -ENOMEM; + goto error_no_mem; } memcpy(&sess_msg->pkt, pkt, get_msg_size(pkt)); @@ -607,11 +608,14 @@ static int hfi_process_session_cvp_msg(u32 device_id, info->response_type = HAL_NO_RESP; + cvp_put_inst(inst); return 0; error_handle_msg: spin_unlock(&sq->lock); cvp_kmem_cache_free(&cvp_driver->msg_cache, sess_msg); +error_no_mem: + cvp_put_inst(inst); return -ENOMEM; } From 0c67e39df2d53970e515f0203f65cc59ba5722c8 Mon Sep 17 00:00:00 2001 From: Pranay Varma Kopanati Date: Sun, 12 May 2024 14:41:32 +0530 Subject: [PATCH 317/317] msm: eva: Adding kref count for cvp_get_inst_from_id Adding count for instance Change-Id: I1de6e3d4371f1b473907390afafa11e41806671b Signed-off-by: Pranay Varma Kopanati --- msm/eva/hfi_response_handler.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/msm/eva/hfi_response_handler.c b/msm/eva/hfi_response_handler.c index 0cb9559f63..f5d153e238 100644 --- a/msm/eva/hfi_response_handler.c +++ b/msm/eva/hfi_response_handler.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2018-2021, The Linux Foundation. All rights reserved. - * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2023-2024, Qualcomm Innovation Center, Inc. All rights reserved. */ #include @@ -487,7 +487,7 @@ retry: } } - inst = match ? inst : NULL; + inst = match && kref_get_unless_zero(&inst->kref) ? inst : NULL; mutex_unlock(&core->lock); } else { if (core->state == CVP_CORE_UNINIT) @@ -546,6 +546,7 @@ static int hfi_process_session_dump_notify(u32 device_id, info->response_type = HAL_SESSION_DUMP_NOTIFY; info->response.cmd = cmd_done; + cvp_put_inst(inst); return 0; } @@ -584,7 +585,7 @@ static int hfi_process_session_cvp_msg(u32 device_id, sess_msg = cvp_kmem_cache_zalloc(&cvp_driver->msg_cache, GFP_KERNEL); if (sess_msg == NULL) { dprintk(CVP_ERR, "%s runs out msg cache memory\n", __func__); - return -ENOMEM; + goto error_no_mem; } memcpy(&sess_msg->pkt, pkt, get_msg_size(pkt)); @@ -607,11 +608,14 @@ static int hfi_process_session_cvp_msg(u32 device_id, info->response_type = HAL_NO_RESP; + cvp_put_inst(inst); return 0; error_handle_msg: spin_unlock(&sq->lock); cvp_kmem_cache_free(&cvp_driver->msg_cache, sess_msg); +error_no_mem: + cvp_put_inst(inst); return -ENOMEM; }