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