Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 85d260ec authored by Camera Software Integration's avatar Camera Software Integration Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: camera: jpeg: Handle JPEG smmu fault with pid info" into camera-kernel.lnx.4.0

parents c5d4ba42 ab5a6389
Loading
Loading
Loading
Loading
+118 −76
Original line number Diff line number Diff line
@@ -694,75 +694,6 @@ static int cam_jpeg_mgr_config_hw(void *hw_mgr_priv, void *config_hw_args)
	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 @@ static int cam_jpeg_mgr_hw_dump(void *hw_mgr_priv, void *dump_hw_args)
	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;
+2 −0
Original line number Diff line number Diff line
@@ -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
Original line number Diff line number Diff line
/* 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,
};

+45 −2
Original line number Diff line number Diff line
// 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/of.h>
@@ -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;
+5 −1
Original line number Diff line number Diff line
/* 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,
Loading