/*
 * (C) Copyright 2006
 * Heiko Schocher, DENX Software Engineering, hs@denx.de
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

/*
 * Altera FPGA configuration support for the ALPR computer from prodrive
 */

#include <common.h>
#include <altera.h>
#include <ACEX1K.h>
#include <command.h>
#include <asm/processor.h>
#include <asm/ppc440.h>
#include "fpga.h"

DECLARE_GLOBAL_DATA_PTR;

#if defined(CONFIG_FPGA)

#ifdef FPGA_DEBUG
#define	PRINTF(fmt, args...)	printf(fmt , ##args)
#else
#define	PRINTF(fmt, args...)
#endif

static unsigned long regval;

#define SET_GPIO_REG_0(reg, bit) do {				\
		regval = in32(reg);				\
		regval &= ~(0x80000000 >> bit);			\
		out32(reg, regval);				\
	} while (0)

#define SET_GPIO_REG_1(reg, bit) do {				\
		regval = in32(reg);				\
		regval |= (0x80000000 >> bit);			\
		out32(reg, regval);				\
	} while (0)

#define	SET_GPIO_0(bit)		SET_GPIO_REG_0(GPIO0_OR, bit)
#define	SET_GPIO_1(bit)		SET_GPIO_REG_1(GPIO0_OR, bit)

#define FPGA_PRG		(0x80000000 >> CONFIG_SYS_GPIO_PROG_EN)
#define FPGA_CONFIG		(0x80000000 >> CONFIG_SYS_GPIO_CONFIG)
#define FPGA_DATA		(0x80000000 >> CONFIG_SYS_GPIO_DATA)
#define FPGA_CLK		(0x80000000 >> CONFIG_SYS_GPIO_CLK)
#define OLD_VAL			(FPGA_PRG | FPGA_CONFIG)

#define SET_FPGA(data)		out32(GPIO0_OR, data)

#define FPGA_WRITE_1 do {							    \
	SET_FPGA(OLD_VAL | 0	    | FPGA_DATA);	/* set data to 1 */ \
	SET_FPGA(OLD_VAL | FPGA_CLK | FPGA_DATA);	/* set data to 1 */ \
} while (0)

#define FPGA_WRITE_0 do {							    \
	SET_FPGA(OLD_VAL | 0	    | 0);		/* set data to 0 */ \
	SET_FPGA(OLD_VAL | FPGA_CLK | 0);		/* set data to 1 */ \
} while (0)

/* Plattforminitializations */
/* Here we have to set the FPGA Chain */
/* PROGRAM_PROG_EN	= HIGH */
/* PROGRAM_SEL_DPR	= LOW */
int fpga_pre_fn(int cookie)
{
	/* Enable the FPGA Chain */
	SET_GPIO_REG_1(GPIO0_TCR, CONFIG_SYS_GPIO_PROG_EN);
	SET_GPIO_REG_0(GPIO0_ODR, CONFIG_SYS_GPIO_PROG_EN);
	SET_GPIO_1(CONFIG_SYS_GPIO_PROG_EN);
	SET_GPIO_REG_1(GPIO0_TCR, CONFIG_SYS_GPIO_SEL_DPR);
	SET_GPIO_REG_0(GPIO0_ODR, CONFIG_SYS_GPIO_SEL_DPR);
	SET_GPIO_0((CONFIG_SYS_GPIO_SEL_DPR));

	/* initialize the GPIO Pins */
	/* output */
	SET_GPIO_0(CONFIG_SYS_GPIO_CLK);
	SET_GPIO_REG_1(GPIO0_TCR, CONFIG_SYS_GPIO_CLK);
	SET_GPIO_REG_0(GPIO0_ODR, CONFIG_SYS_GPIO_CLK);

	/* output */
	SET_GPIO_0(CONFIG_SYS_GPIO_DATA);
	SET_GPIO_REG_1(GPIO0_TCR, CONFIG_SYS_GPIO_DATA);
	SET_GPIO_REG_0(GPIO0_ODR, CONFIG_SYS_GPIO_DATA);

	/* First we set STATUS to 0 then as an input */
	SET_GPIO_REG_1(GPIO0_TCR, CONFIG_SYS_GPIO_STATUS);
	SET_GPIO_REG_0(GPIO0_ODR, CONFIG_SYS_GPIO_STATUS);
	SET_GPIO_0(CONFIG_SYS_GPIO_STATUS);
	SET_GPIO_REG_0(GPIO0_TCR, CONFIG_SYS_GPIO_STATUS);
	SET_GPIO_REG_0(GPIO0_ODR, CONFIG_SYS_GPIO_STATUS);

	/* output */
	SET_GPIO_REG_1(GPIO0_TCR, CONFIG_SYS_GPIO_CONFIG);
	SET_GPIO_REG_0(GPIO0_ODR, CONFIG_SYS_GPIO_CONFIG);
	SET_GPIO_0(CONFIG_SYS_GPIO_CONFIG);

	/* input */
	SET_GPIO_0(CONFIG_SYS_GPIO_CON_DON);
	SET_GPIO_REG_0(GPIO0_TCR, CONFIG_SYS_GPIO_CON_DON);
	SET_GPIO_REG_0(GPIO0_ODR, CONFIG_SYS_GPIO_CON_DON);

	/* CONFIG = 0 STATUS = 0 -> FPGA in reset state */
	SET_GPIO_0(CONFIG_SYS_GPIO_CONFIG);
	return FPGA_SUCCESS;
}

