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

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

Merge "UPSTREAM: Merge commit '4097ccbb' into msm-4.9 - PC122"

parents 90a3f6b7 11b4aa17
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -108,6 +108,23 @@ First Level Node - CAM CPAS device
  Definition: List of strings corresponds clock-rates levels.
  Supported strings: minsvs, lowsvs, svs, svs_l1, nominal, turbo.

- control-camnoc-axi-clk
  Usage: optional
  Value type: <empty>
  Definition: Bool property specifying whether to control camnoc axi
              clock from cpas driver.

- camnoc-bus-width
  Usage: required if control-camnoc-axi-clk is enabled
  Value type: <u32>
  Definition: camnoc bus width.

- camnoc-axi-clk-bw-margin-perc
  Usage: optional
  Value type: <u32>
  Definition: Percentage value to be added to camnoc bw while calculating
              camnoc axi clock frequency.

- qcom,msm-bus,name
- qcom,msm-bus,num-cases
- qcom,msm-bus,num-paths
@@ -211,6 +228,9 @@ Example:
		src-clock-name = "slow_ahb_clk_src";
		clock-rates = <0 0 0 0 80000000 0>;
		clock-cntl-level = "turbo";
		control-camnoc-axi-clk;
		camnoc-bus-width = <32>;
		camnoc-axi-clk-bw-margin-perc = <10>;
		qcom,msm-bus,name = "cam_ahb";
		qcom,msm-bus,num-cases = <4>;
		qcom,msm-bus,num-paths = <1>;
