/*
 * Copyright 2014 Broadcom Corporation.
 * Copyright 2015 Free Electrons.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <config.h>
#include <common.h>

/* #include <fastboot.h> */
/*#include <image-sparse.h> */
#include <aboot.h>
#include <linux/mtd/mtd.h>
#include <jffs2/jffs2.h>
#include <nand.h>
#include <fb_fastboot.h>
#include <amlogic/aml_nand.h>

struct fb_nand_sparse {
	nand_info_t	*nand;
	struct part_info	*part;
};

__weak int board_fastboot_erase_partition_setup(char *name)
{
	return 0;
}

__weak int board_fastboot_write_partition_setup(char *name)
{
	return 0;
}

static int fb_nand_lookup(const char *partname,
			  nand_info_t **nand,
			  struct part_info **part)
{
#ifdef CONFIG_CMD_MTDPARTS
	struct mtd_device *dev;
	int ret;
	u8 pnum;

	ret = mtdparts_init();
	if (ret) {
		error("Cannot initialize MTD partitions\n");
		fastboot_fail("cannot init mtdparts");
		return ret;
	}

	if (strcmp(partname, "dtb") == 0)
		return 0;
	ret = find_dev_and_part(partname, &dev, &pnum, part);
	if (ret) {
		error("cannot find partition: '%s'", partname);
		fastboot_fail("cannot find partition");
		return ret;
	}
#ifndef CONFIFG_AML_MTDPART
	if (dev->id->type != MTD_DEV_TYPE_NAND) {
		error("partition '%s' is not stored on a NAND device",
		      partname);
		fastboot_fail("not a NAND device");
		return -EINVAL;
	}
	*nand = get_nand_dev_by_index(dev->id->num);
#else
	if (strcmp(partname, "bootloader") == 0)
		*nand = get_nand_dev_by_index(0);
	else
		*nand = get_nand_dev_by_index(1);
#endif
	return 0;
#else
	error("%s,\n");
	return -1;
#endif
}

static int _fb_nand_erase(nand_info_t *nand, struct part_info *part)
{
	nand_erase_options_t opts;
	int ret;

	memset(&opts, 0, sizeof(opts));
	opts.offset = part->offset;
	opts.length = part->size;
	opts.quiet = 1;

	printf("Erasing blocks 0x%llx to 0x%llx\n",
	       part->offset, part->offset + part->size);

	ret = nand_erase_opts(nand, &opts);
	if (ret)
		return ret;

	printf("........ erased 0x%llx bytes from '%s'\n",
	       part->size, part->name);

	return 0;
}

static int _fb_nand_write(nand_info_t *nand, struct part_info *part,
			  void *buffer, unsigned int offset,
			  unsigned int length, size_t *written)
{
	/* int flags = WITH_WR_VERIFY; */
	int flags = 0;
	size_t len = 0;

#ifdef CONFIG_FASTBOOT_FLASH_NAND_TRIMFFS
	flags |= WITH_DROP_FFS;
#endif

	len = length;
	return nand_write_skip_bad(nand, offset, &len, written,
				   part->size - (offset - part->offset),
				   (u_char *)buffer, flags);
}

static lbaint_t fb_nand_sparse_write(struct sparse_storage *info,
		lbaint_t blk, lbaint_t blkcnt, const void *buffer)
{
	struct fb_nand_sparse *sparse = info->priv;
	size_t written;
	int ret;

	ret = _fb_nand_write(sparse->nand, sparse->part, (void *)buffer,
			     blk * info->blksz,
			     blkcnt * info->blksz, &written);
	if (ret < 0) {
		printf("Failed to write sparse chunk\n");
		return ret;
	}

/* TODO - verify that the value "written" includes the "bad-blocks" ... */

	/*
	 * the return value must be 'blkcnt' ("good-blocks") plus the
	 * number of "bad-blocks" encountered within this space...
	 */
	return written / info->blksz;
}

static lbaint_t fb_nand_sparse_reserve(struct sparse_storage *info,
		lbaint_t blk, lbaint_t blkcnt)
{
	int bad_blocks = 0;

/*
 * TODO - implement a function to determine the total number
 * of blocks which must be used in order to reserve the specified
 * number ("blkcnt") of "good-blocks", starting at "blk"...
 * ( possibly something like the "check_skip_len()" function )
 */

	/*
	 * the return value must be 'blkcnt' ("good-blocks") plus the
	 * number of "bad-blocks" encountered within this space...
	 */
	return blkcnt + bad_blocks;
}

int abr_wear_leveling_reset_pages(void);

