// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 */

#include "dpu_hwio.h"
#include "dpu_hw_catalog.h"
#include "dpu_hw_vbif.h"

#define VBIF_VERSION			0x0000
#define VBIF_CLK_FORCE_CTRL0		0x0008
#define VBIF_CLK_FORCE_CTRL1		0x000C
#define VBIF_QOS_REMAP_00		0x0020
#define VBIF_QOS_REMAP_01		0x0024
#define VBIF_QOS_REMAP_10		0x0028
#define VBIF_QOS_REMAP_11		0x002C
#define VBIF_WRITE_GATHER_EN		0x00AC
#define VBIF_IN_RD_LIM_CONF0		0x00B0
#define VBIF_IN_RD_LIM_CONF1		0x00B4
#define VBIF_IN_RD_LIM_CONF2		0x00B8
#define VBIF_IN_WR_LIM_CONF0		0x00C0
#define VBIF_IN_WR_LIM_CONF1		0x00C4
#define VBIF_IN_WR_LIM_CONF2		0x00C8
#define VBIF_OUT_RD_LIM_CONF0		0x00D0
#define VBIF_OUT_WR_LIM_CONF0		0x00D4
#define VBIF_OUT_AXI_AMEMTYPE_CONF0	0x0160
#define VBIF_OUT_AXI_AMEMTYPE_CONF1	0x0164
#define VBIF_XIN_PND_ERR		0x0190
#define VBIF_XIN_SRC_ERR		0x0194
#define VBIF_XIN_CLR_ERR		0x019C
#define VBIF_XIN_HALT_CTRL0		0x0200
#define VBIF_XIN_HALT_CTRL1		0x0204
#define VBIF_XINL_QOS_RP_REMAP_000	0x0550
#define VBIF_XINL_QOS_LVL_REMAP_000(v)	(v < DPU_HW_VER_400 ? 0x570 : 0x0590)

static void dpu_hw_clear_errors(struct dpu_hw_vbif *vbif,
		u32 *pnd_errors, u32 *src_errors)
{
	struct dpu_hw_blk_reg_map *c;
	u32 pnd, src;

	if (!vbif)
		return;
	c = &vbif->hw;
	pnd = DPU_REG_READ(c, VBIF_XIN_PND_ERR);
	src = DPU_REG_READ(c, VBIF_XIN_SRC_ERR);

	if (pnd_errors)
		*pnd_errors = pnd;
	if (src_errors)
		*src_errors = src;

	DPU_REG_WRITE(c, VBIF_XIN_CLR_ERR, pnd | src);
}

static void dpu_hw_set_mem_type(struct dpu_hw_vbif *vbif,
		u32 xin_id, u32 value)
{
	struct dpu_hw_blk_reg_map *c;
	u32 reg_off;
	u32 bit_off;
	u32 reg_val;

	/*
	 * Assume 4 bits per bit field, 8 fields per 32-bit register so
	 * 16 bit fields maximum across two registers
	 */
	if (!vbif || xin_id >= MAX_XIN_COUNT || xin_id >= 16)
		return;

	c = &vbif->hw;

	if (xin_id >= 8) {
		xin_id -= 8;
		reg_off = VBIF_OUT_AXI_AMEMTYPE_CONF1;
	} else {
		reg_off = VBIF_OUT_AXI_AMEMTYPE_CONF0;
	}
	bit_off = (xin_id & 0x7) * 4;
	reg_val = DPU_REG_READ(c, reg_off);
	reg_val &= ~(0x7 << bit_off);
	reg_val |= (value & 0x7) << bit_off;
	DPU_REG_WRITE(c, reg_off, reg_val);
}

static void dpu_hw_set_limit_conf(struct dpu_hw_vbif *vbif,
		u32 xin_id, bool rd, u32 limit)
{
	struct dpu_hw_blk_reg_map *c = &vbif->hw;
	u32 reg_val;
	u32 reg_off;
	u32 bit_off;

	if (rd)
		reg_off = VBIF_IN_RD_LIM_CONF0;
	else
		reg_off = VBIF_IN_WR_LIM_CONF0;

	reg_off += (xin_id / 4) * 4;
	bit_off = (xin_id % 4) * 8;
	reg_val = DPU_REG_READ(c, reg_off);
	reg_val &= ~(0xFF << bit_off);
	reg_val |= (limit) << bit_off;
	DPU_REG_WRITE(c, reg_off, reg_val);
}

static u32 dpu_hw_get_limit_conf(struct dpu_hw_vbif *vbif,
		u32 xin_id, bool rd)
{
	struct dpu_hw_blk_reg_map *c = &vbif->hw;
	u32 reg_val;
	u32 reg_off;
	u32 bit_off;
	u32 limit;

	if (rd)
		reg_off = VBIF_IN_RD_LIM_CONF0;
	else
		reg_off = VBIF_IN_WR_LIM_CONF0;

	reg_off += (xin_id / 4) * 4;
	bit_off = (xin_id % 4) * 8;
	reg_val = DPU_REG_READ(c, reg_off);
	limit = (reg_val >> bit_off) & 0xFF;

	return limit;
}

