clk: qcom: clk-branch: Add support for Mem branch mem ops

CBCRs with memories need an update for memory before enabling the clock.

Change-Id: I4d6856640c209471d057a91938c1d51014463550
Signed-off-by: Taniya Das <quic_tdas@quicinc.com>
This commit is contained in:
Taniya Das 2022-01-13 15:56:33 +05:30 committed by Mike Tipton
parent 6e308e1672
commit 79703e7f64
3 changed files with 65 additions and 1 deletions

View File

@ -184,6 +184,12 @@ static void clk_branch2_list_registers(struct seq_file *f, struct clk_hw *hw)
{"APSS_SLEEP_VOTE", 0x4},
};
static struct clk_register_data data2[] = {
{"MEM_ENABLE", 0x0},
{"MEM_ENABLE_ACK", 0x0},
{"MEM_ENABLE_ACK_MASK", 0x0},
};
size = ARRAY_SIZE(data);
for (i = 0; i < size; i++) {
@ -204,6 +210,18 @@ static void clk_branch2_list_registers(struct seq_file *f, struct clk_hw *hw)
}
}
}
if (br->mem_enable_reg && br->mem_ack_reg) {
regmap_read(br->clkr.regmap, br->mem_enable_reg +
data2[0].offset, &val);
clock_debug_output(f, "%20s: 0x%.8x\n", data2[0].name, val);
regmap_read(br->clkr.regmap, br->mem_ack_reg +
data2[1].offset, &val);
clock_debug_output(f, "%20s: 0x%.8x\n", data2[1].name, val);
clock_debug_output(f, "%20s: 0x%.8x\n", data2[2].name,
br->mem_enable_ack_bit);
}
}
static int clk_branch2_set_flags(struct clk_hw *hw, unsigned long flags)
@ -260,6 +278,39 @@ static int clk_branch2_init(struct clk_hw *hw)
return 0;
}
static int clk_branch2_mem_enable(struct clk_hw *hw)
{
struct clk_branch *br = to_clk_branch(hw);
u32 val;
int count = 200;
regmap_update_bits(br->clkr.regmap, br->mem_enable_reg,
br->mem_enable_ack_bit, br->mem_enable_ack_bit);
regmap_read(br->clkr.regmap, br->mem_ack_reg, &val);
pr_debug("%s Val 0x%x\n", __func__, val);
while (count-- > 0) {
if (val & br->mem_enable_ack_bit) {
pr_debug("%s Val 0x%x\n", __func__, val);
return clk_branch2_enable(hw);
}
udelay(1);
regmap_read(br->clkr.regmap, br->mem_ack_reg, &val);
}
return -EBUSY;
}
static void clk_branch2_mem_disable(struct clk_hw *hw)
{
struct clk_branch *br = to_clk_branch(hw);
regmap_update_bits(br->clkr.regmap, br->mem_enable_reg,
br->mem_enable_ack_bit, 0);
return clk_branch2_disable(hw);
}
const struct clk_ops clk_branch2_ops = {
.prepare = clk_prepare_regmap,
.unprepare = clk_unprepare_regmap,
@ -290,6 +341,15 @@ const struct clk_ops clk_branch2_force_off_ops = {
};
EXPORT_SYMBOL(clk_branch2_force_off_ops);
const struct clk_ops clk_branch2_mem_ops = {
.enable = clk_branch2_mem_enable,
.disable = clk_branch2_mem_disable,
.is_enabled = clk_is_enabled_regmap,
.init = clk_branch2_init,
.debug_init = clk_branch_debug_init,
};
EXPORT_SYMBOL(clk_branch2_mem_ops);
static unsigned long clk_branch2_hw_ctl_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{

View File

@ -23,8 +23,11 @@
struct clk_branch {
u32 hwcg_reg;
u32 halt_reg;
u32 mem_enable_reg;
u32 mem_ack_reg;
u8 hwcg_bit;
u8 halt_bit;
u8 mem_enable_ack_bit;
u8 halt_check;
#define BRANCH_VOTED BIT(7) /* Delay on disable */
#define BRANCH_HALT 0 /* pol: 1 = halt */
@ -43,6 +46,7 @@ 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;
extern const struct clk_ops clk_branch2_mem_ops;
#define to_clk_branch(_hw) \
container_of(to_clk_regmap(_hw), struct clk_branch, clkr)

View File

@ -7,7 +7,7 @@
void clk_hw_populate_clock_opp_table(struct device_node *np,
struct clk_hw *hw);
#define MAX_LEN_OPP_HANDLE 50
#define MAX_LEN_OPP_HANDLE 100
#define LEN_OPP_HANDLE 16
#endif