// 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>
#include <linux/bitops.h>
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/export.h>
#include <linux/clk-provider.h>
#include <linux/regmap.h>

#include "clk-branch.h"

static bool clk_branch_in_hwcg_mode(const struct clk_branch *br)
{
	u32 val;

	if (!br->hwcg_reg)
		return false;

	regmap_read(br->clkr.regmap, br->hwcg_reg, &val);

	return !!(val & BIT(br->hwcg_bit));
}

static bool clk_branch_check_halt(const struct clk_branch *br, bool enabling)
{
	bool invert = (br->halt_check & BRANCH_HALT_ENABLE);
	u32 val;

	regmap_read(br->clkr.regmap, br->halt_reg, &val);

	val &= BIT(br->halt_bit);
	if (invert)
		val = !val;

	return !!val == !enabling;
}

static bool clk_branch2_check_halt(const struct clk_branch *br, bool enabling)
{
	u32 val;
	u32 mask;
	bool invert = (br->halt_check & BRANCH_HALT_ENABLE);

	mask = CBCR_NOC_FSM_STATUS;
	mask |= CBCR_CLK_OFF;

	regmap_read(br->clkr.regmap, br->halt_reg, &val);

	if (enabling) {
		val &= mask;
		return (val & CBCR_CLK_OFF) == (invert ? CBCR_CLK_OFF : 0) ||
			FIELD_GET(CBCR_NOC_FSM_STATUS, val) == FSM_STATUS_ON;
	}
	return (val & CBCR_CLK_OFF) == (invert ? 0 : CBCR_CLK_OFF);
}

static int clk_branch_wait(const struct clk_branch *br, bool enabling,
		bool (check_halt)(const struct clk_branch *, bool))
{
	bool voted = br->halt_check & BRANCH_VOTED;
	const char *name = clk_hw_get_name(&br->clkr.hw);

	/*
	 * Skip checking halt bit if we're explicitly ignoring the bit or the
	 * clock is in hardware gated mode
	 */
	if (br->halt_check == BRANCH_HALT_SKIP || clk_branch_in_hwcg_mode(br))
		return 0;

	if (br->halt_check == BRANCH_HALT_DELAY || (!enabling && voted)) {
		udelay(10);
	} else if (br->halt_check == BRANCH_HALT_ENABLE ||
		   br->halt_check == BRANCH_HALT ||
		   (enabling && voted)) {
		int count = 200;

		while (count-- > 0) {
			if (check_halt(br, enabling))
				return 0;
			udelay(1);
		}
		WARN(1, "%s status stuck at 'o%s'", name,
				enabling ? "ff" : "n");
		return -EBUSY;
	}
	return 0;
}

static int clk_branch_toggle(struct clk_hw *hw, bool en,
		bool (check_halt)(const struct clk_branch *, bool))
{
	struct clk_branch *br = to_clk_branch(hw);
	int ret;

	if (en) {
		ret = clk_enable_regmap(hw);
		if (ret)
			return ret;
	} else {
		clk_disable_regmap(hw);
	}

	return clk_branch_wait(br, en, check_halt);
}

static int clk_branch_enable(struct clk_hw *hw)
{
	return clk_branch_toggle(hw, true, clk_branch_check_halt);
}

static void clk_branch_disable(struct clk_hw *hw)
{
	clk_branch_toggle(hw, false, clk_branch_check_halt);
}

const struct clk_ops clk_branch_ops = {
	.enable = clk_branch_enable,
	.disable = clk_branch_disable,
	.is_enabled = clk_is_enabled_regmap,
};
EXPORT_SYMBOL_GPL(clk_branch_ops);

static int clk_branch2_enable(struct clk_hw *hw)
{
	return clk_branch_toggle(hw, true, clk_branch2_check_halt);
}

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,
	.is_enabled = clk_is_enabled_regmap,
};
EXPORT_SYMBOL_GPL(clk_branch2_ops);

const struct clk_ops clk_branch2_aon_ops = {
	.enable = clk_branch2_enable,
	.is_enabled = clk_is_enabled_regmap,
};
EXPORT_SYMBOL_GPL(clk_branch2_aon_ops);

const struct clk_ops clk_branch_simple_ops = {
	.enable = clk_enable_regmap,
	.disable = clk_disable_regmap,
	.is_enabled = clk_is_enabled_regmap,
};
EXPORT_SYMBOL_GPL(clk_branch_simple_ops);

const struct clk_ops clk_branch2_prepare_ops = {
	.prepare = clk_branch2_enable,
	.unprepare = clk_branch2_disable,
	.is_prepared = clk_is_enabled_regmap,
};
EXPORT_SYMBOL_GPL(clk_branch2_prepare_ops);
