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

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

Merge "msm: camera: cpp: Add support for CX iPeak limits Management"

parents 89bfd053 c924ded6
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -70,6 +70,13 @@ Optional properties:
  The first entry is register offset and second entry is register value.
- qcom,micro-reset: Boolean flag indicating if micro reset need to be enabled.
  This needs to present on platforms that support this feature.
- qcom,cpp-cx-ipeak: To handle Cx peak current limit.
                     <phandle bit>
                     phandle - phandle of cx ipeak device node
                     bit     - bit number of client in relevant register
  This is used to access Cx ipeak HW module to limit the current drawn by
  various subsystem blocks on Cx power rail. CPP set their bit in tcsr register
  if it is going to cross its own threshold.

Example:

@@ -105,6 +112,7 @@ Example:
			"micro_iface_clk", "camss_ahb_clk";
			"smmu_cpp_axi_clk", "cpp_vbif_ahb_clk";
		qcom,clock-rates = <0 0 0 0 465000000 0 0 465000000 0 0 0 0>;
		qcom,cpp-cx-ipeak = <&cx_ipeak_lm 2>;
		qcom,min-clock-rate = <320000000>;
		qcom,bus-master = <1>;
		qcom,vbif-qos-setting = <0x20 0x10000000>,
+59 −3
Original line number Diff line number Diff line
@@ -980,6 +980,7 @@ static int cpp_init_hardware(struct cpp_device *cpp_dev)
{
	int rc = 0;
	uint32_t vbif_version;
	cpp_dev->turbo_vote = 0;

	rc = msm_camera_regulator_enable(cpp_dev->cpp_vdd,
		cpp_dev->num_reg, true);
@@ -1432,6 +1433,14 @@ static int cpp_close_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
		return -ENODEV;
	}

	if (cpp_dev->turbo_vote == 1) {
		rc = cx_ipeak_update(cpp_dev->cpp_cx_ipeak, false);
			if (rc)
				pr_err("cx_ipeak_update failed");
			else
				cpp_dev->turbo_vote = 0;
	}

	cpp_dev->cpp_open_cnt--;
	if (cpp_dev->cpp_open_cnt == 0) {
		pr_debug("irq_status: 0x%x\n",
@@ -2955,6 +2964,38 @@ static int msm_cpp_validate_input(unsigned int cmd, void *arg,
	return 0;
}

unsigned long cpp_cx_ipeak_update(struct cpp_device *cpp_dev,
	unsigned long clock, int idx)
{
	unsigned long clock_rate = 0;
	int ret = 0;

	if ((clock >= cpp_dev->hw_info.freq_tbl
		[(cpp_dev->hw_info.freq_tbl_count) - 1]) &&
		(cpp_dev->turbo_vote == 0)) {
		ret = cx_ipeak_update(cpp_dev->cpp_cx_ipeak, true);
		if (ret) {
			pr_err("cx_ipeak voting failed setting clock below turbo");
			clock = cpp_dev->hw_info.freq_tbl
				[(cpp_dev->hw_info.freq_tbl_count) - 2];
		} else {
			cpp_dev->turbo_vote = 1;
		}
		clock_rate = msm_cpp_set_core_clk(cpp_dev, clock, idx);
	} else if (clock < cpp_dev->hw_info.freq_tbl
		[(cpp_dev->hw_info.freq_tbl_count) - 1]) {
		clock_rate = msm_cpp_set_core_clk(cpp_dev, clock, idx);
		if (cpp_dev->turbo_vote == 1) {
			ret = cx_ipeak_update(cpp_dev->cpp_cx_ipeak, false);
			if (ret)
				pr_err("cx_ipeak unvoting failed");
			else
				cpp_dev->turbo_vote = 0;
		}
	}
	return clock_rate;
}

long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
			unsigned int cmd, void *arg)
{
@@ -3337,9 +3378,15 @@ STREAM_BUFF_END:
				mutex_unlock(&cpp_dev->mutex);
				return -EINVAL;
			}
			if (cpp_dev->cpp_cx_ipeak) {
				clock_rate = cpp_cx_ipeak_update(cpp_dev,
					clock_settings.clock_rate,
					msm_cpp_core_clk_idx);
			} else {
				clock_rate = msm_cpp_set_core_clk(cpp_dev,
					clock_settings.clock_rate,
					msm_cpp_core_clk_idx);
			}
			if (rc < 0) {
				pr_err("Fail to set core clk\n");
				mutex_unlock(&cpp_dev->mutex);
@@ -4391,6 +4438,15 @@ static int cpp_probe(struct platform_device *pdev)
		}
	}

	if (of_find_property(pdev->dev.of_node, "qcom,cpp-cx-ipeak", NULL)) {
		cpp_dev->cpp_cx_ipeak = cx_ipeak_register(
			pdev->dev.of_node, "qcom,cpp-cx-ipeak");
		if (cpp_dev->cpp_cx_ipeak)
			CPP_DBG("Cx ipeak Registration Successful ");
		else
			pr_err("Cx ipeak Registration Unsuccessful");
	}

	rc = msm_camera_get_reset_info(pdev,
			&cpp_dev->micro_iface_reset);
	if (rc < 0) {
+4 −1
Original line number Diff line number Diff line
/* Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2017, 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
@@ -24,6 +24,7 @@
#include "cam_soc_api.h"
#include "cam_hw_ops.h"
#include <media/msmb_pproc.h>
#include <soc/qcom/cx_ipeak.h>

/* hw version info:
  31:28  Major version
@@ -284,6 +285,8 @@ struct cpp_device {
	uint32_t micro_reset;
	struct msm_cpp_payload_params payload_params;
	struct msm_cpp_vbif_data *vbif_data;
	bool turbo_vote;
	struct cx_ipeak_client *cpp_cx_ipeak;
};

int msm_cpp_set_micro_clk(struct cpp_device *cpp_dev);