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