/*
 * Copyright (C) Marvell International Ltd. and its affiliates
 *
 * SPDX-License-Identifier:	GPL-2.0
 */

#include <common.h>
#include <i2c.h>
#include <spl.h>
#include <asm/io.h>
#include <asm/arch/cpu.h>
#include <asm/arch/soc.h>

#include "xor.h"
#include "xor_regs.h"

static u32 xor_regs_ctrl_backup;
static u32 xor_regs_base_backup[MAX_CS];
static u32 xor_regs_mask_backup[MAX_CS];

static void mv_xor_hal_init(u32 chan_num);
static int mv_xor_cmd_set(u32 chan, int command);
static int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl);

void mv_sys_xor_init(MV_DRAM_INFO *dram_info)
{
	u32 reg, ui, base, cs_count;

	xor_regs_ctrl_backup = reg_read(XOR_WINDOW_CTRL_REG(0, 0));
	for (ui = 0; ui < MAX_CS; ui++)
		xor_regs_base_backup[ui] = reg_read(XOR_BASE_ADDR_REG(0, ui));
	for (ui = 0; ui < MAX_CS; ui++)
		xor_regs_mask_backup[ui] = reg_read(XOR_SIZE_MASK_REG(0, ui));

	reg = 0;
	for (ui = 0; ui < (dram_info->num_cs + 1); ui++) {
		/* Enable Window x for each CS */
		reg |= (0x1 << (ui));
		/* Enable Window x for each CS */
		reg |= (0x3 << ((ui * 2) + 16));
	}

	reg_write(XOR_WINDOW_CTRL_REG(0, 0), reg);

	/* Last window - Base - 0x40000000, Attribute 0x1E - SRAM */
	base = (SRAM_BASE & 0xFFFF0000) | 0x1E00;
	reg_write(XOR_BASE_ADDR_REG(0, dram_info->num_cs), base);
	/* Last window - Size - 64 MB */
	reg_write(XOR_SIZE_MASK_REG(0, dram_info->num_cs), 0x03FF0000);

	cs_count = 0;
	for (ui = 0; ui < MAX_CS; ui++) {
		if (dram_info->cs_ena & (1 << ui)) {
			/*
			 * Window x - Base - 0x00000000, Attribute 0x0E - DRAM
			 */
			base = 0;
			switch (ui) {
			case 0:
				base |= 0xE00;
				break;
			case 1:
				base |= 0xD00;
				break;
			case 2:
				base |= 0xB00;
				break;
			case 3:
				base |= 0x700;
				break;
			}

			reg_write(XOR_BASE_ADDR_REG(0, cs_count), base);

			/* Window x - Size - 256 MB */
			reg_write(XOR_SIZE_MASK_REG(0, cs_count), 0x0FFF0000);
			cs_count++;
		}
	}

	mv_xor_hal_init(1);

	return;
}

void mv_sys_xor_finish(void)
{
	u32 ui;

	reg_write(XOR_WINDOW_CTRL_REG(0, 0), xor_regs_ctrl_backup);
	for (ui = 0; ui < MAX_CS; ui++)
		reg_write(XOR_BASE_ADDR_REG(0, ui), xor_regs_base_backup[ui]);
	for (ui = 0; ui < MAX_CS; ui++)
		reg_write(XOR_SIZE_MASK_REG(0, ui), xor_regs_mask_backup[ui]);

	reg_write(XOR_ADDR_OVRD_REG(0, 0), 0);
}

/*
 * mv_xor_hal_init - Initialize XOR engine
 *
 * DESCRIPTION:
 *               This function initialize XOR unit.
 * INPUT:
 *       None.
 *
 * OUTPUT:
 *       None.
 *
 * RETURN:
 *       MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
 */
static void mv_xor_hal_init(u32 chan_num)
{
	u32 i;

	/* Abort any XOR activity & set default configuration */
	for (i = 0; i < chan_num; i++) {
		mv_xor_cmd_set(i, MV_STOP);
		mv_xor_ctrl_set(i, (1 << XEXCR_REG_ACC_PROTECT_OFFS) |
				(4 << XEXCR_DST_BURST_LIMIT_OFFS) |
				(4 << XEXCR_SRC_BURST_LIMIT_OFFS));
	}
}

/*
 * mv_xor_ctrl_set - Set XOR channel control registers
 *
 * DESCRIPTION:
 *
 * INPUT:
 *
 * OUTPUT:
 *       None.
 *
 * RETURN:
 *       MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
 * NOTE:
 *    This function does not modify the OperationMode field of control register.
 *
 */
static int mv_xor_ctrl_set(u32 chan, u32 xor_ctrl)
{
	u32 val;

	/* Update the XOR Engine [0..1] Configuration Registers (XExCR) */
	val = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)))
	    & XEXCR_OPERATION_MODE_MASK;
	xor_ctrl &= ~XEXCR_OPERATION_MODE_MASK;
	xor_ctrl |= val;
	reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), xor_ctrl);

	return MV_OK;
}

