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

Commit 1bba5c9f authored by Tony Lijo Jose's avatar Tony Lijo Jose Committed by Gerrit - the friendly Code Review server
Browse files

msm: camera: csiphy: Add clock dynamic voting



Add dynamic voting support for csiphy driver. This change helps to
find a best voting level based on the data rate of the sensor mode.

Change-Id: I49ddd60d029550c71615dd2920b8211dc7f97002
Signed-off-by: default avatarTony Lijo Jose <tjose@codeaurora.org>
parent 6298b5f1
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -224,13 +224,18 @@ int32_t cam_cmd_buf_parser(struct csiphy_device *csiphy_dev,
	csiphy_dev->csiphy_info.csiphy_3phase =
		cam_cmd_csiphy_info->csiphy_3phase;
	csiphy_dev->csiphy_info.combo_mode |= cam_cmd_csiphy_info->combo_mode;
	if (cam_cmd_csiphy_info->combo_mode == 1)
	if (cam_cmd_csiphy_info->combo_mode == 1) {
		csiphy_dev->csiphy_info.settle_time_combo_sensor =
			cam_cmd_csiphy_info->settle_time;
	else
		csiphy_dev->csiphy_info.data_rate_combo_sensor =
			cam_cmd_csiphy_info->data_rate;
	} else {
		csiphy_dev->csiphy_info.settle_time =
			cam_cmd_csiphy_info->settle_time;
	csiphy_dev->csiphy_info.data_rate = cam_cmd_csiphy_info->data_rate;
		csiphy_dev->csiphy_info.data_rate =
			cam_cmd_csiphy_info->data_rate;
	}


	if (cam_cmd_csiphy_info->secure_mode == 1)
		cam_csiphy_update_secure_info(csiphy_dev,
+9 −0
Original line number Diff line number Diff line
@@ -145,6 +145,8 @@ struct csiphy_reg_t {
	uint32_t csiphy_param_type;
};

struct csiphy_device;

/**
 * struct csiphy_ctrl_t
 * @csiphy_reg: Register address
@@ -156,6 +158,9 @@ struct csiphy_reg_t {
 * @csiphy_3ph_reg: 3phase register set
 * @csiphy_2ph_3ph_mode_reg:
 *     2 phase 3phase combo register set
 * @getclockvoting: function pointer which
 *      is used to find the clock voting
 *      for the sensor output data rate
 */
struct csiphy_ctrl_t {
	struct csiphy_reg_parms_t csiphy_reg;
@@ -166,6 +171,7 @@ struct csiphy_ctrl_t {
	struct csiphy_reg_t (*csiphy_2ph_combo_mode_reg)[MAX_SETTINGS_PER_LANE];
	struct csiphy_reg_t (*csiphy_3ph_reg)[MAX_SETTINGS_PER_LANE];
	struct csiphy_reg_t (*csiphy_2ph_3ph_mode_reg)[MAX_SETTINGS_PER_LANE];
	enum   cam_vote_level (*getclockvoting)(struct csiphy_device *phy_dev);
};

/**
@@ -180,6 +186,8 @@ struct csiphy_ctrl_t {
 * @settle_time   :  Settling time in ms
 * @settle_time_combo_sensor   :  Settling time in ms
 * @data_rate     :  Data rate in mbps
 * @data_rate_combo_sensor: data rate of combo sensor
 *                          in the the same phy
 *
 */
struct cam_csiphy_param {
@@ -192,6 +200,7 @@ struct cam_csiphy_param {
	uint64_t    settle_time;
	uint64_t    settle_time_combo_sensor;
	uint64_t    data_rate;
	uint64_t    data_rate_combo_sensor;
};

/**
+65 −4
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.
 */

#include "cam_csiphy_soc.h"
@@ -11,6 +11,9 @@
#include "include/cam_csiphy_1_2_1_hwreg.h"
#include "include/cam_csiphy_2_0_hwreg.h"

#define CSIPHY_3PH_DIVISOR           16
#define CSIPHY_3PH_DIVISOR_12        32
#define CSIPHY_2PH_DIVISOR           8
#define BYTES_PER_REGISTER           4
#define NUM_REGISTER_PER_LINE        4
#define REG_OFFSET(__start, __i)    ((__start) + ((__i) * BYTES_PER_REGISTER))
@@ -73,10 +76,62 @@ int32_t cam_csiphy_mem_dmp(struct cam_hw_soc_info *soc_info)
	return rc;
}

enum cam_vote_level get_clk_vote_default(struct csiphy_device *csiphy_dev)
{
	CAM_DBG(CAM_CSIPHY, "voting for SVS");
	return CAM_SVS_VOTE;
}

enum cam_vote_level get_clk_voting_dynamic(struct csiphy_device *csiphy_dev)
{
	uint32_t cam_vote_level = 0;
	uint32_t last_valid_vote = 0;
	struct cam_hw_soc_info *soc_info;
	uint64_t phy_data_rate = csiphy_dev->csiphy_info.data_rate;

	soc_info = &csiphy_dev->soc_info;

	if (csiphy_dev->is_acquired_dev_combo_mode)
		phy_data_rate = max(phy_data_rate,
			csiphy_dev->csiphy_info.data_rate_combo_sensor);

	if (csiphy_dev->csiphy_info.csiphy_3phase) {
		if (csiphy_dev->is_csiphy_3phase_hw == CSI_3PHASE_HW_12)
			do_div(phy_data_rate, CSIPHY_3PH_DIVISOR_12);
		else
			do_div(phy_data_rate, CSIPHY_3PH_DIVISOR);
	} else {
		do_div(phy_data_rate, CSIPHY_2PH_DIVISOR);
	}

	 /* round off to next integer */
	phy_data_rate += 1;

	for (cam_vote_level = 0;
			cam_vote_level < CAM_MAX_VOTE; cam_vote_level++) {
		if (soc_info->clk_level_valid[cam_vote_level] != true)
			continue;

		if (soc_info->clk_rate[cam_vote_level][0] >
				phy_data_rate) {
			CAM_DBG(CAM_CSIPHY,
				"match detected %s : %llu:%d level : %d",
				soc_info->clk_name[0],
				phy_data_rate,
				soc_info->clk_rate[cam_vote_level][0],
				cam_vote_level);
			return cam_vote_level;
		}
		last_valid_vote = cam_vote_level;
	}
	return last_valid_vote;
}

int32_t cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev)
{
	int32_t rc = 0;
	struct cam_hw_soc_info   *soc_info;
	enum cam_vote_level vote_level = CAM_SVS_VOTE;

	soc_info = &csiphy_dev->soc_info;

@@ -86,8 +141,9 @@ int32_t cam_csiphy_enable_hw(struct csiphy_device *csiphy_dev)
		return rc;
	}

	vote_level = csiphy_dev->ctrl_reg->getclockvoting(csiphy_dev);
	rc = cam_soc_util_enable_platform_resource(soc_info, true,
		CAM_SVS_VOTE, ENABLE_IRQ);
		vote_level, ENABLE_IRQ);
	if (rc < 0) {
		CAM_ERR(CAM_CSIPHY, "failed to enable platform resources %d",
			rc);
@@ -168,6 +224,7 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev,
		csiphy_dev->ctrl_reg->csiphy_common_reg = csiphy_common_reg_1_0;
		csiphy_dev->ctrl_reg->csiphy_reset_reg = csiphy_reset_reg_1_0;
		csiphy_dev->ctrl_reg->csiphy_reg = csiphy_v1_0;
		csiphy_dev->ctrl_reg->getclockvoting = get_clk_vote_default;
		csiphy_dev->hw_version = CSIPHY_VERSION_V10;
		csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW;
		csiphy_dev->clk_lane = 0;
@@ -185,6 +242,7 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev,
		csiphy_dev->ctrl_reg->csiphy_reset_reg =
			csiphy_reset_reg_1_1;
		csiphy_dev->ctrl_reg->csiphy_reg = csiphy_v1_1;
		csiphy_dev->ctrl_reg->getclockvoting = get_clk_vote_default;
		csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW;
		csiphy_dev->hw_version = CSIPHY_VERSION_V11;
		csiphy_dev->clk_lane = 0;
@@ -200,8 +258,9 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev,
			csiphy_common_reg_1_2;
		csiphy_dev->ctrl_reg->csiphy_reset_reg =
			csiphy_reset_reg_1_2;
		csiphy_dev->ctrl_reg->getclockvoting = get_clk_voting_dynamic;
		csiphy_dev->ctrl_reg->csiphy_reg = csiphy_v1_2;
		csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW;
		csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW_12;
		csiphy_dev->hw_version = CSIPHY_VERSION_V12;
		csiphy_dev->clk_lane = 0;
	} else if (of_device_is_compatible(soc_info->dev->of_node,
@@ -217,7 +276,8 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev,
		csiphy_dev->ctrl_reg->csiphy_reset_reg =
			csiphy_reset_reg_1_2_1;
		csiphy_dev->ctrl_reg->csiphy_reg = csiphy_v1_2_1;
		csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW;
		csiphy_dev->ctrl_reg->getclockvoting = get_clk_voting_dynamic;
		csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW_12;
		csiphy_dev->hw_version = CSIPHY_VERSION_V121;
		csiphy_dev->clk_lane = 0;
	} else if (of_device_is_compatible(soc_info->dev->of_node,
@@ -231,6 +291,7 @@ int32_t cam_csiphy_parse_dt_info(struct platform_device *pdev,
		csiphy_dev->ctrl_reg->csiphy_common_reg = csiphy_common_reg_2_0;
		csiphy_dev->ctrl_reg->csiphy_reset_reg = csiphy_reset_reg_2_0;
		csiphy_dev->ctrl_reg->csiphy_reg = csiphy_v2_0;
		csiphy_dev->ctrl_reg->getclockvoting = get_clk_vote_default;
		csiphy_dev->hw_version = CSIPHY_VERSION_V20;
		csiphy_dev->is_csiphy_3phase_hw = CSI_3PHASE_HW;
		csiphy_dev->clk_lane = 0;
+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@
#define CDBG(fmt, args...) pr_debug(fmt, ##args)

#define CSI_3PHASE_HW                               1
#define CSI_3PHASE_HW_12                          0x12
#define CSIPHY_VERSION_V35                        0x35
#define CSIPHY_VERSION_V10                        0x10
#define CSIPHY_VERSION_V11                        0x11