linux/drivers/staging/gs_fpgaboot/gs_fpgaboot.c
<<
>>
Prefs
   1/*
   2 * This program is free software; you can redistribute it and/or modify
   3 * it under the terms of the GNU General Public License as published by
   4 * the Free Software Foundation; either version 2 of the License, or
   5 * (at your option) any later version.
   6 *
   7 * This program is distributed in the hope that it will be useful,
   8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
   9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10 * GNU General Public License for more details.
  11 */
  12
  13#include <linux/kernel.h>
  14#include <linux/init.h>
  15#include <linux/module.h>
  16#include <linux/types.h>
  17#include <linux/device.h>
  18#include <linux/string.h>
  19#include <linux/slab.h>
  20#include <linux/fs.h>
  21#include <linux/platform_device.h>
  22#include <linux/of.h>
  23#include <linux/delay.h>
  24#include <linux/io.h>
  25#include <linux/firmware.h>
  26
  27#include "gs_fpgaboot.h"
  28#include "io.h"
  29
  30#define DEVICE_NAME "device"
  31#define CLASS_NAME  "fpgaboot"
  32
  33static u8 bits_magic[] = {
  34        0x0, 0x9, 0xf, 0xf0, 0xf, 0xf0,
  35        0xf, 0xf0, 0xf, 0xf0, 0x0, 0x0, 0x1};
  36
  37/* fake device for request_firmware */
  38static struct platform_device   *firmware_pdev;
  39
  40static char     *file = "xlinx_fpga_firmware.bit";
  41module_param(file, charp, 0444);
  42MODULE_PARM_DESC(file, "Xilinx FPGA firmware file.");
  43
  44static void read_bitstream(char *bitdata, char *buf, int *offset, int rdsize)
  45{
  46        memcpy(buf, bitdata + *offset, rdsize);
  47        *offset += rdsize;
  48}
  49
  50static void readinfo_bitstream(char *bitdata, char *buf, int *offset)
  51{
  52        char tbuf[64];
  53        s32 len;
  54
  55        /* read section char */
  56        read_bitstream(bitdata, tbuf, offset, 1);
  57
  58        /* read length */
  59        read_bitstream(bitdata, tbuf, offset, 2);
  60
  61        len = tbuf[0] << 8 | tbuf[1];
  62
  63        read_bitstream(bitdata, buf, offset, len);
  64        buf[len] = '\0';
  65}
  66
  67/*
  68 * read bitdata length
  69 */
  70static int readlength_bitstream(char *bitdata, int *lendata, int *offset)
  71{
  72        char tbuf[64];
  73
  74        /* read section char */
  75        read_bitstream(bitdata, tbuf, offset, 1);
  76
  77        /* make sure it is section 'e' */
  78        if (tbuf[0] != 'e') {
  79                pr_err("error: length section is not 'e', but %c\n", tbuf[0]);
  80                return -1;
  81        }
  82
  83        /* read 4bytes length */
  84        read_bitstream(bitdata, tbuf, offset, 4);
  85
  86        *lendata = tbuf[0] << 24 | tbuf[1] << 16 |
  87                tbuf[2] << 8 | tbuf[3];
  88
  89        return 0;
  90}
  91
  92/*
  93 * read first 13 bytes to check bitstream magic number
  94 */
  95static int readmagic_bitstream(char *bitdata, int *offset)
  96{
  97        char buf[13];
  98        int r;
  99
 100        read_bitstream(bitdata, buf, offset, 13);
 101        r = memcmp(buf, bits_magic, 13);
 102        if (r) {
 103                pr_err("error: corrupted header");
 104                return -1;
 105        }
 106        pr_info("bitstream file magic number Ok\n");
 107
 108        *offset = 13;   /* magic length */
 109
 110        return 0;
 111}
 112
 113/*
 114 * NOTE: supports only bitstream format
 115 */
 116static enum fmt_image get_imageformat(struct fpgaimage *fimage)
 117{
 118        return f_bit;
 119}
 120
 121static void gs_print_header(struct fpgaimage *fimage)
 122{
 123        pr_info("file: %s\n", fimage->filename);
 124        pr_info("part: %s\n", fimage->part);
 125        pr_info("date: %s\n", fimage->date);
 126        pr_info("time: %s\n", fimage->time);
 127        pr_info("lendata: %d\n", fimage->lendata);
 128}
 129
 130static void gs_read_bitstream(struct fpgaimage *fimage)
 131{
 132        char *bitdata;
 133        int offset;
 134
 135        offset = 0;
 136        bitdata = (char *)fimage->fw_entry->data;
 137
 138        readmagic_bitstream(bitdata, &offset);
 139        readinfo_bitstream(bitdata, fimage->filename, &offset);
 140        readinfo_bitstream(bitdata, fimage->part, &offset);
 141        readinfo_bitstream(bitdata, fimage->date, &offset);
 142        readinfo_bitstream(bitdata, fimage->time, &offset);
 143        readlength_bitstream(bitdata, &fimage->lendata, &offset);
 144
 145        fimage->fpgadata = bitdata + offset;
 146}
 147
 148static int gs_read_image(struct fpgaimage *fimage)
 149{
 150        int img_fmt;
 151
 152        img_fmt = get_imageformat(fimage);
 153
 154        switch (img_fmt) {
 155        case f_bit:
 156                pr_info("image is bitstream format\n");
 157                gs_read_bitstream(fimage);
 158                break;
 159        default:
 160                pr_err("unsupported fpga image format\n");
 161                return -1;
 162        }
 163
 164        gs_print_header(fimage);
 165
 166        return 0;
 167}
 168
 169static int gs_load_image(struct fpgaimage *fimage, char *fw_file)
 170{
 171        int err;
 172
 173        pr_info("load fpgaimage %s\n", fw_file);
 174
 175        err = request_firmware(&fimage->fw_entry, fw_file, &firmware_pdev->dev);
 176        if (err != 0) {
 177                pr_err("firmware %s is missing, cannot continue.\n", fw_file);
 178                return err;
 179        }
 180
 181        return 0;
 182}
 183
 184static int gs_download_image(struct fpgaimage *fimage, enum wbus bus_bytes)
 185{
 186        char *bitdata;
 187        int size, i, cnt;
 188
 189        cnt = 0;
 190        bitdata = (char *)fimage->fpgadata;
 191        size = fimage->lendata;
 192
 193#ifdef DEBUG_FPGA
 194        print_hex_dump_bytes("bitfile sample: ", DUMP_PREFIX_OFFSET,
 195                             bitdata, 0x100);
 196#endif /* DEBUG_FPGA */
 197        if (!xl_supported_prog_bus_width(bus_bytes)) {
 198                pr_err("unsupported program bus width %d\n",
 199                       bus_bytes);
 200                return -1;
 201        }
 202
 203        /* Bring csi_b, rdwr_b Low and program_b High */
 204        xl_program_b(1);
 205        xl_rdwr_b(0);
 206        xl_csi_b(0);
 207
 208        /* Configuration reset */
 209        xl_program_b(0);
 210        msleep(20);
 211        xl_program_b(1);
 212
 213        /* Wait for Device Initialization */
 214        while (xl_get_init_b() == 0)
 215                ;
 216
 217        pr_info("device init done\n");
 218
 219        for (i = 0; i < size; i += bus_bytes)
 220                xl_shift_bytes_out(bus_bytes, bitdata + i);
 221
 222        pr_info("program done\n");
 223
 224        /* Check INIT_B */
 225        if (xl_get_init_b() == 0) {
 226                pr_err("init_b 0\n");
 227                return -1;
 228        }
 229
 230        while (xl_get_done_b() == 0) {
 231                if (cnt++ > MAX_WAIT_DONE) {
 232                        pr_err("init_B %d\n", xl_get_init_b());
 233                        break;
 234                }
 235        }
 236
 237        if (cnt > MAX_WAIT_DONE) {
 238                pr_err("fpga download fail\n");
 239                return -1;
 240        }
 241
 242        pr_info("download fpgaimage\n");
 243
 244        /* Compensate for Special Startup Conditions */
 245        xl_shift_cclk(8);
 246
 247        return 0;
 248}
 249
 250static int gs_release_image(struct fpgaimage *fimage)
 251{
 252        release_firmware(fimage->fw_entry);
 253        pr_info("release fpgaimage\n");
 254
 255        return 0;
 256}
 257
 258/*
 259 * NOTE: supports systemmap parallel programming
 260 */
 261static int gs_set_download_method(struct fpgaimage *fimage)
 262{
 263        pr_info("set program method\n");
 264
 265        fimage->dmethod = m_systemmap;
 266
 267        pr_info("systemmap program method\n");
 268
 269        return 0;
 270}
 271
 272static int init_driver(void)
 273{
 274        firmware_pdev = platform_device_register_simple("fpgaboot", -1,
 275                                                        NULL, 0);
 276        return PTR_ERR_OR_ZERO(firmware_pdev);
 277}
 278
 279static int gs_fpgaboot(void)
 280{
 281        int err;
 282        struct fpgaimage        *fimage;
 283
 284        fimage = kmalloc(sizeof(*fimage), GFP_KERNEL);
 285        if (!fimage)
 286                return -ENOMEM;
 287
 288        err = gs_load_image(fimage, file);
 289        if (err) {
 290                pr_err("gs_load_image error\n");
 291                goto err_out1;
 292        }
 293
 294        err = gs_read_image(fimage);
 295        if (err) {
 296                pr_err("gs_read_image error\n");
 297                goto err_out2;
 298        }
 299
 300        err = gs_set_download_method(fimage);
 301        if (err) {
 302                pr_err("gs_set_download_method error\n");
 303                goto err_out2;
 304        }
 305
 306        err = gs_download_image(fimage, bus_2byte);
 307        if (err) {
 308                pr_err("gs_download_image error\n");
 309                goto err_out2;
 310        }
 311
 312        err = gs_release_image(fimage);
 313        if (err) {
 314                pr_err("gs_release_image error\n");
 315                goto err_out1;
 316        }
 317
 318        kfree(fimage);
 319        return 0;
 320
 321err_out2:
 322        err = gs_release_image(fimage);
 323        if (err)
 324                pr_err("gs_release_image error\n");
 325err_out1:
 326        kfree(fimage);
 327
 328        return -1;
 329}
 330
 331static int __init gs_fpgaboot_init(void)
 332{
 333        int err;
 334
 335        pr_info("FPGA DOWNLOAD --->\n");
 336
 337        pr_info("FPGA image file name: %s\n", file);
 338
 339        err = init_driver();
 340        if (err) {
 341                pr_err("FPGA DRIVER INIT FAIL!!\n");
 342                return err;
 343        }
 344
 345        err = xl_init_io();
 346        if (err) {
 347                pr_err("GPIO INIT FAIL!!\n");
 348                goto errout;
 349        }
 350
 351        err = gs_fpgaboot();
 352        if (err) {
 353                pr_err("FPGA DOWNLOAD FAIL!!\n");
 354                goto errout;
 355        }
 356
 357        pr_info("FPGA DOWNLOAD DONE <---\n");
 358
 359        return 0;
 360
 361errout:
 362        platform_device_unregister(firmware_pdev);
 363
 364        return err;
 365}
 366
 367static void __exit gs_fpgaboot_exit(void)
 368{
 369        platform_device_unregister(firmware_pdev);
 370        pr_info("FPGA image download module removed\n");
 371}
 372
 373module_init(gs_fpgaboot_init);
 374module_exit(gs_fpgaboot_exit);
 375
 376MODULE_AUTHOR("Insop Song");
 377MODULE_DESCRIPTION("Xlinix FPGA firmware download");
 378MODULE_LICENSE("GPL");
 379