// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2018 MediaTek Inc.
 * Author: Owen Chen <Owen.Chen@mediatek.com>
 */
#include <linux/ktime.h>
#include <linux/mfd/syscon.h>
#include <linux/of_device.h>
#include <linux/regmap.h>
#include <linux/soc/mediatek/scpsys-ext.h>

#define MTK_POLL_DELAY_US   10
#define MTK_POLL_TIMEOUT    (jiffies_to_usecs(HZ))

static int set_way_en(struct regmap *map, struct regmap *ack, u32 mask,
				u32 ack_mask, u32 reg_set, u32 reg_sta,
				u32 reg_en)
{
	u32 val;

	if (reg_set)
		regmap_write(map, reg_set, mask);
	else
		regmap_update_bits(map, reg_en, mask, mask);

	return regmap_read_poll_timeout(ack, reg_sta,
			val, (val & ack_mask) == ack_mask,
			MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
}

static int clear_way_en(struct regmap *map, struct regmap *ack, u32 mask,
				u32 ack_mask, u32 reg_clr, u32 reg_sta,
				u32 reg_en)
{
	u32 val;

	if (reg_clr)
		regmap_write(map, reg_clr, mask);
	else
		regmap_update_bits(map, reg_en, mask, 0);

	return regmap_read_poll_timeout(ack, reg_sta,
			val, (val & ack_mask) == ack_mask,
			MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
}

static int set_bus_protection(struct regmap *map, u32 mask, u32 ack_mask,
				u32 reg_set, u32 reg_sta, u32 reg_en)
{
	u32 val;

	if (reg_set)
		regmap_write(map, reg_set, mask);
	else
		regmap_update_bits(map, reg_en, mask, mask);

	return regmap_read_poll_timeout(map, reg_sta,
			val, (val & ack_mask) == ack_mask,
			MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
}

static int clear_bus_protection(struct regmap *map, u32 mask, u32 ack_mask,
				u32 reg_clr, u32 reg_sta, u32 reg_en)
{
	u32 val;

	if (reg_clr)
		regmap_write(map, reg_clr, mask);
	else
		regmap_update_bits(map, reg_en, mask, 0);

	return regmap_read_poll_timeout(map, reg_sta,
			val, !(val & ack_mask),
			MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
}

int mtk_scpsys_ext_set_bus_protection(const struct bus_prot *bp_table,
	struct regmap *infracfg, struct regmap *smi_common,
	struct regmap *infracfg_nao)
{
	int i;

	for (i = 0; i < MAX_STEPS && bp_table[i].mask; i++) {
		int ret;

		switch (bp_table[i].type) {
		case IFR_TYPE:
			ret = set_bus_protection(infracfg, bp_table[i].mask,
					bp_table[i].mask, bp_table[i].set_ofs,
					bp_table[i].sta_ofs,
					bp_table[i].en_ofs);
			break;
		case SMI_TYPE:
			ret = set_bus_protection(smi_common, bp_table[i].mask,
					bp_table[i].mask, bp_table[i].set_ofs,
					bp_table[i].sta_ofs,
					bp_table[i].en_ofs);
			break;
		case IFR_WAYEN_TYPE:
			ret = clear_way_en(infracfg, infracfg_nao,
					bp_table[i].mask,
					bp_table[i].clr_ack_mask,
					bp_table[i].clr_ofs,
					bp_table[i].sta_ofs,
					bp_table[i].en_ofs);
			break;
		default:
			return -EINVAL;
		}

		if (ret)
			return ret;
	}

	return 0;
}

int mtk_scpsys_ext_clear_bus_protection(const struct bus_prot *bp_table,
	struct regmap *infracfg, struct regmap *smi_common,
	struct regmap *infracfg_nao)
{
	int i;

	for (i = MAX_STEPS - 1; i >= 0; i--) {
		int ret;

		switch (bp_table[i].type) {
		case IFR_TYPE:
			ret = clear_bus_protection(infracfg, bp_table[i].mask,
						bp_table[i].clr_ack_mask,
						bp_table[i].clr_ofs,
						bp_table[i].sta_ofs,
						bp_table[i].en_ofs);
			break;
		case SMI_TYPE:
			ret = clear_bus_protection(smi_common,
						bp_table[i].mask,
						bp_table[i].clr_ack_mask,
						bp_table[i].clr_ofs,
						bp_table[i].sta_ofs,
						bp_table[i].en_ofs);
			break;
		case IFR_WAYEN_TYPE:
			ret = set_way_en(infracfg, infracfg_nao,
						bp_table[i].mask,
						bp_table[i].set_ack_mask,
						bp_table[i].set_ofs,
						bp_table[i].sta_ofs,
						bp_table[i].en_ofs);
			break;
		default:
			return -EINVAL;
		}

		if (ret)
			return ret;
	}

	return 0;
}
