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

Commit a2117785 authored by Rahul Sharma's avatar Rahul Sharma Committed by Gerrit - the friendly Code Review server
Browse files

msm: ais: Camera clock voting fixes for LA XO



AIS camera voting on VFE and ISPIF clocks cause XO shutdown failure.
So, add new AIS manager driver, to control AIS camera clock votes.
Also add a new method in early camera driver to turn on/off clocks
when it's needed.

Change-Id: I43090b51cb29ca9de62dfa191f77b7aa9dae8613
Signed-off-by: default avatarRahul Sharma <sharah@codeaurora.org>
parent 04b6b652
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -21,4 +21,5 @@ obj-$(CONFIG_MSM_AIS) += ispif/
obj-$(CONFIG_MSM_AIS_JPEG) += jpeg_10/
obj-$(CONFIG_MSM_AIS_JPEGDMA) += jpeg_dma/
obj-$(CONFIG_MSM_AIS) += msm_buf_mgr/
obj-$(CONFIG_MSM_AIS) += msm_ais_mgr/
obj-$(CONFIG_MSM_AIS_FD) += fd/
+1 −10
Original line number Diff line number Diff line
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2018, 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
@@ -306,19 +306,12 @@ int msm_vfe47_init_hardware(struct vfe_device *vfe_dev)
	vfe_dev->common_data->dual_vfe_res->vfe_base[vfe_dev->pdev->id] =
		vfe_dev->vfe_base;

	rc = msm_isp_update_bandwidth(ISP_VFE0 + vfe_dev->pdev->id,
					MSM_ISP_MIN_AB, MSM_ISP_MIN_IB);
	if (rc)
		goto bw_enable_fail;

	rc = msm_camera_enable_irq(vfe_dev->vfe_irq, 1);
	if (rc < 0)
		goto irq_enable_fail;

	return rc;
irq_enable_fail:
	msm_isp_update_bandwidth(ISP_VFE0 + vfe_dev->pdev->id, 0, 0);
bw_enable_fail:
	vfe_dev->common_data->dual_vfe_res->vfe_base[vfe_dev->pdev->id] = NULL;
	if (cam_config_ahb_clk(NULL, 0, id, CAM_AHB_SUSPEND_VOTE) < 0)
		pr_err("%s: failed to remove vote for AHB\n", __func__);
@@ -347,8 +340,6 @@ void msm_vfe47_release_hardware(struct vfe_device *vfe_dev)

	vfe_dev->common_data->dual_vfe_res->vfe_base[vfe_dev->pdev->id] = NULL;

	msm_isp_update_bandwidth(ISP_VFE0 + vfe_dev->pdev->id, 0, 0);

	if (vfe_dev->pdev->id == 0)
		id = CAM_AHB_CLIENT_VFE0;
	else
