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

Commit 662fb4b7 authored by Alok Chauhan's avatar Alok Chauhan
Browse files

msm: camera: ope: add page fault handlers in ope driver



Add page fault handler functions to ope driver. Add logic
to find closest buffer and related port to page fault address.

CRs-Fixed: 2693184
Change-Id: Iaea12795b4553eaca1642cd64acd7879342d94d8
Signed-off-by: default avatarAlok Chauhan <alokc@codeaurora.org>
parent 5a2e6a78
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1256,7 +1256,7 @@ static void cam_hw_cdm_iommu_fault_handler(struct iommu_domain *domain,
		for (i = 0; i < core->offsets->reg_data->num_bl_fifo; i++)
			mutex_unlock(&core->bl_fifo[i].fifo_lock);
		mutex_unlock(&cdm_hw->hw_mutex);
		CAM_ERR_RATE_LIMIT(CAM_CDM, "Page fault iova addr %pK\n",
		CAM_ERR_RATE_LIMIT(CAM_CDM, "Page fault iova addr %pK",
			(void *)iova);
		cam_cdm_notify_clients(cdm_hw, CAM_CDM_CB_STATUS_PAGEFAULT,
			(void *)iova);
+107 −1
Original line number Diff line number Diff line
@@ -3339,6 +3339,112 @@ static int cam_ope_mgr_config_hw(void *hw_priv, void *hw_config_args)
	return rc;
}

static void cam_ope_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_OPE,
					"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_OPE, "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 rc %d mem %x",
					rc, io_cfg[i].mem_handle[j]);
				continue;
			}
			if ((iova_addr & 0xFFFFFFFF) != iova_addr) {
				CAM_ERR(CAM_OPE, "Invalid mapped address");
				rc = -EINVAL;
				continue;
			}

			CAM_INFO(CAM_OPE,
				"pln %d dir %d w %d h %d s %u sh %u sz %d addr 0x%x off 0x%x memh %x",
				j, io_cfg[i].direction,
				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]);

			iova_addr += io_cfg[i].offsets[j];

		}
	}
	cam_packet_dump_patch_info(packet, ope_hw_mgr->iommu_hdl,
		ope_hw_mgr->iommu_sec_hdl);
}

static int cam_ope_mgr_cmd(void *hw_mgr_priv, void *cmd_args)
{
	int rc = 0;
	struct cam_hw_cmd_args *hw_cmd_args = cmd_args;
	struct cam_ope_hw_mgr  *hw_mgr = hw_mgr_priv;

	if (!hw_mgr_priv || !cmd_args) {
		CAM_ERR(CAM_OPE, "Invalid arguments");
		return -EINVAL;
	}

	switch (hw_cmd_args->cmd_type) {
	case CAM_HW_MGR_CMD_DUMP_PF_INFO:
		cam_ope_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);

		break;
	default:
		CAM_ERR(CAM_OPE, "Invalid cmd");
	}

	return rc;
}

static int cam_ope_mgr_hw_open_u(void *hw_priv, void *fw_download_args)
{
	struct cam_ope_hw_mgr *hw_mgr;
@@ -3815,7 +3921,7 @@ int cam_ope_hw_mgr_init(struct device_node *of_node, uint64_t *hw_mgr_hdl,
	hw_mgr_intf->hw_config = cam_ope_mgr_config_hw;
	hw_mgr_intf->hw_read   = NULL;
	hw_mgr_intf->hw_write  = NULL;
	hw_mgr_intf->hw_cmd = NULL;
	hw_mgr_intf->hw_cmd = cam_ope_mgr_cmd;
	hw_mgr_intf->hw_open = cam_ope_mgr_hw_open_u;
	hw_mgr_intf->hw_close = cam_ope_mgr_hw_close_u;
	hw_mgr_intf->hw_flush = cam_ope_mgr_hw_flush;