// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright 2019 NXP.
 *
 * Scaling algorithms were contributed by Dzung Hoang <dzung.hoang@nxp.com>
 */

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

#include "dcss-dev.h"

#define DCSS_SCALER_CTRL			0x00
#define   SCALER_EN				BIT(0)
#define   REPEAT_EN				BIT(4)
#define   SCALE2MEM_EN				BIT(8)
#define   MEM2OFIFO_EN				BIT(12)
#define DCSS_SCALER_OFIFO_CTRL			0x04
#define   OFIFO_LOW_THRES_POS			0
#define   OFIFO_LOW_THRES_MASK			GENMASK(9, 0)
#define   OFIFO_HIGH_THRES_POS			16
#define   OFIFO_HIGH_THRES_MASK			GENMASK(25, 16)
#define   UNDERRUN_DETECT_CLR			BIT(26)
#define   LOW_THRES_DETECT_CLR			BIT(27)
#define   HIGH_THRES_DETECT_CLR			BIT(28)
#define   UNDERRUN_DETECT_EN			BIT(29)
#define   LOW_THRES_DETECT_EN			BIT(30)
#define   HIGH_THRES_DETECT_EN			BIT(31)
#define DCSS_SCALER_SDATA_CTRL			0x08
#define   YUV_EN				BIT(0)
#define   RTRAM_8LINES				BIT(1)
#define   Y_UV_BYTE_SWAP			BIT(4)
#define   A2R10G10B10_FORMAT_POS		8
#define   A2R10G10B10_FORMAT_MASK		GENMASK(11, 8)
#define DCSS_SCALER_BIT_DEPTH			0x0C
#define   LUM_BIT_DEPTH_POS			0
#define   LUM_BIT_DEPTH_MASK			GENMASK(1, 0)
#define   CHR_BIT_DEPTH_POS			4
#define   CHR_BIT_DEPTH_MASK			GENMASK(5, 4)
#define DCSS_SCALER_SRC_FORMAT			0x10
#define DCSS_SCALER_DST_FORMAT			0x14
#define   FORMAT_MASK				GENMASK(1, 0)
#define DCSS_SCALER_SRC_LUM_RES			0x18
#define DCSS_SCALER_SRC_CHR_RES			0x1C
#define DCSS_SCALER_DST_LUM_RES			0x20
#define DCSS_SCALER_DST_CHR_RES			0x24
#define   WIDTH_POS				0
#define   WIDTH_MASK				GENMASK(11, 0)
#define   HEIGHT_POS				16
#define   HEIGHT_MASK				GENMASK(27, 16)
#define DCSS_SCALER_V_LUM_START			0x48
#define   V_START_MASK				GENMASK(15, 0)
#define DCSS_SCALER_V_LUM_INC			0x4C
#define   V_INC_MASK				GENMASK(15, 0)
#define DCSS_SCALER_H_LUM_START			0x50
#define   H_START_MASK				GENMASK(18, 0)
#define DCSS_SCALER_H_LUM_INC			0x54
#define   H_INC_MASK				GENMASK(15, 0)
#define DCSS_SCALER_V_CHR_START			0x58
#define DCSS_SCALER_V_CHR_INC			0x5C
#define DCSS_SCALER_H_CHR_START			0x60
#define DCSS_SCALER_H_CHR_INC			0x64
#define DCSS_SCALER_COEF_VLUM			0x80
#define DCSS_SCALER_COEF_HLUM			0x140
#define DCSS_SCALER_COEF_VCHR			0x200
#define DCSS_SCALER_COEF_HCHR			0x300

struct dcss_scaler_ch {
	void __iomem *base_reg;
	u32 base_ofs;
	struct dcss_scaler *scl;

	u32 sdata_ctrl;
	u32 scaler_ctrl;

	bool scaler_ctrl_chgd;

	u32 c_vstart;
	u32 c_hstart;
};

struct dcss_scaler {
	struct device *dev;

	struct dcss_ctxld *ctxld;
	u32 ctx_id;

	struct dcss_scaler_ch ch[3];
};

