// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Copyright (C) 2012-2016 Mentor Graphics Inc.
 * Copyright (C) 2005-2009 Freescale Semiconductor, Inc.
 */
#include <linux/io.h>
#include "ipu-prv.h"

struct ipu_vdi {
	void __iomem *base;
	u32 module;
	spinlock_t lock;
	int use_count;
	struct ipu_soc *ipu;
};


/* VDI Register Offsets */
#define VDI_FSIZE 0x0000
#define VDI_C     0x0004

/* VDI Register Fields */
#define VDI_C_CH_420             (0 << 1)
#define VDI_C_CH_422             (1 << 1)
#define VDI_C_MOT_SEL_MASK       (0x3 << 2)
#define VDI_C_MOT_SEL_FULL       (2 << 2)
#define VDI_C_MOT_SEL_LOW        (1 << 2)
#define VDI_C_MOT_SEL_MED        (0 << 2)
#define VDI_C_BURST_SIZE1_4      (3 << 4)
#define VDI_C_BURST_SIZE2_4      (3 << 8)
#define VDI_C_BURST_SIZE3_4      (3 << 12)
#define VDI_C_BURST_SIZE_MASK    0xF
#define VDI_C_BURST_SIZE1_OFFSET 4
#define VDI_C_BURST_SIZE2_OFFSET 8
#define VDI_C_BURST_SIZE3_OFFSET 12
#define VDI_C_VWM1_SET_1         (0 << 16)
#define VDI_C_VWM1_SET_2         (1 << 16)
#define VDI_C_VWM1_CLR_2         (1 << 19)
#define VDI_C_VWM3_SET_1         (0 << 22)
#define VDI_C_VWM3_SET_2         (1 << 22)
#define VDI_C_VWM3_CLR_2         (1 << 25)
#define VDI_C_TOP_FIELD_MAN_1    (1 << 30)
#define VDI_C_TOP_FIELD_AUTO_1   (1 << 31)

static inline u32 ipu_vdi_read(struct ipu_vdi *vdi, unsigned int offset)
{
	return readl(vdi->base + offset);
}

static inline void ipu_vdi_write(struct ipu_vdi *vdi, u32 value,
				 unsigned int offset)
{
	writel(value, vdi->base + offset);
}

void ipu_vdi_set_field_order(struct ipu_vdi *vdi, v4l2_std_id std, u32 field)
{
	bool top_field_0 = false;
	unsigned long flags;
	u32 reg;

	switch (field) {
	case V4L2_FIELD_INTERLACED_TB:
	case V4L2_FIELD_SEQ_TB:
	case V4L2_FIELD_TOP:
		top_field_0 = true;
		break;
	case V4L2_FIELD_INTERLACED_BT:
	case V4L2_FIELD_SEQ_BT:
	case V4L2_FIELD_BOTTOM:
		top_field_0 = false;
		break;
	default:
		top_field_0 = (std & V4L2_STD_525_60) ? true : false;
		break;
	}

	spin_lock_irqsave(&vdi->lock, flags);

	reg = ipu_vdi_read(vdi, VDI_C);
	if (top_field_0)
		reg &= ~(VDI_C_TOP_FIELD_MAN_1 | VDI_C_TOP_FIELD_AUTO_1);
	else
		reg |= VDI_C_TOP_FIELD_MAN_1 | VDI_C_TOP_FIELD_AUTO_1;
	ipu_vdi_write(vdi, reg, VDI_C);

	spin_unlock_irqrestore(&vdi->lock, flags);
}
EXPORT_SYMBOL_GPL(ipu_vdi_set_field_order);

void ipu_vdi_set_motion(struct ipu_vdi *vdi, enum ipu_motion_sel motion_sel)
{
	unsigned long flags;
	u32 reg;

	spin_lock_irqsave(&vdi->lock, flags);

	reg = ipu_vdi_read(vdi, VDI_C);

	reg &= ~VDI_C_MOT_SEL_MASK;

	switch (motion_sel) {
	case MED_MOTION:
		reg |= VDI_C_MOT_SEL_MED;
		break;
	case HIGH_MOTION:
		reg |= VDI_C_MOT_SEL_FULL;
		break;
	default:
		reg |= VDI_C_MOT_SEL_LOW;
		break;
	}

	ipu_vdi_write(vdi, reg, VDI_C);

	spin_unlock_irqrestore(&vdi->lock, flags);
}
EXPORT_SYMBOL_GPL(ipu_vdi_set_motion);

