Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

clk: qcom: branch: Add mem ops support for branch2 clocks

Add the support for mem ops implementation to handle the sequence of
enable/disable of the memories in ethernet PHY, prior to enable/disable
of the respective clocks, which helps retain the respecive block's
register contents.

Signed-off-by: Taniya Das <quic_tdas@quicinc.com>
Signed-off-by: Imran Shaik <quic_imrashai@quicinc.com>
Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Link: https://lore.kernel.org/r/20231123064735.2979802-3-quic_imrashai@quicinc.com
Signed-off-by: Bjorn Andersson <andersson@kernel.org>

authored by

Taniya Das and committed by
Bjorn Andersson
261625e0 cdf1c63d

+59
+38
drivers/clk/qcom/clk-branch.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* 3 3 * Copyright (c) 2013, The Linux Foundation. All rights reserved. 4 + * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved. 4 5 */ 5 6 6 7 #include <linux/kernel.h> ··· 134 133 { 135 134 clk_branch_toggle(hw, false, clk_branch2_check_halt); 136 135 } 136 + 137 + static int clk_branch2_mem_enable(struct clk_hw *hw) 138 + { 139 + struct clk_mem_branch *mem_br = to_clk_mem_branch(hw); 140 + struct clk_branch branch = mem_br->branch; 141 + u32 val; 142 + int ret; 143 + 144 + regmap_update_bits(branch.clkr.regmap, mem_br->mem_enable_reg, 145 + mem_br->mem_enable_ack_mask, mem_br->mem_enable_ack_mask); 146 + 147 + ret = regmap_read_poll_timeout(branch.clkr.regmap, mem_br->mem_ack_reg, 148 + val, val & mem_br->mem_enable_ack_mask, 0, 200); 149 + if (ret) { 150 + WARN(1, "%s mem enable failed\n", clk_hw_get_name(&branch.clkr.hw)); 151 + return ret; 152 + } 153 + 154 + return clk_branch2_enable(hw); 155 + } 156 + 157 + static void clk_branch2_mem_disable(struct clk_hw *hw) 158 + { 159 + struct clk_mem_branch *mem_br = to_clk_mem_branch(hw); 160 + 161 + regmap_update_bits(mem_br->branch.clkr.regmap, mem_br->mem_enable_reg, 162 + mem_br->mem_enable_ack_mask, 0); 163 + 164 + return clk_branch2_disable(hw); 165 + } 166 + 167 + const struct clk_ops clk_branch2_mem_ops = { 168 + .enable = clk_branch2_mem_enable, 169 + .disable = clk_branch2_mem_disable, 170 + .is_enabled = clk_is_enabled_regmap, 171 + }; 172 + EXPORT_SYMBOL_GPL(clk_branch2_mem_ops); 137 173 138 174 const struct clk_ops clk_branch2_ops = { 139 175 .enable = clk_branch2_enable,
+21
drivers/clk/qcom/clk-branch.h
··· 38 38 struct clk_regmap clkr; 39 39 }; 40 40 41 + /** 42 + * struct clk_mem_branch - gating clock which are associated with memories 43 + * 44 + * @mem_enable_reg: branch clock memory gating register 45 + * @mem_ack_reg: branch clock memory ack register 46 + * @mem_enable_ack_mask: branch clock memory enable and ack field in @mem_ack_reg 47 + * @branch: branch clock gating handle 48 + * 49 + * Clock which can gate its memories. 50 + */ 51 + struct clk_mem_branch { 52 + u32 mem_enable_reg; 53 + u32 mem_ack_reg; 54 + u32 mem_enable_ack_mask; 55 + struct clk_branch branch; 56 + }; 57 + 41 58 /* Branch clock common bits for HLOS-owned clocks */ 42 59 #define CBCR_CLK_OFF BIT(31) 43 60 #define CBCR_NOC_FSM_STATUS GENMASK(30, 28) ··· 102 85 extern const struct clk_ops clk_branch2_ops; 103 86 extern const struct clk_ops clk_branch_simple_ops; 104 87 extern const struct clk_ops clk_branch2_aon_ops; 88 + extern const struct clk_ops clk_branch2_mem_ops; 105 89 106 90 #define to_clk_branch(_hw) \ 107 91 container_of(to_clk_regmap(_hw), struct clk_branch, clkr) 92 + 93 + #define to_clk_mem_branch(_hw) \ 94 + container_of(to_clk_branch(_hw), struct clk_mem_branch, branch) 108 95 109 96 #endif