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

Commit a5d4d558 authored by Taniya Das's avatar Taniya Das Committed by David Collins
Browse files

clk: qcom: Add support for clock dependency



Add clock ops for taking care of a dependent clock when the actual
clock requests are made.

Change-Id: I52691ef9f183da035ddf9c05fb73811f48fef74c
Signed-off-by: default avatarTaniya Das <tdas@codeaurora.org>
parent ee6a9d64
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -171,6 +171,7 @@ extern const struct clk_ops clk_pixel_ops;
extern const struct clk_ops clk_gfx3d_ops;
extern const struct clk_ops clk_rcg2_shared_ops;
extern const struct clk_ops clk_dp_ops;
extern const struct clk_ops clk_rcg2_dependent_ops;

struct clk_rcg_dfs_data {
	struct clk_rcg2 *rcg;
+101 −0
Original line number Diff line number Diff line
@@ -1497,3 +1497,104 @@ int qcom_cc_register_rcg_dfs(struct regmap *regmap,
	return 0;
}
EXPORT_SYMBOL_GPL(qcom_cc_register_rcg_dfs);

static int clk_rcg2_dependent_enable(struct clk_hw *hw)
{
	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
	int ret;

	ret = clk_rcg2_enable(hw);
	if (ret < 0)
		return ret;

	return clk_enable(rcg->clkr.dependent_hw->clk);
}

static void clk_rcg2_dependent_disable(struct clk_hw *hw)
{
	struct clk_rcg2 *rcg = to_clk_rcg2(hw);

	clk_rcg2_disable(hw);
	clk_disable(rcg->clkr.dependent_hw->clk);
}

static int clk_rcg2_dependent_set_parent(struct clk_hw *hw, u8 index)
{
	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
	struct clk_hw *p_hw;
	int ret;

	ret = clk_rcg2_set_parent(hw, index);
	if (ret < 0)
		return ret;

	p_hw = clk_hw_get_parent_by_index(rcg->clkr.dependent_hw, index);
	return clk_set_parent(rcg->clkr.dependent_hw->clk, p_hw->clk);
}

static int clk_rcg2_dependent_determine_rate(struct clk_hw *hw,
						 struct clk_rate_request *req)
{
	struct clk_rcg2 *rcg = to_clk_rcg2(hw);

	__clk_determine_rate(rcg->clkr.dependent_hw, req);

	return clk_rcg2_determine_rate(hw, req);
}

static int clk_rcg2_dependent_set_rate(struct clk_hw *hw,
				unsigned long rate, unsigned long parent_rate)
{
	int ret;
	struct clk_rcg2 *rcg = to_clk_rcg2(hw);

	ret = clk_rcg2_set_rate(hw, rate, parent_rate);
	if (ret < 0)
		return ret;

	return clk_set_rate(rcg->clkr.dependent_hw->clk, rate);
}

static int clk_rcg2_dependent_set_rate_and_parent(struct clk_hw *hw,
		unsigned long rate, unsigned long parent_rate, u8 index)
{
	struct clk_rcg2 *rcg = to_clk_rcg2(hw);
	int ret;

	ret = clk_rcg2_set_rate_and_parent(hw, rate, parent_rate, index);
	if (ret < 0)
		return ret;

	return clk_set_rate(rcg->clkr.dependent_hw->clk, rate);
}

static int clk_rcg2_dependent_prepare(struct clk_hw *hw)
{
	struct clk_rcg2 *rcg = to_clk_rcg2(hw);

	return clk_prepare(rcg->clkr.dependent_hw->clk);
}

static void clk_rcg2_dependent_unprepare(struct clk_hw *hw)
{
	struct clk_rcg2 *rcg = to_clk_rcg2(hw);

	clk_unprepare(rcg->clkr.dependent_hw->clk);
}

const struct clk_ops clk_rcg2_dependent_ops = {
	.is_enabled = clk_rcg2_is_enabled,
	.prepare = clk_rcg2_dependent_prepare,
	.unprepare = clk_rcg2_dependent_unprepare,
	.enable = clk_rcg2_dependent_enable,
	.disable = clk_rcg2_dependent_disable,
	.get_parent = clk_rcg2_get_parent,
	.set_parent = clk_rcg2_dependent_set_parent,
	.recalc_rate = clk_rcg2_recalc_rate,
	.determine_rate = clk_rcg2_dependent_determine_rate,
	.set_rate = clk_rcg2_dependent_set_rate,
	.set_rate_and_parent = clk_rcg2_dependent_set_rate_and_parent,
	.list_rate = clk_rcg2_list_rate,
	.list_registers = clk_rcg2_list_registers,
};
EXPORT_SYMBOL(clk_rcg2_dependent_ops);
+3 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2014, 2017, The Linux Foundation. All rights reserved. */
/* Copyright (c) 2014, 2017-2018, The Linux Foundation. All rights reserved. */

#ifndef __QCOM_CLK_REGMAP_H__
#define __QCOM_CLK_REGMAP_H__
@@ -12,6 +12,7 @@ struct regmap;
/**
 * struct clk_regmap - regmap supporting clock
 * @hw:		handle between common and hardware-specific interfaces
 * @dependent_hw: dependent clocks clock hw
 * @regmap:	regmap to use for regmap helpers and/or by providers
 * @enable_reg: register when using regmap enable/disable ops
 * @enable_mask: mask when using regmap enable/disable ops
@@ -20,6 +21,7 @@ struct regmap;
 */
struct clk_regmap {
	struct clk_hw hw;
	struct clk_hw *dependent_hw;
	struct regmap *regmap;
	unsigned int enable_reg;
	unsigned int enable_mask;