Commit 261625e0 authored by Taniya Das's avatar Taniya Das Committed by Bjorn Andersson
Browse files

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: default avatarTaniya Das <quic_tdas@quicinc.com>
Signed-off-by: default avatarImran Shaik <quic_imrashai@quicinc.com>
Reviewed-by: default avatarKonrad Dybcio <konrad.dybcio@linaro.org>
Link: https://lore.kernel.org/r/20231123064735.2979802-3-quic_imrashai@quicinc.com


Signed-off-by: default avatarBjorn Andersson <andersson@kernel.org>
parent cdf1c63d
Loading
Loading
Loading
Loading
+38 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
 * Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
 */

#include <linux/kernel.h>
@@ -134,6 +135,43 @@ static void clk_branch2_disable(struct clk_hw *hw)
	clk_branch_toggle(hw, false, clk_branch2_check_halt);
}

static int clk_branch2_mem_enable(struct clk_hw *hw)
{
	struct clk_mem_branch *mem_br = to_clk_mem_branch(hw);
	struct clk_branch branch = mem_br->branch;
	u32 val;
	int ret;

	regmap_update_bits(branch.clkr.regmap, mem_br->mem_enable_reg,
			   mem_br->mem_enable_ack_mask, mem_br->mem_enable_ack_mask);

	ret = regmap_read_poll_timeout(branch.clkr.regmap, mem_br->mem_ack_reg,
				       val, val & mem_br->mem_enable_ack_mask, 0, 200);
	if (ret) {
		WARN(1, "%s mem enable failed\n", clk_hw_get_name(&branch.clkr.hw));
		return ret;
	}

	return clk_branch2_enable(hw);
}

static void clk_branch2_mem_disable(struct clk_hw *hw)
{
	struct clk_mem_branch *mem_br = to_clk_mem_branch(hw);

	regmap_update_bits(mem_br->branch.clkr.regmap, mem_br->mem_enable_reg,
			   mem_br->mem_enable_ack_mask, 0);

	return clk_branch2_disable(hw);
}

const struct clk_ops clk_branch2_mem_ops = {
	.enable = clk_branch2_mem_enable,
	.disable = clk_branch2_mem_disable,
	.is_enabled = clk_is_enabled_regmap,
};
EXPORT_SYMBOL_GPL(clk_branch2_mem_ops);

const struct clk_ops clk_branch2_ops = {
	.enable = clk_branch2_enable,
	.disable = clk_branch2_disable,
+21 −0
Original line number Diff line number Diff line
@@ -38,6 +38,23 @@ struct clk_branch {
	struct clk_regmap clkr;
};

/**
 * struct clk_mem_branch - gating clock which are associated with memories
 *
 * @mem_enable_reg: branch clock memory gating register
 * @mem_ack_reg: branch clock memory ack register
 * @mem_enable_ack_mask: branch clock memory enable and ack field in @mem_ack_reg
 * @branch: branch clock gating handle
 *
 * Clock which can gate its memories.
 */
struct clk_mem_branch {
	u32	mem_enable_reg;
	u32	mem_ack_reg;
	u32	mem_enable_ack_mask;
	struct clk_branch branch;
};

/* Branch clock common bits for HLOS-owned clocks */
#define CBCR_CLK_OFF			BIT(31)
#define CBCR_NOC_FSM_STATUS		GENMASK(30, 28)
@@ -85,8 +102,12 @@ extern const struct clk_ops clk_branch_ops;
extern const struct clk_ops clk_branch2_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_mem_ops;

#define to_clk_branch(_hw) \
	container_of(to_clk_regmap(_hw), struct clk_branch, clkr)

#define to_clk_mem_branch(_hw) \
	container_of(to_clk_branch(_hw), struct clk_mem_branch, branch)

#endif