void ipu_vdi_setup(struct ipu_vdi *vdi, u32 code, int xres, int yres)
{
	unsigned long flags;
	u32 pixel_fmt, reg;

	spin_lock_irqsave(&vdi->lock, flags);

	reg = ((yres - 1) << 16) | (xres - 1);
	ipu_vdi_write(vdi, reg, VDI_FSIZE);

	/*
	 * Full motion, only vertical filter is used.
	 * Burst size is 4 accesses
	 */
	if (code == MEDIA_BUS_FMT_UYVY8_2X8 ||
	    code == MEDIA_BUS_FMT_UYVY8_1X16 ||
	    code == MEDIA_BUS_FMT_YUYV8_2X8 ||
	    code == MEDIA_BUS_FMT_YUYV8_1X16)
		pixel_fmt = VDI_C_CH_422;
	else
		pixel_fmt = VDI_C_CH_420;

	reg = ipu_vdi_read(vdi, VDI_C);
	reg |= pixel_fmt;
	reg |= VDI_C_BURST_SIZE2_4;
	reg |= VDI_C_BURST_SIZE1_4 | VDI_C_VWM1_CLR_2;
	reg |= VDI_C_BURST_SIZE3_4 | VDI_C_VWM3_CLR_2;
	ipu_vdi_write(vdi, reg, VDI_C);

	spin_unlock_irqrestore(&vdi->lock, flags);
}
EXPORT_SYMBOL_GPL(ipu_vdi_setup);

void ipu_vdi_unsetup(struct ipu_vdi *vdi)
{
	unsigned long flags;

	spin_lock_irqsave(&vdi->lock, flags);
	ipu_vdi_write(vdi, 0, VDI_FSIZE);
	ipu_vdi_write(vdi, 0, VDI_C);
	spin_unlock_irqrestore(&vdi->lock, flags);
}
EXPORT_SYMBOL_GPL(ipu_vdi_unsetup);

int ipu_vdi_enable(struct ipu_vdi *vdi)
{
	unsigned long flags;

	spin_lock_irqsave(&vdi->lock, flags);

	if (!vdi->use_count)
		ipu_module_enable(vdi->ipu, vdi->module);

	vdi->use_count++;

	spin_unlock_irqrestore(&vdi->lock, flags);

	return 0;
}
EXPORT_SYMBOL_GPL(ipu_vdi_enable);

int ipu_vdi_disable(struct ipu_vdi *vdi)
{
	unsigned long flags;

	spin_lock_irqsave(&vdi->lock, flags);

	if (vdi->use_count) {
		if (!--vdi->use_count)
			ipu_module_disable(vdi->ipu, vdi->module);
	}

	spin_unlock_irqrestore(&vdi->lock, flags);

	return 0;
}
EXPORT_SYMBOL_GPL(ipu_vdi_disable);

struct ipu_vdi *ipu_vdi_get(struct ipu_soc *ipu)
{
	return ipu->vdi_priv;
}
EXPORT_SYMBOL_GPL(ipu_vdi_get);

void ipu_vdi_put(struct ipu_vdi *vdi)
{
}
EXPORT_SYMBOL_GPL(ipu_vdi_put);

int ipu_vdi_init(struct ipu_soc *ipu, struct device *dev,
		 unsigned long base, u32 module)
{
	struct ipu_vdi *vdi;

	vdi = devm_kzalloc(dev, sizeof(*vdi), GFP_KERNEL);
	if (!vdi)
		return -ENOMEM;

	ipu->vdi_priv = vdi;

	spin_lock_init(&vdi->lock);
	vdi->module = module;
	vdi->base = devm_ioremap(dev, base, PAGE_SIZE);
	if (!vdi->base)
		return -ENOMEM;

	dev_dbg(dev, "VDI base: 0x%08lx remapped to %p\n", base, vdi->base);
	vdi->ipu = ipu;

	return 0;
}

void ipu_vdi_exit(struct ipu_soc *ipu)
{
}
