Loading drivers/media/platform/msm/vidc_3x/msm_smem.c +7 −2 Original line number Diff line number Diff line /* * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -430,7 +430,12 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, } ion_flags |= ION_FLAG_SECURE | secure_flag; if (res->cma_status) { heap_mask = ION_HEAP(ION_VIDEO_HEAP_ID); ion_flags |= ION_FLAG_CP_CAMERA_ENCODE; } else { heap_mask = ION_HEAP(ION_SECURE_HEAP_ID); } if (res->slave_side_cp) { heap_mask = ION_HEAP(ION_CP_MM_HEAP_ID); Loading drivers/media/platform/msm/vidc_3x/msm_v4l2_vidc.c +27 −1 Original line number Diff line number Diff line /* * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -586,6 +586,32 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) "Failed to create link name sysfs for encoder"); goto err_enc_attr_link_name; } /* setup the encoder device with cma */ core->vdev[MSM_VIDC_ENCODER_CMA].vdev.release = msm_vidc_release_video_device; core->vdev[MSM_VIDC_ENCODER_CMA].vdev.fops = &msm_v4l2_vidc_fops; core->vdev[MSM_VIDC_ENCODER_CMA].vdev.ioctl_ops = &msm_v4l2_ioctl_ops; core->vdev[MSM_VIDC_ENCODER_CMA].vdev.vfl_dir = VFL_DIR_M2M; core->vdev[MSM_VIDC_ENCODER_CMA].type = MSM_VIDC_ENCODER_CMA; core->vdev[MSM_VIDC_ENCODER_CMA].vdev.v4l2_dev = &core->v4l2_dev; rc = video_register_device(&core->vdev[MSM_VIDC_ENCODER_CMA].vdev, VFL_TYPE_GRABBER, nr + 3); if (rc) { dprintk(VIDC_ERR, "Failed to register video cma encoder device"); goto err_enc_register; } video_set_drvdata(&core->vdev[MSM_VIDC_ENCODER_CMA].vdev, core); dev = &core->vdev[MSM_VIDC_ENCODER_CMA].vdev.dev; rc = device_create_file(dev, &dev_attr_link_name); if (rc) { dprintk(VIDC_ERR, "Failed to create link name sysfs for encoder cma"); goto err_enc_attr_link_name; } /* finish setting up the 'core' */ mutex_lock(&vidc_driver->lock); Loading drivers/media/platform/msm/vidc_3x/msm_vidc.c +72 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <linux/delay.h> #include "vidc_hfi_api.h" #include "msm_vidc_dcvs.h" #include "msm_vidc_res_parse.h" #define MAX_EVENTS 30 Loading Loading @@ -1242,6 +1243,9 @@ void *msm_vidc_open(int core_id, int session_type) struct msm_vidc_core *core = NULL; int rc = 0; int i = 0; bool reconfig_core = false; bool is_cma_enabled = false; struct hfi_device *hdev = NULL; if (core_id >= MSM_VIDC_CORES_MAX || session_type >= MSM_VIDC_MAX_DEVICES) { Loading @@ -1256,6 +1260,13 @@ void *msm_vidc_open(int core_id, int session_type) goto err_invalid_core; } if ((session_type == MSM_VIDC_ENCODER_CMA) && !core->resources.cma_exist) { dprintk(VIDC_ERR, "Failed cma not enabled\n"); goto err_invalid_core; } inst = kzalloc(sizeof(*inst), GFP_KERNEL); if (!inst) { dprintk(VIDC_ERR, "Failed to allocate memory\n"); Loading @@ -1280,6 +1291,18 @@ void *msm_vidc_open(int core_id, int session_type) kref_init(&inst->kref); is_cma_enabled = core->resources.cma_status; reconfig_core = ((!is_cma_enabled && session_type == MSM_VIDC_ENCODER_CMA) || (is_cma_enabled && session_type != MSM_VIDC_ENCODER_CMA)) ? true : false; dprintk(VIDC_DBG, "reconfig_core %d , cma_status %d , session_type %d ", reconfig_core, core->resources.cma_status, session_type); if (session_type == MSM_VIDC_ENCODER_CMA) session_type = MSM_VIDC_ENCODER; inst->session_type = session_type; inst->state = MSM_VIDC_CORE_UNINIT_DONE; inst->core = core; Loading Loading @@ -1322,6 +1345,50 @@ void *msm_vidc_open(int core_id, int session_type) setup_event_queue(inst, &core->vdev[session_type].vdev); if (reconfig_core) { mutex_lock(&core->lock); if (!list_empty(&core->instances)) { dprintk(VIDC_ERR, "failed due to pending instances in core"); mutex_unlock(&core->lock); goto fail_toggle_cma; } mutex_unlock(&core->lock); rc = msm_comm_try_state(inst, MSM_VIDC_CORE_UNINIT); if (rc) { dprintk(VIDC_ERR, "MSM_VIDC_CORE_UNINIT failed\n"); } cancel_delayed_work(&core->fw_unload_work); mutex_lock(&core->lock); hdev = core->device; rc = call_hfi_op(hdev, core_release, hdev->hfi_device_data); if (rc) { dprintk(VIDC_ERR, "Failed to release core, id = %d\n", core->id); mutex_unlock(&core->lock); goto fail_toggle_cma; } core->state = VIDC_CORE_UNINIT; kfree(core->capabilities); core->capabilities = NULL; msm_vidc_enable_cma(&core->resources, !is_cma_enabled); if (rc) { dprintk(VIDC_ERR, "%s CMA failed\n", is_cma_enabled ? "enable":"disable"); mutex_unlock(&core->lock); goto fail_toggle_cma; } core->resources.cma_status = !is_cma_enabled; mutex_unlock(&core->lock); } mutex_lock(&core->lock); list_add_tail(&inst->list, &core->instances); mutex_unlock(&core->lock); Loading @@ -1343,11 +1410,15 @@ void *msm_vidc_open(int core_id, int session_type) msm_vidc_debugfs_init_inst(inst, core->debugfs_root); return inst; fail_init: mutex_lock(&core->lock); list_del(&inst->list); mutex_unlock(&core->lock); fail_toggle_cma: mutex_lock(&core->lock); v4l2_fh_del(&inst->event_handler); v4l2_fh_exit(&inst->event_handler); list_del(&inst->list); mutex_unlock(&core->lock); vb2_queue_release(&inst->bufq[OUTPUT_PORT].vb2_bufq); Loading drivers/media/platform/msm/vidc_3x/msm_vidc_res_parse.c +153 −14 Original line number Diff line number Diff line Loading @@ -20,9 +20,14 @@ #include "msm_vidc_resources.h" #include "msm_vidc_res_parse.h" #include "venus_boot.h" #include <soc/qcom/scm.h> #include "soc/qcom/secure_buffer.h" #include <asm/cacheflush.h> #include <linux/io.h> #define VENUS_DEVICE_ID 0x0 #define SECURE_SYSCALL_ID 0x18 enum clock_properties { CLOCK_PROP_HAS_SCALING = 1 << 0, }; Loading Loading @@ -1265,12 +1270,63 @@ static int get_secure_vmid(struct context_bank_info *cb) return VMID_INVAL; } static int msm_vidc_switch_vmid(int vmid, struct context_bank_info *cb) { struct scm_desc desc = {0}; uint32_t *sid_info = NULL; int rc = 0; if (!cb) { dprintk(VIDC_ERR, "%s: invalid context bank device\n", __func__); return -EIO; } sid_info = kzalloc(sizeof(uint32_t) * cb->num_sids, GFP_KERNEL); if (!sid_info) { dprintk(VIDC_ERR, "%s: memory allocation failred\n", __func__); return -ENOMEM; } memcpy(sid_info, &cb->sids, sizeof(uint32_t) * cb->num_sids); desc.arginfo = SCM_ARGS(4, SCM_VAL, SCM_RW, SCM_VAL, SCM_VAL); desc.args[0] = VENUS_DEVICE_ID; desc.args[1] = SCM_BUFFER_PHYS(sid_info); desc.args[2] = sizeof(uint32_t) * cb->num_sids; desc.args[3] = vmid; dmac_flush_range(sid_info, sid_info + 1); if (scm_call2(SCM_SIP_FNID(SCM_SVC_MP, SECURE_SYSCALL_ID), &desc)) { dprintk(VIDC_ERR, "call to hypervisor failed\n"); rc = -EINVAL; } dprintk(VIDC_DBG, "%s switched to 0x%x vmid\n", cb->name, vmid); kfree(sid_info); return rc; } static void msm_vidc_detach_context_banks( struct msm_vidc_platform_resources *res) { struct context_bank_info *cb = NULL; list_for_each_entry(cb, &res->context_banks, list) { arm_iommu_detach_device(cb->dev); if (cb->mapping) arm_iommu_release_mapping(cb->mapping); } } static int msm_vidc_setup_context_bank(struct context_bank_info *cb, struct device *dev) struct device *dev, int cma_enable) { int rc = 0; int secure_vmid = VMID_INVAL; struct bus_type *bus; u32 start_addr = 0, pool_size = 0; int s1_bypass = 1; if (!dev || !cb) { dprintk(VIDC_ERR, Loading @@ -1286,8 +1342,15 @@ static int msm_vidc_setup_context_bank(struct context_bank_info *cb, goto remove_cb; } cb->mapping = arm_iommu_create_mapping(bus, cb->addr_range.start, cb->addr_range.size); if (cma_enable) { start_addr = cb->cma.addr_range.start; pool_size = cb->cma.addr_range.size; } else { start_addr = cb->addr_range.start; pool_size = cb->addr_range.size; } cb->mapping = arm_iommu_create_mapping(bus, start_addr, pool_size); if (IS_ERR_OR_NULL(cb->mapping)) { dprintk(VIDC_ERR, "%s - failed to create mapping\n", __func__); rc = PTR_ERR(cb->mapping) ?: -ENODEV; Loading @@ -1296,16 +1359,30 @@ static int msm_vidc_setup_context_bank(struct context_bank_info *cb, if (cb->is_secure) { secure_vmid = get_secure_vmid(cb); if (cma_enable && cb->cma.s1_bypass) secure_vmid = VMID_CP_CAMERA_ENCODE; rc = iommu_domain_set_attr(cb->mapping->domain, DOMAIN_ATTR_SECURE_VMID, &secure_vmid); if (rc) { dprintk(VIDC_ERR, "%s - programming secure vmid failed: %s %d\n", "%s - programming secure vmid failed: %s 0x%x\n", __func__, dev_name(dev), rc); goto release_mapping; } } if (cma_enable && cb->cma.s1_bypass) { s1_bypass = cb->cma.s1_bypass; rc = iommu_domain_set_attr(cb->mapping->domain, DOMAIN_ATTR_S1_BYPASS, &s1_bypass); if (rc) { dprintk(VIDC_ERR, "%s S1 bypass failed rc %d ", __func__, rc); goto release_mapping; } } rc = arm_iommu_attach_device(cb->dev, cb->mapping); if (rc) { dprintk(VIDC_ERR, "%s - Couldn't arm_iommu_attach_device\n", Loading @@ -1324,11 +1401,12 @@ static int msm_vidc_setup_context_bank(struct context_bank_info *cb, dma_set_max_seg_size(dev, DMA_BIT_MASK(32)); dma_set_seg_boundary(dev, (unsigned long)DMA_BIT_MASK(64)); dprintk(VIDC_DBG, "Attached %s and created mapping\n", dev_name(dev)); dprintk(VIDC_DBG, "Attached %s and created mapping cma status %d\n", dev_name(dev), cma_enable); dprintk(VIDC_DBG, "Context bank name:%s, buffer_type: %#x, is_secure: %d, address range start: %#x, size: %#x, dev: %pK, mapping: %pK", cb->name, cb->buffer_type, cb->is_secure, cb->addr_range.start, cb->addr_range.size, cb->dev, cb->mapping); cb->name, cb->buffer_type, cb->is_secure, start_addr, pool_size, cb->dev, cb->mapping); return rc; Loading Loading @@ -1426,6 +1504,7 @@ static int msm_vidc_populate_context_bank(struct device *dev, int rc = 0; struct context_bank_info *cb = NULL; struct device_node *np = NULL; unsigned int i = 0, j = 0, count = 0; if (!dev || !core) { dprintk(VIDC_ERR, "%s - invalid inputs\n", __func__); Loading @@ -1448,8 +1527,21 @@ static int msm_vidc_populate_context_bank(struct device *dev, "Failed to read cb label from device tree\n"); rc = 0; } dprintk(VIDC_DBG, "%s: context bank has name %s\n", __func__, cb->name); of_get_property(np, "iommus", &count); memset(&cb->sids, -1, sizeof(cb->sids)); count /= 4; for (i = 1, j = 0 ; i < count; i = i+2, j++) { rc = of_property_read_u32_index(dev->of_node, "iommus", i, &cb->sids[j]); if (rc < 0) dprintk(VIDC_ERR, "can't fetch SID\n"); dprintk(VIDC_DBG, "%s sid[%d]:0x%x\n", cb->name, j, cb->sids[j]); } cb->num_sids = j; rc = of_property_read_u32_array(np, "virtual-addr-pool", (u32 *)&cb->addr_range, 2); if (rc) { Loading @@ -1459,6 +1551,13 @@ static int msm_vidc_populate_context_bank(struct device *dev, goto err_setup_cb; } rc = of_property_read_u32_array(np, "cma-addr-pool", (u32 *)&cb->cma.addr_range, 2); cb->cma.s1_bypass = of_property_read_bool(np, "qcom,cma-s1-bypass"); if (cb->cma.s1_bypass && !rc) core->resources.cma_exist = true; cb->is_secure = of_property_read_bool(np, "qcom,secure-context-bank"); dprintk(VIDC_DBG, "context bank %s : secure = %d\n", cb->name, cb->is_secure); Loading @@ -1471,11 +1570,12 @@ static int msm_vidc_populate_context_bank(struct device *dev, goto err_setup_cb; } dprintk(VIDC_DBG, "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); "context bank %s address start = %x size = %x cma address start = %x size = %x s1 bypass = %d buffer_type = %x\n", cb->name, cb->addr_range.start, cb->addr_range.size, cb->cma.addr_range.start, cb->cma.addr_range.size, cb->cma.s1_bypass, cb->buffer_type); rc = msm_vidc_setup_context_bank(cb, dev); rc = msm_vidc_setup_context_bank(cb, dev, false); if (rc) { dprintk(VIDC_ERR, "Cannot setup context bank %d\n", rc); goto err_setup_cb; Loading Loading @@ -1572,7 +1672,7 @@ static int msm_vidc_populate_legacy_context_bank( goto err_setup_cb; } rc = msm_vidc_setup_context_bank(cb, cb->dev); rc = msm_vidc_setup_context_bank(cb, cb->dev, false); if (rc) { dprintk(VIDC_ERR, "Cannot setup context bank %d\n", rc); goto err_setup_cb; Loading Loading @@ -1659,3 +1759,42 @@ int read_bus_resources_from_dt(struct platform_device *pdev) return msm_vidc_populate_bus(&pdev->dev, &core->resources); } int msm_vidc_enable_cma(struct msm_vidc_platform_resources *res, bool enable) { int rc; int secure_vmid = VMID_INVAL; struct context_bank_info *cb = NULL; dprintk(VIDC_DBG, "%s: In enable status %d\n", __func__, enable); msm_vidc_detach_context_banks(res); list_for_each_entry(cb, &res->context_banks, list) { if (cb->is_secure && cb->cma.s1_bypass) { if (enable) { rc = msm_vidc_switch_vmid(VMID_CP_CAMERA_ENCODE, cb); if (rc) { dprintk(VIDC_ERR, "failed SID switching\n"); goto detach_cb; } } else { secure_vmid = get_secure_vmid(cb); rc = msm_vidc_switch_vmid(secure_vmid, cb); if (rc) goto detach_cb; } } rc = msm_vidc_setup_context_bank(cb, cb->dev, enable); if (rc) goto detach_cb; } return rc; detach_cb: dprintk(VIDC_DBG, "%s: - failed %d\n", __func__, enable); msm_vidc_detach_context_banks(res); return rc; } drivers/media/platform/msm/vidc_3x/msm_vidc_res_parse.h +1 −0 Original line number Diff line number Diff line Loading @@ -31,4 +31,5 @@ int msm_vidc_load_u32_table(struct platform_device *pdev, struct device_node *of_node, char *table_name, int struct_size, u32 **table, u32 *num_elements); int msm_vidc_enable_cma(struct msm_vidc_platform_resources *res, bool enable); #endif Loading
drivers/media/platform/msm/vidc_3x/msm_smem.c +7 −2 Original line number Diff line number Diff line /* * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -430,7 +430,12 @@ static int alloc_dma_mem(size_t size, u32 align, u32 flags, } ion_flags |= ION_FLAG_SECURE | secure_flag; if (res->cma_status) { heap_mask = ION_HEAP(ION_VIDEO_HEAP_ID); ion_flags |= ION_FLAG_CP_CAMERA_ENCODE; } else { heap_mask = ION_HEAP(ION_SECURE_HEAP_ID); } if (res->slave_side_cp) { heap_mask = ION_HEAP(ION_CP_MM_HEAP_ID); Loading
drivers/media/platform/msm/vidc_3x/msm_v4l2_vidc.c +27 −1 Original line number Diff line number Diff line /* * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -586,6 +586,32 @@ static int msm_vidc_probe_vidc_device(struct platform_device *pdev) "Failed to create link name sysfs for encoder"); goto err_enc_attr_link_name; } /* setup the encoder device with cma */ core->vdev[MSM_VIDC_ENCODER_CMA].vdev.release = msm_vidc_release_video_device; core->vdev[MSM_VIDC_ENCODER_CMA].vdev.fops = &msm_v4l2_vidc_fops; core->vdev[MSM_VIDC_ENCODER_CMA].vdev.ioctl_ops = &msm_v4l2_ioctl_ops; core->vdev[MSM_VIDC_ENCODER_CMA].vdev.vfl_dir = VFL_DIR_M2M; core->vdev[MSM_VIDC_ENCODER_CMA].type = MSM_VIDC_ENCODER_CMA; core->vdev[MSM_VIDC_ENCODER_CMA].vdev.v4l2_dev = &core->v4l2_dev; rc = video_register_device(&core->vdev[MSM_VIDC_ENCODER_CMA].vdev, VFL_TYPE_GRABBER, nr + 3); if (rc) { dprintk(VIDC_ERR, "Failed to register video cma encoder device"); goto err_enc_register; } video_set_drvdata(&core->vdev[MSM_VIDC_ENCODER_CMA].vdev, core); dev = &core->vdev[MSM_VIDC_ENCODER_CMA].vdev.dev; rc = device_create_file(dev, &dev_attr_link_name); if (rc) { dprintk(VIDC_ERR, "Failed to create link name sysfs for encoder cma"); goto err_enc_attr_link_name; } /* finish setting up the 'core' */ mutex_lock(&vidc_driver->lock); Loading
drivers/media/platform/msm/vidc_3x/msm_vidc.c +72 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ #include <linux/delay.h> #include "vidc_hfi_api.h" #include "msm_vidc_dcvs.h" #include "msm_vidc_res_parse.h" #define MAX_EVENTS 30 Loading Loading @@ -1242,6 +1243,9 @@ void *msm_vidc_open(int core_id, int session_type) struct msm_vidc_core *core = NULL; int rc = 0; int i = 0; bool reconfig_core = false; bool is_cma_enabled = false; struct hfi_device *hdev = NULL; if (core_id >= MSM_VIDC_CORES_MAX || session_type >= MSM_VIDC_MAX_DEVICES) { Loading @@ -1256,6 +1260,13 @@ void *msm_vidc_open(int core_id, int session_type) goto err_invalid_core; } if ((session_type == MSM_VIDC_ENCODER_CMA) && !core->resources.cma_exist) { dprintk(VIDC_ERR, "Failed cma not enabled\n"); goto err_invalid_core; } inst = kzalloc(sizeof(*inst), GFP_KERNEL); if (!inst) { dprintk(VIDC_ERR, "Failed to allocate memory\n"); Loading @@ -1280,6 +1291,18 @@ void *msm_vidc_open(int core_id, int session_type) kref_init(&inst->kref); is_cma_enabled = core->resources.cma_status; reconfig_core = ((!is_cma_enabled && session_type == MSM_VIDC_ENCODER_CMA) || (is_cma_enabled && session_type != MSM_VIDC_ENCODER_CMA)) ? true : false; dprintk(VIDC_DBG, "reconfig_core %d , cma_status %d , session_type %d ", reconfig_core, core->resources.cma_status, session_type); if (session_type == MSM_VIDC_ENCODER_CMA) session_type = MSM_VIDC_ENCODER; inst->session_type = session_type; inst->state = MSM_VIDC_CORE_UNINIT_DONE; inst->core = core; Loading Loading @@ -1322,6 +1345,50 @@ void *msm_vidc_open(int core_id, int session_type) setup_event_queue(inst, &core->vdev[session_type].vdev); if (reconfig_core) { mutex_lock(&core->lock); if (!list_empty(&core->instances)) { dprintk(VIDC_ERR, "failed due to pending instances in core"); mutex_unlock(&core->lock); goto fail_toggle_cma; } mutex_unlock(&core->lock); rc = msm_comm_try_state(inst, MSM_VIDC_CORE_UNINIT); if (rc) { dprintk(VIDC_ERR, "MSM_VIDC_CORE_UNINIT failed\n"); } cancel_delayed_work(&core->fw_unload_work); mutex_lock(&core->lock); hdev = core->device; rc = call_hfi_op(hdev, core_release, hdev->hfi_device_data); if (rc) { dprintk(VIDC_ERR, "Failed to release core, id = %d\n", core->id); mutex_unlock(&core->lock); goto fail_toggle_cma; } core->state = VIDC_CORE_UNINIT; kfree(core->capabilities); core->capabilities = NULL; msm_vidc_enable_cma(&core->resources, !is_cma_enabled); if (rc) { dprintk(VIDC_ERR, "%s CMA failed\n", is_cma_enabled ? "enable":"disable"); mutex_unlock(&core->lock); goto fail_toggle_cma; } core->resources.cma_status = !is_cma_enabled; mutex_unlock(&core->lock); } mutex_lock(&core->lock); list_add_tail(&inst->list, &core->instances); mutex_unlock(&core->lock); Loading @@ -1343,11 +1410,15 @@ void *msm_vidc_open(int core_id, int session_type) msm_vidc_debugfs_init_inst(inst, core->debugfs_root); return inst; fail_init: mutex_lock(&core->lock); list_del(&inst->list); mutex_unlock(&core->lock); fail_toggle_cma: mutex_lock(&core->lock); v4l2_fh_del(&inst->event_handler); v4l2_fh_exit(&inst->event_handler); list_del(&inst->list); mutex_unlock(&core->lock); vb2_queue_release(&inst->bufq[OUTPUT_PORT].vb2_bufq); Loading
drivers/media/platform/msm/vidc_3x/msm_vidc_res_parse.c +153 −14 Original line number Diff line number Diff line Loading @@ -20,9 +20,14 @@ #include "msm_vidc_resources.h" #include "msm_vidc_res_parse.h" #include "venus_boot.h" #include <soc/qcom/scm.h> #include "soc/qcom/secure_buffer.h" #include <asm/cacheflush.h> #include <linux/io.h> #define VENUS_DEVICE_ID 0x0 #define SECURE_SYSCALL_ID 0x18 enum clock_properties { CLOCK_PROP_HAS_SCALING = 1 << 0, }; Loading Loading @@ -1265,12 +1270,63 @@ static int get_secure_vmid(struct context_bank_info *cb) return VMID_INVAL; } static int msm_vidc_switch_vmid(int vmid, struct context_bank_info *cb) { struct scm_desc desc = {0}; uint32_t *sid_info = NULL; int rc = 0; if (!cb) { dprintk(VIDC_ERR, "%s: invalid context bank device\n", __func__); return -EIO; } sid_info = kzalloc(sizeof(uint32_t) * cb->num_sids, GFP_KERNEL); if (!sid_info) { dprintk(VIDC_ERR, "%s: memory allocation failred\n", __func__); return -ENOMEM; } memcpy(sid_info, &cb->sids, sizeof(uint32_t) * cb->num_sids); desc.arginfo = SCM_ARGS(4, SCM_VAL, SCM_RW, SCM_VAL, SCM_VAL); desc.args[0] = VENUS_DEVICE_ID; desc.args[1] = SCM_BUFFER_PHYS(sid_info); desc.args[2] = sizeof(uint32_t) * cb->num_sids; desc.args[3] = vmid; dmac_flush_range(sid_info, sid_info + 1); if (scm_call2(SCM_SIP_FNID(SCM_SVC_MP, SECURE_SYSCALL_ID), &desc)) { dprintk(VIDC_ERR, "call to hypervisor failed\n"); rc = -EINVAL; } dprintk(VIDC_DBG, "%s switched to 0x%x vmid\n", cb->name, vmid); kfree(sid_info); return rc; } static void msm_vidc_detach_context_banks( struct msm_vidc_platform_resources *res) { struct context_bank_info *cb = NULL; list_for_each_entry(cb, &res->context_banks, list) { arm_iommu_detach_device(cb->dev); if (cb->mapping) arm_iommu_release_mapping(cb->mapping); } } static int msm_vidc_setup_context_bank(struct context_bank_info *cb, struct device *dev) struct device *dev, int cma_enable) { int rc = 0; int secure_vmid = VMID_INVAL; struct bus_type *bus; u32 start_addr = 0, pool_size = 0; int s1_bypass = 1; if (!dev || !cb) { dprintk(VIDC_ERR, Loading @@ -1286,8 +1342,15 @@ static int msm_vidc_setup_context_bank(struct context_bank_info *cb, goto remove_cb; } cb->mapping = arm_iommu_create_mapping(bus, cb->addr_range.start, cb->addr_range.size); if (cma_enable) { start_addr = cb->cma.addr_range.start; pool_size = cb->cma.addr_range.size; } else { start_addr = cb->addr_range.start; pool_size = cb->addr_range.size; } cb->mapping = arm_iommu_create_mapping(bus, start_addr, pool_size); if (IS_ERR_OR_NULL(cb->mapping)) { dprintk(VIDC_ERR, "%s - failed to create mapping\n", __func__); rc = PTR_ERR(cb->mapping) ?: -ENODEV; Loading @@ -1296,16 +1359,30 @@ static int msm_vidc_setup_context_bank(struct context_bank_info *cb, if (cb->is_secure) { secure_vmid = get_secure_vmid(cb); if (cma_enable && cb->cma.s1_bypass) secure_vmid = VMID_CP_CAMERA_ENCODE; rc = iommu_domain_set_attr(cb->mapping->domain, DOMAIN_ATTR_SECURE_VMID, &secure_vmid); if (rc) { dprintk(VIDC_ERR, "%s - programming secure vmid failed: %s %d\n", "%s - programming secure vmid failed: %s 0x%x\n", __func__, dev_name(dev), rc); goto release_mapping; } } if (cma_enable && cb->cma.s1_bypass) { s1_bypass = cb->cma.s1_bypass; rc = iommu_domain_set_attr(cb->mapping->domain, DOMAIN_ATTR_S1_BYPASS, &s1_bypass); if (rc) { dprintk(VIDC_ERR, "%s S1 bypass failed rc %d ", __func__, rc); goto release_mapping; } } rc = arm_iommu_attach_device(cb->dev, cb->mapping); if (rc) { dprintk(VIDC_ERR, "%s - Couldn't arm_iommu_attach_device\n", Loading @@ -1324,11 +1401,12 @@ static int msm_vidc_setup_context_bank(struct context_bank_info *cb, dma_set_max_seg_size(dev, DMA_BIT_MASK(32)); dma_set_seg_boundary(dev, (unsigned long)DMA_BIT_MASK(64)); dprintk(VIDC_DBG, "Attached %s and created mapping\n", dev_name(dev)); dprintk(VIDC_DBG, "Attached %s and created mapping cma status %d\n", dev_name(dev), cma_enable); dprintk(VIDC_DBG, "Context bank name:%s, buffer_type: %#x, is_secure: %d, address range start: %#x, size: %#x, dev: %pK, mapping: %pK", cb->name, cb->buffer_type, cb->is_secure, cb->addr_range.start, cb->addr_range.size, cb->dev, cb->mapping); cb->name, cb->buffer_type, cb->is_secure, start_addr, pool_size, cb->dev, cb->mapping); return rc; Loading Loading @@ -1426,6 +1504,7 @@ static int msm_vidc_populate_context_bank(struct device *dev, int rc = 0; struct context_bank_info *cb = NULL; struct device_node *np = NULL; unsigned int i = 0, j = 0, count = 0; if (!dev || !core) { dprintk(VIDC_ERR, "%s - invalid inputs\n", __func__); Loading @@ -1448,8 +1527,21 @@ static int msm_vidc_populate_context_bank(struct device *dev, "Failed to read cb label from device tree\n"); rc = 0; } dprintk(VIDC_DBG, "%s: context bank has name %s\n", __func__, cb->name); of_get_property(np, "iommus", &count); memset(&cb->sids, -1, sizeof(cb->sids)); count /= 4; for (i = 1, j = 0 ; i < count; i = i+2, j++) { rc = of_property_read_u32_index(dev->of_node, "iommus", i, &cb->sids[j]); if (rc < 0) dprintk(VIDC_ERR, "can't fetch SID\n"); dprintk(VIDC_DBG, "%s sid[%d]:0x%x\n", cb->name, j, cb->sids[j]); } cb->num_sids = j; rc = of_property_read_u32_array(np, "virtual-addr-pool", (u32 *)&cb->addr_range, 2); if (rc) { Loading @@ -1459,6 +1551,13 @@ static int msm_vidc_populate_context_bank(struct device *dev, goto err_setup_cb; } rc = of_property_read_u32_array(np, "cma-addr-pool", (u32 *)&cb->cma.addr_range, 2); cb->cma.s1_bypass = of_property_read_bool(np, "qcom,cma-s1-bypass"); if (cb->cma.s1_bypass && !rc) core->resources.cma_exist = true; cb->is_secure = of_property_read_bool(np, "qcom,secure-context-bank"); dprintk(VIDC_DBG, "context bank %s : secure = %d\n", cb->name, cb->is_secure); Loading @@ -1471,11 +1570,12 @@ static int msm_vidc_populate_context_bank(struct device *dev, goto err_setup_cb; } dprintk(VIDC_DBG, "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); "context bank %s address start = %x size = %x cma address start = %x size = %x s1 bypass = %d buffer_type = %x\n", cb->name, cb->addr_range.start, cb->addr_range.size, cb->cma.addr_range.start, cb->cma.addr_range.size, cb->cma.s1_bypass, cb->buffer_type); rc = msm_vidc_setup_context_bank(cb, dev); rc = msm_vidc_setup_context_bank(cb, dev, false); if (rc) { dprintk(VIDC_ERR, "Cannot setup context bank %d\n", rc); goto err_setup_cb; Loading Loading @@ -1572,7 +1672,7 @@ static int msm_vidc_populate_legacy_context_bank( goto err_setup_cb; } rc = msm_vidc_setup_context_bank(cb, cb->dev); rc = msm_vidc_setup_context_bank(cb, cb->dev, false); if (rc) { dprintk(VIDC_ERR, "Cannot setup context bank %d\n", rc); goto err_setup_cb; Loading Loading @@ -1659,3 +1759,42 @@ int read_bus_resources_from_dt(struct platform_device *pdev) return msm_vidc_populate_bus(&pdev->dev, &core->resources); } int msm_vidc_enable_cma(struct msm_vidc_platform_resources *res, bool enable) { int rc; int secure_vmid = VMID_INVAL; struct context_bank_info *cb = NULL; dprintk(VIDC_DBG, "%s: In enable status %d\n", __func__, enable); msm_vidc_detach_context_banks(res); list_for_each_entry(cb, &res->context_banks, list) { if (cb->is_secure && cb->cma.s1_bypass) { if (enable) { rc = msm_vidc_switch_vmid(VMID_CP_CAMERA_ENCODE, cb); if (rc) { dprintk(VIDC_ERR, "failed SID switching\n"); goto detach_cb; } } else { secure_vmid = get_secure_vmid(cb); rc = msm_vidc_switch_vmid(secure_vmid, cb); if (rc) goto detach_cb; } } rc = msm_vidc_setup_context_bank(cb, cb->dev, enable); if (rc) goto detach_cb; } return rc; detach_cb: dprintk(VIDC_DBG, "%s: - failed %d\n", __func__, enable); msm_vidc_detach_context_banks(res); return rc; }
drivers/media/platform/msm/vidc_3x/msm_vidc_res_parse.h +1 −0 Original line number Diff line number Diff line Loading @@ -31,4 +31,5 @@ int msm_vidc_load_u32_table(struct platform_device *pdev, struct device_node *of_node, char *table_name, int struct_size, u32 **table, u32 *num_elements); int msm_vidc_enable_cma(struct msm_vidc_platform_resources *res, bool enable); #endif