/*
 * Copyright (C) STMicroelectronics SA 2014
 * Author: Vincent Abriou <vincent.abriou@st.com> for STMicroelectronics.
 * License terms:  GNU General Public License (GPL), version 2
 */

#include "sti_awg_utils.h"

#define AWG_OPCODE_OFFSET 10

enum opcode {
	SET,
	RPTSET,
	RPLSET,
	SKIP,
	STOP,
	REPEAT,
	REPLAY,
	JUMP,
	HOLD,
};

static int awg_generate_instr(enum opcode opcode,
			      long int arg,
			      long int mux_sel,
			      long int data_en,
			      struct awg_code_generation_params *fwparams)
{
	u32 instruction = 0;
	u32 mux = (mux_sel << 8) & 0x1ff;
	u32 data_enable = (data_en << 9) & 0x2ff;
	long int arg_tmp = arg;

	/* skip, repeat and replay arg should not exceed 1023.
	 * If user wants to exceed this value, the instruction should be
	 * duplicate and arg should be adjust for each duplicated instruction.
	 */

	while (arg_tmp > 0) {
		arg = arg_tmp;
		if (fwparams->instruction_offset >= AWG_MAX_INST) {
			DRM_ERROR("too many number of instructions\n");
			return -EINVAL;
		}

		switch (opcode) {
		case SKIP:
			/* leave 'arg' + 1 pixel elapsing without changing
			 * output bus */
			arg--; /* pixel adjustment */
			arg_tmp--;

			if (arg < 0) {
				/* SKIP instruction not needed */
				return 0;
			}

			if (arg == 0) {
				/* SKIP 0 not permitted but we want to skip 1
				 * pixel. So we transform SKIP into SET
				 * instruction */
				opcode = SET;
				break;
			}

			mux = 0;
			data_enable = 0;
			arg = (arg << 22) >> 22;
			arg &= (0x3ff);
			break;
		case REPEAT:
		case REPLAY:
			if (arg == 0) {
				/* REPEAT or REPLAY instruction not needed */
				return 0;
			}

			mux = 0;
			data_enable = 0;
			arg = (arg << 22) >> 22;
			arg &= (0x3ff);
			break;
		case JUMP:
			mux = 0;
			data_enable = 0;
			arg |= 0x40; /* for jump instruction 7th bit is 1 */
			arg = (arg << 22) >> 22;
			arg &= 0x3ff;
			break;
		case STOP:
			arg = 0;
			break;
		case SET:
		case RPTSET:
		case RPLSET:
		case HOLD:
			arg = (arg << 24) >> 24;
			arg &= (0x0ff);
			break;
		default:
			DRM_ERROR("instruction %d does not exist\n", opcode);
			return -EINVAL;
		}

		arg_tmp = arg_tmp - arg;

		arg = ((arg + mux) + data_enable);

		instruction = ((opcode) << AWG_OPCODE_OFFSET) | arg;
		fwparams->ram_code[fwparams->instruction_offset] =
			instruction & (0x3fff);
		fwparams->instruction_offset++;
	}
	return 0;
}

int sti_awg_generate_code_data_enable_mode(
		struct awg_code_generation_params *fwparams,
		struct awg_timing *timing)
{
	long int val;
	long int data_en;
	int ret = 0;

	if (timing->trailing_lines > 0) {
		/* skip trailing lines */
		val = timing->blanking_level;
		data_en = 0;
		ret |= awg_generate_instr(RPLSET, val, 0, data_en, fwparams);

		val = timing->trailing_lines - 1;
		data_en = 0;
		ret |= awg_generate_instr(REPLAY, val, 0, data_en, fwparams);
	}

	if (timing->trailing_pixels > 0) {
		/* skip trailing pixel */
		val = timing->blanking_level;
		data_en = 0;
		ret |= awg_generate_instr(RPLSET, val, 0, data_en, fwparams);

		val = timing->trailing_pixels - 1;
		data_en = 0;
		ret |= awg_generate_instr(SKIP, val, 0, data_en, fwparams);
	}

	/* set DE signal high */
	val = timing->blanking_level;
	data_en = 1;
	ret |= awg_generate_instr((timing->trailing_pixels > 0) ? SET : RPLSET,
			val, 0, data_en, fwparams);

	if (timing->blanking_pixels > 0) {
		/* skip the number of active pixel */
		val = timing->active_pixels - 1;
		data_en = 1;
		ret |= awg_generate_instr(SKIP, val, 0, data_en, fwparams);

		/* set DE signal low */
		val = timing->blanking_level;
		data_en = 0;
		ret |= awg_generate_instr(SET, val, 0, data_en, fwparams);
	}

	/* replay the sequence as many active lines defined */
	val = timing->active_lines - 1;
	data_en = 0;
	ret |= awg_generate_instr(REPLAY, val, 0, data_en, fwparams);

	if (timing->blanking_lines > 0) {
		/* skip blanking lines */
		val = timing->blanking_level;
		data_en = 0;
		ret |= awg_generate_instr(RPLSET, val, 0, data_en, fwparams);

		val = timing->blanking_lines - 1;
		data_en = 0;
		ret |= awg_generate_instr(REPLAY, val, 0, data_en, fwparams);
	}

	return ret;
}