int mv_xor_mem_init(u32 chan, u32 start_ptr, u32 block_size, u32 init_val_high,
		    u32 init_val_low)
{
	u32 tmp;

	/* Parameter checking */
	if (chan >= MV_XOR_MAX_CHAN)
		return MV_BAD_PARAM;

	if (MV_ACTIVE == mv_xor_state_get(chan))
		return MV_BUSY;

	if ((block_size < XEXBSR_BLOCK_SIZE_MIN_VALUE) ||
	    (block_size > XEXBSR_BLOCK_SIZE_MAX_VALUE))
		return MV_BAD_PARAM;

	/* Set the operation mode to Memory Init */
	tmp = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
	tmp &= ~XEXCR_OPERATION_MODE_MASK;
	tmp |= XEXCR_OPERATION_MODE_MEM_INIT;
	reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), tmp);

	/*
	 * Update the start_ptr field in XOR Engine [0..1] Destination Pointer
	 * Register (XExDPR0)
	 */
	reg_write(XOR_DST_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)), start_ptr);

	/*
	 * Update the BlockSize field in the XOR Engine[0..1] Block Size
	 * Registers (XExBSR)
	 */
	reg_write(XOR_BLOCK_SIZE_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
		  block_size);

	/*
	 * Update the field InitValL in the XOR Engine Initial Value Register
	 * Low (XEIVRL)
	 */
	reg_write(XOR_INIT_VAL_LOW_REG(XOR_UNIT(chan)), init_val_low);

	/*
	 * Update the field InitValH in the XOR Engine Initial Value Register
	 * High (XEIVRH)
	 */
	reg_write(XOR_INIT_VAL_HIGH_REG(XOR_UNIT(chan)), init_val_high);

	/* Start transfer */
	reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
		    XEXACTR_XESTART_MASK);

	return MV_OK;
}

/*
 * mv_xor_transfer - Transfer data from source to destination on one of
 *                 three modes (XOR,CRC32,DMA)
 *
 * DESCRIPTION:
 *       This function initiates XOR channel, according to function parameters,
 *       in order to perform XOR or CRC32 or DMA transaction.
 *       To gain maximum performance the user is asked to keep the following
 *       restrictions:
 *       1) Selected engine is available (not busy).
 *       1) This module does not take into consideration CPU MMU issues.
 *          In order for the XOR engine to access the appropreate source
 *          and destination, address parameters must be given in system
 *          physical mode.
 *       2) This API does not take care of cache coherency issues. The source,
 *          destination and in case of chain the descriptor list are assumed
 *          to be cache coherent.
 *       4) Parameters validity. For example, does size parameter exceeds
 *          maximum byte count of descriptor mode (16M or 64K).
 *
 * INPUT:
 *       chan          - XOR channel number. See MV_XOR_CHANNEL enumerator.
 *       xor_type      - One of three: XOR, CRC32 and DMA operations.
 *       xor_chain_ptr - address of chain pointer
 *
 * OUTPUT:
 *       None.
 *
 * RETURS:
 *       MV_BAD_PARAM if parameters to function invalid, MV_OK otherwise.
 *
 */
int mv_xor_transfer(u32 chan, int xor_type, u32 xor_chain_ptr)
{
	u32 tmp;

	/* Parameter checking */
	if (chan >= MV_XOR_MAX_CHAN) {
		debug("%s: ERR. Invalid chan num %d\n", __func__, chan);
		return MV_BAD_PARAM;
	}

	if (MV_ACTIVE == mv_xor_state_get(chan)) {
		debug("%s: ERR. Channel is already active\n", __func__);
		return MV_BUSY;
	}

	if (0x0 == xor_chain_ptr) {
		debug("%s: ERR. xor_chain_ptr is NULL pointer\n", __func__);
		return MV_BAD_PARAM;
	}

	/* Read configuration register and mask the operation mode field */
	tmp = reg_read(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
	tmp &= ~XEXCR_OPERATION_MODE_MASK;

	switch (xor_type) {
	case MV_XOR:
		if (0 != (xor_chain_ptr & XEXDPR_DST_PTR_XOR_MASK)) {
			debug("%s: ERR. Invalid chain pointer (bits [5:0] must be cleared)\n",
			      __func__);
			return MV_BAD_PARAM;
		}

		/* Set the operation mode to XOR */
		tmp |= XEXCR_OPERATION_MODE_XOR;
		break;

	case MV_DMA:
		if (0 != (xor_chain_ptr & XEXDPR_DST_PTR_DMA_MASK)) {
			debug("%s: ERR. Invalid chain pointer (bits [4:0] must be cleared)\n",
			      __func__);
			return MV_BAD_PARAM;
		}

		/* Set the operation mode to DMA */
		tmp |= XEXCR_OPERATION_MODE_DMA;
		break;

	case MV_CRC32:
		if (0 != (xor_chain_ptr & XEXDPR_DST_PTR_CRC_MASK)) {
			debug("%s: ERR. Invalid chain pointer (bits [4:0] must be cleared)\n",
			      __func__);
			return MV_BAD_PARAM;
		}

		/* Set the operation mode to CRC32 */
		tmp |= XEXCR_OPERATION_MODE_CRC;
		break;

	default:
		return MV_BAD_PARAM;
	}

	/* Write the operation mode to the register */
	reg_write(XOR_CONFIG_REG(XOR_UNIT(chan), XOR_CHAN(chan)), tmp);

	/*
	 * Update the NextDescPtr field in the XOR Engine [0..1] Next Descriptor
	 * Pointer Register (XExNDPR)
	 */
	reg_write(XOR_NEXT_DESC_PTR_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
		  xor_chain_ptr);

	/* Start transfer */
	reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
		    XEXACTR_XESTART_MASK);

	return MV_OK;
}

