From ab5a6389c6d21ea58dd07ec13d9f845a62dbb0d2 Mon Sep 17 00:00:00 2001 From: Ravikishore Pampana Date: Wed, 16 Dec 2020 13:12:28 +0530 Subject: [PATCH] msm: camera: jpeg: Handle JPEG smmu fault with pid info Kernel apis provide information fault caused pid and mid data. Handle the JPEG smmu fault using pid and mid data. Based on the mid data, dump only corresponding port info which caused the fault. Pid and mid values are target dependent, these values will be updated on the jpeg node dt entries. CRs-Fixed: 2878371 Change-Id: I0d2d1e474d4662707d85efd022ccce87e67f0d93 Signed-off-by: Ravikishore Pampana --- drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c | 194 +++++++++++------- drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h | 2 + .../jpeg_hw/include/cam_jpeg_hw_intf.h | 12 +- .../jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c | 47 ++++- .../jpeg_hw/jpeg_dma_hw/jpeg_dma_core.h | 6 +- .../jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c | 16 +- .../jpeg_hw/jpeg_dma_hw/jpeg_dma_soc.c | 36 +++- .../jpeg_hw/jpeg_dma_hw/jpeg_dma_soc.h | 20 +- .../jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c | 47 ++++- .../jpeg_hw/jpeg_enc_hw/jpeg_enc_core.h | 6 +- .../jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c | 16 +- .../jpeg_hw/jpeg_enc_hw/jpeg_enc_soc.c | 35 +++- .../jpeg_hw/jpeg_enc_hw/jpeg_enc_soc.h | 20 +- 13 files changed, 366 insertions(+), 91 deletions(-) diff --git a/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c b/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c index 7d3b42e7a740..8078ee59dc20 100644 --- a/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c +++ b/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c @@ -694,75 +694,6 @@ err_after_dq_free_list: return rc; } -static void cam_jpeg_mgr_print_io_bufs(struct cam_packet *packet, - int32_t iommu_hdl, int32_t sec_mmu_hdl, uint32_t pf_buf_info, - bool *mem_found) -{ - dma_addr_t iova_addr; - size_t src_buf_size; - int i; - int j; - int rc = 0; - int32_t mmu_hdl; - struct cam_buf_io_cfg *io_cfg = NULL; - - if (mem_found) - *mem_found = false; - - io_cfg = (struct cam_buf_io_cfg *)((uint32_t *)&packet->payload + - packet->io_configs_offset / 4); - - for (i = 0; i < packet->num_io_configs; i++) { - for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) { - if (!io_cfg[i].mem_handle[j]) - break; - - if (GET_FD_FROM_HANDLE(io_cfg[i].mem_handle[j]) == - GET_FD_FROM_HANDLE(pf_buf_info)) { - CAM_INFO(CAM_JPEG, - "Found PF at port: %d mem %x fd: %x", - io_cfg[i].resource_type, - io_cfg[i].mem_handle[j], - pf_buf_info); - if (mem_found) - *mem_found = true; - } - - CAM_INFO(CAM_JPEG, "port: %d f: %u format: %d dir %d", - io_cfg[i].resource_type, - io_cfg[i].fence, - io_cfg[i].format, - io_cfg[i].direction); - - mmu_hdl = cam_mem_is_secure_buf( - io_cfg[i].mem_handle[j]) ? sec_mmu_hdl : - iommu_hdl; - rc = cam_mem_get_io_buf(io_cfg[i].mem_handle[j], - mmu_hdl, &iova_addr, &src_buf_size); - if (rc < 0) { - CAM_ERR(CAM_UTIL, "get src buf address fail"); - continue; - } - if ((iova_addr & 0xFFFFFFFF) != iova_addr) { - CAM_ERR(CAM_JPEG, "Invalid mapped address"); - rc = -EINVAL; - continue; - } - - CAM_INFO(CAM_JPEG, - "pln %u w %u h %u stride %u slice %u size %d addr 0x%x offset 0x%x memh %x", - j, io_cfg[i].planes[j].width, - io_cfg[i].planes[j].height, - io_cfg[i].planes[j].plane_stride, - io_cfg[i].planes[j].slice_height, - (int32_t)src_buf_size, - (unsigned int)iova_addr, - io_cfg[i].offsets[j], - io_cfg[i].mem_handle[j]); - } - } -} - static int cam_jpeg_mgr_prepare_hw_update(void *hw_mgr_priv, void *prepare_hw_update_args) { @@ -1570,6 +1501,18 @@ static int cam_jpeg_init_devices(struct device_node *of_node, g_jpeg_hw_mgr.cdm_reg_map[CAM_JPEG_DEV_DMA][0] = &dma_soc_info->reg_map[0]; + rc = g_jpeg_hw_mgr.devices[CAM_JPEG_DEV_ENC][0]->hw_ops.process_cmd( + g_jpeg_hw_mgr.devices[CAM_JPEG_DEV_ENC][0]->hw_priv, + CAM_JPEG_CMD_GET_NUM_PID, + &g_jpeg_hw_mgr.num_pid[CAM_JPEG_DEV_ENC], + sizeof(uint32_t)); + + rc = g_jpeg_hw_mgr.devices[CAM_JPEG_DEV_DMA][0]->hw_ops.process_cmd( + g_jpeg_hw_mgr.devices[CAM_JPEG_DEV_DMA][0]->hw_priv, + CAM_JPEG_CMD_GET_NUM_PID, + &g_jpeg_hw_mgr.num_pid[CAM_JPEG_DEV_DMA], + sizeof(uint32_t)); + *p_num_enc_dev = num_dev; *p_num_dma_dev = num_dma_dev; @@ -1722,6 +1665,109 @@ hw_dump: return rc; } +static void cam_jpeg_mgr_dump_pf_data( + struct cam_jpeg_hw_mgr *hw_mgr, + struct cam_hw_cmd_args *hw_cmd_args) +{ + struct cam_jpeg_hw_ctx_data *ctx_data; + struct cam_packet *packet; + struct cam_jpeg_match_pid_args jpeg_pid_mid_args; + struct cam_buf_io_cfg *io_cfg = NULL; + uint32_t dev_type; + dma_addr_t iova_addr; + size_t src_buf_size; + int i, j; + int32_t mmu_hdl; + bool hw_pid_support = true; + int rc = 0; + + ctx_data = (struct cam_jpeg_hw_ctx_data *)hw_cmd_args->ctxt_to_hw_map; + packet = hw_cmd_args->u.pf_args.pf_data.packet; + + jpeg_pid_mid_args.fault_mid = hw_cmd_args->u.pf_args.mid; + jpeg_pid_mid_args.pid = hw_cmd_args->u.pf_args.pid; + dev_type = ctx_data->jpeg_dev_acquire_info.dev_type; + + if (!hw_mgr->num_pid[dev_type]) { + hw_pid_support = false; + goto iodump; + } + + rc = hw_mgr->devices[dev_type][0]->hw_ops.process_cmd( + hw_mgr->devices[dev_type][0]->hw_priv, + CAM_JPEG_CMD_MATCH_PID_MID, + &jpeg_pid_mid_args, sizeof(jpeg_pid_mid_args)); + if (rc) { + CAM_ERR(CAM_JPEG, "CAM_JPEG_CMD_MATCH_PID_MID failed %d", rc); + return; + } + + if (!jpeg_pid_mid_args.pid_match_found) { + CAM_INFO(CAM_JPEG, "This context data is not matched with pf pid and mid"); + return; + } + +iodump: + io_cfg = (struct cam_buf_io_cfg *)((uint32_t *)&packet->payload + + packet->io_configs_offset / 4); + + for (i = 0; i < packet->num_io_configs; i++) { + if (hw_pid_support) { + if (io_cfg[i].resource_type != + jpeg_pid_mid_args.match_res) + continue; + + if (i == packet->num_io_configs) { + CAM_ERR(CAM_JPEG, + "getting io port for mid resource id failed req id:%lld res id:0x%x", + packet->header.request_id, + jpeg_pid_mid_args.match_res); + return; + } + } + + for (j = 0; j < CAM_PACKET_MAX_PLANES; j++) { + if (!io_cfg[i].mem_handle[j]) + break; + + CAM_INFO(CAM_JPEG, "port: %d f: %u format: %d dir %d", + io_cfg[i].resource_type, + io_cfg[i].fence, + io_cfg[i].format, + io_cfg[i].direction); + + mmu_hdl = cam_mem_is_secure_buf( + io_cfg[i].mem_handle[j]) ? hw_mgr->iommu_sec_hdl : + hw_mgr->iommu_hdl; + rc = cam_mem_get_io_buf(io_cfg[i].mem_handle[j], + mmu_hdl, &iova_addr, &src_buf_size); + if (rc < 0) { + CAM_ERR(CAM_UTIL, "get src buf address fail"); + continue; + } + if ((iova_addr & 0xFFFFFFFF) != iova_addr) { + CAM_ERR(CAM_JPEG, "Invalid mapped address"); + rc = -EINVAL; + continue; + } + + CAM_INFO(CAM_JPEG, + "pln %u w %u h %u stride %u slice %u size %d addr 0x%x offset 0x%x memh %x", + j, io_cfg[i].planes[j].width, + io_cfg[i].planes[j].height, + io_cfg[i].planes[j].plane_stride, + io_cfg[i].planes[j].slice_height, + (int32_t)src_buf_size, + (unsigned int)iova_addr, + io_cfg[i].offsets[j], + io_cfg[i].mem_handle[j]); + } + + if (hw_pid_support) + return; + } +} + static int cam_jpeg_mgr_cmd(void *hw_mgr_priv, void *cmd_args) { int rc = 0; @@ -1735,15 +1781,11 @@ static int cam_jpeg_mgr_cmd(void *hw_mgr_priv, void *cmd_args) switch (hw_cmd_args->cmd_type) { case CAM_HW_MGR_CMD_DUMP_PF_INFO: - cam_jpeg_mgr_print_io_bufs( - hw_cmd_args->u.pf_args.pf_data.packet, - hw_mgr->iommu_hdl, - hw_mgr->iommu_sec_hdl, - hw_cmd_args->u.pf_args.buf_info, - hw_cmd_args->u.pf_args.mem_found); + cam_jpeg_mgr_dump_pf_data(hw_mgr, hw_cmd_args); break; default: - CAM_ERR(CAM_JPEG, "Invalid cmd"); + CAM_ERR(CAM_JPEG, "Invalid cmd :%d", + hw_cmd_args->cmd_type); } return rc; diff --git a/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h b/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h index 4e90f5386f32..c4cd35307701 100644 --- a/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h +++ b/drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.h @@ -132,6 +132,7 @@ struct cam_jpeg_hw_ctx_data { * @hw_config_req_list: Pending hw update requests list * @free_req_list: Free nodes for above list * @req_list: Nodes of hw update list + * @num_pid: num of pids supported in the device */ struct cam_jpeg_hw_mgr { struct mutex hw_mgr_mutex; @@ -160,6 +161,7 @@ struct cam_jpeg_hw_mgr { struct list_head hw_config_req_list; struct list_head free_req_list; struct cam_jpeg_hw_cfg_req req_list[CAM_JPEG_HW_CFG_Q_MAX]; + uint32_t num_pid[CAM_JPEG_DEV_TYPE_MAX]; }; #endif /* CAM_JPEG_HW_MGR_H */ diff --git a/drivers/cam_jpeg/jpeg_hw/include/cam_jpeg_hw_intf.h b/drivers/cam_jpeg/jpeg_hw/include/cam_jpeg_hw_intf.h index df552c4d04cf..1856e6e3cc13 100644 --- a/drivers/cam_jpeg/jpeg_hw/include/cam_jpeg_hw_intf.h +++ b/drivers/cam_jpeg/jpeg_hw/include/cam_jpeg_hw_intf.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ #ifndef CAM_JPEG_HW_INTF_H @@ -17,6 +17,7 @@ #define CAM_JPEG_HW_DUMP_TAG_MAX_LEN 32 #define CAM_JPEG_HW_DUMP_NUM_WORDS 5 +#define CAM_JPEG_HW_MAX_NUM_PID 2 enum cam_jpeg_hw_type { CAM_JPEG_DEV_ENC, @@ -43,10 +44,19 @@ struct cam_jpeg_hw_dump_header { uint32_t word_size; }; +struct cam_jpeg_match_pid_args { + uint32_t pid; + uint32_t fault_mid; + bool pid_match_found; + uint32_t match_res; +}; + enum cam_jpeg_cmd_type { CAM_JPEG_CMD_CDM_CFG, CAM_JPEG_CMD_SET_IRQ_CB, CAM_JPEG_CMD_HW_DUMP, + CAM_JPEG_CMD_GET_NUM_PID, + CAM_JPEG_CMD_MATCH_PID_MID, CAM_JPEG_CMD_MAX, }; diff --git a/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c b/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c index 87431897d4b1..bae4f3d9982d 100644 --- a/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c +++ b/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ #include @@ -377,7 +377,9 @@ int cam_jpeg_dma_process_cmd(void *device_priv, uint32_t cmd_type, { struct cam_hw_info *jpeg_dma_dev = device_priv; struct cam_jpeg_dma_device_core_info *core_info = NULL; - int rc; + struct cam_jpeg_match_pid_args *match_pid_mid = NULL; + uint32_t *num_pid = NULL; + int i, rc = 0; if (!device_priv) { CAM_ERR(CAM_JPEG, "Invalid arguments"); @@ -412,6 +414,47 @@ int cam_jpeg_dma_process_cmd(void *device_priv, uint32_t cmd_type, rc = 0; break; } + case CAM_JPEG_CMD_GET_NUM_PID: + if (!cmd_args) { + CAM_ERR(CAM_JPEG, "cmd args NULL"); + return -EINVAL; + } + + num_pid = (uint32_t *)cmd_args; + *num_pid = core_info->num_pid; + + break; + case CAM_JPEG_CMD_MATCH_PID_MID: + match_pid_mid = (struct cam_jpeg_match_pid_args *)cmd_args; + + if (!cmd_args) { + CAM_ERR(CAM_JPEG, "cmd args NULL"); + return -EINVAL; + } + + for (i = 0; i < core_info->num_pid; i++) { + if (core_info->pid[i] == match_pid_mid->pid) + break; + } + + if (i == core_info->num_pid) + match_pid_mid->pid_match_found = false; + else + match_pid_mid->pid_match_found = true; + + if (match_pid_mid->pid_match_found) { + if (match_pid_mid->fault_mid == core_info->rd_mid) { + match_pid_mid->match_res = + CAM_JPEG_DMA_INPUT_IMAGE; + } else if (match_pid_mid->fault_mid == + core_info->wr_mid) { + match_pid_mid->match_res = + CAM_JPEG_DMA_OUTPUT_IMAGE; + } else + match_pid_mid->pid_match_found = false; + } + + break; default: rc = -EINVAL; break; diff --git a/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.h b/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.h index 94085814b472..8f08033b04f6 100644 --- a/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.h +++ b/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ #ifndef CAM_JPEG_DMA_CORE_H @@ -63,6 +63,10 @@ struct cam_jpeg_dma_device_core_info { int32_t ref_count; struct mutex core_mutex; int32_t result_size; + uint32_t num_pid; + uint32_t pid[CAM_JPEG_HW_MAX_NUM_PID]; + uint32_t rd_mid; + uint32_t wr_mid; }; int cam_jpeg_dma_init_hw(void *device_priv, diff --git a/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c b/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c index 214bde71bcb6..c5c4b78cc1f4 100644 --- a/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c +++ b/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_dev.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ #include @@ -66,7 +66,8 @@ static int cam_jpeg_dma_component_bind(struct device *dev, const struct of_device_id *match_dev = NULL; struct cam_jpeg_dma_device_core_info *core_info = NULL; struct cam_jpeg_dma_device_hw_info *hw_info = NULL; - int rc; + struct cam_jpeg_dma_soc_private *soc_private; + int i, rc; struct platform_device *pdev = to_platform_device(dev); jpeg_dma_dev_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL); @@ -135,6 +136,17 @@ static int cam_jpeg_dma_component_bind(struct device *dev, spin_lock_init(&jpeg_dma_dev->hw_lock); init_completion(&jpeg_dma_dev->hw_complete); CAM_DBG(CAM_JPEG, "JPEG-DMA component bound successfully"); + + soc_private = (struct cam_jpeg_dma_soc_private *) + jpeg_dma_dev->soc_info.soc_private; + + core_info->num_pid = soc_private->num_pid; + for (i = 0; i < soc_private->num_pid; i++) + core_info->pid[i] = soc_private->pid[i]; + + core_info->rd_mid = soc_private->rd_mid; + core_info->wr_mid = soc_private->wr_mid; + return rc; error_reg_cpas: diff --git a/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_soc.c b/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_soc.c index 9dda8f284c35..b5abbd499087 100644 --- a/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_soc.c +++ b/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_soc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019, 2021 The Linux Foundation. All rights reserved. */ #include @@ -16,8 +16,20 @@ int cam_jpeg_dma_init_soc_resources(struct cam_hw_soc_info *soc_info, irq_handler_t jpeg_dma_irq_handler, void *irq_data) { + struct cam_jpeg_dma_soc_private *soc_private; + struct platform_device *pdev = NULL; + int num_pid = 0, i = 0; int rc; + soc_private = kzalloc(sizeof(struct cam_jpeg_dma_soc_private), + GFP_KERNEL); + if (!soc_private) { + CAM_DBG(CAM_JPEG, "Error! soc_private Alloc Failed"); + return -ENOMEM; + } + soc_info->soc_private = soc_private; + pdev = soc_info->pdev; + rc = cam_soc_util_get_dt_properties(soc_info); if (rc) return rc; @@ -28,6 +40,28 @@ int cam_jpeg_dma_init_soc_resources(struct cam_hw_soc_info *soc_info, if (rc) CAM_ERR(CAM_JPEG, "init soc failed %d", rc); + soc_private->num_pid = 0; + soc_private->rd_mid = UINT_MAX; + soc_private->wr_mid = UINT_MAX; + + num_pid = of_property_count_u32_elems(pdev->dev.of_node, "cam_hw_pid"); + CAM_DBG(CAM_JPEG, "jpeg:%d pid count %d", soc_info->index, num_pid); + + if (num_pid <= 0 || num_pid > CAM_JPEG_HW_MAX_NUM_PID) + goto end; + + soc_private->num_pid = num_pid; + for (i = 0; i < num_pid; i++) + of_property_read_u32_index(pdev->dev.of_node, "cam_hw_pid", i, + &soc_private->pid[i]); + + of_property_read_u32(pdev->dev.of_node, + "cam_hw_rd_mid", &soc_private->rd_mid); + + of_property_read_u32(pdev->dev.of_node, + "cam_hw_wr_mid", &soc_private->wr_mid); + +end: return rc; } diff --git a/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_soc.h b/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_soc.h index a0c07489ee77..418dd1efe3ce 100644 --- a/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_soc.h +++ b/drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_soc.h @@ -1,12 +1,30 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018, 2021 The Linux Foundation. All rights reserved. */ #ifndef _CAM_JPEG_DMA_SOC_H_ #define _CAM_JPEG_DMA_SOC_H_ #include "cam_soc_util.h" +#include "cam_jpeg_hw_intf.h" + +/* + * struct cam_jpeg_dma_soc_private: + * + * @Brief: Private SOC data specific to JPEG DMA Driver + * + * @num_pid JPEG number of pids + * @pid: JPEG DMA pid value list + * @rd_mid: JPEG DMA inport read mid value + * @wr_mid: JPEG DMA outport write mid value + */ +struct cam_jpeg_dma_soc_private { + uint32_t num_pid; + uint32_t pid[CAM_JPEG_HW_MAX_NUM_PID]; + uint32_t rd_mid; + uint32_t wr_mid; +}; int cam_jpeg_dma_init_soc_resources(struct cam_hw_soc_info *soc_info, irq_handler_t jpeg_dma_irq_handler, void *irq_data); diff --git a/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c b/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c index 8661dbfc72e6..5f79260e1391 100644 --- a/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c +++ b/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ #include @@ -498,7 +498,9 @@ int cam_jpeg_enc_process_cmd(void *device_priv, uint32_t cmd_type, { struct cam_hw_info *jpeg_enc_dev = device_priv; struct cam_jpeg_enc_device_core_info *core_info = NULL; - int rc; + struct cam_jpeg_match_pid_args *match_pid_mid = NULL; + uint32_t *num_pid = NULL; + int i, rc = 0; if (!device_priv) { CAM_ERR(CAM_JPEG, "Invalid arguments"); @@ -539,6 +541,47 @@ int cam_jpeg_enc_process_cmd(void *device_priv, uint32_t cmd_type, cmd_args); break; } + case CAM_JPEG_CMD_GET_NUM_PID: + if (!cmd_args) { + CAM_ERR(CAM_JPEG, "cmd args NULL"); + return -EINVAL; + } + + num_pid = (uint32_t *)cmd_args; + *num_pid = core_info->num_pid; + + break; + case CAM_JPEG_CMD_MATCH_PID_MID: + match_pid_mid = (struct cam_jpeg_match_pid_args *)cmd_args; + + if (!cmd_args) { + CAM_ERR(CAM_JPEG, "cmd args NULL"); + return -EINVAL; + } + + for (i = 0 ; i < core_info->num_pid; i++) { + if (core_info->pid[i] == match_pid_mid->pid) + break; + } + + if (i == core_info->num_pid) + match_pid_mid->pid_match_found = false; + else + match_pid_mid->pid_match_found = true; + + if (match_pid_mid->pid_match_found) { + if (match_pid_mid->fault_mid == core_info->rd_mid) { + match_pid_mid->match_res = + CAM_JPEG_ENC_INPUT_IMAGE; + } else if (match_pid_mid->fault_mid == + core_info->wr_mid) { + match_pid_mid->match_res = + CAM_JPEG_ENC_OUTPUT_IMAGE; + } else + match_pid_mid->pid_match_found = false; + } + + break; default: rc = -EINVAL; break; diff --git a/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.h b/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.h index db505bf5bab7..8dfc443ccd70 100644 --- a/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.h +++ b/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ #ifndef CAM_JPEG_ENC_CORE_H @@ -66,6 +66,10 @@ struct cam_jpeg_enc_device_core_info { struct cam_jpeg_set_irq_cb irq_cb; int32_t ref_count; struct mutex core_mutex; + uint32_t num_pid; + uint32_t pid[CAM_JPEG_HW_MAX_NUM_PID]; + uint32_t rd_mid; + uint32_t wr_mid; }; int cam_jpeg_enc_init_hw(void *device_priv, diff --git a/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c b/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c index e9c9ebd6e193..5b6c307778a8 100644 --- a/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c +++ b/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_dev.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. */ #include @@ -66,8 +66,10 @@ static int cam_jpeg_enc_component_bind(struct device *dev, const struct of_device_id *match_dev = NULL; struct cam_jpeg_enc_device_core_info *core_info = NULL; struct cam_jpeg_enc_device_hw_info *hw_info = NULL; - int rc; struct platform_device *pdev = to_platform_device(dev); + struct cam_jpeg_enc_soc_private *soc_private; + int i; + int rc; jpeg_enc_dev_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL); if (!jpeg_enc_dev_intf) @@ -136,6 +138,16 @@ static int cam_jpeg_enc_component_bind(struct device *dev, init_completion(&jpeg_enc_dev->hw_complete); CAM_DBG(CAM_JPEG, "JPEG-Encoder component bound successfully"); + soc_private = (struct cam_jpeg_enc_soc_private *) + jpeg_enc_dev->soc_info.soc_private; + + core_info->num_pid = soc_private->num_pid; + for (i = 0; i < soc_private->num_pid; i++) + core_info->pid[i] = soc_private->pid[i]; + + core_info->rd_mid = soc_private->rd_mid; + core_info->wr_mid = soc_private->wr_mid; + return rc; error_reg_cpas: diff --git a/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_soc.c b/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_soc.c index 4a5d9e0a9b60..79428a6c4ca4 100644 --- a/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_soc.c +++ b/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_soc.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2019, 2021 The Linux Foundation. All rights reserved. */ #include @@ -16,8 +16,19 @@ int cam_jpeg_enc_init_soc_resources(struct cam_hw_soc_info *soc_info, irq_handler_t jpeg_enc_irq_handler, void *irq_data) { + struct cam_jpeg_enc_soc_private *soc_private; + struct platform_device *pdev = NULL; + int num_pid = 0, i = 0; int rc; + soc_private = kzalloc(sizeof(struct cam_jpeg_enc_soc_private), + GFP_KERNEL); + if (!soc_private) { + CAM_DBG(CAM_ISP, "Error! soc_private Alloc Failed"); + return -ENOMEM; + } + soc_info->soc_private = soc_private; + rc = cam_soc_util_get_dt_properties(soc_info); if (rc) return rc; @@ -28,6 +39,28 @@ int cam_jpeg_enc_init_soc_resources(struct cam_hw_soc_info *soc_info, if (rc) CAM_ERR(CAM_JPEG, "init soc failed %d", rc); + soc_private->num_pid = 0; + soc_private->rd_mid = UINT_MAX; + soc_private->wr_mid = UINT_MAX; + + pdev = soc_info->pdev; + num_pid = of_property_count_u32_elems(pdev->dev.of_node, "cam_hw_pid"); + CAM_DBG(CAM_JPEG, "jpeg enc:%d pid count %d", soc_info->index, num_pid); + + if (num_pid <= 0 || num_pid > CAM_JPEG_HW_MAX_NUM_PID) + goto end; + + soc_private->num_pid = num_pid; + for (i = 0; i < num_pid; i++) + of_property_read_u32_index(pdev->dev.of_node, "cam_hw_pid", i, + &soc_private->pid[i]); + + of_property_read_u32(pdev->dev.of_node, + "cam_hw_rd_mid", &soc_private->rd_mid); + + of_property_read_u32(pdev->dev.of_node, + "cam_hw_wr_mid", &soc_private->wr_mid); +end: return rc; } diff --git a/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_soc.h b/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_soc.h index e0fb0103de75..6e7938c87b1b 100644 --- a/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_soc.h +++ b/drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_soc.h @@ -1,12 +1,30 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2017-2018, 2021 The Linux Foundation. All rights reserved. */ #ifndef _CAM_JPEG_ENC_SOC_H_ #define _CAM_JPEG_ENC_SOC_H_ #include "cam_soc_util.h" +#include "cam_jpeg_hw_intf.h" + +/* + * struct cam_jpeg_enc_soc_private: + * + * @Brief: Private SOC data specific to JPEG ENC Driver + * + * @num_pid JPEG number of pids + * @pid: JPEG enc pid value list + * @rd_mid: JPEG enc inport read mid value + * @wr_mid: JPEG enc outport write mid value + */ +struct cam_jpeg_enc_soc_private { + uint32_t num_pid; + uint32_t pid[CAM_JPEG_HW_MAX_NUM_PID]; + uint32_t rd_mid; + uint32_t wr_mid; +}; int cam_jpeg_enc_init_soc_resources(struct cam_hw_soc_info *soc_info, irq_handler_t jpeg_enc_irq_handler, void *irq_data);