diff --git a/drivers/clk/qcom/clk-branch.c b/drivers/clk/qcom/clk-branch.c index 2aab7777aaed..213f4b942540 100644 --- a/drivers/clk/qcom/clk-branch.c +++ b/drivers/clk/qcom/clk-branch.c @@ -47,6 +47,7 @@ static bool clk_branch_check_halt(const struct clk_branch *br, bool enabling) #define BRANCH_NOC_FSM_STATUS_SHIFT 28 #define BRANCH_NOC_FSM_STATUS_MASK 0x7 #define BRANCH_NOC_FSM_STATUS_ON (0x2 << BRANCH_NOC_FSM_STATUS_SHIFT) +#define BRANCH_CLK_DIS_MASK BIT(22) static bool clk_branch2_check_halt(const struct clk_branch *br, bool enabling) { @@ -150,6 +151,26 @@ static void clk_branch2_disable(struct clk_hw *hw) clk_branch_toggle(hw, false, clk_branch2_check_halt); } +static int clk_branch2_force_off_enable(struct clk_hw *hw) +{ + struct clk_regmap *rclk = to_clk_regmap(hw); + + regmap_update_bits(rclk->regmap, rclk->enable_reg, + BRANCH_CLK_DIS_MASK, + 0x0); + return clk_branch2_enable(hw); +} + +static void clk_branch2_force_off_disable(struct clk_hw *hw) +{ + struct clk_regmap *rclk = to_clk_regmap(hw); + + regmap_update_bits(rclk->regmap, rclk->enable_reg, + BRANCH_CLK_DIS_MASK, + BRANCH_CLK_DIS_MASK); + clk_branch2_disable(hw); +} + static void clk_branch2_list_registers(struct seq_file *f, struct clk_hw *hw) { struct clk_branch *br = to_clk_branch(hw); @@ -220,6 +241,15 @@ const struct clk_ops clk_branch2_aon_ops = { }; EXPORT_SYMBOL_GPL(clk_branch2_aon_ops); +const struct clk_ops clk_branch2_force_off_ops = { + .enable = clk_branch2_force_off_enable, + .disable = clk_branch2_force_off_disable, + .is_enabled = clk_is_enabled_regmap, + .init = clk_branch2_init, + .debug_init = clk_branch_debug_init, +}; +EXPORT_SYMBOL(clk_branch2_force_off_ops); + static unsigned long clk_branch2_hw_ctl_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { diff --git a/drivers/clk/qcom/clk-branch.h b/drivers/clk/qcom/clk-branch.h index 8f71551b2aea..eeabc1573bec 100644 --- a/drivers/clk/qcom/clk-branch.h +++ b/drivers/clk/qcom/clk-branch.h @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2013, 2016, The Linux Foundation. All rights reserved. */ +/* Copyright (c) 2013, 2016, 2020 The Linux Foundation. All rights reserved. */ #ifndef __QCOM_CLK_BRANCH_H__ #define __QCOM_CLK_BRANCH_H__ @@ -42,6 +42,7 @@ 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; +extern const struct clk_ops clk_branch2_force_off_ops; #define to_clk_branch(_hw) \ container_of(to_clk_regmap(_hw), struct clk_branch, clkr) diff --git a/drivers/clk/qcom/gcc-shima.c b/drivers/clk/qcom/gcc-shima.c index 88a873acc856..95f5dcb4ed4b 100644 --- a/drivers/clk/qcom/gcc-shima.c +++ b/drivers/clk/qcom/gcc-shima.c @@ -3189,7 +3189,7 @@ static struct clk_branch gcc_video_axi0_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_video_axi0_clk", - .ops = &clk_branch2_ops, + .ops = &clk_branch2_force_off_ops, }, }, }; @@ -3204,7 +3204,7 @@ static struct clk_branch gcc_video_axi1_clk = { .enable_mask = BIT(0), .hw.init = &(struct clk_init_data){ .name = "gcc_video_axi1_clk", - .ops = &clk_branch2_ops, + .ops = &clk_branch2_force_off_ops, }, }, };