/*
 * mv_xor_state_get - Get XOR channel state.
 *
 * DESCRIPTION:
 *       XOR channel activity state can be active, idle, paused.
 *       This function retrunes the channel activity state.
 *
 * INPUT:
 *       chan     - the channel number
 *
 * OUTPUT:
 *       None.
 *
 * RETURN:
 *       XOR_CHANNEL_IDLE    - If the engine is idle.
 *       XOR_CHANNEL_ACTIVE  - If the engine is busy.
 *       XOR_CHANNEL_PAUSED  - If the engine is paused.
 *       MV_UNDEFINED_STATE  - If the engine state is undefind or there is no
 *                             such engine
 *
 */
int mv_xor_state_get(u32 chan)
{
	u32 state;

	/* Parameter checking */
	if (chan >= MV_XOR_MAX_CHAN) {
		debug("%s: ERR. Invalid chan num %d\n", __func__, chan);
		return MV_UNDEFINED_STATE;
	}

	/* Read the current state */
	state = reg_read(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)));
	state &= XEXACTR_XESTATUS_MASK;

	/* Return the state */
	switch (state) {
	case XEXACTR_XESTATUS_IDLE:
		return MV_IDLE;
	case XEXACTR_XESTATUS_ACTIVE:
		return MV_ACTIVE;
	case XEXACTR_XESTATUS_PAUSED:
		return MV_PAUSED;
	}

	return MV_UNDEFINED_STATE;
}

/*
 * mv_xor_cmd_set - Set command of XOR channel
 *
 * DESCRIPTION:
 *       XOR channel can be started, idle, paused and restarted.
 *       Paused can be set only if channel is active.
 *       Start can be set only if channel is idle or paused.
 *       Restart can be set only if channel is paused.
 *       Stop can be set only if channel is active.
 *
 * INPUT:
 *       chan     - The channel number
 *       command  - The command type (start, stop, restart, pause)
 *
 * OUTPUT:
 *       None.
 *
 * RETURN:
 *       MV_OK on success , MV_BAD_PARAM on erroneous parameter, MV_ERROR on
 *       undefind XOR engine mode
 *
 */
static int mv_xor_cmd_set(u32 chan, int command)
{
	int state;

	/* Parameter checking */
	if (chan >= MV_XOR_MAX_CHAN) {
		debug("%s: ERR. Invalid chan num %d\n", __func__, chan);
		return MV_BAD_PARAM;
	}

	/* Get the current state */
	state = mv_xor_state_get(chan);

	/* Command is start and current state is idle */
	if ((command == MV_START) && (state == MV_IDLE)) {
		reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
			    XEXACTR_XESTART_MASK);
		return MV_OK;
	}
	/* Command is stop and current state is active */
	else if ((command == MV_STOP) && (state == MV_ACTIVE)) {
		reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
			    XEXACTR_XESTOP_MASK);
		return MV_OK;
	}
	/* Command is paused and current state is active */
	else if ((command == MV_PAUSED) && (state == MV_ACTIVE)) {
		reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
			    XEXACTR_XEPAUSE_MASK);
		return MV_OK;
	}
	/* Command is restart and current state is paused */
	else if ((command == MV_RESTART) && (state == MV_PAUSED)) {
		reg_bit_set(XOR_ACTIVATION_REG(XOR_UNIT(chan), XOR_CHAN(chan)),
			    XEXACTR_XERESTART_MASK);
		return MV_OK;
	}
	/* Command is stop and current state is active */
	else if ((command == MV_STOP) && (state == MV_IDLE))
		return MV_OK;

	/* Illegal command */
	debug("%s: ERR. Illegal command\n", __func__);

	return MV_BAD_PARAM;
}