static void dpu_hw_set_halt_ctrl(struct dpu_hw_vbif *vbif,
		u32 xin_id, bool enable)
{
	struct dpu_hw_blk_reg_map *c = &vbif->hw;
	u32 reg_val;

	reg_val = DPU_REG_READ(c, VBIF_XIN_HALT_CTRL0);

	if (enable)
		reg_val |= BIT(xin_id);
	else
		reg_val &= ~BIT(xin_id);

	DPU_REG_WRITE(c, VBIF_XIN_HALT_CTRL0, reg_val);
}

static bool dpu_hw_get_halt_ctrl(struct dpu_hw_vbif *vbif,
		u32 xin_id)
{
	struct dpu_hw_blk_reg_map *c = &vbif->hw;
	u32 reg_val;

	reg_val = DPU_REG_READ(c, VBIF_XIN_HALT_CTRL1);

	return (reg_val & BIT(xin_id)) ? true : false;
}

static void dpu_hw_set_qos_remap(struct dpu_hw_vbif *vbif,
		u32 xin_id, u32 level, u32 remap_level)
{
	struct dpu_hw_blk_reg_map *c;
	u32 reg_lvl, reg_val, reg_val_lvl, mask, reg_high, reg_shift;

	if (!vbif)
		return;

	c = &vbif->hw;

	reg_lvl = VBIF_XINL_QOS_LVL_REMAP_000(c->hwversion);
	reg_high = ((xin_id & 0x8) >> 3) * 4 + (level * 8);
	reg_shift = (xin_id & 0x7) * 4;

	reg_val = DPU_REG_READ(c, VBIF_XINL_QOS_RP_REMAP_000 + reg_high);
	reg_val_lvl = DPU_REG_READ(c, reg_lvl + reg_high);

	mask = 0x7 << reg_shift;

	reg_val &= ~mask;
	reg_val |= (remap_level << reg_shift) & mask;

	reg_val_lvl &= ~mask;
	reg_val_lvl |= (remap_level << reg_shift) & mask;

	DPU_REG_WRITE(c, VBIF_XINL_QOS_RP_REMAP_000 + reg_high, reg_val);
	DPU_REG_WRITE(c, reg_lvl + reg_high, reg_val_lvl);
}

static void dpu_hw_set_write_gather_en(struct dpu_hw_vbif *vbif, u32 xin_id)
{
	struct dpu_hw_blk_reg_map *c;
	u32 reg_val;

	if (!vbif || xin_id >= MAX_XIN_COUNT)
		return;

	c = &vbif->hw;

	reg_val = DPU_REG_READ(c, VBIF_WRITE_GATHER_EN);
	reg_val |= BIT(xin_id);
	DPU_REG_WRITE(c, VBIF_WRITE_GATHER_EN, reg_val);
}

static void _setup_vbif_ops(struct dpu_hw_vbif_ops *ops,
		unsigned long cap)
{
	ops->set_limit_conf = dpu_hw_set_limit_conf;
	ops->get_limit_conf = dpu_hw_get_limit_conf;
	ops->set_halt_ctrl = dpu_hw_set_halt_ctrl;
	ops->get_halt_ctrl = dpu_hw_get_halt_ctrl;
	if (test_bit(DPU_VBIF_QOS_REMAP, &cap))
		ops->set_qos_remap = dpu_hw_set_qos_remap;
	ops->set_mem_type = dpu_hw_set_mem_type;
	ops->clear_errors = dpu_hw_clear_errors;
	ops->set_write_gather_en = dpu_hw_set_write_gather_en;
}

static const struct dpu_vbif_cfg *_top_offset(enum dpu_vbif vbif,
		const struct dpu_mdss_cfg *m,
		void __iomem *addr,
		struct dpu_hw_blk_reg_map *b)
{
	int i;

	for (i = 0; i < m->vbif_count; i++) {
		if (vbif == m->vbif[i].id) {
			b->base_off = addr;
			b->blk_off = m->vbif[i].base;
			b->length = m->vbif[i].len;
			b->hwversion = m->hwversion;
			b->log_mask = DPU_DBG_MASK_VBIF;
			return &m->vbif[i];
		}
	}

	return ERR_PTR(-EINVAL);
}

struct dpu_hw_vbif *dpu_hw_vbif_init(enum dpu_vbif idx,
		void __iomem *addr,
		const struct dpu_mdss_cfg *m)
{
	struct dpu_hw_vbif *c;
	const struct dpu_vbif_cfg *cfg;

	c = kzalloc(sizeof(*c), GFP_KERNEL);
	if (!c)
		return ERR_PTR(-ENOMEM);

	cfg = _top_offset(idx, m, addr, &c->hw);
	if (IS_ERR_OR_NULL(cfg)) {
		kfree(c);
		return ERR_PTR(-EINVAL);
	}

	/*
	 * Assign ops
	 */
	c->idx = idx;
	c->cap = cfg;
	_setup_vbif_ops(&c->ops, c->cap->features);

	/* no need to register sub-range in dpu dbg, dump entire vbif io base */

	return c;
}

void dpu_hw_vbif_destroy(struct dpu_hw_vbif *vbif)
{
	kfree(vbif);
}
