/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/device.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/firmware.h>
#include <asm/unaligned.h>

#include "gs_fpgaboot.h"
#include "io.h"

#define DEVICE_NAME "device"
#define CLASS_NAME  "fpgaboot"

static u8 bits_magic[] = {
	0x0, 0x9, 0xf, 0xf0, 0xf, 0xf0,
	0xf, 0xf0, 0xf, 0xf0, 0x0, 0x0, 0x1};

/* fake device for request_firmware */
static struct platform_device	*firmware_pdev;

static char	*file = "xlinx_fpga_firmware.bit";
module_param(file, charp, 0444);
MODULE_PARM_DESC(file, "Xilinx FPGA firmware file.");

static void read_bitstream(u8 *bitdata, u8 *buf, int *offset, int rdsize)
{
	memcpy(buf, bitdata + *offset, rdsize);
	*offset += rdsize;
}

static int readinfo_bitstream(u8 *bitdata, u8 *buf, int size, int *offset)
{
	u8 tbuf[2];
	u16 len;

	/* read section char */
	read_bitstream(bitdata, tbuf, offset, 1);

	/* read length */
	read_bitstream(bitdata, tbuf, offset, 2);

	len = get_unaligned_be16(tbuf);
	if (len >= size) {
		pr_err("error: readinfo buffer too small\n");
		return -EINVAL;
	}

	read_bitstream(bitdata, buf, offset, len);
	buf[len] = '\0';

	return 0;
}

/*
 * read bitdata length
 */
static int readlength_bitstream(u8 *bitdata, int *lendata, int *offset)
{
	u8 tbuf[4];

	/* read section char */
	read_bitstream(bitdata, tbuf, offset, 1);

	/* make sure it is section 'e' */
	if (tbuf[0] != 'e') {
		pr_err("error: length section is not 'e', but %c\n", tbuf[0]);
		return -EINVAL;
	}

	/* read 4bytes length */
	read_bitstream(bitdata, tbuf, offset, 4);

	*lendata = get_unaligned_be32(tbuf);

	return 0;
}

/*
 * read first 13 bytes to check bitstream magic number
 */
static int readmagic_bitstream(u8 *bitdata, int *offset)
{
	u8 buf[13];
	int r;

	read_bitstream(bitdata, buf, offset, 13);
	r = memcmp(buf, bits_magic, 13);
	if (r) {
		pr_err("error: corrupted header");
		return -EINVAL;
	}
	pr_info("bitstream file magic number Ok\n");

	*offset = 13;	/* magic length */

	return 0;
}

/*
 * NOTE: supports only bitstream format
 */
static enum fmt_image get_imageformat(void)
{
	return f_bit;
}

static void gs_print_header(struct fpgaimage *fimage)
{
	pr_info("file: %s\n", fimage->filename);
	pr_info("part: %s\n", fimage->part);
	pr_info("date: %s\n", fimage->date);
	pr_info("time: %s\n", fimage->time);
	pr_info("lendata: %d\n", fimage->lendata);
}

static int gs_read_bitstream(struct fpgaimage *fimage)
{
	u8 *bitdata;
	int offset;
	int err;

	offset = 0;
	bitdata = (u8 *)fimage->fw_entry->data;

	err = readmagic_bitstream(bitdata, &offset);
	if (err)
		return err;

	err = readinfo_bitstream(bitdata, fimage->filename, MAX_STR, &offset);
	if (err)
		return err;
	err = readinfo_bitstream(bitdata, fimage->part, MAX_STR, &offset);
	if (err)
		return err;
	err = readinfo_bitstream(bitdata, fimage->date, MAX_STR, &offset);
	if (err)
		return err;
	err = readinfo_bitstream(bitdata, fimage->time, MAX_STR, &offset);
	if (err)
		return err;

	err = readlength_bitstream(bitdata, &fimage->lendata, &offset);
	if (err)
		return err;

	fimage->fpgadata = bitdata + offset;

	return 0;
}

static int gs_read_image(struct fpgaimage *fimage)
{
	int img_fmt;
	int err;

	img_fmt = get_imageformat();

	switch (img_fmt) {
	case f_bit:
		pr_info("image is bitstream format\n");
		err = gs_read_bitstream(fimage);
		if (err)
			return err;
		break;
	default:
		pr_err("unsupported fpga image format\n");
		return -EINVAL;
	}

	gs_print_header(fimage);

	return 0;
}

static int gs_load_image(struct fpgaimage *fimage, char *fw_file)
{
	int err;

	pr_info("load fpgaimage %s\n", fw_file);

	err = request_firmware(&fimage->fw_entry, fw_file, &firmware_pdev->dev);
	if (err != 0) {
		pr_err("firmware %s is missing, cannot continue.\n", fw_file);
		return err;
	}

	return 0;
}

