/*
 * 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 <sparse_format.h>

#include <linux/mtd/mtd.h>
#include <jffs2/jffs2.h>
#include <nand.h>

static char *response_str;

struct fb_nand_sparse {
	struct mtd_info		*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, char *response,
			  struct mtd_info **nand,
			  struct part_info **part)
{
	struct mtd_device *dev;
	int ret;
	u8 pnum;

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

	ret = find_dev_and_part(partname, &dev, &pnum, part);
	if (ret) {
		error("cannot find partition: '%s'", partname);
		fastboot_fail(response_str, "cannot find partition");
		return ret;
	}

	if (dev->id->type != MTD_DEV_TYPE_NAND) {
		error("partition '%s' is not stored on a NAND device",
		      partname);
		fastboot_fail(response_str, "not a NAND device");
		return -EINVAL;
	}

	*mtd = nand_info[dev->id->num];

	return 0;
}

static int _fb_nand_erase(struct mtd_info *mtd, 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(mtd, &opts);
	if (ret)
		return ret;

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

	return 0;
}

static int _fb_nand_write(struct mtd_info *mtd, struct part_info *part,
			  void *buffer, unsigned int offset,
			  unsigned int length, size_t *written)
{
	int flags = WITH_WR_VERIFY;

#ifdef CONFIG_FASTBOOT_FLASH_NAND_TRIMFFS
	flags |= WITH_DROP_FFS;
#endif

	return nand_write_skip_bad(mtd, offset, &length, written,
				   part->size - (offset - part->offset),
				   buffer, flags);
}

static int fb_nand_sparse_write(struct sparse_storage *storage,
				void *priv,
				unsigned int offset,
				unsigned int size,
				char *data)
{
	struct fb_nand_sparse *sparse = priv;
	size_t written;
	int ret;

	ret = _fb_nand_write(sparse->nand, sparse->part, data,
			     offset * storage->block_sz,
			     size * storage->block_sz, &written);
	if (ret < 0) {
		printf("Failed to write sparse chunk\n");
		return ret;
	}

	return written / storage->block_sz;
}

void fb_nand_flash_write(const char *partname, unsigned int session_id,
			 void *download_buffer, unsigned int download_bytes,
			 char *response)
{
	struct part_info *part;
	struct mtd_info *mtd = NULL;
	int ret;

	/* initialize the response buffer */
	response_str = response;

	ret = fb_nand_lookup(partname, response, &mtd, &part);
	if (ret) {
		error("invalid NAND device");
		fastboot_fail(response_str, "invalid NAND device");
		return;
	}

	ret = board_fastboot_write_partition_setup(part->name);
	if (ret)
		return;

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

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

		sparse.block_sz = mtd->writesize;
		sparse.start = part->offset / sparse.block_sz;
		sparse.size = part->size  / sparse.block_sz;
		sparse.name = part->name;
		sparse.write = fb_nand_sparse_write;

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

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

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

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

	fastboot_okay(response_str, "");
}

void fb_nand_erase(const char *partname, char *response)
{
	struct part_info *part;
	struct mtd_info *mtd = NULL;
	int ret;

	/* initialize the response buffer */
	response_str = response;

	ret = fb_nand_lookup(partname, response, &mtd, &part);
	if (ret) {
		error("invalid NAND device");
		fastboot_fail(response_str, "invalid NAND device");
		return;
	}

	ret = board_fastboot_erase_partition_setup(part->name);
	if (ret)
		return;

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

	fastboot_okay(response_str, "");
}
