aboutsummaryrefslogtreecommitdiffstats
path: root/roms/u-boot/board/prodrive/alpr/fpga.c
diff options
context:
space:
mode:
Diffstat (limited to 'roms/u-boot/board/prodrive/alpr/fpga.c')
-rw-r--r--roms/u-boot/board/prodrive/alpr/fpga.c239
1 files changed, 239 insertions, 0 deletions
diff --git a/roms/u-boot/board/prodrive/alpr/fpga.c b/roms/u-boot/board/prodrive/alpr/fpga.c
new file mode 100644
index 00000000..3133f942
--- /dev/null
+++ b/roms/u-boot/board/prodrive/alpr/fpga.c
@@ -0,0 +1,239 @@
+/*
+ * (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