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

Commit 743c3c5a authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "Merge remote-tracking branch 'dev/msm-4.14' into msm-4.9 05/20"

parents 83110208 1f291b32
Loading
Loading
Loading
Loading
+12 −1
Original line number Diff line number Diff line
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2019, 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
@@ -251,6 +251,17 @@ struct cam_cdm_intf_mgr {
	int32_t refcount;
};

/**
 * struct cam_cdm_debugfs_entry : debugfs entry struct
 *
 * @dentry                       : entry of debugfs
 * @dump_register                : flag to dump registers
 */
struct cam_cdm_debugfs_entry {
	struct dentry   *dentry;
	bool             dump_register;
};

int cam_cdm_intf_register_hw_cdm(struct cam_hw_intf *hw,
	struct cam_cdm_private_dt_data *data, enum cam_cdm_type type,
	uint32_t *index);
+31 −0
Original line number Diff line number Diff line
@@ -38,6 +38,8 @@

static void cam_hw_cdm_work(struct work_struct *work);

static struct cam_cdm_debugfs_entry debugfs_entry;

/* DT match table entry for all CDM variants*/
static const struct of_device_id msm_cam_hw_cdm_dt_match[] = {
	{
@@ -69,6 +71,31 @@ int cam_hw_cdm_bl_fifo_pending_bl_rb(struct cam_hw_info *cdm_hw,
	return rc;
}

static int cam_hw_cdm_create_debugfs_entry(void)
{
	int rc = 0;

	debugfs_entry.dentry = debugfs_create_dir("camera_cdm", NULL);
	if (!debugfs_entry.dentry)
		return -ENOMEM;

	if (!debugfs_create_bool("dump_register",
		0644,
		debugfs_entry.dentry,
		&debugfs_entry.dump_register)) {
		CAM_ERR(CAM_CDM,
			"failed to create dump_register entry");
		rc = -ENOMEM;
		goto err;
	}

	return rc;
err:
	debugfs_remove_recursive(debugfs_entry.dentry);
	debugfs_entry.dentry = NULL;
	return rc;
}

static int cam_hw_cdm_enable_bl_done_irq(struct cam_hw_info *cdm_hw,
	bool enable)
{
@@ -186,6 +213,9 @@ void cam_hw_cdm_dump_core_debug_registers(
{
	uint32_t dump_reg, core_dbg, loop_cnt;

	if (!debugfs_entry.dump_register)
		return;

	mutex_lock(&cdm_hw->hw_mutex);
	cam_cdm_read_hw_reg(cdm_hw, CDM_CFG_CORE_EN, &dump_reg);
	CAM_ERR(CAM_CDM, "CDM HW core status=%x", dump_reg);
@@ -1020,6 +1050,7 @@ int cam_hw_cdm_probe(struct platform_device *pdev)
	}
	cdm_hw->open_count--;
	mutex_unlock(&cdm_hw->hw_mutex);
	cam_hw_cdm_create_debugfs_entry();

	CAM_DBG(CAM_CDM, "CDM%d probe successful", cdm_hw_intf->hw_idx);

+10 −0
Original line number Diff line number Diff line
@@ -45,6 +45,14 @@ static int cam_icp_context_dump_active_request(void *data, unsigned long iova,
		return -EINVAL;
	}

	mutex_lock(&ctx->ctx_mutex);

	if (ctx->state < CAM_CTX_ACQUIRED || ctx->state > CAM_CTX_ACTIVATED) {
		CAM_ERR(CAM_ICP, "Invalid state icp ctx %d state %d",
			ctx->ctx_id, ctx->state);
		goto end;
	}

	CAM_INFO(CAM_ICP, "iommu fault for icp ctx %d state %d",
		ctx->ctx_id, ctx->state);

@@ -63,6 +71,8 @@ static int cam_icp_context_dump_active_request(void *data, unsigned long iova,
				req->request_id, rc);
	}

end:
	mutex_unlock(&ctx->ctx_mutex);
	return rc;
}

+38 −1
Original line number Diff line number Diff line
@@ -64,6 +64,37 @@ static struct cam_icp_hw_mgr icp_hw_mgr;

static void cam_icp_mgr_process_dbg_buf(unsigned int debug_lvl);

static int cam_icp_dump_io_cfg(struct cam_icp_hw_ctx_data *ctx_data,
	int32_t buf_handle)
{
	uintptr_t vaddr_ptr;
	uint32_t  *ptr;
	size_t    len;
	int       rc, i;
	char      buf[512];
	int       used = 0;

	rc = cam_mem_get_cpu_buf(buf_handle, &vaddr_ptr, &len);
	if (rc) {
		CAM_ERR(CAM_ICP, "Unable to get io_cfg buf address for %d",
			ctx_data->ctx_id);
		return rc;
	}

	len = len / sizeof(uint32_t);
	ptr = (uint32_t *)vaddr_ptr;
	for (i = 0; i < len; i++) {
		used += snprintf(buf + used,
			sizeof(buf) - used, "0X%08X-", ptr[i]);
		if (!(i % 8)) {
			CAM_INFO(CAM_ICP, "%s: %s", __func__, buf);
			used = 0;
		}
	}

	return rc;
}

static int cam_icp_send_ubwc_cfg(struct cam_icp_hw_mgr *hw_mgr)
{
	struct cam_hw_intf *a5_dev_intf = NULL;
@@ -4059,8 +4090,12 @@ static int cam_icp_mgr_prepare_hw_update(void *hw_mgr_priv,

	packet = prepare_args->packet;

	if (cam_packet_util_validate_packet(packet, prepare_args->remain_len))
	if (cam_packet_util_validate_packet(packet, prepare_args->remain_len)) {
		mutex_unlock(&ctx_data->ctx_mutex);
		CAM_ERR(CAM_ICP, "ctx id: %u packet req id %lld validate fail",
			ctx_data->ctx_id, packet->header.request_id);
		return -EINVAL;
	}

	rc = cam_icp_mgr_pkt_validation(packet);
	if (rc) {
@@ -4681,6 +4716,8 @@ static int cam_icp_mgr_acquire_hw(void *hw_mgr_priv, void *acquire_hw_args)
	rc = cam_icp_mgr_send_config_io(ctx_data, io_buf_addr);
	if (rc) {
		CAM_ERR(CAM_ICP, "IO Config command failed %d", rc);
		cam_icp_dump_io_cfg(ctx_data,
			icp_dev_acquire_info->io_config_cmd_handle);
		goto ioconfig_failed;
	}

+48 −85
Original line number Diff line number Diff line
@@ -46,7 +46,7 @@
#define CAM_CSID_IRQ_SOF_DEBUG_CNT_MAX 12

/* Max CSI Rx irq error count threshold value */
#define CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT               100
#define CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT               5

static int cam_ife_csid_is_ipp_ppp_format_supported(
	uint32_t in_format)
@@ -1478,15 +1478,13 @@ static void cam_ife_csid_halt_csi2(

	csid_reg = csid_hw->csid_info->csid_reg;
	soc_info = &csid_hw->hw_info->soc_info;
	CAM_INFO(CAM_ISP, "CSID: %d cnt: %d Halt csi2 rx",
		csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt);

	/* Disable the CSI2 rx inerrupts */
	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
	cam_io_w(0, soc_info->reg_map[0].mem_base +
		csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);

	/* Reset the Rx CFG registers */
	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
	cam_io_w(0, soc_info->reg_map[0].mem_base +
		csid_reg->csi2_reg->csid_csi2_rx_cfg0_addr);
	cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
		csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
@@ -3091,13 +3089,11 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
	cam_io_w_mb(1, soc_info->reg_map[0].mem_base +
		csid_reg->cmn_reg->csid_irq_cmd_addr);

	CAM_DBG(CAM_ISP, "irq_status_top = 0x%x", irq_status_top);
	CAM_DBG(CAM_ISP, "irq_status_rx = 0x%x", irq_status_rx);
	CAM_DBG(CAM_ISP, "irq_status_ipp = 0x%x", irq_status_ipp);
	CAM_DBG(CAM_ISP, "irq_status_ppp = 0x%x", irq_status_ppp);
	CAM_DBG(CAM_ISP, "irq_status_rdi0= 0x%x", irq_status_rdi[0]);
	CAM_DBG(CAM_ISP, "irq_status_rdi1= 0x%x", irq_status_rdi[1]);
	CAM_DBG(CAM_ISP, "irq_status_rdi2= 0x%x", irq_status_rdi[2]);
	CAM_DBG(CAM_ISP,
		"CSID %d irq status 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
		csid_hw->hw_intf->hw_idx, irq_status_top,
		irq_status_rx, irq_status_ipp, irq_status_ppp,
		irq_status_rdi[0], irq_status_rdi[1], irq_status_rdi[2]);

	if (irq_status_rx & BIT(csid_reg->csi2_reg->csi2_rst_done_shift_val)) {
		CAM_DBG(CAM_ISP, "csi rx reset complete");
@@ -3107,71 +3103,38 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
	spin_lock_irqsave(&csid_hw->lock_state, flags);
	if (csid_hw->device_enabled == 1) {
		if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW) {
			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 0 over flow",
				 csid_hw->hw_intf->hw_idx);
			fatal_err_detected = true;
			goto handle_fatal_error;
		}
		if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW) {
			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 1 over flow",
				 csid_hw->hw_intf->hw_idx);
			fatal_err_detected = true;
			goto handle_fatal_error;
		}
		if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW) {
			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 2 over flow",
				 csid_hw->hw_intf->hw_idx);
			fatal_err_detected = true;
			goto handle_fatal_error;
		}
		if (irq_status_rx & CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW) {
			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d lane 3 over flow",
				 csid_hw->hw_intf->hw_idx);
			fatal_err_detected = true;
			goto handle_fatal_error;
		}
		if (irq_status_rx & CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW) {
			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d TG OVER FLOW",
				 csid_hw->hw_intf->hw_idx);
			fatal_err_detected = true;
			goto handle_fatal_error;
		}
		if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION) {
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d CPHY_EOT_RECEPTION",
				 csid_hw->hw_intf->hw_idx);
			csid_hw->error_irq_count++;
		}
		if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION) {
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d CPHY_SOT_RECEPTION",
				 csid_hw->hw_intf->hw_idx);
			csid_hw->error_irq_count++;
		}
		if (irq_status_rx & CSID_CSI2_RX_ERROR_CPHY_PH_CRC) {
			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d CPHY_PH_CRC",
				 csid_hw->hw_intf->hw_idx);
		}
		if (irq_status_rx & CSID_CSI2_RX_ERROR_CRC) {
			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d ERROR_CRC",
				 csid_hw->hw_intf->hw_idx);
		}
		if (irq_status_rx & CSID_CSI2_RX_ERROR_ECC) {
			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d ERROR_ECC",
				 csid_hw->hw_intf->hw_idx);
		}
		if (irq_status_rx & CSID_CSI2_RX_ERROR_MMAPPED_VC_DT) {
			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d MMAPPED_VC_DT",
				 csid_hw->hw_intf->hw_idx);
		}
		if (irq_status_rx & CSID_CSI2_RX_ERROR_STREAM_UNDERFLOW) {
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d ERROR_STREAM_UNDERFLOW",
				 csid_hw->hw_intf->hw_idx);
			csid_hw->error_irq_count++;
		}
		if (irq_status_rx & CSID_CSI2_RX_ERROR_UNBOUNDED_FRAME) {
			CAM_ERR_RATE_LIMIT(CAM_ISP, "CSID:%d UNBOUNDED_FRAME",
				 csid_hw->hw_intf->hw_idx);
			csid_hw->error_irq_count++;
		}
	}
	spin_unlock_irqrestore(&csid_hw->lock_state, flags);

	if (csid_hw->error_irq_count >
		CAM_IFE_CSID_MAX_IRQ_ERROR_COUNT) {
@@ -3179,8 +3142,15 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
		csid_hw->error_irq_count = 0;
	}

	if (fatal_err_detected)