static int gs_download_image(struct fpgaimage *fimage, enum wbus bus_bytes)
{
	u8 *bitdata;
	int size, i, cnt;

	cnt = 0;
	bitdata = (u8 *)fimage->fpgadata;
	size = fimage->lendata;

#ifdef DEBUG_FPGA
	print_hex_dump_bytes("bitfile sample: ", DUMP_PREFIX_OFFSET,
			     bitdata, 0x100);
#endif /* DEBUG_FPGA */
	if (!xl_supported_prog_bus_width(bus_bytes)) {
		pr_err("unsupported program bus width %d\n",
		       bus_bytes);
		return -EINVAL;
	}

	/* Bring csi_b, rdwr_b Low and program_b High */
	xl_program_b(1);
	xl_rdwr_b(0);
	xl_csi_b(0);

	/* Configuration reset */
	xl_program_b(0);
	msleep(20);
	xl_program_b(1);

	/* Wait for Device Initialization */
	while (xl_get_init_b() == 0)
		;

	pr_info("device init done\n");

	for (i = 0; i < size; i += bus_bytes)
		xl_shift_bytes_out(bus_bytes, bitdata + i);

	pr_info("program done\n");

	/* Check INIT_B */
	if (xl_get_init_b() == 0) {
		pr_err("init_b 0\n");
		return -EIO;
	}

	while (xl_get_done_b() == 0) {
		if (cnt++ > MAX_WAIT_DONE) {
			pr_err("init_B %d\n", xl_get_init_b());
			break;
		}
	}

	if (cnt > MAX_WAIT_DONE) {
		pr_err("fpga download fail\n");
		return -EIO;
	}

	pr_info("download fpgaimage\n");

	/* Compensate for Special Startup Conditions */
	xl_shift_cclk(8);

	return 0;
}

static int gs_release_image(struct fpgaimage *fimage)
{
	release_firmware(fimage->fw_entry);
	pr_info("release fpgaimage\n");

	return 0;
}

/*
 * NOTE: supports systemmap parallel programming
 */
static int gs_set_download_method(struct fpgaimage *fimage)
{
	pr_info("set program method\n");

	fimage->dmethod = m_systemmap;

	pr_info("systemmap program method\n");

	return 0;
}

static int init_driver(void)
{
	firmware_pdev = platform_device_register_simple("fpgaboot", -1,
							NULL, 0);
	return PTR_ERR_OR_ZERO(firmware_pdev);
}

static int gs_fpgaboot(void)
{
	int err;
	struct fpgaimage	*fimage;

	fimage = kmalloc(sizeof(*fimage), GFP_KERNEL);
	if (!fimage)
		return -ENOMEM;

	err = gs_load_image(fimage, file);
	if (err) {
		pr_err("gs_load_image error\n");
		goto err_out1;
	}

	err = gs_read_image(fimage);
	if (err) {
		pr_err("gs_read_image error\n");
		goto err_out2;
	}

	err = gs_set_download_method(fimage);
	if (err) {
		pr_err("gs_set_download_method error\n");
		goto err_out2;
	}

	err = gs_download_image(fimage, bus_2byte);
	if (err) {
		pr_err("gs_download_image error\n");
		goto err_out2;
	}

	err = gs_release_image(fimage);
	if (err) {
		pr_err("gs_release_image error\n");
		goto err_out1;
	}

	kfree(fimage);
	return 0;

err_out2:
	err = gs_release_image(fimage);
	if (err)
		pr_err("gs_release_image error\n");
err_out1:
	kfree(fimage);

	return err;
}

static int __init gs_fpgaboot_init(void)
{
	int err;

	pr_info("FPGA DOWNLOAD --->\n");

	pr_info("FPGA image file name: %s\n", file);

	err = init_driver();
	if (err) {
		pr_err("FPGA DRIVER INIT FAIL!!\n");
		return err;
	}

	err = xl_init_io();
	if (err) {
		pr_err("GPIO INIT FAIL!!\n");
		goto errout;
	}

	err = gs_fpgaboot();
	if (err) {
		pr_err("FPGA DOWNLOAD FAIL!!\n");
		goto errout;
	}

	pr_info("FPGA DOWNLOAD DONE <---\n");

	return 0;

errout:
	platform_device_unregister(firmware_pdev);

	return err;
}

static void __exit gs_fpgaboot_exit(void)
{
	platform_device_unregister(firmware_pdev);
	pr_info("FPGA image download module removed\n");
}

module_init(gs_fpgaboot_init);
module_exit(gs_fpgaboot_exit);

MODULE_AUTHOR("Insop Song");
MODULE_DESCRIPTION("Xlinix FPGA firmware download");
MODULE_LICENSE("GPL");
