// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2019 NXP.
 */

#include <linux/device.h>
#include <linux/slab.h>

#include "dcss-dev.h"

#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)

struct dcss_ss {
	struct device *dev;
	void __iomem *base_reg;
	u32 base_ofs;

	struct dcss_ctxld *ctxld;
	u32 ctx_id;

	bool in_use;
};

static void dcss_ss_write(struct dcss_ss *ss, u32 val, u32 ofs)
{
	if (!ss->in_use)
		dcss_writel(val, ss->base_reg + ofs);

	dcss_ctxld_write(ss->ctxld, ss->ctx_id, val,
			 ss->base_ofs + ofs);
}

int dcss_ss_init(struct dcss_dev *dcss, unsigned long ss_base)
{
	struct dcss_ss *ss;

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

	dcss->ss = ss;
	ss->dev = dcss->dev;
	ss->ctxld = dcss->ctxld;

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

	ss->base_ofs = ss_base;
	ss->ctx_id = CTX_SB_HP;

	return 0;
}

void dcss_ss_exit(struct dcss_ss *ss)
{
	/* stop SS */
	dcss_writel(0, ss->base_reg + DCSS_SS_SYS_CTRL);
}

void dcss_ss_subsam_set(struct dcss_ss *ss)
{
	dcss_ss_write(ss, 0x41614161, DCSS_SS_COEFF);
	dcss_ss_write(ss, 0, DCSS_SS_MODE);
	dcss_ss_write(ss, 0x03ff0000, DCSS_SS_CLIP_CB);
	dcss_ss_write(ss, 0x03ff0000, DCSS_SS_CLIP_CR);
}

void dcss_ss_sync_set(struct dcss_ss *ss, struct videomode *vm,
		      bool phsync, bool pvsync)
{
	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) |
		      ((u32)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) |
		      ((u32)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 | ((u32)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);
}

void dcss_ss_enable(struct dcss_ss *ss)
{
	dcss_ss_write(ss, RUN_EN, DCSS_SS_SYS_CTRL);
	ss->in_use = true;
}

void dcss_ss_shutoff(struct dcss_ss *ss)
{
	dcss_writel(0, ss->base_reg + DCSS_SS_SYS_CTRL);
	ss->in_use = false;
}
