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

Commit 519d453d authored by Karthik Anantha Ram's avatar Karthik Anantha Ram Committed by Mukund Madhusudan Atre
Browse files

msm: camera: icp: Update A5 clock per frame



A5 (ICP) clock corners IPE clock source. This change
updates ICP clock based on the rate updated for IPE.

Change-Id: I2c0b711d34ea8ab8ccf458ecb77402ecf6bf967e
Signed-off-by: default avatarKarthik Anantha Ram <kartanan@codeaurora.org>
Signed-off-by: default avatarMukund Madhusudan Atre <matre@codeaurora.org>
parent 827791ea
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -519,6 +519,25 @@ int cam_a5_process_cmd(void *device_priv, uint32_t cmd_type,

		break;
	}
	case CAM_ICP_A5_CMD_CLK_UPDATE: {
		int32_t clk_level = 0;

		if (!cmd_args) {
			CAM_ERR(CAM_ICP, "Invalid args");
			return -EINVAL;
		}

		clk_level = *((int32_t *)cmd_args);
		CAM_DBG(CAM_ICP,
			"Update ICP clock to level [%d]", clk_level);
		rc = cam_a5_update_clk_rate(soc_info, clk_level);
		if (rc)
			CAM_ERR(CAM_ICP,
				"Failed to update clk to level: %d rc: %d",
				clk_level, rc);

		break;
	}
	default:
		break;
	}
+44 −0
Original line number Diff line number Diff line
@@ -196,3 +196,47 @@ int cam_a5_disable_soc_resources(struct cam_hw_soc_info *soc_info)

	return rc;
}

int cam_a5_update_clk_rate(struct cam_hw_soc_info *soc_info,
	int32_t clk_level)
{
	int32_t src_clk_idx = 0;
	int32_t clk_rate = 0;

	if (!soc_info) {
		CAM_ERR(CAM_ICP, "Invalid args");
		return -EINVAL;
	}

	if ((clk_level < 0) || (clk_level >= CAM_MAX_VOTE)) {
		CAM_ERR(CAM_ICP, "clock level %d is not valid",
			clk_level);
		return -EINVAL;
	}

	if (!soc_info->clk_level_valid[clk_level]) {
		CAM_ERR(CAM_ICP,
			"Clock level %d not supported",
			clk_level);
		return -EINVAL;
	}

	src_clk_idx = soc_info->src_clk_idx;
	if ((src_clk_idx < 0) || (src_clk_idx >= CAM_SOC_MAX_CLK)) {
		CAM_WARN(CAM_ICP, "src_clk not defined for %s",
			soc_info->dev_name);
		return -EINVAL;
	}

	clk_rate = soc_info->clk_rate[clk_level][src_clk_idx];
	if ((soc_info->clk_level_valid[CAM_TURBO_VOTE]) &&
		(soc_info->clk_rate[CAM_TURBO_VOTE][src_clk_idx] != 0) &&
		(clk_rate > soc_info->clk_rate[CAM_TURBO_VOTE][src_clk_idx])) {
		CAM_DBG(CAM_ICP, "clk_rate %d greater than max, reset to %d",
			clk_rate,
			soc_info->clk_rate[CAM_TURBO_VOTE][src_clk_idx]);
		clk_rate = soc_info->clk_rate[CAM_TURBO_VOTE][src_clk_idx];
	}

	return cam_soc_util_set_src_clk_rate(soc_info, clk_rate);
}
+2 −0
Original line number Diff line number Diff line
@@ -34,4 +34,6 @@ int cam_a5_enable_soc_resources(struct cam_hw_soc_info *soc_info);

int cam_a5_disable_soc_resources(struct cam_hw_soc_info *soc_info);

int cam_a5_update_clk_rate(struct cam_hw_soc_info *soc_info,
	int32_t clk_level);
#endif
+14 −2
Original line number Diff line number Diff line
@@ -1320,12 +1320,14 @@ static int cam_icp_update_clk_rate(struct cam_icp_hw_mgr *hw_mgr,
	struct cam_hw_intf *ipe0_dev_intf = NULL;
	struct cam_hw_intf *ipe1_dev_intf = NULL;
	struct cam_hw_intf *bps_dev_intf = NULL;
	struct cam_hw_intf *a5_dev_intf = NULL;
	struct cam_hw_intf *dev_intf = NULL;
	struct cam_a5_clk_update_cmd clk_upd_cmd;

	ipe0_dev_intf = hw_mgr->ipe0_dev_intf;
	ipe1_dev_intf = hw_mgr->ipe1_dev_intf;
	bps_dev_intf = hw_mgr->bps_dev_intf;
	a5_dev_intf = hw_mgr->a5_dev_intf;


	if ((!ipe0_dev_intf) || (!bps_dev_intf)) {
@@ -1347,16 +1349,26 @@ static int cam_icp_update_clk_rate(struct cam_icp_hw_mgr *hw_mgr,
		ctx_data->icp_dev_acquire_info->dev_type);
	clk_upd_cmd.curr_clk_rate = curr_clk_rate;
	clk_upd_cmd.ipe_bps_pc_enable = icp_hw_mgr.ipe_bps_pc_flag;
	clk_upd_cmd.clk_level = -1;

	dev_intf->hw_ops.process_cmd(dev_intf->hw_priv, id,
		&clk_upd_cmd, sizeof(struct cam_a5_clk_update_cmd));

	if (ctx_data->icp_dev_acquire_info->dev_type != CAM_ICP_RES_TYPE_BPS)
		if (ipe1_dev_intf)
	if (ctx_data->icp_dev_acquire_info->dev_type != CAM_ICP_RES_TYPE_BPS) {
		if (ipe1_dev_intf) {
			ipe1_dev_intf->hw_ops.process_cmd(
				ipe1_dev_intf->hw_priv, id,
				&clk_upd_cmd,
				sizeof(struct cam_a5_clk_update_cmd));
		}

		/* update a5 clock */
		CAM_DBG(CAM_ICP, "Update ICP clk to level [%d]",
			clk_upd_cmd.clk_level);
		a5_dev_intf->hw_ops.process_cmd(a5_dev_intf->hw_priv,
			CAM_ICP_A5_CMD_CLK_UPDATE, &clk_upd_cmd.clk_level,
			sizeof(clk_upd_cmd.clk_level));
	}

	return 0;
}
+2 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
 */

#ifndef CAM_A5_HW_INTF_H
@@ -26,6 +26,7 @@ enum cam_icp_a5_cmd_type {
	CAM_ICP_A5_CMD_CPAS_STOP,
	CAM_ICP_A5_CMD_UBWC_CFG,
	CAM_ICP_A5_CMD_PC_PREP,
	CAM_ICP_A5_CMD_CLK_UPDATE,
	CAM_ICP_A5_CMD_MAX,
};

Loading