/* scaler coefficients generator */
#define PSC_FRAC_BITS 30
#define PSC_FRAC_SCALE BIT(PSC_FRAC_BITS)
#define PSC_BITS_FOR_PHASE 4
#define PSC_NUM_PHASES 16
#define PSC_STORED_PHASES (PSC_NUM_PHASES / 2 + 1)
#define PSC_NUM_TAPS 7
#define PSC_NUM_TAPS_RGBA 5
#define PSC_COEFF_PRECISION 10
#define PSC_PHASE_FRACTION_BITS 13
#define PSC_PHASE_MASK (PSC_NUM_PHASES - 1)
#define PSC_Q_FRACTION 19
#define PSC_Q_ROUND_OFFSET (1 << (PSC_Q_FRACTION - 1))

/**
 * mult_q() - Performs fixed-point multiplication.
 * @A: multiplier
 * @B: multiplicand
 */
static int mult_q(int A, int B)
{
	int result;
	s64 temp;

	temp = (int64_t)A * (int64_t)B;
	temp += PSC_Q_ROUND_OFFSET;
	result = (int)(temp >> PSC_Q_FRACTION);
	return result;
}

/**
 * div_q() - Performs fixed-point division.
 * @A: dividend
 * @B: divisor
 */
static int div_q(int A, int B)
{
	int result;
	s64 temp;

	temp = (int64_t)A << PSC_Q_FRACTION;
	if ((temp >= 0 && B >= 0) || (temp < 0 && B < 0))
		temp += B / 2;
	else
		temp -= B / 2;

	result = (int)(temp / B);
	return result;
}

/**
 * exp_approx_q() - Compute approximation to exp(x) function using Taylor
 *		    series.
 * @x: fixed-point argument of exp function
 */
static int exp_approx_q(int x)
{
	int sum = 1 << PSC_Q_FRACTION;
	int term = 1 << PSC_Q_FRACTION;

	term = mult_q(term, div_q(x, 1 << PSC_Q_FRACTION));
	sum += term;
	term = mult_q(term, div_q(x, 2 << PSC_Q_FRACTION));
	sum += term;
	term = mult_q(term, div_q(x, 3 << PSC_Q_FRACTION));
	sum += term;
	term = mult_q(term, div_q(x, 4 << PSC_Q_FRACTION));
	sum += term;

	return sum;
}

/**
 * dcss_scaler_gaussian_filter() - Generate gaussian prototype filter.
 * @fc_q: fixed-point cutoff frequency normalized to range [0, 1]
 * @use_5_taps: indicates whether to use 5 taps or 7 taps
 * @coef: output filter coefficients
 */
static void dcss_scaler_gaussian_filter(int fc_q, bool use_5_taps,
					bool phase0_identity,
					int coef[][PSC_NUM_TAPS])
{
	int sigma_q, g0_q, g1_q, g2_q;
	int tap_cnt1, tap_cnt2, tap_idx, phase_cnt;
	int mid;
	int phase;
	int i;
	int taps;

	if (use_5_taps)
		for (phase = 0; phase < PSC_STORED_PHASES; phase++) {
			coef[phase][0] = 0;
			coef[phase][PSC_NUM_TAPS - 1] = 0;
		}

	/* seed coefficient scanner */
	taps = use_5_taps ? PSC_NUM_TAPS_RGBA : PSC_NUM_TAPS;
	mid = (PSC_NUM_PHASES * taps) / 2 - 1;
	phase_cnt = (PSC_NUM_PHASES * (PSC_NUM_TAPS + 1)) / 2;
	tap_cnt1 = (PSC_NUM_PHASES * PSC_NUM_TAPS) / 2;
	tap_cnt2 = (PSC_NUM_PHASES * PSC_NUM_TAPS) / 2;

	/* seed gaussian filter generator */
	sigma_q = div_q(PSC_Q_ROUND_OFFSET, fc_q);
	g0_q = 1 << PSC_Q_FRACTION;
	g1_q = exp_approx_q(div_q(-PSC_Q_ROUND_OFFSET,
				  mult_q(sigma_q, sigma_q)));
	g2_q = mult_q(g1_q, g1_q);
	coef[phase_cnt & PSC_PHASE_MASK][tap_cnt1 >> PSC_BITS_FOR_PHASE] = g0_q;

	for (i = 0; i < mid; i++) {
		phase_cnt++;
		tap_cnt1--;
		tap_cnt2++;

		g0_q = mult_q(g0_q, g1_q);
		g1_q = mult_q(g1_q, g2_q);

		if ((phase_cnt & PSC_PHASE_MASK) <= 8) {
			tap_idx = tap_cnt1 >> PSC_BITS_FOR_PHASE;
			coef[phase_cnt & PSC_PHASE_MASK][tap_idx] = g0_q;
		}
		if (((-phase_cnt) & PSC_PHASE_MASK) <= 8) {
			tap_idx = tap_cnt2 >> PSC_BITS_FOR_PHASE;
			coef[(-phase_cnt) & PSC_PHASE_MASK][tap_idx] = g0_q;
		}
	}

	phase_cnt++;
	tap_cnt1--;
	coef[phase_cnt & PSC_PHASE_MASK][tap_cnt1 >> PSC_BITS_FOR_PHASE] = 0;

	/* override phase 0 with identity filter if specified */
	if (phase0_identity)
		for (i = 0; i < PSC_NUM_TAPS; i++)
			coef[0][i] = i == (PSC_NUM_TAPS >> 1) ?
						(1 << PSC_COEFF_PRECISION) : 0;

	/* normalize coef */
	for (phase = 0; phase < PSC_STORED_PHASES; phase++) {
		int sum = 0;
		s64 ll_temp;

		for (i = 0; i < PSC_NUM_TAPS; i++)
			sum += coef[phase][i];
		for (i = 0; i < PSC_NUM_TAPS; i++) {
			ll_temp = coef[phase][i];
			ll_temp <<= PSC_COEFF_PRECISION;
			ll_temp += sum >> 1;
			ll_temp /= sum;
			coef[phase][i] = (int)ll_temp;
		}
	}
}

