/*
 * Copyright (C) 2017 NXP
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

#include <linux/device.h>
#include <linux/bitops.h>
#include <linux/io.h>
#include <video/videomode.h>
#include <drm/drm_fourcc.h>

#include <video/imx-dcss.h>
#include "dcss-prv.h"

#define USE_CTXLD

#define DCSS_SS_SYS_CTRL			0x00
#define   RUN_EN				BIT(0)
#define DCSS_SS_DISPLAY				0x10
#define   LRC_X_POS				0
#define   LRC_X_MASK				GENMASK(12, 0)
#define   LRC_Y_POS				16
#define   LRC_Y_MASK				GENMASK(28, 16)
#define DCSS_SS_HSYNC				0x20
#define DCSS_SS_VSYNC				0x30
#define   SYNC_START_POS			0
#define   SYNC_START_MASK			GENMASK(12, 0)
#define   SYNC_END_POS				16
#define   SYNC_END_MASK				GENMASK(28, 16)
#define   SYNC_POL				BIT(31)
#define DCSS_SS_DE_ULC				0x40
#define   ULC_X_POS				0
#define   ULC_X_MASK				GENMASK(12, 0)
#define   ULC_Y_POS				16
#define   ULC_Y_MASK				GENMASK(28, 16)
#define   ULC_POL				BIT(31)
#define DCSS_SS_DE_LRC				0x50
#define DCSS_SS_MODE				0x60
#define   PIPE_MODE_POS				0
#define   PIPE_MODE_MASK			GENMASK(1, 0)
#define DCSS_SS_COEFF				0x70
#define   HORIZ_A_POS				0
#define   HORIZ_A_MASK				GENMASK(3, 0)
#define   HORIZ_B_POS				4
#define   HORIZ_B_MASK				GENMASK(7, 4)
#define   HORIZ_C_POS				8
#define   HORIZ_C_MASK				GENMASK(11, 8)
#define   HORIZ_H_NORM_POS			12
#define   HORIZ_H_NORM_MASK			GENMASK(14, 12)
#define   VERT_A_POS				16
#define   VERT_A_MASK				GENMASK(19, 16)
#define   VERT_B_POS				20
#define   VERT_B_MASK				GENMASK(23, 20)
#define   VERT_C_POS				24
#define   VERT_C_MASK				GENMASK(27, 24)
#define   VERT_H_NORM_POS			28
#define   VERT_H_NORM_MASK			GENMASK(30, 28)
#define DCSS_SS_CLIP_CB				0x80
#define DCSS_SS_CLIP_CR				0x90
#define   CLIP_MIN_POS				0
#define   CLIP_MIN_MASK				GENMASK(9, 0)
#define   CLIP_MAX_POS				0
#define   CLIP_MAX_MASK				GENMASK(23, 16)
#define DCSS_SS_INTER_MODE			0xA0
#define   INT_EN				BIT(0)
#define   VSYNC_SHIFT				BIT(1)

static struct dcss_debug_reg ss_debug_reg[] = {
	DCSS_DBG_REG(DCSS_SS_SYS_CTRL),
	DCSS_DBG_REG(DCSS_SS_DISPLAY),
	DCSS_DBG_REG(DCSS_SS_HSYNC),
	DCSS_DBG_REG(DCSS_SS_VSYNC),
	DCSS_DBG_REG(DCSS_SS_DE_ULC),
	DCSS_DBG_REG(DCSS_SS_DE_LRC),
	DCSS_DBG_REG(DCSS_SS_MODE),
	DCSS_DBG_REG(DCSS_SS_COEFF),
	DCSS_DBG_REG(DCSS_SS_CLIP_CB),
	DCSS_DBG_REG(DCSS_SS_CLIP_CR),
	DCSS_DBG_REG(DCSS_SS_INTER_MODE),
};

struct dcss_ss_priv {
	struct dcss_soc *dcss;
	void __iomem *base_reg;
	u32 base_ofs;

	u32 ctx_id;

	bool in_use;
};

static void dcss_ss_write(struct dcss_ss_priv *ss, u32 val, u32 ofs)
{
	if (!ss->in_use)
		dcss_writel(val, ss->base_reg + ofs);
#if defined(USE_CTXLD)
	dcss_ctxld_write(ss->dcss, ss->ctx_id, val,
			 ss->base_ofs + ofs);
#endif
}

#ifdef CONFIG_DEBUG_FS
void dcss_ss_dump_regs(struct seq_file *s, void *data)
{
	struct dcss_soc *dcss = data;
	int j;

	seq_puts(s, ">> Dumping SUBSAM:\n");
	for (j = 0; j < ARRAY_SIZE(ss_debug_reg); j++)
		seq_printf(s, "%-35s(0x%04x) -> 0x%08x\n",
			   ss_debug_reg[j].name,
			   ss_debug_reg[j].ofs,
			   dcss_readl(dcss->ss_priv->base_reg +
				      ss_debug_reg[j].ofs));
}
#endif

int dcss_ss_init(struct dcss_soc *dcss, unsigned long ss_base)
{
	struct dcss_ss_priv *ss;

	ss = devm_kzalloc(dcss->dev, sizeof(*ss), GFP_KERNEL);
	if (!ss)
		return -ENOMEM;

	dcss->ss_priv = ss;
	ss->dcss = dcss;

	ss->base_reg = devm_ioremap(dcss->dev, ss_base, SZ_4K);
	if (!ss->base_reg) {
		dev_err(dcss->dev, "ss: unable to remap ss base\n");
		return -ENOMEM;
	}

	ss->base_ofs = ss_base;

#if defined(USE_CTXLD)
	ss->ctx_id = CTX_SB_HP;
#endif

	return 0;
}

void dcss_ss_exit(struct dcss_soc *dcss)
{
	dcss_writel(0, dcss->ss_priv->base_reg + DCSS_SS_SYS_CTRL);
}

void dcss_ss_subsam_set(struct dcss_soc *dcss, u32 pix_format)
{
	if (pix_format == DRM_FORMAT_P010) {
		dcss_ss_write(dcss->ss_priv, 0x21612161, DCSS_SS_COEFF);
		dcss_ss_write(dcss->ss_priv, 2, DCSS_SS_MODE);
		dcss_ss_write(dcss->ss_priv, 0x03c00040, DCSS_SS_CLIP_CB);
		dcss_ss_write(dcss->ss_priv, 0x03c00040, DCSS_SS_CLIP_CR);

		return;
	}

	dcss_ss_write(dcss->ss_priv, 0x41614161, DCSS_SS_COEFF);
	dcss_ss_write(dcss->ss_priv, 0, DCSS_SS_MODE);
	dcss_ss_write(dcss->ss_priv, 0x03ff0000, DCSS_SS_CLIP_CB);
	dcss_ss_write(dcss->ss_priv, 0x03ff0000, DCSS_SS_CLIP_CR);
}

void dcss_ss_sync_set(struct dcss_soc *dcss, struct videomode *vm,
		      bool phsync, bool pvsync)
{
	struct dcss_ss_priv *ss = dcss->ss_priv;
	u16 lrc_x, lrc_y;
	u16 hsync_start, hsync_end;
	u16 vsync_start, vsync_end;
	u16 de_ulc_x, de_ulc_y;
	u16 de_lrc_x, de_lrc_y;

	lrc_x = vm->hfront_porch + vm->hback_porch + vm->hsync_len +
		vm->hactive - 1;
	lrc_y = vm->vfront_porch + vm->vback_porch + vm->vsync_len +
		vm->vactive - 1;

	dcss_ss_write(ss, (lrc_y << LRC_Y_POS) | lrc_x, DCSS_SS_DISPLAY);

	hsync_start = vm->hfront_porch + vm->hback_porch + vm->hsync_len +
		      vm->hactive - 1;
	hsync_end = vm->hsync_len - 1;

	dcss_ss_write(ss, (phsync ? SYNC_POL : 0) |
		      (hsync_end << SYNC_END_POS) | hsync_start,
		      DCSS_SS_HSYNC);

	vsync_start = vm->vfront_porch - 1;
	vsync_end = vm->vfront_porch + vm->vsync_len - 1;

	dcss_ss_write(ss, (pvsync ? SYNC_POL : 0) |
		      (vsync_end << SYNC_END_POS) | vsync_start, DCSS_SS_VSYNC);

	de_ulc_x = vm->hsync_len + vm->hback_porch - 1;
	de_ulc_y = vm->vsync_len + vm->vfront_porch + vm->vback_porch;

	dcss_ss_write(ss, SYNC_POL | (de_ulc_y << ULC_Y_POS) | de_ulc_x,
		      DCSS_SS_DE_ULC);

	de_lrc_x = vm->hsync_len + vm->hback_porch + vm->hactive - 1;
	de_lrc_y = vm->vsync_len + vm->vfront_porch + vm->vback_porch +
		   vm->vactive - 1;

	dcss_ss_write(ss, (de_lrc_y << LRC_Y_POS) | de_lrc_x, DCSS_SS_DE_LRC);
}
EXPORT_SYMBOL(dcss_ss_sync_set);

void dcss_ss_enable(struct dcss_soc *dcss, bool en)
{
	struct dcss_ss_priv *ss = dcss->ss_priv;

	dcss_ss_write(ss, en ? RUN_EN : 0, DCSS_SS_SYS_CTRL);
}
EXPORT_SYMBOL(dcss_ss_enable);