+1 −3
Original line number Diff line number Diff line
@@ -234,9 +234,7 @@
		msm_cam_smmu_lrme {
			compatible = "qcom,msm-cam-smmu-cb";
			iommus = <&apps_smmu 0x1038 0x0>,
				<&apps_smmu 0x1058 0x0>,
				<&apps_smmu 0x1039 0x0>,
				<&apps_smmu 0x1059 0x0>;
				<&apps_smmu 0x1058 0x0>;
			label = "lrme";
			lrme_iova_mem_map: iova-mem-map {
				iova-mem-region-shared {
+2 −4
Original line number Diff line number Diff line
/*
 * Copyright (c) 2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2017-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
@@ -161,9 +161,7 @@
		msm_cam_smmu_lrme {
			compatible = "qcom,msm-cam-smmu-cb";
			iommus = <&apps_smmu 0x1038 0x0>,
				<&apps_smmu 0x1058 0x0>,
				<&apps_smmu 0x1039 0x0>,
				<&apps_smmu 0x1059 0x0>;
				<&apps_smmu 0x1058 0x0>;
			label = "lrme";
			lrme_iova_mem_map: iova-mem-map {
				iova-mem-region-shared {
+81 −8
Original line number Diff line number Diff line
@@ -543,10 +543,71 @@ static int cam_cpas_hw_reg_read(struct cam_hw_info *cpas_hw,
	return rc;
}

static int cam_cpas_util_set_camnoc_axi_clk_rate(
	struct cam_hw_info *cpas_hw)
{
	struct cam_cpas *cpas_core = (struct cam_cpas *) cpas_hw->core_info;
	struct cam_cpas_private_soc *soc_private =
		(struct cam_cpas_private_soc *) cpas_hw->soc_info.soc_private;
	int rc = 0;

	CAM_DBG(CAM_CPAS, "control_camnoc_axi_clk=%d",
		soc_private->control_camnoc_axi_clk);

	if (soc_private->control_camnoc_axi_clk) {
		struct cam_hw_soc_info *soc_info = &cpas_hw->soc_info;
		struct cam_cpas_axi_port *curr_axi_port = NULL;
		struct cam_cpas_axi_port *temp_axi_port = NULL;
		uint64_t required_camnoc_bw = 0;
		int32_t clk_rate = 0;

		list_for_each_entry_safe(curr_axi_port, temp_axi_port,
			&cpas_core->axi_ports_list_head, sibling_port) {

			if (curr_axi_port->consolidated_axi_vote.uncompressed_bw
				> required_camnoc_bw)
				required_camnoc_bw = curr_axi_port->
					consolidated_axi_vote.uncompressed_bw;

			CAM_DBG(CAM_CPAS, "[%s] : curr=%llu, overal=%llu",
				curr_axi_port->axi_port_name,
				curr_axi_port->consolidated_axi_vote.
				uncompressed_bw,
				required_camnoc_bw);
		}

		required_camnoc_bw += (required_camnoc_bw *
			soc_private->camnoc_axi_clk_bw_margin) / 100;

		if ((required_camnoc_bw > 0) &&
			(required_camnoc_bw < CAM_CPAS_AXI_MIN_CAMNOC_IB_BW))
			required_camnoc_bw = CAM_CPAS_AXI_MIN_CAMNOC_IB_BW;

		clk_rate = required_camnoc_bw / soc_private->camnoc_bus_width;

		CAM_DBG(CAM_CPAS, "Setting camnoc axi clk rate : %llu %d",
			required_camnoc_bw, clk_rate);

		rc = cam_soc_util_set_clk_rate(
			soc_info->clk[soc_info->src_clk_idx],
			soc_info->clk_name[soc_info->src_clk_idx],
			clk_rate);
		if (!rc)
			CAM_ERR(CAM_CPAS,
				"Failed in setting camnoc axi clk %llu %d %d",
				required_camnoc_bw, clk_rate, rc);
	}

	return rc;
}

static int cam_cpas_util_apply_client_axi_vote(
	struct cam_cpas *cpas_core, struct cam_cpas_private_soc *soc_private,
	struct cam_cpas_client *cpas_client, struct cam_axi_vote *axi_vote)
	struct cam_hw_info *cpas_hw,
	struct cam_cpas_client *cpas_client,
	struct cam_axi_vote *axi_vote)
{
	struct cam_cpas_private_soc *soc_private =
		(struct cam_cpas_private_soc *) cpas_hw->soc_info.soc_private;
	struct cam_cpas_client *curr_client;
	struct cam_cpas_client *temp_client;
	struct cam_axi_vote req_axi_vote = *axi_vote;
@@ -587,6 +648,9 @@ static int cam_cpas_util_apply_client_axi_vote(
	if ((!soc_private->axi_camnoc_based) && (mnoc_bw < camnoc_bw))
		mnoc_bw = camnoc_bw;

	axi_port->consolidated_axi_vote.compressed_bw = mnoc_bw;
	axi_port->consolidated_axi_vote.uncompressed_bw = camnoc_bw;

	CAM_DBG(CAM_CPAS,
		"axi[(%d, %d),(%d, %d)] : camnoc_bw[%llu], mnoc_bw[%llu]",
		axi_port->mnoc_bus.src, axi_port->mnoc_bus.dst,
@@ -613,6 +677,14 @@ static int cam_cpas_util_apply_client_axi_vote(
		}
	}

	mutex_unlock(&axi_port->lock);

	rc = cam_cpas_util_set_camnoc_axi_clk_rate(cpas_hw);
	if (rc)
		CAM_ERR(CAM_CPAS, "Failed in setting axi clk rate rc=%d", rc);

	return rc;

unlock_axi_port:
	mutex_unlock(&axi_port->lock);
	return rc;
@@ -645,6 +717,7 @@ static int cam_cpas_hw_update_axi_vote(struct cam_hw_info *cpas_hw,
	if (!CAM_CPAS_CLIENT_VALID(client_indx))
		return -EINVAL;

	mutex_lock(&cpas_hw->hw_mutex);
	mutex_lock(&cpas_core->client_mutex[client_indx]);

	if (!CAM_CPAS_CLIENT_STARTED(cpas_core, client_indx)) {
@@ -658,12 +731,12 @@ static int cam_cpas_hw_update_axi_vote(struct cam_hw_info *cpas_hw,
		client_indx, axi_vote.compressed_bw,
		axi_vote.uncompressed_bw);

	rc = cam_cpas_util_apply_client_axi_vote(cpas_core,
		cpas_hw->soc_info.soc_private,
	rc = cam_cpas_util_apply_client_axi_vote(cpas_hw,
		cpas_core->cpas_client[client_indx], &axi_vote);

unlock_client:
	mutex_unlock(&cpas_core->client_mutex[client_indx]);
	mutex_unlock(&cpas_hw->hw_mutex);
	return rc;
}

@@ -897,8 +970,8 @@ static int cam_cpas_hw_start(void *hw_priv, void *start_args,
		"AXI client[%d] compressed_bw[%llu], uncompressed_bw[%llu]",
		client_indx, axi_vote->compressed_bw,
		axi_vote->uncompressed_bw);
	rc = cam_cpas_util_apply_client_axi_vote(cpas_core,
		cpas_hw->soc_info.soc_private, cpas_client, axi_vote);
	rc = cam_cpas_util_apply_client_axi_vote(cpas_hw,
		cpas_client, axi_vote);
	if (rc)
		goto done;

@@ -1040,8 +1113,8 @@ static int cam_cpas_hw_stop(void *hw_priv, void *stop_args,

	axi_vote.uncompressed_bw = 0;
	axi_vote.compressed_bw = 0;
	rc = cam_cpas_util_apply_client_axi_vote(cpas_core,
		cpas_hw->soc_info.soc_private, cpas_client, &axi_vote);
	rc = cam_cpas_util_apply_client_axi_vote(cpas_hw,
		cpas_client, &axi_vote);

done:
	mutex_unlock(&cpas_core->client_mutex[client_indx]);
+2 −0
Original line number Diff line number Diff line
@@ -145,6 +145,7 @@ struct cam_cpas_bus_client {
 * @axi_port_node: Node representing this AXI Port
 * @axi_port_mnoc_node: Node representing mnoc in this AXI Port
 * @axi_port_camnoc_node: Node representing camnoc in this AXI Port
 * @consolidated_axi_vote: Consolidated axi bw values for this AXI port
 *
 */
struct cam_cpas_axi_port {
@@ -157,6 +158,7 @@ struct cam_cpas_axi_port {
	struct device_node *axi_port_node;
	struct device_node *axi_port_mnoc_node;
	struct device_node *axi_port_camnoc_node;
	struct cam_axi_vote consolidated_axi_vote;
};

/**
Loading