Loading drivers/media/platform/msm/cvp/Makefile +2 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ msm-cvp-objs := cvp.o \ msm_cvp_clocks.o \ msm_cvp_dsp.o \ msm_cvp_buf.o \ msm_cvp_synx.o msm_cvp_synx.o \ cvp_fw_load.o obj-$(CONFIG_MSM_CVP) := msm-cvp.o drivers/media/platform/msm/cvp/cvp_core_hfi.h +2 −0 Original line number Diff line number Diff line Loading @@ -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 drivers/media/platform/msm/cvp/cvp_fw_load.c 0 → 100644 +166 −0 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2020, The Linux Foundation. All rights reserved. */ #include <linux/of.h> #include <linux/pm_qos.h> #include <linux/platform_device.h> #include <linux/qcom_scm.h> #include "msm_cvp_debug.h" #include "cvp_comm_def.h" #include "cvp_core_hfi.h" #include "cvp_hfi.h" #ifdef CVP_MDT_ENABLED #include <linux/of_address.h> #include <linux/firmware.h> #include <linux/soc/qcom/mdt_loader.h> #else #include <soc/qcom/subsystem_restart.h> #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; } drivers/media/platform/msm/cvp/cvp_hfi.c +4 −29 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ #include <linux/soc/qcom/llcc-qcom.h> #include <linux/qcom_scm.h> #include <linux/soc/qcom/smem.h> #include <soc/qcom/subsystem_restart.h> #include <linux/dma-mapping.h> #include <linux/reset.h> #include "hfi_packetization.h" Loading Loading @@ -3623,11 +3622,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) { Loading Loading @@ -4305,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: Loading @@ -4348,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"); Loading drivers/media/platform/msm/cvp/cvp_hfi.h +5 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #include <media/msm_media_info.h> #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 + \ Loading Loading @@ -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, Loading Loading
drivers/media/platform/msm/cvp/Makefile +2 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ msm-cvp-objs := cvp.o \ msm_cvp_clocks.o \ msm_cvp_dsp.o \ msm_cvp_buf.o \ msm_cvp_synx.o msm_cvp_synx.o \ cvp_fw_load.o obj-$(CONFIG_MSM_CVP) := msm-cvp.o
drivers/media/platform/msm/cvp/cvp_core_hfi.h +2 −0 Original line number Diff line number Diff line Loading @@ -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
drivers/media/platform/msm/cvp/cvp_fw_load.c 0 → 100644 +166 −0 Original line number Diff line number Diff line // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2020, The Linux Foundation. All rights reserved. */ #include <linux/of.h> #include <linux/pm_qos.h> #include <linux/platform_device.h> #include <linux/qcom_scm.h> #include "msm_cvp_debug.h" #include "cvp_comm_def.h" #include "cvp_core_hfi.h" #include "cvp_hfi.h" #ifdef CVP_MDT_ENABLED #include <linux/of_address.h> #include <linux/firmware.h> #include <linux/soc/qcom/mdt_loader.h> #else #include <soc/qcom/subsystem_restart.h> #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; }
drivers/media/platform/msm/cvp/cvp_hfi.c +4 −29 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ #include <linux/soc/qcom/llcc-qcom.h> #include <linux/qcom_scm.h> #include <linux/soc/qcom/smem.h> #include <soc/qcom/subsystem_restart.h> #include <linux/dma-mapping.h> #include <linux/reset.h> #include "hfi_packetization.h" Loading Loading @@ -3623,11 +3622,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) { Loading Loading @@ -4305,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: Loading @@ -4348,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"); Loading
drivers/media/platform/msm/cvp/cvp_hfi.h +5 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #include <media/msm_media_info.h> #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 + \ Loading Loading @@ -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, Loading