handle_fatal_error:
	spin_unlock_irqrestore(&csid_hw->lock_state, flags);
	if (fatal_err_detected) {
		CAM_INFO(CAM_ISP,
			"CSID: %d cnt: %d Halt csi2 rx irq_status_rx:0x%x",
			csid_hw->hw_intf->hw_idx, csid_hw->csi2_cfg_cnt,
			irq_status_rx);
		cam_ife_csid_halt_csi2(csid_hw);
	}

	if (csid_hw->csid_debug & CSID_DEBUG_ENABLE_EOT_IRQ) {
		if (irq_status_rx & CSID_CSI2_RX_INFO_PHY_DL0_EOT_CAPTURED) {
@@ -3281,7 +3251,6 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
		/* IPP reset done bit */
		if (irq_status_ipp &
			BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
			CAM_DBG(CAM_ISP, "CSID IPP reset complete");
			complete(&csid_hw->csid_ipp_complete);
		}

@@ -3298,28 +3267,25 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
			CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d IPP EOF received",
				csid_hw->hw_intf->hw_idx);

		if ((irq_status_ipp & CSID_PATH_ERROR_CCIF_VIOLATION))
			CAM_INFO_RATE_LIMIT(CAM_ISP,
				"CSID:%d IPP CCIF violation",
				csid_hw->hw_intf->hw_idx);

		if (irq_status_ipp & CSID_PATH_ERROR_FIFO_OVERFLOW) {
		if ((irq_status_ipp & CSID_PATH_ERROR_CCIF_VIOLATION) ||
			(irq_status_ipp & CSID_PATH_ERROR_FIFO_OVERFLOW)) {
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d IPP fifo over flow",
				csid_hw->hw_intf->hw_idx);
				"CSID:%d irq_status_ipp:0x%x",
				csid_hw->hw_intf->hw_idx, irq_status_ipp);
			if (irq_status_ipp & CSID_PATH_ERROR_FIFO_OVERFLOW) {
				/* Stop IPP path immediately */
				cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
					soc_info->reg_map[0].mem_base +
					csid_reg->ipp_reg->csid_pxl_ctrl_addr);
			}
		}
	}

	/*read PPP errors */
	if (csid_reg->cmn_reg->num_ppp) {
		/* PPP reset done bit */
		if (irq_status_ppp &
			BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
			CAM_DBG(CAM_ISP, "CSID PPP reset complete");
			complete(&csid_hw->csid_ppp_complete);
		}

@@ -3336,26 +3302,23 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
			CAM_INFO_RATE_LIMIT(CAM_ISP, "CSID:%d PPP EOF received",
				csid_hw->hw_intf->hw_idx);

		if ((irq_status_ipp & CSID_PATH_ERROR_CCIF_VIOLATION))
			CAM_INFO_RATE_LIMIT(CAM_ISP,
				"CSID:%d PPP CCIF violation",
				csid_hw->hw_intf->hw_idx);

		if (irq_status_ppp & CSID_PATH_ERROR_FIFO_OVERFLOW) {
		if ((irq_status_ppp & CSID_PATH_ERROR_CCIF_VIOLATION) ||
			(irq_status_ppp & CSID_PATH_ERROR_FIFO_OVERFLOW)) {
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d PPP fifo over flow",
				csid_hw->hw_intf->hw_idx);
				"CSID:%d irq_status_ppp:0x%x",
				csid_hw->hw_intf->hw_idx, irq_status_ppp);
			if (irq_status_ppp & CSID_PATH_ERROR_FIFO_OVERFLOW) {
				/* Stop PPP path immediately */
				cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
					soc_info->reg_map[0].mem_base +
					csid_reg->ppp_reg->csid_pxl_ctrl_addr);
			}
		}
	}

	for (i = 0; i < csid_reg->cmn_reg->num_rdis; i++) {
		if (irq_status_rdi[i] &
			BIT(csid_reg->cmn_reg->path_rst_done_shift_val)) {
			CAM_DBG(CAM_ISP, "CSID RDI%d reset complete", i);
			complete(&csid_hw->csid_rdin_complete[i]);
		}

@@ -3372,14 +3335,14 @@ irqreturn_t cam_ife_csid_irq(int irq_num, void *data)
			CAM_INFO_RATE_LIMIT(CAM_ISP,
				"CSID RDI:%d EOF received", i);

		if ((irq_status_rdi[i] & CSID_PATH_ERROR_CCIF_VIOLATION))
			CAM_INFO_RATE_LIMIT(CAM_ISP,
			"CSIDi RDI :%d CCIF violation", i);

		if (irq_status_rdi[i] & CSID_PATH_ERROR_FIFO_OVERFLOW) {
		if ((irq_status_rdi[i] & CSID_PATH_ERROR_CCIF_VIOLATION) ||
			(irq_status_rdi[i] & CSID_PATH_ERROR_FIFO_OVERFLOW)) {
			CAM_ERR_RATE_LIMIT(CAM_ISP,
				"CSID:%d RDI fifo over flow",
				csid_hw->hw_intf->hw_idx);
				"CSID:%d irq_status_rdi[%d]:0x%x",
				csid_hw->hw_intf->hw_idx, i,
				irq_status_rdi[i]);
		}
		if (irq_status_rdi[i] & CSID_PATH_ERROR_FIFO_OVERFLOW) {
			/* Stop RDI path immediately */
			cam_io_w_mb(CAM_CSID_HALT_IMMEDIATELY,
				soc_info->reg_map[0].mem_base +
Loading