/* * (C) Copyright 2002 * Rich Ireland, Enterasys Networks, rireland@enterasys.com. * Keith Outwater, keith_outwater@mvis.com. * * (C) Copyright 2008 * Andre Schwarz, Matrix Vision GmbH, andre.schwarz@matrix-vision.de * * SPDX-License-Identifier: GPL-2.0+ */ #include #include #include #include "fpga.h" #include "mvblm7.h" #ifdef FPGA_DEBUG #define fpga_debug(fmt, args...) printf("%s: "fmt, __func__, ##args) #else #define fpga_debug(fmt, args...) #endif Altera_CYC2_Passive_Serial_fns altera_fns = { fpga_null_fn, fpga_config_fn, fpga_status_fn, fpga_done_fn, fpga_wr_fn, fpga_null_fn, fpga_null_fn, }; Altera_desc cyclone2 = { Altera_CYC2, passive_serial, Altera_EP2C20_SIZE, (void *) &altera_fns, NULL, 0 }; DECLARE_GLOBAL_DATA_PTR; int mvblm7_init_fpga(void) { fpga_debug("Initialize FPGA interface\n"); fpga_init(); fpga_add(fpga_altera, &cyclone2); fpga_config_fn(0, 1, 0); udelay(60); return 1; } int fpga_null_fn(int cookie) { return 0; } int fpga_config_fn(int assert, int flush, int cookie) { volatile immap_t *im = (volatile immap_t *)CONFIG_SYS_IMMR; volatile gpio83xx_t *gpio = (volatile gpio83xx_t *)&im->gpio[0]; u32 dvo = gpio->dat; fpga_debug("SET config : %s\n", assert ? "low" : "high"); if (assert) dvo |= FPGA_CONFIG; else dvo &= ~FPGA_CONFIG; if (flush) gpio->dat = dvo; return assert; } int fpga_done_fn(int cookie) { volatile immap_t *im = (volatile immap_t *)CONFIG_SYS_IMMR; volatile gpio83xx_t *gpio = (volatile gpio83xx_t *)&im->gpio[0]; int result = 0; udelay(10); fpga_debug("CONF_DONE check ... "); if (gpio->dat & FPGA_CONF_DONE) { fpga_debug("high\n"); result = 1; } else fpga_debug("low\n"); return result; } int fpga_status_fn(int cookie) { volatile immap_t *im = (volatile immap_t *)CONFIG_SYS_IMMR; volatile gpio83xx_t *gpio = (volatile gpio83xx_t *)&im->gpio[0]; int result = 0; fpga_debug("STATUS check ... "); if (gpio->dat & FPGA_STATUS) { fpga_debug("high\n"); result = 1; } else fpga_debug("low\n"); return result; } int fpga_clk_fn(int assert_clk, int flush, int cookie) { volatile immap_t *im = (volatile immap_t *)CONFIG_SYS_IMMR; volatile gpio83xx_t *gpio = (volatile gpio83xx_t *)&im->gpio[0]; u32 dvo = gpio->dat; fpga_debug("CLOCK %s\n", assert_clk ? "high" : "low"); if (assert_clk) dvo |= FPGA_CCLK; else dvo &= ~FPGA_CCLK; if (flush) gpio->dat = dvo; return assert_clk; } static inline int _write_fpga(u8 val, int dump) { volatile immap_t *im = (volatile immap_t *)CONFIG_SYS_IMMR; volatile gpio83xx_t *gpio = (volatile gpio83xx_t *)&im->gpio[0]; int i; u32 dvo = gpio->dat; if (dump) fpga_debug(" %02x -> ", val); for (i = 0; i < 8; i++) { dvo &= ~FPGA_CCLK; gpio->dat = dvo; dvo &= ~FPGA_DIN; if (dump) fpga_debug("%d ", val&1); if (val & 1) dvo |= FPGA_DIN; gpio->dat = dvo; dvo |= FPGA_CCLK; gpio->dat = dvo; val >>= 1; } if (dump) fpga_debug("\n"); return 0; } int fpga_wr_fn(const void *buf, size_t len, int flush, int cookie) { unsigned char *data = (unsigned char *) buf; int i; fpga_debug("fpga_wr: buf %p / size %d\n", buf, len); for (i = 0; i < len; i++) _write_fpga(data[i], 0); fpga_debug("\n"); return FPGA_SUCCESS; }