Loading Documentation/devicetree/bindings/media/video/msm-vidc.txt +4 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,9 @@ Optional properties: gate-able = 0x2 (if the driver should disable the clock if no load) - qcom,sw-power-collapse = A bool indicating if video hardware core can be power collapsed in idle state. - qcom,early-fw-load = A bool indicating if video firmware should be loaded during probe. When no video session is active, the video hardware will be power collapsed. - qcom,use-non-secure-pil = A bool indicating which type of pil to use to load the fw. - qcom,use-dynamic-bw-update = A bool indicating whether dynamic bandwidth Loading Loading @@ -133,6 +136,7 @@ Example: clock-names = "foo_clk", "bar_clk", "baz_clk"; qcom,clock-configs = <0x3 0x1 0x0>; qcom,sw-power-collapse; qcom,early-fw-load; qcom,enable-idle-indicator; qcom,msm-bus-clients { qcom,msm-bus-client@0 { Loading drivers/media/platform/msm/vidc/msm_v4l2_vidc.c +64 −3 Original line number Diff line number Diff line Loading @@ -23,15 +23,17 @@ #include <linux/qcom_iommu.h> #include <linux/msm_iommu_domains.h> #include <media/msm_vidc.h> #include "msm_vidc_internal.h" #include "msm_vidc_common.h" #include "msm_vidc_debug.h" #include "vidc_hfi_api.h" #include "vidc_hfi_api.h" #include "msm_vidc_internal.h" #include "msm_vidc_resources.h" #include "msm_vidc_res_parse.h" #include "venus_boot.h" #include "vidc_hfi_api.h" #define BASE_DEVICE_NUMBER 32 #define EARLY_FIRMWARE_LOAD_DELAY 1000 struct msm_vidc_drv *vidc_driver; Loading Loading @@ -432,6 +434,62 @@ static struct attribute_group msm_vidc_core_attr_group = { .attrs = msm_vidc_core_attrs, }; struct fw_load_handler_data { struct msm_vidc_core *core; struct delayed_work work; }; static void fw_load_handler(struct work_struct *work) { struct msm_vidc_core *core = NULL; struct fw_load_handler_data *handler = NULL; int rc = 0; handler = container_of(work, struct fw_load_handler_data, work.work); if (!handler || !handler->core) { dprintk(VIDC_ERR, "%s - invalid work or core handle\n", __func__); goto exit; } core = handler->core; rc = msm_comm_load_fw(core); if (rc) { dprintk(VIDC_ERR, "%s - failed to load fw\n", __func__); goto exit; } rc = msm_comm_check_core_init(core); if (rc) { dprintk(VIDC_ERR, "%s - failed to init core\n", __func__); goto exit; } dprintk(VIDC_DBG, "%s - firmware loaded successfully\n", __func__); msm_vidc_suspend(core->id); exit: kfree(handler); } static void load_firmware(struct msm_vidc_core *core) { struct fw_load_handler_data *handler = NULL; handler = kzalloc(sizeof(*handler), GFP_KERNEL); if (!handler) { dprintk(VIDC_ERR, "%s - failed to allocate sys error handler\n", __func__); return; } handler->core = core; INIT_DELAYED_WORK(&handler->work, fw_load_handler); schedule_delayed_work(&handler->work, msecs_to_jiffies(EARLY_FIRMWARE_LOAD_DELAY)); } static int msm_vidc_probe(struct platform_device *pdev) { int rc = 0; Loading Loading @@ -551,6 +609,9 @@ static int msm_vidc_probe(struct platform_device *pdev) core->debugfs_root = msm_vidc_debugfs_init_core( core, vidc_driver->debugfs_root); pdev->dev.platform_data = core; load_firmware(core); return rc; err_non_sec_pil_init: vidc_hfi_deinitialize(core->hfi_type, core->device); Loading drivers/media/platform/msm/vidc/msm_vidc_common.c +50 −14 Original line number Diff line number Diff line Loading @@ -2230,15 +2230,15 @@ void msm_comm_handle_thermal_event() } } static int msm_comm_init_core_done(struct msm_vidc_inst *inst) int msm_comm_check_core_init(struct msm_vidc_core *core) { struct msm_vidc_core *core = inst->core; int rc = 0; mutex_lock(&core->lock); if (core->state >= VIDC_CORE_INIT_DONE) { dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n", core->id, core->state); goto core_already_inited; goto exit; } dprintk(VIDC_DBG, "Waiting for SYS_INIT_DONE\n"); rc = wait_for_completion_timeout( Loading @@ -2251,20 +2251,30 @@ static int msm_comm_init_core_done(struct msm_vidc_inst *inst) goto exit; } else { core->state = VIDC_CORE_INIT_DONE; rc = 0; } dprintk(VIDC_DBG, "SYS_INIT_DONE!!!\n"); core_already_inited: change_inst_state(inst, MSM_VIDC_CORE_INIT_DONE); rc = 0; exit: mutex_unlock(&core->lock); return rc; } static int msm_comm_init_core(struct msm_vidc_inst *inst) static int msm_comm_init_core_done(struct msm_vidc_inst *inst) { int rc = 0; rc = msm_comm_check_core_init(inst->core); if (rc) { dprintk(VIDC_ERR, "%s - failed to initialize core\n", __func__); return rc; } change_inst_state(inst, MSM_VIDC_CORE_INIT_DONE); return rc; } int msm_comm_load_fw(struct msm_vidc_core *core) { int rc = 0; struct msm_vidc_core *core = inst->core; struct hfi_device *hdev; if (!core || !core->device) Loading Loading @@ -2319,7 +2329,6 @@ static int msm_comm_init_core(struct msm_vidc_inst *inst) } core_already_inited: change_inst_state(inst, MSM_VIDC_CORE_INIT); mutex_unlock(&core->lock); return rc; Loading @@ -2334,6 +2343,23 @@ fail_vote_bus: return rc; } static int msm_comm_init_core(struct msm_vidc_inst *inst) { int rc = 0; if (!inst || !inst->core) return -EINVAL; rc = msm_comm_load_fw(inst->core); if (rc) { dprintk(VIDC_ERR, "%s - firmware loading failed\n", __func__); return rc; } change_inst_state(inst, MSM_VIDC_CORE_INIT); return rc; } static int msm_vidc_deinit_core(struct msm_vidc_inst *inst) { struct msm_vidc_core *core; Loading @@ -2358,6 +2384,16 @@ static int msm_vidc_deinit_core(struct msm_vidc_inst *inst) msm_comm_scale_clocks_and_bus(inst); mutex_lock(&core->lock); /* * If firmware is configured to be always loaded in memory, * then unload it only if the core has gone in to bad state. */ if (core->resources.early_fw_load && core->state != VIDC_CORE_INVALID) { goto core_already_uninited; } if (list_empty(&core->instances)) { cancel_delayed_work(&core->fw_unload_work); Loading drivers/media/platform/msm/vidc/msm_vidc_common.h +2 −0 Original line number Diff line number Diff line Loading @@ -73,4 +73,6 @@ int msm_comm_smem_get_domain_partition(struct msm_vidc_inst *inst, u32 flags, enum hal_buffer buffer_type, int *domain_num, int *partition_num); enum hal_video_codec get_hal_codec_type(int fourcc); int msm_comm_load_fw(struct msm_vidc_core *core); int msm_comm_check_core_init(struct msm_vidc_core *core); #endif drivers/media/platform/msm/vidc/msm_vidc_res_parse.c +5 −0 Original line number Diff line number Diff line Loading @@ -577,6 +577,11 @@ static int msm_vidc_load_clock_table( dprintk(VIDC_DBG, "Power collapse supported = %s\n", res->sw_power_collapsible ? "yes" : "no"); res->early_fw_load = of_property_read_bool(pdev->dev.of_node, "qcom,early-fw-load"); dprintk(VIDC_DBG, "Early fw load = %s\n", res->early_fw_load ? "yes" : "no"); return 0; err_load_clk_prop_fail: Loading Loading
Documentation/devicetree/bindings/media/video/msm-vidc.txt +4 −0 Original line number Diff line number Diff line Loading @@ -97,6 +97,9 @@ Optional properties: gate-able = 0x2 (if the driver should disable the clock if no load) - qcom,sw-power-collapse = A bool indicating if video hardware core can be power collapsed in idle state. - qcom,early-fw-load = A bool indicating if video firmware should be loaded during probe. When no video session is active, the video hardware will be power collapsed. - qcom,use-non-secure-pil = A bool indicating which type of pil to use to load the fw. - qcom,use-dynamic-bw-update = A bool indicating whether dynamic bandwidth Loading Loading @@ -133,6 +136,7 @@ Example: clock-names = "foo_clk", "bar_clk", "baz_clk"; qcom,clock-configs = <0x3 0x1 0x0>; qcom,sw-power-collapse; qcom,early-fw-load; qcom,enable-idle-indicator; qcom,msm-bus-clients { qcom,msm-bus-client@0 { Loading
drivers/media/platform/msm/vidc/msm_v4l2_vidc.c +64 −3 Original line number Diff line number Diff line Loading @@ -23,15 +23,17 @@ #include <linux/qcom_iommu.h> #include <linux/msm_iommu_domains.h> #include <media/msm_vidc.h> #include "msm_vidc_internal.h" #include "msm_vidc_common.h" #include "msm_vidc_debug.h" #include "vidc_hfi_api.h" #include "vidc_hfi_api.h" #include "msm_vidc_internal.h" #include "msm_vidc_resources.h" #include "msm_vidc_res_parse.h" #include "venus_boot.h" #include "vidc_hfi_api.h" #define BASE_DEVICE_NUMBER 32 #define EARLY_FIRMWARE_LOAD_DELAY 1000 struct msm_vidc_drv *vidc_driver; Loading Loading @@ -432,6 +434,62 @@ static struct attribute_group msm_vidc_core_attr_group = { .attrs = msm_vidc_core_attrs, }; struct fw_load_handler_data { struct msm_vidc_core *core; struct delayed_work work; }; static void fw_load_handler(struct work_struct *work) { struct msm_vidc_core *core = NULL; struct fw_load_handler_data *handler = NULL; int rc = 0; handler = container_of(work, struct fw_load_handler_data, work.work); if (!handler || !handler->core) { dprintk(VIDC_ERR, "%s - invalid work or core handle\n", __func__); goto exit; } core = handler->core; rc = msm_comm_load_fw(core); if (rc) { dprintk(VIDC_ERR, "%s - failed to load fw\n", __func__); goto exit; } rc = msm_comm_check_core_init(core); if (rc) { dprintk(VIDC_ERR, "%s - failed to init core\n", __func__); goto exit; } dprintk(VIDC_DBG, "%s - firmware loaded successfully\n", __func__); msm_vidc_suspend(core->id); exit: kfree(handler); } static void load_firmware(struct msm_vidc_core *core) { struct fw_load_handler_data *handler = NULL; handler = kzalloc(sizeof(*handler), GFP_KERNEL); if (!handler) { dprintk(VIDC_ERR, "%s - failed to allocate sys error handler\n", __func__); return; } handler->core = core; INIT_DELAYED_WORK(&handler->work, fw_load_handler); schedule_delayed_work(&handler->work, msecs_to_jiffies(EARLY_FIRMWARE_LOAD_DELAY)); } static int msm_vidc_probe(struct platform_device *pdev) { int rc = 0; Loading Loading @@ -551,6 +609,9 @@ static int msm_vidc_probe(struct platform_device *pdev) core->debugfs_root = msm_vidc_debugfs_init_core( core, vidc_driver->debugfs_root); pdev->dev.platform_data = core; load_firmware(core); return rc; err_non_sec_pil_init: vidc_hfi_deinitialize(core->hfi_type, core->device); Loading
drivers/media/platform/msm/vidc/msm_vidc_common.c +50 −14 Original line number Diff line number Diff line Loading @@ -2230,15 +2230,15 @@ void msm_comm_handle_thermal_event() } } static int msm_comm_init_core_done(struct msm_vidc_inst *inst) int msm_comm_check_core_init(struct msm_vidc_core *core) { struct msm_vidc_core *core = inst->core; int rc = 0; mutex_lock(&core->lock); if (core->state >= VIDC_CORE_INIT_DONE) { dprintk(VIDC_INFO, "Video core: %d is already in state: %d\n", core->id, core->state); goto core_already_inited; goto exit; } dprintk(VIDC_DBG, "Waiting for SYS_INIT_DONE\n"); rc = wait_for_completion_timeout( Loading @@ -2251,20 +2251,30 @@ static int msm_comm_init_core_done(struct msm_vidc_inst *inst) goto exit; } else { core->state = VIDC_CORE_INIT_DONE; rc = 0; } dprintk(VIDC_DBG, "SYS_INIT_DONE!!!\n"); core_already_inited: change_inst_state(inst, MSM_VIDC_CORE_INIT_DONE); rc = 0; exit: mutex_unlock(&core->lock); return rc; } static int msm_comm_init_core(struct msm_vidc_inst *inst) static int msm_comm_init_core_done(struct msm_vidc_inst *inst) { int rc = 0; rc = msm_comm_check_core_init(inst->core); if (rc) { dprintk(VIDC_ERR, "%s - failed to initialize core\n", __func__); return rc; } change_inst_state(inst, MSM_VIDC_CORE_INIT_DONE); return rc; } int msm_comm_load_fw(struct msm_vidc_core *core) { int rc = 0; struct msm_vidc_core *core = inst->core; struct hfi_device *hdev; if (!core || !core->device) Loading Loading @@ -2319,7 +2329,6 @@ static int msm_comm_init_core(struct msm_vidc_inst *inst) } core_already_inited: change_inst_state(inst, MSM_VIDC_CORE_INIT); mutex_unlock(&core->lock); return rc; Loading @@ -2334,6 +2343,23 @@ fail_vote_bus: return rc; } static int msm_comm_init_core(struct msm_vidc_inst *inst) { int rc = 0; if (!inst || !inst->core) return -EINVAL; rc = msm_comm_load_fw(inst->core); if (rc) { dprintk(VIDC_ERR, "%s - firmware loading failed\n", __func__); return rc; } change_inst_state(inst, MSM_VIDC_CORE_INIT); return rc; } static int msm_vidc_deinit_core(struct msm_vidc_inst *inst) { struct msm_vidc_core *core; Loading @@ -2358,6 +2384,16 @@ static int msm_vidc_deinit_core(struct msm_vidc_inst *inst) msm_comm_scale_clocks_and_bus(inst); mutex_lock(&core->lock); /* * If firmware is configured to be always loaded in memory, * then unload it only if the core has gone in to bad state. */ if (core->resources.early_fw_load && core->state != VIDC_CORE_INVALID) { goto core_already_uninited; } if (list_empty(&core->instances)) { cancel_delayed_work(&core->fw_unload_work); Loading
drivers/media/platform/msm/vidc/msm_vidc_common.h +2 −0 Original line number Diff line number Diff line Loading @@ -73,4 +73,6 @@ int msm_comm_smem_get_domain_partition(struct msm_vidc_inst *inst, u32 flags, enum hal_buffer buffer_type, int *domain_num, int *partition_num); enum hal_video_codec get_hal_codec_type(int fourcc); int msm_comm_load_fw(struct msm_vidc_core *core); int msm_comm_check_core_init(struct msm_vidc_core *core); #endif
drivers/media/platform/msm/vidc/msm_vidc_res_parse.c +5 −0 Original line number Diff line number Diff line Loading @@ -577,6 +577,11 @@ static int msm_vidc_load_clock_table( dprintk(VIDC_DBG, "Power collapse supported = %s\n", res->sw_power_collapsible ? "yes" : "no"); res->early_fw_load = of_property_read_bool(pdev->dev.of_node, "qcom,early-fw-load"); dprintk(VIDC_DBG, "Early fw load = %s\n", res->early_fw_load ? "yes" : "no"); return 0; err_load_clk_prop_fail: Loading