void fb_nand_flash_write(const char *cmd, void *download_buffer,
			unsigned int download_bytes)
{
	struct part_info *part;
	nand_info_t *nand = NULL;
	int ret, err;
	int copy_num = 0, i = 0;
	u64 off = 0;
	size_t rwsize = 0, limit = 0;

	ret = fb_nand_lookup(cmd, &nand, &part);

	if (ret) {
		error(" invalid NAND device");
		fastboot_fail(" invalid NAND device");
		return;
	}

	if (strcmp(cmd, "bootloader") == 0) {
		bool success = false;
#ifdef CONFIG_DISCRETE_BOOTLOADER
		rwsize = download_bytes;
		copy_num = CONFIG_BL2_COPY_NUM;
		limit = nand->size / CONFIG_BL2_COPY_NUM;
#else
		rwsize = download_bytes;
		copy_num = get_boot_num(nand, rwsize);
		limit = nand->size / copy_num;
#endif
		for (i = 0; i < copy_num; i++) {
			printf("off = 0x%llx,wsize = 0x%lx\n", off, rwsize);
			err = nand_write_skip_bad(nand, off, &rwsize,
						NULL, limit,
						(u_char *)download_buffer, 0);
			if (err) {
				rwsize = download_bytes;
				error("bootloader write err,code = %d\n",err);
			} else {
				success = true;
			}
			off += nand->size / copy_num;
		}
		if (success) {
			fastboot_okay("write bootloader");
		} else {
			fastboot_fail("failed to write bootloader");
		}
		return;
	}
#ifdef CONFIG_DISCRETE_BOOTLOADER
	if (strcmp(cmd, "tpl") == 0) {
		copy_num = CONFIG_TPL_COPY_NUM;
		rwsize = download_bytes;
		limit = CONFIG_TPL_SIZE_PER_COPY;
		off = 1024 * nand->writesize +
			RESERVED_BLOCK_NUM * nand->erasesize;

		for (i = 0; i < copy_num; i++) {
			printf("off = 0x%llx,wsize = 0x%lx\n", off, rwsize);
			err = nand_write_skip_bad(nand, off, &rwsize,
						NULL, limit,
						(u_char *)download_buffer, 0);
			if (err) {
				rwsize = download_bytes;
				error("tpl write err,code = %d\n",err);
			}
			off += CONFIG_TPL_SIZE_PER_COPY;
		}
#ifdef CONFIG_ABR_WEAR_LEVELING
		if ((err = abr_wear_leveling_reset_pages())) {
			error("failed to reset abr wear leveling pages");
		}
#endif
		fastboot_okay("write tpl");
		return;
	}
#endif
#ifndef CONFIG_SHORT_RSV
	if (strcmp(cmd, "dtb") == 0) {
		ret = amlnf_dtb_save((u8 *)download_buffer, download_bytes);
		printf("Flashing dtb...len:0x%x\n", download_bytes);
		if (ret) {
			printf("write dtb fail,result code %d\n", ret);
			fastboot_fail("write dtb");
		} else {
			fastboot_okay("write dtb");
		}
		return;
	}
#endif
	ret = board_fastboot_write_partition_setup(part->name);
	if (ret)
		return;

	if (is_sparse_image(download_buffer)) {
		struct fb_nand_sparse sparse_priv;
		struct sparse_storage sparse;

		sparse_priv.nand = nand;
		sparse_priv.part = part;

		sparse.blksz = nand->writesize;
		sparse.start = part->offset / sparse.blksz;
		sparse.size = part->size / sparse.blksz;
		sparse.write = fb_nand_sparse_write;
		sparse.reserve = fb_nand_sparse_reserve;

		printf("Flashing sparse image at offset " LBAFU "\n",
		       sparse.start);

		sparse.priv = &sparse_priv;
		ret = write_sparse_image(&sparse, cmd, download_buffer,
				   download_bytes);
	} else {
		printf("Flashing raw image at offset 0x%llx\n",
		       part->offset);

		ret = _fb_nand_write(nand, part, download_buffer, part->offset,
				     download_bytes, NULL);

		printf("........ wrote %u bytes to '%s'\n",
		       download_bytes, part->name);
	}

	if (ret) {
		fastboot_fail("error writing the image");
		return;
	}

	fastboot_okay("");
}

void fb_nand_erase(const char *cmd, void *download_buffer)
{
	struct part_info *part;
	nand_info_t *nand = NULL;
	int ret;

	ret = fb_nand_lookup(cmd, &nand, &part);
	if (ret) {
		error("invalid NAND device");
		fastboot_fail("invalid NAND device");
		return;
	}

#ifndef CONFIG_SHORT_RSV
	if (strcmp(cmd, "dtb") == 0) {
		ret = amlnf_dtb_erase();
		if (ret) {
			printf("erase dtb fail,result code %d\n", ret);
			fastboot_fail("erase dtb");
		} else {
			fastboot_okay("erase dtb");
		}
		return;
	}
#endif
	ret = board_fastboot_erase_partition_setup(part->name);
	if (ret)
		return;

	ret = _fb_nand_erase(nand, part);
	if (ret) {
		error("failed erasing from device %s", nand->name);
		fastboot_fail("failed erasing from device");
		return;
	}

	fastboot_okay("");
}