/* Set the state of CONFIG Pin */
int fpga_config_fn(int assert_config, int flush, int cookie)
{
	if (assert_config)
		SET_GPIO_1(CONFIG_SYS_GPIO_CONFIG);
	else
		SET_GPIO_0(CONFIG_SYS_GPIO_CONFIG);

	return FPGA_SUCCESS;
}

/* Returns the state of STATUS Pin */
int fpga_status_fn(int cookie)
{
	unsigned long	reg;

	reg = in32(GPIO0_IR);
	if (reg & (0x80000000 >> CONFIG_SYS_GPIO_STATUS)) {
		PRINTF("STATUS = HIGH\n");
		return FPGA_FAIL;
	}
	PRINTF("STATUS = LOW\n");
	return FPGA_SUCCESS;
}

/* Returns the state of CONF_DONE Pin */
int fpga_done_fn(int cookie)
{
	unsigned long	reg;
	reg = in32(GPIO0_IR);
	if (reg & (0x80000000 >> CONFIG_SYS_GPIO_CON_DON)) {
		PRINTF("CONF_DON = HIGH\n");
		return FPGA_FAIL;
	}
	PRINTF("CONF_DON = LOW\n");
	return FPGA_SUCCESS;
}

/* writes the complete buffer to the FPGA
   writing the complete buffer in one function is much faster,
   then calling it for every bit */
int fpga_write_fn(const void *buf, size_t len, int flush, int cookie)
{
	size_t bytecount = 0;
	unsigned char *data = (unsigned char *) buf;
	unsigned char val = 0;
	int		i;
	int len_40 = len / 40;

	while (bytecount < len) {
		val = data[bytecount++];
		i = 8;
		do {
			if (val & 0x01)
				FPGA_WRITE_1;
			else
				FPGA_WRITE_0;

			val >>= 1;
			i--;
		} while (i > 0);

#ifdef CONFIG_SYS_FPGA_PROG_FEEDBACK
		if (bytecount % len_40 == 0) {
			putc('.');		/* let them know we are alive */
#ifdef CONFIG_SYS_FPGA_CHECK_CTRLC
			if (ctrlc())
				return FPGA_FAIL;
#endif
		}
#endif
	}
	return FPGA_SUCCESS;
}

/* called, when programming is aborted */
int fpga_abort_fn(int cookie)
{
	SET_GPIO_1((CONFIG_SYS_GPIO_SEL_DPR));
	return FPGA_SUCCESS;
}

/* called, when programming was succesful */
int fpga_post_fn(int cookie)
{
	return fpga_abort_fn(cookie);
}

/* Note that these are pointers to code that is in Flash.  They will be
 * relocated at runtime.
 */
Altera_CYC2_Passive_Serial_fns fpga_fns = {
	fpga_pre_fn,
	fpga_config_fn,
	fpga_status_fn,
	fpga_done_fn,
	fpga_write_fn,
	fpga_abort_fn,
	fpga_post_fn
};

Altera_desc fpga[CONFIG_FPGA_COUNT] = {
	{Altera_CYC2,
	 passive_serial,
	 Altera_EP2C35_SIZE,
	 (void *) &fpga_fns,
	 NULL,
	 0}
};

/*
 * Initialize the fpga.  Return 1 on success, 0 on failure.
 */
int alpr_fpga_init(void)
{
	int i;

	PRINTF("%s:%d: Initialize FPGA interface\n", __func__, __LINE__);
	fpga_init();

	for (i = 0; i < CONFIG_FPGA_COUNT; i++) {
		PRINTF("%s:%d: Adding fpga %d\n", __func__, __LINE__, i);
		fpga_add(fpga_altera, &fpga[i]);
	}
	return 1;
}

#endif
