diff options
Diffstat (limited to 'roms/u-boot/board/prodrive/alpr/fpga.c')
-rw-r--r-- | roms/u-boot/board/prodrive/alpr/fpga.c | 239 |
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 |