diff options
author | Yang Zhang <yang.z.zhang@intel.com> | 2015-08-28 09:58:54 +0800 |
---|---|---|
committer | Yang Zhang <yang.z.zhang@intel.com> | 2015-09-01 12:44:00 +0800 |
commit | e44e3482bdb4d0ebde2d8b41830ac2cdb07948fb (patch) | |
tree | 66b09f592c55df2878107a468a91d21506104d3f /qemu/roms/u-boot/board/esd/pmc440/fpga.c | |
parent | 9ca8dbcc65cfc63d6f5ef3312a33184e1d726e00 (diff) |
Add qemu 2.4.0
Change-Id: Ic99cbad4b61f8b127b7dc74d04576c0bcbaaf4f5
Signed-off-by: Yang Zhang <yang.z.zhang@intel.com>
Diffstat (limited to 'qemu/roms/u-boot/board/esd/pmc440/fpga.c')
-rw-r--r-- | qemu/roms/u-boot/board/esd/pmc440/fpga.c | 446 |
1 files changed, 446 insertions, 0 deletions
diff --git a/qemu/roms/u-boot/board/esd/pmc440/fpga.c b/qemu/roms/u-boot/board/esd/pmc440/fpga.c new file mode 100644 index 000000000..f876da855 --- /dev/null +++ b/qemu/roms/u-boot/board/esd/pmc440/fpga.c @@ -0,0 +1,446 @@ +/* + * (C) Copyright 2007 + * Matthias Fuchs, esd gmbh, matthias.fuchs@esd-electronics.com. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <spartan2.h> +#include <spartan3.h> +#include <command.h> +#include "fpga.h" +#include "pmc440.h" + +DECLARE_GLOBAL_DATA_PTR; + +#if defined(CONFIG_FPGA) + +#define USE_SP_CODE + +#ifdef USE_SP_CODE +xilinx_spartan3_slave_parallel_fns pmc440_fpga_fns = { + fpga_pre_config_fn, + fpga_pgm_fn, + fpga_init_fn, + NULL, /* err */ + fpga_done_fn, + fpga_clk_fn, + fpga_cs_fn, + fpga_wr_fn, + NULL, /* rdata */ + fpga_wdata_fn, + fpga_busy_fn, + fpga_abort_fn, + fpga_post_config_fn, +}; +#else +xilinx_spartan3_slave_serial_fns pmc440_fpga_fns = { + fpga_pre_config_fn, + fpga_pgm_fn, + fpga_clk_fn, + fpga_init_fn, + fpga_done_fn, + fpga_wr_fn, + fpga_post_config_fn, +}; +#endif + +xilinx_spartan2_slave_serial_fns ngcc_fpga_fns = { + ngcc_fpga_pre_config_fn, + ngcc_fpga_pgm_fn, + ngcc_fpga_clk_fn, + ngcc_fpga_init_fn, + ngcc_fpga_done_fn, + ngcc_fpga_wr_fn, + ngcc_fpga_post_config_fn +}; + +xilinx_desc fpga[CONFIG_FPGA_COUNT] = { + XILINX_XC3S1200E_DESC( +#ifdef USE_SP_CODE + slave_parallel, +#else + slave_serial, +#endif + (void *)&pmc440_fpga_fns, + 0), + XILINX_XC2S200_DESC( + slave_serial, + (void *)&ngcc_fpga_fns, + 0) +}; + + +/* + * Set the active-low FPGA reset signal. + */ +void fpga_reset(int assert) +{ + debug("%s:%d: RESET ", __FUNCTION__, __LINE__); + if (assert) { + out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) & ~GPIO1_FPGA_DATA); + debug("asserted\n"); + } else { + out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) | GPIO1_FPGA_DATA); + debug("deasserted\n"); + } +} + + +/* + * Initialize the SelectMap interface. We assume that the mode and the + * initial state of all of the port pins have already been set! + */ +void fpga_serialslave_init(void) +{ + debug("%s:%d: Initialize serial slave interface\n", __FUNCTION__, + __LINE__); + fpga_pgm_fn(false, false, 0); /* make sure program pin is inactive */ +} + + +/* + * Set the FPGA's active-low SelectMap program line to the specified level + */ +int fpga_pgm_fn(int assert, int flush, int cookie) +{ + debug("%s:%d: FPGA PROGRAM ", + __FUNCTION__, __LINE__); + + if (assert) { + out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) & ~GPIO1_FPGA_PRG); + debug("asserted\n"); + } else { + out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) | GPIO1_FPGA_PRG); + debug("deasserted\n"); + } + return assert; +} + + +/* + * Test the state of the active-low FPGA INIT line. Return 1 on INIT + * asserted (low). + */ +int fpga_init_fn(int cookie) +{ + if (in_be32((void*)GPIO1_IR) & GPIO1_FPGA_INIT) + return 0; + else + return 1; +} + +#ifdef USE_SP_CODE +int fpga_abort_fn(int cookie) +{ + return 0; +} + + +int fpga_cs_fn(int assert_cs, int flush, int cookie) +{ + return assert_cs; +} + + +int fpga_busy_fn(int cookie) +{ + return 1; +} +#endif + + +/* + * Test the state of the active-high FPGA DONE pin + */ +int fpga_done_fn(int cookie) +{ + if (in_be32((void*)GPIO1_IR) & GPIO1_FPGA_DONE) + return 1; + else + return 0; +} + + +/* + * FPGA pre-configuration function. Just make sure that + * FPGA reset is asserted to keep the FPGA from starting up after + * configuration. + */ +int fpga_pre_config_fn(int cookie) +{ + debug("%s:%d: FPGA pre-configuration\n", __FUNCTION__, __LINE__); + fpga_reset(true); + + /* release init# */ + out_be32((void*)GPIO0_OR, in_be32((void*)GPIO0_OR) | GPIO0_FPGA_FORCEINIT); + /* disable PLD IOs */ + out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) | GPIO1_IOEN_N); + return 0; +} + + +/* + * FPGA post configuration function. Blip the FPGA reset line and then see if + * the FPGA appears to be running. + */ +int fpga_post_config_fn(int cookie) +{ + pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA; + int rc=0; + char *s; + + debug("%s:%d: FPGA post configuration\n", __FUNCTION__, __LINE__); + + /* enable PLD0..7 pins */ + out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) & ~GPIO1_IOEN_N); + + fpga_reset(true); + udelay (100); + fpga_reset(false); + udelay (100); + + FPGA_OUT32(&fpga->status, (gd->board_type << STATUS_HWREV_SHIFT) & STATUS_HWREV_MASK); + + /* NGCC/CANDES only: enable ledlink */ + if ((s = getenv("bd_type")) && + ((!strcmp(s, "ngcc")) || (!strcmp(s, "candes")))) + FPGA_SETBITS(&fpga->ctrla, 0x29f8c000); + + return rc; +} + + +int fpga_clk_fn(int assert_clk, int flush, int cookie) +{ + if (assert_clk) + out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) | GPIO1_FPGA_CLK); + else + out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) & ~GPIO1_FPGA_CLK); + + return assert_clk; +} + + +int fpga_wr_fn(int assert_write, int flush, int cookie) +{ + if (assert_write) + out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) | GPIO1_FPGA_DATA); + else + out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) & ~GPIO1_FPGA_DATA); + + return assert_write; +} + +#ifdef USE_SP_CODE +int fpga_wdata_fn(uchar data, int flush, int cookie) +{ + uchar val = data; + ulong or = in_be32((void*)GPIO1_OR); + int i = 7; + do { + /* Write data */ + if (val & 0x80) + or = (or & ~GPIO1_FPGA_CLK) | GPIO1_FPGA_DATA; + else + or = or & ~(GPIO1_FPGA_CLK | GPIO1_FPGA_DATA); + + out_be32((void*)GPIO1_OR, or); + + /* Assert the clock */ + or |= GPIO1_FPGA_CLK; + out_be32((void*)GPIO1_OR, or); + val <<= 1; + i --; + } while (i > 0); + + /* Write last data bit (the 8th clock comes from the sp_load() code */ + if (val & 0x80) + or = (or & ~GPIO1_FPGA_CLK) | GPIO1_FPGA_DATA; + else + or = or & ~(GPIO1_FPGA_CLK | GPIO1_FPGA_DATA); + + out_be32((void*)GPIO1_OR, or); + + return 0; +} +#endif + +#define NGCC_FPGA_PRG CLOCK_EN +#define NGCC_FPGA_DATA RESET_OUT +#define NGCC_FPGA_DONE CLOCK_IN +#define NGCC_FPGA_INIT IRIGB_R_IN +#define NGCC_FPGA_CLK CLOCK_OUT + +void ngcc_fpga_serialslave_init(void) +{ + debug("%s:%d: Initialize serial slave interface\n", + __FUNCTION__, __LINE__); + + /* make sure program pin is inactive */ + ngcc_fpga_pgm_fn(false, false, 0); +} + +/* + * Set the active-low FPGA reset signal. + */ +void ngcc_fpga_reset(int assert) +{ + debug("%s:%d: RESET ", __FUNCTION__, __LINE__); + + if (assert) { + FPGA_CLRBITS(NGCC_CTRL_BASE, NGCC_CTRL_FPGARST_N); + debug("asserted\n"); + } else { + FPGA_SETBITS(NGCC_CTRL_BASE, NGCC_CTRL_FPGARST_N); + debug("deasserted\n"); + } +} + + +/* + * Set the FPGA's active-low SelectMap program line to the specified level + */ +int ngcc_fpga_pgm_fn(int assert, int flush, int cookie) +{ + pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA; + + debug("%s:%d: FPGA PROGRAM ", __FUNCTION__, __LINE__); + + if (assert) { + FPGA_CLRBITS(&fpga->ctrla, NGCC_FPGA_PRG); + debug("asserted\n"); + } else { + FPGA_SETBITS(&fpga->ctrla, NGCC_FPGA_PRG); + debug("deasserted\n"); + } + + return assert; +} + + +/* + * Test the state of the active-low FPGA INIT line. Return 1 on INIT + * asserted (low). + */ +int ngcc_fpga_init_fn(int cookie) +{ + pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA; + + debug("%s:%d: INIT check... ", __FUNCTION__, __LINE__); + if (FPGA_IN32(&fpga->status) & NGCC_FPGA_INIT) { + debug("high\n"); + return 0; + } else { + debug("low\n"); + return 1; + } +} + + +/* + * Test the state of the active-high FPGA DONE pin + */ +int ngcc_fpga_done_fn(int cookie) +{ + pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA; + + debug("%s:%d: DONE check... ", __FUNCTION__, __LINE__); + if (FPGA_IN32(&fpga->status) & NGCC_FPGA_DONE) { + debug("DONE high\n"); + return 1; + } else { + debug("low\n"); + return 0; + } +} + + +/* + * FPGA pre-configuration function. + */ +int ngcc_fpga_pre_config_fn(int cookie) +{ + pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA; + debug("%s:%d: FPGA pre-configuration\n", __FUNCTION__, __LINE__); + + ngcc_fpga_reset(true); + FPGA_CLRBITS(&fpga->ctrla, 0xfffffe00); + + ngcc_fpga_reset(true); + return 0; +} + + +/* + * FPGA post configuration function. Blip the FPGA reset line and then see if + * the FPGA appears to be running. + */ +int ngcc_fpga_post_config_fn(int cookie) +{ + pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA; + + debug("%s:%d: NGCC FPGA post configuration\n", __FUNCTION__, __LINE__); + + udelay (100); + ngcc_fpga_reset(false); + + FPGA_SETBITS(&fpga->ctrla, 0x29f8c000); + + return 0; +} + + +int ngcc_fpga_clk_fn(int assert_clk, int flush, int cookie) +{ + pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA; + + if (assert_clk) + FPGA_SETBITS(&fpga->ctrla, NGCC_FPGA_CLK); + else + FPGA_CLRBITS(&fpga->ctrla, NGCC_FPGA_CLK); + + return assert_clk; +} + + +int ngcc_fpga_wr_fn(int assert_write, int flush, int cookie) +{ + pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA; + + if (assert_write) + FPGA_SETBITS(&fpga->ctrla, NGCC_FPGA_DATA); + else + FPGA_CLRBITS(&fpga->ctrla, NGCC_FPGA_DATA); + + return assert_write; +} + + +/* + * Initialize the fpga. Return 1 on success, 0 on failure. + */ +int pmc440_init_fpga(void) +{ + char *s; + + debug("%s:%d: Initialize FPGA interface\n", + __FUNCTION__, __LINE__); + fpga_init(); + + fpga_serialslave_init (); + debug("%s:%d: Adding fpga 0\n", __FUNCTION__, __LINE__); + fpga_add (fpga_xilinx, &fpga[0]); + + /* NGCC only */ + if ((s = getenv("bd_type")) && !strcmp(s, "ngcc")) { + ngcc_fpga_serialslave_init (); + debug("%s:%d: Adding fpga 1\n", __FUNCTION__, __LINE__); + fpga_add (fpga_xilinx, &fpga[1]); + } + + return 0; +} +#endif /* CONFIG_FPGA */ |