Jelajahi Sumber

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 <[email protected]>
Ravikishore Pampana 4 tahun lalu
induk
melakukan
72a587b0fd

+ 118 - 76
drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.c

@@ -697,75 +697,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, NULL);
-			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 %zx addr 0x%llx 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,
-				src_buf_size, 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)
 {
@@ -1573,6 +1504,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;
 
@@ -1725,6 +1668,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, NULL);
+			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;
@@ -1738,15 +1784,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;

+ 3 - 1
drivers/cam_jpeg/jpeg_hw/cam_jpeg_hw_mgr.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_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 */

+ 11 - 1
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,
 };
 

+ 44 - 1
drivers/cam_jpeg/jpeg_hw/jpeg_dma_hw/jpeg_dma_core.c

@@ -380,7 +380,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");
@@ -415,6 +417,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;

+ 5 - 1
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,

+ 14 - 2
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 <linux/module.h>
@@ -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:

+ 35 - 1
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 <linux/io.h>
@@ -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;
 }
 

+ 19 - 1
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);

+ 44 - 1
drivers/cam_jpeg/jpeg_hw/jpeg_enc_hw/jpeg_enc_core.c

@@ -502,7 +502,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");
@@ -543,6 +545,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;

+ 5 - 1
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,

+ 14 - 2
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 <linux/module.h>
@@ -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:

+ 34 - 1
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 <linux/io.h>
@@ -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;
 }
 

+ 19 - 1
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);