From 03d6ee77cf267df1a4629b0698bbf3acd7697e07 Mon Sep 17 00:00:00 2001 From: Kedareswara rao Appana Date: Wed, 27 May 2015 18:51:42 +0530 Subject: [PATCH] mcap: linux: Add support for partial reconfiguration clear file This patch adds support for programming the partial Reconfiguration clear file. Signed-off-by: Kedareswara rao Appana Reviewed-by: Srikanth Vemula --- mcap/linux/mcap.c | 14 +++++++-- mcap/linux/mcap_lib.c | 73 +++++++++++++++++++++++++++++++++++++++---- mcap/linux/mcap_lib.h | 5 ++- 3 files changed, 83 insertions(+), 9 deletions(-) diff --git a/mcap/linux/mcap.c b/mcap/linux/mcap.c index d04148ef..7e6055f0 100644 --- a/mcap/linux/mcap.c +++ b/mcap/linux/mcap.c @@ -38,13 +38,14 @@ #include "mcap_lib.h" -static const char options[] = "x:p:rmfdvHhDc::"; +static const char options[] = "x:pC:rmfdvHhDc::"; static char help_msg[] = "Usage: mcap [options]\n" "\n" "Options:\n" "\t-x\t\tSpecify MCAP Device Id in hex (MANDATORY)\n" "\t-p \tProgram Bitstream (.bin/.bit/.rbt)\n" +"\t-C \tPartial Reconfiguration Clear File(.bin/.bit/.rbt)\n" "\t-r\t\tPerforms Simple Reset\n" "\t-m\t\tPerforms Module Reset\n" "\t-f\t\tPerforms Full Reset\n" @@ -65,6 +66,7 @@ int main(int argc, char **argv) int i, modreset = 0, fullreset = 0, reset = 0; int program = 0, verbose = 0, device_id = 0; int data_regs = 0, dump_regs = 0, access_config = 0; + int programconfigfile = 0; while ((i = getopt(argc, argv, options)) != -1) { switch (i) { @@ -90,6 +92,9 @@ int main(int argc, char **argv) case 'H': printf("%s", help_msg); return 1; + case 'C': + programconfigfile = 1; + break; case 'p': program = 1; break; @@ -145,8 +150,13 @@ int main(int argc, char **argv) goto free; } + if (programconfigfile) { + MCapConfigureFPGA(mdev, argv[4], EMCAP_PARTIALCONFIG_FILE); + goto free; + } + if (program) { - MCapConfigureFPGA(mdev, argv[4]); + MCapConfigureFPGA(mdev, argv[4], EMCAP_CONFIG_FILE); goto free; } diff --git a/mcap/linux/mcap_lib.c b/mcap/linux/mcap_lib.c index 7174baf7..2f16aa05 100644 --- a/mcap/linux/mcap_lib.c +++ b/mcap/linux/mcap_lib.c @@ -224,6 +224,61 @@ static int Checkforcompletion(struct mcap_dev *mdev) return 0; } +static int MCapWritePartialBitStream(struct mcap_dev *mdev, u32 *data, + int len, u8 bswap) +{ + u32 set, restore; + int err, count = 0, i; + + if (!data || !len) { + pr_err("Invalid Arguments\n"); + return -EMCAPWRITE; + } + + err = MCapClearRequestByConfigure(mdev, &restore); + if (err) + return err; + + if (IsErrSet(mdev) || IsRegReadComplete(mdev) || + IsFifoOverflow(mdev)) { + pr_err("Failed to initialize configuring FPGA\n"); + MCapRegWrite(mdev, MCAP_CONTROL, restore); + return -EMCAPWRITE; + } + + /* Set 'Mode', 'In Use by PCIe' and 'Data Reg Protect' bits */ + set = MCapRegRead(mdev, MCAP_CONTROL); + set |= MCAP_CTRL_MODE_MASK | MCAP_CTRL_IN_USE_MASK | + MCAP_CTRL_DATA_REG_PROT_MASK; + + /* Clear 'Reset', 'Module Reset' and 'Register Read' bits */ + set &= ~(MCAP_CTRL_RESET_MASK | MCAP_CTRL_MOD_RESET_MASK | + MCAP_CTRL_REG_READ_MASK | MCAP_CTRL_DESIGN_SWITCH_MASK); + + MCapRegWrite(mdev, MCAP_CONTROL, set); + + /* Write Data */ + if (!bswap) { + for (count = 0; count < len; count++) + MCapRegWrite(mdev, MCAP_DATA, data[count]); + } else { + for (count = 0; count < len; count++) + MCapRegWrite(mdev, MCAP_DATA, __bswap_32(data[count])); + } + + for (i = 0 ; i < EMCAP_EOS_LOOP_COUNT; i++) { + MCapRegWrite(mdev, MCAP_DATA, EMCAP_NOOP_VAL); + } + + if (IsErrSet(mdev) || IsFifoOverflow(mdev)) { + pr_err("Failed to Write Bitstream\n"); + MCapRegWrite(mdev, MCAP_CONTROL, restore); + return -EMCAPWRITE; + } + + return 0; +} + static int MCapWriteBitStream(struct mcap_dev *mdev, u32 *data, int len, u8 bswap) { @@ -525,7 +580,7 @@ void MCapDumpRegs(struct mcap_dev *mdev) MCapDumpReadRegs(mdev); } -int MCapConfigureFPGA(struct mcap_dev *mdev, char *file_path) +int MCapConfigureFPGA(struct mcap_dev *mdev, char *file_path, u32 bitfile_type) { FILE *fptr; u32 *data; @@ -570,11 +625,17 @@ int MCapConfigureFPGA(struct mcap_dev *mdev, char *file_path) } /* Program FPGA */ - err = MCapWriteBitStream(mdev, data, wrdatasz, bswap); - if (err) - return -EMCAPCFG; - - pr_info("FPGA Configuration Done!!\n"); + if (bitfile_type == EMCAP_PARTIALCONFIG_FILE) { + err = MCapWritePartialBitStream(mdev, data, wrdatasz, bswap); + if (err) + return -EMCAPCFG; + pr_info("FPGA Partial Configuration Done!!\n"); + } else if (bitfile_type == EMCAP_CONFIG_FILE) { + err = MCapWriteBitStream(mdev, data, wrdatasz, bswap); + if (err) + return -EMCAPCFG; + pr_info("FPGA Configuration Done!!\n"); + } free_resources: if (data) diff --git a/mcap/linux/mcap_lib.h b/mcap/linux/mcap_lib.h index a42e517c..3f105477 100644 --- a/mcap/linux/mcap_lib.h +++ b/mcap/linux/mcap_lib.h @@ -96,6 +96,9 @@ #define EMCAP_EOS_LOOP_COUNT 100 #define EMCAP_NOOP_VAL 0x2000000 +/* Bitfile Type */ +#define EMCAP_CONFIG_FILE 0 +#define EMCAP_PARTIALCONFIG_FILE 1 #undef DEBUG #ifndef DEBUG @@ -157,6 +160,6 @@ int MCapReset(struct mcap_dev *mdev); int MCapModuleReset(struct mcap_dev *mdev); int MCapFullReset(struct mcap_dev *mdev); int MCapShowDevice(struct mcap_dev *mdev, int verbose); -int MCapConfigureFPGA(struct mcap_dev *mdev, char *file_path); +int MCapConfigureFPGA(struct mcap_dev *mdev, char *file_path, u32 bitfile_type); int MCapReadRegisters(struct mcap_dev *mdev, u32 *data); int MCapAccessConfigSpace(struct mcap_dev *mdev, int argc, char **argv);