mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-12 15:49:17 -04:00
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: Taniya Das <tdas@codeaurora.org> Signed-off-by: David Collins <collinsd@codeaurora.org>
This commit is contained in:
parent
b3394e839b
commit
228b95aa74
3 changed files with 104 additions and 2 deletions
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -1411,3 +1411,102 @@ 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,
|
||||
};
|
||||
EXPORT_SYMBOL(clk_rcg2_dependent_ops);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/* Copyright (c) 2014, The Linux Foundation. All rights reserved. */
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/* Copyright (c) 2014, 2016-2018, The Linux Foundation. All rights reserved. */
|
||||
|
||||
#ifndef __QCOM_CLK_REGMAP_H__
|
||||
#define __QCOM_CLK_REGMAP_H__
|
||||
|
|
@ -11,6 +11,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
|
||||
|
|
@ -19,6 +20,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;
|
||||
|
|
|
|||
Loading…
Reference in a new issue