/**
 * dcss_scaler_filter_design() - Compute filter coefficients using
 *				 Gaussian filter.
 * @src_length: length of input
 * @dst_length: length of output
 * @use_5_taps: 0 for 7 taps per phase, 1 for 5 taps
 * @coef: output coefficients
 */
static void dcss_scaler_filter_design(int src_length, int dst_length,
				      bool use_5_taps, bool phase0_identity,
				      int coef[][PSC_NUM_TAPS])
{
	int fc_q;

	/* compute cutoff frequency */
	if (dst_length >= src_length)
		fc_q = div_q(1, PSC_NUM_PHASES);
	else
		fc_q = div_q(dst_length, src_length * PSC_NUM_PHASES);

	/* compute gaussian filter coefficients */
	dcss_scaler_gaussian_filter(fc_q, use_5_taps, phase0_identity, coef);
}

static void dcss_scaler_write(struct dcss_scaler_ch *ch, u32 val, u32 ofs)
{
	struct dcss_scaler *scl = ch->scl;

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

static int dcss_scaler_ch_init_all(struct dcss_scaler *scl,
				   unsigned long scaler_base)
{
	struct dcss_scaler_ch *ch;
	int i;

	for (i = 0; i < 3; i++) {
		ch = &scl->ch[i];

		ch->base_ofs = scaler_base + i * 0x400;

		ch->base_reg = ioremap(ch->base_ofs, SZ_4K);
		if (!ch->base_reg) {
			dev_err(scl->dev, "scaler: unable to remap ch base\n");
			return -ENOMEM;
		}

		ch->scl = scl;
	}

	return 0;
}

int dcss_scaler_init(struct dcss_dev *dcss, unsigned long scaler_base)
{
	struct dcss_scaler *scaler;

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

	dcss->scaler = scaler;
	scaler->dev = dcss->dev;
	scaler->ctxld = dcss->ctxld;
	scaler->ctx_id = CTX_SB_HP;

	if (dcss_scaler_ch_init_all(scaler, scaler_base)) {
		int i;

		for (i = 0; i < 3; i++) {
			if (scaler->ch[i].base_reg)
				iounmap(scaler->ch[i].base_reg);
		}

		kfree(scaler);

		return -ENOMEM;
	}

	return 0;
}

void dcss_scaler_exit(struct dcss_scaler *scl)
{
	int ch_no;

	for (ch_no = 0; ch_no < 3; ch_no++) {
		struct dcss_scaler_ch *ch = &scl->ch[ch_no];

		dcss_writel(0, ch->base_reg + DCSS_SCALER_CTRL);

		if (ch->base_reg)
			iounmap(ch->base_reg);
	}

	kfree(scl);
}

void dcss_scaler_ch_enable(struct dcss_scaler *scl, int ch_num, bool en)
{
	struct dcss_scaler_ch *ch = &scl->ch[ch_num];
	u32 scaler_ctrl;

	scaler_ctrl = en ? SCALER_EN | REPEAT_EN : 0;

	if (en)
		dcss_scaler_write(ch, ch->sdata_ctrl, DCSS_SCALER_SDATA_CTRL);

	if (ch->scaler_ctrl != scaler_ctrl)
		ch->scaler_ctrl_chgd = true;

	ch->scaler_ctrl = scaler_ctrl;
}

static void dcss_scaler_yuv_enable(struct dcss_scaler_ch *ch, bool en)
{
	ch->sdata_ctrl &= ~YUV_EN;
	ch->sdata_ctrl |= en ? YUV_EN : 0;
}

static void dcss_scaler_rtr_8lines_enable(struct dcss_scaler_ch *ch, bool en)
{
	ch->sdata_ctrl &= ~RTRAM_8LINES;
	ch->sdata_ctrl |= en ? RTRAM_8LINES : 0;
}

static void dcss_scaler_bit_depth_set(struct dcss_scaler_ch *ch, int depth)
{
	u32 val;

	val = depth == 30 ? 2 : 0;

	dcss_scaler_write(ch,
			  ((val << CHR_BIT_DEPTH_POS) & CHR_BIT_DEPTH_MASK) |
			  ((val << LUM_BIT_DEPTH_POS) & LUM_BIT_DEPTH_MASK),
			  DCSS_SCALER_BIT_DEPTH);
}

enum buffer_format {
	BUF_FMT_YUV420,
	BUF_FMT_YUV422,
	BUF_FMT_ARGB8888_YUV444,
};

enum chroma_location {
	PSC_LOC_HORZ_0_VERT_1_OVER_4 = 0,
	PSC_LOC_HORZ_1_OVER_4_VERT_1_OVER_4 = 1,
	PSC_LOC_HORZ_0_VERT_0 = 2,
	PSC_LOC_HORZ_1_OVER_4_VERT_0 = 3,
	PSC_LOC_HORZ_0_VERT_1_OVER_2 = 4,
	PSC_LOC_HORZ_1_OVER_4_VERT_1_OVER_2 = 5
};

static void dcss_scaler_format_set(struct dcss_scaler_ch *ch,
				   enum buffer_format src_fmt,
				   enum buffer_format dst_fmt)
{
	dcss_scaler_write(ch, src_fmt, DCSS_SCALER_SRC_FORMAT);
	dcss_scaler_write(ch, dst_fmt, DCSS_SCALER_DST_FORMAT);
}

static void dcss_scaler_res_set(struct dcss_scaler_ch *ch,
				int src_xres, int src_yres,
				int dst_xres, int dst_yres,
				u32 pix_format, enum buffer_format dst_format)
{
	u32 lsrc_xres, lsrc_yres, csrc_xres, csrc_yres;
	u32 ldst_xres, ldst_yres, cdst_xres, cdst_yres;
	bool src_is_444 = true;

	lsrc_xres = src_xres;
	csrc_xres = src_xres;
	lsrc_yres = src_yres;
	csrc_yres = src_yres;
	ldst_xres = dst_xres;
	cdst_xres = dst_xres;
	ldst_yres = dst_yres;
	cdst_yres = dst_yres;

	if (pix_format == DRM_FORMAT_UYVY || pix_format == DRM_FORMAT_VYUY ||
	    pix_format == DRM_FORMAT_YUYV || pix_format == DRM_FORMAT_YVYU) {
		csrc_xres >>= 1;
		src_is_444 = false;
	} else if (pix_format == DRM_FORMAT_NV12 ||
		   pix_format == DRM_FORMAT_NV21) {
		csrc_xres >>= 1;
		csrc_yres >>= 1;
		src_is_444 = false;
	}

	if (dst_format == BUF_FMT_YUV422)
		cdst_xres >>= 1;

	/* for 4:4:4 to 4:2:2 conversion, source height should be 1 less */
	if (src_is_444 && dst_format == BUF_FMT_YUV422) {
		lsrc_yres--;
		csrc_yres--;
	}

	dcss_scaler_write(ch, (((lsrc_yres - 1) << HEIGHT_POS) & HEIGHT_MASK) |
			       (((lsrc_xres - 1) << WIDTH_POS) & WIDTH_MASK),
			  DCSS_SCALER_SRC_LUM_RES);
	dcss_scaler_write(ch, (((csrc_yres - 1) << HEIGHT_POS) & HEIGHT_MASK) |
			       (((csrc_xres - 1) << WIDTH_POS) & WIDTH_MASK),
			  DCSS_SCALER_SRC_CHR_RES);
	dcss_scaler_write(ch, (((ldst_yres - 1) << HEIGHT_POS) & HEIGHT_MASK) |
			       (((ldst_xres - 1) << WIDTH_POS) & WIDTH_MASK),
			  DCSS_SCALER_DST_LUM_RES);
	dcss_scaler_write(ch, (((cdst_yres - 1) << HEIGHT_POS) & HEIGHT_MASK) |
			       (((cdst_xres - 1) << WIDTH_POS) & WIDTH_MASK),
			  DCSS_SCALER_DST_CHR_RES);
}

#define downscale_fp(factor, fp_pos)		((factor) << (fp_pos))
#define upscale_fp(factor, fp_pos)		((1 << (fp_pos)) / (factor))

struct dcss_scaler_factors {
	int downscale;
	int upscale;
};

static const struct dcss_scaler_factors dcss_scaler_factors[] = {
	{3, 8}, {5, 8}, {5, 8},
};

static void dcss_scaler_fractions_set(struct dcss_scaler_ch *ch,
				      int src_xres, int src_yres,
				      int dst_xres, int dst_yres,
				      u32 src_format, u32 dst_format,
				      enum chroma_location src_chroma_loc)
{
	int src_c_xres, src_c_yres, dst_c_xres, dst_c_yres;
	u32 l_vinc, l_hinc, c_vinc, c_hinc;
	u32 c_vstart, c_hstart;

	src_c_xres = src_xres;
	src_c_yres = src_yres;
	dst_c_xres = dst_xres;
	dst_c_yres = dst_yres;

	c_vstart = 0;
	c_hstart = 0;

	/* adjustments for source chroma location */
	if (src_format == BUF_FMT_YUV420) {
		/* vertical input chroma position adjustment */
		switch (src_chroma_loc) {
		case PSC_LOC_HORZ_0_VERT_1_OVER_4:
		case PSC_LOC_HORZ_1_OVER_4_VERT_1_OVER_4:
			/*
			 * move chroma up to first luma line
			 * (1/4 chroma input line spacing)
			 */
			c_vstart -= (1 << (PSC_PHASE_FRACTION_BITS - 2));
			break;
		case PSC_LOC_HORZ_0_VERT_1_OVER_2:
		case PSC_LOC_HORZ_1_OVER_4_VERT_1_OVER_2:
			/*
			 * move chroma up to first luma line
			 * (1/2 chroma input line spacing)
			 */
			c_vstart -= (1 << (PSC_PHASE_FRACTION_BITS - 1));
			break;
		default:
			break;
		}
		/* horizontal input chroma position adjustment */
		switch (src_chroma_loc) {
		case PSC_LOC_HORZ_1_OVER_4_VERT_1_OVER_4:
		case PSC_LOC_HORZ_1_OVER_4_VERT_0:
		case PSC_LOC_HORZ_1_OVER_4_VERT_1_OVER_2:
			/* move chroma left 1/4 chroma input sample spacing */
			c_hstart -= (1 << (PSC_PHASE_FRACTION_BITS - 2));
			break;
		default:
			break;
		}
	}

	/* adjustments to chroma resolution */
	if (src_format == BUF_FMT_YUV420) {
		src_c_xres >>= 1;
		src_c_yres >>= 1;
	} else if (src_format == BUF_FMT_YUV422) {
		src_c_xres >>= 1;
	}

	if (dst_format == BUF_FMT_YUV422)
		dst_c_xres >>= 1;

	l_vinc = ((src_yres << 13) + (dst_yres >> 1)) / dst_yres;
	c_vinc = ((src_c_yres << 13) + (dst_c_yres >> 1)) / dst_c_yres;
	l_hinc = ((src_xres << 13) + (dst_xres >> 1)) / dst_xres;
	c_hinc = ((src_c_xres << 13) + (dst_c_xres >> 1)) / dst_c_xres;

	/* save chroma start phase */
	ch->c_vstart = c_vstart;
	ch->c_hstart = c_hstart;

	dcss_scaler_write(ch, 0, DCSS_SCALER_V_LUM_START);
	dcss_scaler_write(ch, l_vinc, DCSS_SCALER_V_LUM_INC);

	dcss_scaler_write(ch, 0, DCSS_SCALER_H_LUM_START);
	dcss_scaler_write(ch, l_hinc, DCSS_SCALER_H_LUM_INC);

	dcss_scaler_write(ch, c_vstart, DCSS_SCALER_V_CHR_START);
	dcss_scaler_write(ch, c_vinc, DCSS_SCALER_V_CHR_INC);

	dcss_scaler_write(ch, c_hstart, DCSS_SCALER_H_CHR_START);
	dcss_scaler_write(ch, c_hinc, DCSS_SCALER_H_CHR_INC);
}

int dcss_scaler_get_min_max_ratios(struct dcss_scaler *scl, int ch_num,
				   int *min, int *max)
{
	*min = upscale_fp(dcss_scaler_factors[ch_num].upscale, 16);
	*max = downscale_fp(dcss_scaler_factors[ch_num].downscale, 16);

	return 0;
}

static void dcss_scaler_program_5_coef_set(struct dcss_scaler_ch *ch,
					   int base_addr,
					   int coef[][PSC_NUM_TAPS])
{
	int i, phase;

	for (i = 0; i < PSC_STORED_PHASES; i++) {
		dcss_scaler_write(ch, ((coef[i][1] & 0xfff) << 16 |
				       (coef[i][2] & 0xfff) << 4  |
				       (coef[i][3] & 0xf00) >> 8),
				  base_addr + i * sizeof(u32));
		dcss_scaler_write(ch, ((coef[i][3] & 0x0ff) << 20 |
				       (coef[i][4] & 0xfff) << 8  |
				       (coef[i][5] & 0xff0) >> 4),
				  base_addr + 0x40 + i * sizeof(u32));
		dcss_scaler_write(ch, ((coef[i][5] & 0x00f) << 24),
				  base_addr + 0x80 + i * sizeof(u32));
	}

	/* reverse both phase and tap orderings */
	for (phase = (PSC_NUM_PHASES >> 1) - 1;
			i < PSC_NUM_PHASES; i++, phase--) {
		dcss_scaler_write(ch, ((coef[phase][5] & 0xfff) << 16 |
				       (coef[phase][4] & 0xfff) << 4  |
				       (coef[phase][3] & 0xf00) >> 8),
				  base_addr + i * sizeof(u32));
		dcss_scaler_write(ch, ((coef[phase][3] & 0x0ff) << 20 |
				       (coef[phase][2] & 0xfff) << 8  |
				       (coef[phase][1] & 0xff0) >> 4),
				  base_addr + 0x40 + i * sizeof(u32));
		dcss_scaler_write(ch, ((coef[phase][1] & 0x00f) << 24),
				  base_addr + 0x80 + i * sizeof(u32));
	}
}

static void dcss_scaler_program_7_coef_set(struct dcss_scaler_ch *ch,
					   int base_addr,
					   int coef[][PSC_NUM_TAPS])
{
	int i, phase;

	for (i = 0; i < PSC_STORED_PHASES; i++) {
		dcss_scaler_write(ch, ((coef[i][0] & 0xfff) << 16 |
				       (coef[i][1] & 0xfff) << 4  |
				       (coef[i][2] & 0xf00) >> 8),
				  base_addr + i * sizeof(u32));
		dcss_scaler_write(ch, ((coef[i][2] & 0x0ff) << 20 |
				       (coef[i][3] & 0xfff) << 8  |
				       (coef[i][4] & 0xff0) >> 4),
				  base_addr + 0x40 + i * sizeof(u32));
		dcss_scaler_write(ch, ((coef[i][4] & 0x00f) << 24 |
				       (coef[i][5] & 0xfff) << 12 |
				       (coef[i][6] & 0xfff)),
				  base_addr + 0x80 + i * sizeof(u32));
	}

	/* reverse both phase and tap orderings */
	for (phase = (PSC_NUM_PHASES >> 1) - 1;
			i < PSC_NUM_PHASES; i++, phase--) {
		dcss_scaler_write(ch, ((coef[phase][6] & 0xfff) << 16 |
				       (coef[phase][5] & 0xfff) << 4  |
				       (coef[phase][4] & 0xf00) >> 8),
				  base_addr + i * sizeof(u32));
		dcss_scaler_write(ch, ((coef[phase][4] & 0x0ff) << 20 |
				       (coef[phase][3] & 0xfff) << 8  |
				       (coef[phase][2] & 0xff0) >> 4),
				  base_addr + 0x40 + i * sizeof(u32));
		dcss_scaler_write(ch, ((coef[phase][2] & 0x00f) << 24 |
				       (coef[phase][1] & 0xfff) << 12 |
				       (coef[phase][0] & 0xfff)),
				  base_addr + 0x80 + i * sizeof(u32));
	}
}

static void dcss_scaler_yuv_coef_set(struct dcss_scaler_ch *ch,
				     enum buffer_format src_format,
				     enum buffer_format dst_format,
				     bool use_5_taps,
				     int src_xres, int src_yres, int dst_xres,
				     int dst_yres)
{
	int coef[PSC_STORED_PHASES][PSC_NUM_TAPS];
	bool program_5_taps = use_5_taps ||
			      (dst_format == BUF_FMT_YUV422 &&
			       src_format == BUF_FMT_ARGB8888_YUV444);

	/* horizontal luma */
	dcss_scaler_filter_design(src_xres, dst_xres, false,
				  src_xres == dst_xres, coef);
	dcss_scaler_program_7_coef_set(ch, DCSS_SCALER_COEF_HLUM, coef);

	/* vertical luma */
	dcss_scaler_filter_design(src_yres, dst_yres, program_5_taps,
				  src_yres == dst_yres, coef);

	if (program_5_taps)
		dcss_scaler_program_5_coef_set(ch, DCSS_SCALER_COEF_VLUM, coef);
	else
		dcss_scaler_program_7_coef_set(ch, DCSS_SCALER_COEF_VLUM, coef);

	/* adjust chroma resolution */
	if (src_format != BUF_FMT_ARGB8888_YUV444)
		src_xres >>= 1;
	if (src_format == BUF_FMT_YUV420)
		src_yres >>= 1;
	if (dst_format != BUF_FMT_ARGB8888_YUV444)
		dst_xres >>= 1;
	if (dst_format == BUF_FMT_YUV420) /* should not happen */
		dst_yres >>= 1;

	/* horizontal chroma */
	dcss_scaler_filter_design(src_xres, dst_xres, false,
				  (src_xres == dst_xres) && (ch->c_hstart == 0),
				  coef);

	dcss_scaler_program_7_coef_set(ch, DCSS_SCALER_COEF_HCHR, coef);

	/* vertical chroma */
	dcss_scaler_filter_design(src_yres, dst_yres, program_5_taps,
				  (src_yres == dst_yres) && (ch->c_vstart == 0),
				  coef);
	if (program_5_taps)
		dcss_scaler_program_5_coef_set(ch, DCSS_SCALER_COEF_VCHR, coef);
	else
		dcss_scaler_program_7_coef_set(ch, DCSS_SCALER_COEF_VCHR, coef);
}

static void dcss_scaler_rgb_coef_set(struct dcss_scaler_ch *ch,
				     int src_xres, int src_yres, int dst_xres,
				     int dst_yres)
{
	int coef[PSC_STORED_PHASES][PSC_NUM_TAPS];

	/* horizontal RGB */
	dcss_scaler_filter_design(src_xres, dst_xres, false,
				  src_xres == dst_xres, coef);
	dcss_scaler_program_7_coef_set(ch, DCSS_SCALER_COEF_HLUM, coef);

	/* vertical RGB */
	dcss_scaler_filter_design(src_yres, dst_yres, false,
				  src_yres == dst_yres, coef);
	dcss_scaler_program_7_coef_set(ch, DCSS_SCALER_COEF_VLUM, coef);
}

static void dcss_scaler_set_rgb10_order(struct dcss_scaler_ch *ch,
					const struct drm_format_info *format)
{
	u32 a2r10g10b10_format;

	if (format->is_yuv)
		return;

	ch->sdata_ctrl &= ~A2R10G10B10_FORMAT_MASK;

	if (format->depth != 30)
		return;

	switch (format->format) {
	case DRM_FORMAT_ARGB2101010:
	case DRM_FORMAT_XRGB2101010:
		a2r10g10b10_format = 0;
		break;

	case DRM_FORMAT_ABGR2101010:
	case DRM_FORMAT_XBGR2101010:
		a2r10g10b10_format = 5;
		break;

	case DRM_FORMAT_RGBA1010102:
	case DRM_FORMAT_RGBX1010102:
		a2r10g10b10_format = 6;
		break;

	case DRM_FORMAT_BGRA1010102:
	case DRM_FORMAT_BGRX1010102:
		a2r10g10b10_format = 11;
		break;

	default:
		a2r10g10b10_format = 0;
		break;
	}

	ch->sdata_ctrl |= a2r10g10b10_format << A2R10G10B10_FORMAT_POS;
}

void dcss_scaler_setup(struct dcss_scaler *scl, int ch_num,
		       const struct drm_format_info *format,
		       int src_xres, int src_yres, int dst_xres, int dst_yres,
		       u32 vrefresh_hz)
{
	struct dcss_scaler_ch *ch = &scl->ch[ch_num];
	unsigned int pixel_depth = 0;
	bool rtr_8line_en = false;
	bool use_5_taps = false;
	enum buffer_format src_format = BUF_FMT_ARGB8888_YUV444;
	enum buffer_format dst_format = BUF_FMT_ARGB8888_YUV444;
	u32 pix_format = format->format;

	if (format->is_yuv) {
		dcss_scaler_yuv_enable(ch, true);

		if (pix_format == DRM_FORMAT_NV12 ||
		    pix_format == DRM_FORMAT_NV21) {
			rtr_8line_en = true;
			src_format = BUF_FMT_YUV420;
		} else if (pix_format == DRM_FORMAT_UYVY ||
			   pix_format == DRM_FORMAT_VYUY ||
			   pix_format == DRM_FORMAT_YUYV ||
			   pix_format == DRM_FORMAT_YVYU) {
			src_format = BUF_FMT_YUV422;
		}

		use_5_taps = !rtr_8line_en;
	} else {
		dcss_scaler_yuv_enable(ch, false);

		pixel_depth = format->depth;
	}

	dcss_scaler_fractions_set(ch, src_xres, src_yres, dst_xres,
				  dst_yres, src_format, dst_format,
				  PSC_LOC_HORZ_0_VERT_1_OVER_4);

	if (format->is_yuv)
		dcss_scaler_yuv_coef_set(ch, src_format, dst_format,
					 use_5_taps, src_xres, src_yres,
					 dst_xres, dst_yres);
	else
		dcss_scaler_rgb_coef_set(ch, src_xres, src_yres,
					 dst_xres, dst_yres);

	dcss_scaler_rtr_8lines_enable(ch, rtr_8line_en);
	dcss_scaler_bit_depth_set(ch, pixel_depth);
	dcss_scaler_set_rgb10_order(ch, format);
	dcss_scaler_format_set(ch, src_format, dst_format);
	dcss_scaler_res_set(ch, src_xres, src_yres, dst_xres, dst_yres,
			    pix_format, dst_format);
}

/* This function will be called from interrupt context. */
void dcss_scaler_write_sclctrl(struct dcss_scaler *scl)
{
	int chnum;

	dcss_ctxld_assert_locked(scl->ctxld);

	for (chnum = 0; chnum < 3; chnum++) {
		struct dcss_scaler_ch *ch = &scl->ch[chnum];

		if (ch->scaler_ctrl_chgd) {
			dcss_ctxld_write_irqsafe(scl->ctxld, scl->ctx_id,
						 ch->scaler_ctrl,
						 ch->base_ofs +
						 DCSS_SCALER_CTRL);
			ch->scaler_ctrl_chgd = false;
		}
	}
}