+6 −5
Original line number Diff line number Diff line
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2018, 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
@@ -1106,9 +1106,11 @@ void msm_isp_calculate_bandwidth(
	int bpp = 0;

	if (stream_info->stream_src < RDI_INTF_0) {
		stream_info->max_width = max(stream_info->max_width,
			axi_data->src_info[VFE_PIX_0].width);
		stream_info->bandwidth =
			(axi_data->src_info[VFE_PIX_0].pixel_clock /
			axi_data->src_info[VFE_PIX_0].width) *
			(axi_data->src_info[VFE_PIX_0].pixel_clock *
			axi_data->src_info[VFE_PIX_0].width) /
			stream_info->max_width;
		stream_info->bandwidth = (unsigned long)stream_info->bandwidth *
			stream_info->format_factor / ISP_Q2;
@@ -2272,8 +2274,7 @@ int msm_isp_update_stream_bandwidth(struct vfe_device *vfe_dev,

	total_bandwidth = total_pix_bandwidth + total_rdi_bandwidth;
		rc = msm_isp_update_bandwidth(ISP_VFE0 + vfe_dev->pdev->id,
			(total_bandwidth + vfe_dev->hw_info->min_ab),
			(total_bandwidth + vfe_dev->hw_info->min_ib));
			total_bandwidth, total_bandwidth);
	if (rc < 0)
		pr_err("%s: update failed\n", __func__);

+24 −1
Original line number Diff line number Diff line
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2018, 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
@@ -2217,6 +2217,7 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
{
	struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd);
	long rc = 0;
	enum cam_ahb_clk_client id;

	ISP_DBG("%s open_cnt %u\n", __func__, vfe_dev->vfe_open_cnt);

@@ -2291,6 +2292,17 @@ int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
	cam_smmu_reg_client_page_fault_handler(
			vfe_dev->buf_mgr->iommu_hdl,
			msm_vfe_iommu_fault_handler, vfe_dev);

	/* Disable vfe clks and allow device to go XO shutdown mode */
	if (vfe_dev->pdev->id == 0)
		id = CAM_AHB_CLIENT_VFE0;
	else
		id = CAM_AHB_CLIENT_VFE1;
	if (cam_config_ahb_clk(NULL, 0, id, CAM_AHB_SUSPEND_VOTE) < 0)
		pr_err("%s: failed to remove vote for AHB\n", __func__);
	vfe_dev->hw_info->vfe_ops.platform_ops.enable_clks(vfe_dev, 0);
	vfe_dev->hw_info->vfe_ops.platform_ops.enable_regulators(vfe_dev, 0);

	mutex_unlock(&vfe_dev->core_mutex);
	mutex_unlock(&vfe_dev->realtime_mutex);
	return 0;
@@ -2313,11 +2325,22 @@ int msm_isp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
	long rc = 0;
	int wm;
	struct vfe_device *vfe_dev = v4l2_get_subdevdata(sd);
	enum cam_ahb_clk_client id;

	ISP_DBG("%s E open_cnt %u\n", __func__, vfe_dev->vfe_open_cnt);
	mutex_lock(&vfe_dev->realtime_mutex);
	mutex_lock(&vfe_dev->core_mutex);

	/* Enable vfe clks to wake up from XO shutdown mode */
	if (vfe_dev->pdev->id == 0)
		id = CAM_AHB_CLIENT_VFE0;
	else
		id = CAM_AHB_CLIENT_VFE1;
	if (cam_config_ahb_clk(NULL, 0, id, CAM_AHB_SVS_VOTE) < 0)
		pr_err("%s: failed to vote for AHB\n", __func__);
	vfe_dev->hw_info->vfe_ops.platform_ops.enable_clks(vfe_dev, 1);
	vfe_dev->hw_info->vfe_ops.platform_ops.enable_regulators(vfe_dev, 1);

	if (!vfe_dev->vfe_open_cnt) {
		pr_err("%s invalid state open cnt %d\n", __func__,
			vfe_dev->vfe_open_cnt);
+10 −8
Original line number Diff line number Diff line
/* Copyright (c) 2013-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2018, 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
@@ -1437,13 +1437,6 @@ static int msm_ispif_init(struct ispif_device *ispif,
			return -ENOMEM;
	}

	rc = cam_config_ahb_clk(NULL, 0,
			CAM_AHB_CLIENT_ISPIF, CAM_AHB_SVS_VOTE);
	if (rc < 0) {
		pr_err("%s: failed to vote for AHB\n", __func__);
		return rc;
	}

	rc = msm_ispif_reset_hw(ispif);
	if (rc)
		goto error_ahb;
@@ -1608,6 +1601,11 @@ static int ispif_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
		rc = msm_camera_enable_irq(ispif->irq, 1);
		if (rc)
			goto irq_enable_fail;

		/* Disable ispif clk and allow device to go XO shutdown */
		msm_ispif_clk_ahb_enable(ispif, 0);
		msm_ispif_set_regulators(ispif->ispif_vdd,
					ispif->ispif_vdd_count, 0);
	}
	/* mem remap is done in init when the clock is on */
	ispif->open_cnt++;
@@ -1640,6 +1638,10 @@ static int ispif_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
	}
	ispif->open_cnt--;
	if (ispif->open_cnt == 0) {
		/* Enable ispif clk to wake up from XO shutdown mode */
		msm_ispif_clk_ahb_enable(ispif, 1);
		msm_ispif_set_regulators(ispif->ispif_vdd,
					ispif->ispif_vdd_count, 1);
		msm_ispif_release(ispif);
		/* disable clocks and regulator on last close */
		msm_ispif_clk_ahb_enable(ispif, 0);
Loading