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

Commit b81eb44c authored by Harsh Shah's avatar Harsh Shah Committed by Senthil Rajagopal
Browse files

msm: camera: util: Add support for option clk



Camera devices can have clocks which need not be turned ON
by default and only in some usecases. These are represented in
DT by clock-names-option and clocks-option. Add APIs for the
devices to get references to these clocks and then enable them
using the existing clk_enable API.

Change-Id: I12812e9cbe754e37d2c9a074a91ee1d02c323352
Signed-off-by: default avatarHarsh Shah <harshs@codeaurora.org>
parent cd0be6b6
Loading
Loading
Loading
Loading
+20 −0
Original line number Original line Diff line number Diff line
@@ -12,6 +12,7 @@ The VFE device is described in one level of the device node.
======================================
======================================
First Level Node - CAM VFE device
First Level Node - CAM VFE device
======================================
======================================
Required properties:
- compatible
- compatible
  Usage: required
  Usage: required
  Value type: <string>
  Value type: <string>
@@ -74,6 +75,22 @@ First Level Node - CAM VFE device
  Value type: <string>
  Value type: <string>
  Definition: Source clock name.
  Definition: Source clock name.


Optional properties:
- clock-names-option
  Usage: optional
  Value type: <string>
  Definition: Optional clock names.

- clocks-option
  Usage: required if clock-names-option defined
  Value type: <phandle>
  Definition: List of optinal clocks used for VFE HW.

- clock-rates-option
  Usage: required if clock-names-option defined
  Value type: <u32>
  Definition: List of clocks rates for optional clocks.

Example:
Example:
	qcom,vfe0@acaf000 {
	qcom,vfe0@acaf000 {
		cell-index = <0>;
		cell-index = <0>;
@@ -105,5 +122,8 @@ Example:
			<&clock_camcc CAM_CC_IFE_0_AXI_CLK>,
			<&clock_camcc CAM_CC_IFE_0_AXI_CLK>,
		clock-rates = <0 0 80000000 0 320000000 0 384000000 0 0 0>;
		clock-rates = <0 0 80000000 0 320000000 0 384000000 0 0 0>;
		src-clock-name = "ife_clk_src";
		src-clock-name = "ife_clk_src";
		clock-names-option = "ife_dsp_clk";
		clocks-option = <&clock_camcc CAM_CC_IFE_0_DSP_CLK>;
		clock-rates-option = <600000000>;
		status = "ok";
		status = "ok";
	};
	};
+87 −1
Original line number Original line Diff line number Diff line
@@ -196,6 +196,92 @@ int cam_soc_util_set_clk_rate(struct clk *clk, const char *clk_name,
	return rc;
	return rc;
}
}


int cam_soc_util_clk_put(struct clk **clk)
{
	if (!(*clk)) {
		CAM_ERR(CAM_UTIL, "Invalid params clk");
		return -EINVAL;
	}

	clk_put(*clk);
	*clk = NULL;

	return 0;
}

static struct clk *cam_soc_util_option_clk_get(struct device_node *np,
	int index)
{
	struct of_phandle_args clkspec;
	struct clk *clk;
	int rc;

	if (index < 0)
		return ERR_PTR(-EINVAL);

	rc = of_parse_phandle_with_args(np, "clocks-option", "#clock-cells",
		index, &clkspec);
	if (rc)
		return ERR_PTR(rc);

	clk = of_clk_get_from_provider(&clkspec);
	of_node_put(clkspec.np);

	return clk;
}

int cam_soc_util_get_option_clk_by_name(struct cam_hw_soc_info *soc_info,
	const char *clk_name, struct clk **clk, int32_t *clk_index,
	int32_t *clk_rate)
{
	int index = 0;
	int rc = 0;
	struct device_node *of_node = NULL;

	if (!soc_info || !clk_name || !clk) {
		CAM_ERR(CAM_UTIL,
			"Invalid params soc_info %pK clk_name %s clk %pK",
			soc_info, clk_name, clk);
		return -EINVAL;
	}

	of_node = soc_info->dev->of_node;

	index = of_property_match_string(of_node, "clock-names-option",
		clk_name);

	*clk = cam_soc_util_option_clk_get(of_node, index);
	if (IS_ERR(*clk)) {
		CAM_ERR(CAM_UTIL, "No clk named %s found. Dev %s", clk_name,
			soc_info->dev_name);
		*clk_index = -1;
		return -EFAULT;
	}
	*clk_index = index;

	rc = of_property_read_u32_index(of_node, "clock-rates-option",
		index, clk_rate);
	if (rc) {
		CAM_ERR(CAM_UTIL,
			"Error reading clock-rates clk_name %s index %d",
			clk_name, index);
		cam_soc_util_clk_put(clk);
		*clk_rate = 0;
		return rc;
	}

	/*
	 * Option clocks are assumed to be available to single Device here.
	 * Hence use INIT_RATE instead of NO_SET_RATE.
	 */
	*clk_rate = (*clk_rate == 0) ? (int32_t)INIT_RATE : *clk_rate;

	CAM_DBG(CAM_UTIL, "clk_name %s index %d clk_rate %d",
		clk_name, *clk_index, *clk_rate);

	return 0;
}

int cam_soc_util_clk_enable(struct clk *clk, const char *clk_name,
int cam_soc_util_clk_enable(struct clk *clk, const char *clk_name,
	int32_t clk_rate)
	int32_t clk_rate)
{
{
@@ -407,7 +493,7 @@ static int cam_soc_util_get_dt_clk_info(struct cam_hw_soc_info *soc_info)


			soc_info->clk_rate[level][j] =
			soc_info->clk_rate[level][j] =
				(soc_info->clk_rate[level][j] == 0) ?
				(soc_info->clk_rate[level][j] == 0) ?
				(long)NO_SET_RATE :
				(int32_t)NO_SET_RATE :
				soc_info->clk_rate[level][j];
				soc_info->clk_rate[level][j];


			CAM_DBG(CAM_UTIL, "soc_info->clk_rate[%d][%d] = %d",
			CAM_DBG(CAM_UTIL, "soc_info->clk_rate[%d][%d] = %d",
+29 −0
Original line number Original line Diff line number Diff line
@@ -376,6 +376,35 @@ int cam_soc_util_set_clk_flags(struct cam_hw_soc_info *soc_info,
int cam_soc_util_set_clk_rate(struct clk *clk, const char *clk_name,
int cam_soc_util_set_clk_rate(struct clk *clk, const char *clk_name,
	int32_t clk_rate);
	int32_t clk_rate);


/**
 * cam_soc_util_get_option_clk_by_name()
 *
 * @brief:              Get reference to optional clk using name
 *
 * @soc_info:           Device soc information
 * @clk_name:           Name of clock to find reference for
 * @clk:                Clock reference pointer to be filled if Success
 * @clk_index:          Clk index in the option clk array to be returned
 * @clk_rate:           Clk rate in the option clk array
 *
 * @return:             0: Success
 *                      Negative: Failure
 */
int cam_soc_util_get_option_clk_by_name(struct cam_hw_soc_info *soc_info,
	const char *clk_name, struct clk **clk, int32_t *clk_index,
	int32_t *clk_rate);

/**
 * cam_soc_util_clk_put()
 *
 * @brief:              Put clock specified in params
 *
 * @clk:                Reference to the Clock that needs to be put
 *
 * @return:             Success or failure
 */
int cam_soc_util_clk_put(struct clk **clk);

/**
/**
 * cam_soc_util_clk_enable()
 * cam_soc_util_clk_enable()
 *
 *