clk: qcom: Add support for hardware control branch clocks

Add new ops to allow clock clients to enable/disable hardware
dynamic gating of the clock branch.

Change-Id: I14abed3827de8cefc31f3deb3c1e589136c32b8d
Signed-off-by: Taniya Das <tdas@codeaurora.org>
Signed-off-by: Deepak Katragadda <dkatraga@codeaurora.org>
Signed-off-by: David Dai <daidavid1@codeaurora.org>
Signed-off-by: David Collins <collinsd@codeaurora.org>
This commit is contained in:
Deepak Katragadda 2016-09-29 13:28:59 +05:30 committed by Mike Tipton
parent fc8bd86451
commit 8e88bc5ff9
2 changed files with 57 additions and 4 deletions

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2013, The Linux Foundation. All rights reserved.
* Copyright (c) 2013, 2016, The Linux Foundation. All rights reserved.
*/
#include <linux/kernel.h>
@ -8,6 +8,7 @@
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/export.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/regmap.h>
@ -152,6 +153,57 @@ const struct clk_ops clk_branch2_aon_ops = {
};
EXPORT_SYMBOL_GPL(clk_branch2_aon_ops);
static unsigned long clk_branch2_hw_ctl_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
return parent_rate;
}
static int clk_branch2_hw_ctl_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
struct clk_hw *clkp;
clkp = clk_hw_get_parent(hw);
if (!clkp)
return -EINVAL;
req->best_parent_hw = clkp;
req->best_parent_rate = clk_round_rate(clkp->clk, req->rate);
return 0;
}
static int clk_branch2_hw_ctl_enable(struct clk_hw *hw)
{
struct clk_hw *parent = clk_hw_get_parent(hw);
/* The parent branch clock should have been prepared prior to this. */
if (!parent || (parent && !clk_hw_is_prepared(parent)))
return -EINVAL;
return clk_enable_regmap(hw);
}
static void clk_branch2_hw_ctl_disable(struct clk_hw *hw)
{
struct clk_hw *parent = clk_hw_get_parent(hw);
if (!parent)
return;
clk_disable_regmap(hw);
}
const struct clk_ops clk_branch2_hw_ctl_ops = {
.enable = clk_branch2_hw_ctl_enable,
.disable = clk_branch2_hw_ctl_disable,
.is_enabled = clk_is_enabled_regmap,
.recalc_rate = clk_branch2_hw_ctl_recalc_rate,
.determine_rate = clk_branch2_hw_ctl_determine_rate,
};
EXPORT_SYMBOL(clk_branch2_hw_ctl_ops);
const struct clk_ops clk_branch_simple_ops = {
.enable = clk_enable_regmap,
.disable = clk_disable_regmap,

View File

@ -1,5 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) 2013, The Linux Foundation. All rights reserved. */
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2013, 2016, The Linux Foundation. All rights reserved. */
#ifndef __QCOM_CLK_BRANCH_H__
#define __QCOM_CLK_BRANCH_H__
@ -39,6 +39,7 @@ struct clk_branch {
extern const struct clk_ops clk_branch_ops;
extern const struct clk_ops clk_branch2_ops;
extern const struct clk_ops clk_branch2_hw_ctl_ops;
extern const struct clk_ops clk_branch_simple_ops;
extern const struct clk_ops clk_branch2_aon_ops;