/*
 * Freescale i.MX28 image generator
 *
 * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
 * on behalf of DENX Software Engineering GmbH
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "compiler.h"

/*
 * Default BCB layout.
 *
 * TWEAK this if you have blown any OCOTP fuses.
 */
#define	STRIDE_PAGES		64
#define	STRIDE_COUNT		4

/*
 * Layout for 256Mb big NAND with 2048b page size, 64b OOB size and
 * 128kb erase size.
 *
 * TWEAK this if you have different kind of NAND chip.
 */
uint32_t nand_writesize = 2048;
uint32_t nand_oobsize = 64;
uint32_t nand_erasesize = 128 * 1024;

/*
 * Sector on which the SigmaTel boot partition (0x53) starts.
 */
uint32_t sd_sector = 2048;

/*
 * Each of the U-Boot bootstreams is at maximum 1MB big.
 *
 * TWEAK this if, for some wild reason, you need to boot bigger image.
 */
#define	MAX_BOOTSTREAM_SIZE	(1 * 1024 * 1024)

/* i.MX28 NAND controller-specific constants. DO NOT TWEAK! */
#define	MXS_NAND_DMA_DESCRIPTOR_COUNT		4
#define	MXS_NAND_CHUNK_DATA_CHUNK_SIZE		512
#define	MXS_NAND_METADATA_SIZE			10
#define	MXS_NAND_COMMAND_BUFFER_SIZE		32

struct mx28_nand_fcb {
	uint32_t		checksum;
	uint32_t		fingerprint;
	uint32_t		version;
	struct {
		uint8_t			data_setup;
		uint8_t			data_hold;
		uint8_t			address_setup;
		uint8_t			dsample_time;
		uint8_t			nand_timing_state;
		uint8_t			rea;
		uint8_t			rloh;
		uint8_t			rhoh;
	}			timing;
	uint32_t		page_data_size;
	uint32_t		total_page_size;
	uint32_t		sectors_per_block;
	uint32_t		number_of_nands;		/* Ignored */
	uint32_t		total_internal_die;		/* Ignored */
	uint32_t		cell_type;			/* Ignored */
	uint32_t		ecc_block_n_ecc_type;
	uint32_t		ecc_block_0_size;
	uint32_t		ecc_block_n_size;
	uint32_t		ecc_block_0_ecc_type;
	uint32_t		metadata_bytes;
	uint32_t		num_ecc_blocks_per_page;
	uint32_t		ecc_block_n_ecc_level_sdk;	/* Ignored */
	uint32_t		ecc_block_0_size_sdk;		/* Ignored */
	uint32_t		ecc_block_n_size_sdk;		/* Ignored */
	uint32_t		ecc_block_0_ecc_level_sdk;	/* Ignored */
	uint32_t		num_ecc_blocks_per_page_sdk;	/* Ignored */
	uint32_t		metadata_bytes_sdk;		/* Ignored */
	uint32_t		erase_threshold;
	uint32_t		boot_patch;
	uint32_t		patch_sectors;
	uint32_t		firmware1_starting_sector;
	uint32_t		firmware2_starting_sector;
	uint32_t		sectors_in_firmware1;
	uint32_t		sectors_in_firmware2;
	uint32_t		dbbt_search_area_start_address;
	uint32_t		badblock_marker_byte;
	uint32_t		badblock_marker_start_bit;
	uint32_t		bb_marker_physical_offset;
};

struct mx28_nand_dbbt {
	uint32_t		checksum;
	uint32_t		fingerprint;
	uint32_t		version;
	uint32_t		number_bb;
	uint32_t		number_2k_pages_bb;
};

struct mx28_nand_bbt {
	uint32_t		nand;
	uint32_t		number_bb;
	uint32_t		badblock[510];
};

struct mx28_sd_drive_info {
	uint32_t		chip_num;
	uint32_t		drive_type;
	uint32_t		tag;
	uint32_t		first_sector_number;
	uint32_t		sector_count;
};

struct mx28_sd_config_block {
	uint32_t			signature;
	uint32_t			primary_boot_tag;
	uint32_t			secondary_boot_tag;
	uint32_t			num_copies;
	struct mx28_sd_drive_info	drv_info[1];
};

static inline uint32_t mx28_nand_ecc_size_in_bits(uint32_t ecc_strength)
{
	return ecc_strength * 13;
}

static inline uint32_t mx28_nand_get_ecc_strength(uint32_t page_data_size,
						uint32_t page_oob_size)
{
	if (page_data_size == 2048)
		return 8;

	if (page_data_size == 4096) {
		if (page_oob_size == 128)
			return 8;

		if (page_oob_size == 218)
			return 16;
	}

	return 0;
}

static inline uint32_t mx28_nand_get_mark_offset(uint32_t page_data_size,
						uint32_t ecc_strength)
{
	uint32_t chunk_data_size_in_bits;
	uint32_t chunk_ecc_size_in_bits;
	uint32_t chunk_total_size_in_bits;
	uint32_t block_mark_chunk_number;
	uint32_t block_mark_chunk_bit_offset;
	uint32_t block_mark_bit_offset;

	chunk_data_size_in_bits = MXS_NAND_CHUNK_DATA_CHUNK_SIZE * 8;
	chunk_ecc_size_in_bits  = mx28_nand_ecc_size_in_bits(ecc_strength);

	chunk_total_size_in_bits =
			chunk_data_size_in_bits + chunk_ecc_size_in_bits;

	/* Compute the bit offset of the block mark within the physical page. */
	block_mark_bit_offset = page_data_size * 8;

	/* Subtract the metadata bits. */
	block_mark_bit_offset -= MXS_NAND_METADATA_SIZE * 8;

	/*
	 * Compute the chunk number (starting at zero) in which the block mark
	 * appears.
	 */
	block_mark_chunk_number =
			block_mark_bit_offset / chunk_total_size_in_bits;

	/*
	 * Compute the bit offset of the block mark within its chunk, and
	 * validate it.
	 */
	block_mark_chunk_bit_offset = block_mark_bit_offset -
			(block_mark_chunk_number * chunk_total_size_in_bits);

	if (block_mark_chunk_bit_offset > chunk_data_size_in_bits)
		return 1;

	/*
	 * Now that we know the chunk number in which the block mark appears,
	 * we can subtract all the ECC bits that appear before it.
	 */
	block_mark_bit_offset -=
		block_mark_chunk_number * chunk_ecc_size_in_bits;

	return block_mark_bit_offset;
}

static inline uint32_t mx28_nand_mark_byte_offset(void)
{
	uint32_t ecc_strength;
	ecc_strength = mx28_nand_get_ecc_strength(nand_writesize, nand_oobsize);
	return mx28_nand_get_mark_offset(nand_writesize, ecc_strength) >> 3;
}

static inline uint32_t mx28_nand_mark_bit_offset(void)
{
	uint32_t ecc_strength;
	ecc_strength = mx28_nand_get_ecc_strength(nand_writesize, nand_oobsize);
	return mx28_nand_get_mark_offset(nand_writesize, ecc_strength) & 0x7;
}

static uint32_t mx28_nand_block_csum(uint8_t *block, uint32_t size)
{
	uint32_t csum = 0;
	int i;

	for (i = 0; i < size; i++)
		csum += block[i];

	return csum ^ 0xffffffff;
}

static struct mx28_nand_fcb *mx28_nand_get_fcb(uint32_t size)
{
	struct mx28_nand_fcb *fcb;
	uint32_t bcb_size_bytes;
	uint32_t stride_size_bytes;
	uint32_t bootstream_size_pages;
	uint32_t fw1_start_page;
	uint32_t fw2_start_page;

	fcb = malloc(nand_writesize);
	if (!fcb) {
		printf("MX28 NAND: Unable to allocate FCB\n");
		return NULL;
	}

	memset(fcb, 0, nand_writesize);

	fcb->fingerprint =			0x20424346;
	fcb->version =				0x01000000;

	/*
	 * FIXME: These here are default values as found in kobs-ng. We should
	 * probably retrieve the data from NAND or something.
	 */
	fcb->timing.data_setup =		80;
	fcb->timing.data_hold =			60;
	fcb->timing.address_setup =		25;
	fcb->timing.dsample_time =		6;

	fcb->page_data_size =		nand_writesize;
	fcb->total_page_size =		nand_writesize + nand_oobsize;
	fcb->sectors_per_block =	nand_erasesize / nand_writesize;

	fcb->num_ecc_blocks_per_page =	(nand_writesize / 512) - 1;
	fcb->ecc_block_0_size =		512;
	fcb->ecc_block_n_size =		512;
	fcb->metadata_bytes =		10;

	if (nand_writesize == 2048) {
		fcb->ecc_block_n_ecc_type =		4;
		fcb->ecc_block_0_ecc_type =		4;
	} else if (nand_writesize == 4096) {
		if (nand_oobsize == 128) {
			fcb->ecc_block_n_ecc_type =	4;
			fcb->ecc_block_0_ecc_type =	4;
		} else if (nand_oobsize == 218) {
			fcb->ecc_block_n_ecc_type =	8;
			fcb->ecc_block_0_ecc_type =	8;
		}
	}

	if (fcb->ecc_block_n_ecc_type == 0) {
		printf("MX28 NAND: Unsupported NAND geometry\n");
		goto err;
	}

	fcb->boot_patch =			0;
	fcb->patch_sectors =			0;

	fcb->badblock_marker_byte =	mx28_nand_mark_byte_offset();
	fcb->badblock_marker_start_bit = mx28_nand_mark_bit_offset();
	fcb->bb_marker_physical_offset = nand_writesize;

	stride_size_bytes = STRIDE_PAGES * nand_writesize;
	bcb_size_bytes = stride_size_bytes * STRIDE_COUNT;

	bootstream_size_pages = (size + (nand_writesize - 1)) /
					nand_writesize;

	fw1_start_page = 2 * bcb_size_bytes / nand_writesize;
	fw2_start_page = (2 * bcb_size_bytes + MAX_BOOTSTREAM_SIZE) /
				nand_writesize;

	fcb->firmware1_starting_sector =	fw1_start_page;
	fcb->firmware2_starting_sector =	fw2_start_page;
	fcb->sectors_in_firmware1 =		bootstream_size_pages;
	fcb->sectors_in_firmware2 =		bootstream_size_pages;

	fcb->dbbt_search_area_start_address =	STRIDE_PAGES * STRIDE_COUNT;

	return fcb;

err:
	free(fcb);
	return NULL;
}

static struct mx28_nand_dbbt *mx28_nand_get_dbbt(void)
{
	struct mx28_nand_dbbt *dbbt;

	dbbt = malloc(nand_writesize);
	if (!dbbt) {
		printf("MX28 NAND: Unable to allocate DBBT\n");
		return NULL;
	}

	memset(dbbt, 0, nand_writesize);

	dbbt->fingerprint	= 0x54424244;
	dbbt->version		= 0x1;

	return dbbt;
}

static inline uint8_t mx28_nand_parity_13_8(const uint8_t b)
{
	uint32_t parity = 0, tmp;

	tmp = ((b >> 6) ^ (b >> 5) ^ (b >> 3) ^ (b >> 2)) & 1;
	parity |= tmp << 0;

	tmp = ((b >> 7) ^ (b >> 5) ^ (b >> 4) ^ (b >> 2) ^ (b >> 1)) & 1;
	parity |= tmp << 1;

	tmp = ((b >> 7) ^ (b >> 6) ^ (b >> 5) ^ (b >> 1) ^ (b >> 0)) & 1;
	parity |= tmp << 2;

	tmp = ((b >> 7) ^ (b >> 4) ^ (b >> 3) ^ (b >> 0)) & 1;
	parity |= tmp << 3;

	tmp = ((b >> 6) ^ (b >> 4) ^ (b >> 3) ^
		(b >> 2) ^ (b >> 1) ^ (b >> 0)) & 1;
	parity |= tmp << 4;

	return parity;
}

static uint8_t *mx28_nand_fcb_block(struct mx28_nand_fcb *fcb)
{
	uint8_t *block;
	uint8_t *ecc;
	int i;

	block = malloc(nand_writesize + nand_oobsize);
	if (!block) {
		printf("MX28 NAND: Unable to allocate FCB block\n");
		return NULL;
	}

	memset(block, 0, nand_writesize + nand_oobsize);

	/* Update the FCB checksum */
	fcb->checksum = mx28_nand_block_csum(((uint8_t *)fcb) + 4, 508);

	/* Figure 12-11. in iMX28RM, rev. 1, says FCB is at offset 12 */
	memcpy(block + 12, fcb, sizeof(struct mx28_nand_fcb));

	/* ECC is at offset 12 + 512 */
	ecc = block + 12 + 512;

	/* Compute the ECC parity */
	for (i = 0; i < sizeof(struct mx28_nand_fcb); i++)
		ecc[i] = mx28_nand_parity_13_8(block[i + 12]);

	return block;
}

static int mx28_nand_write_fcb(struct mx28_nand_fcb *fcb, char *buf)
{
	uint32_t offset;
	uint8_t *fcbblock;
	int ret = 0;
	int i;

	fcbblock = mx28_nand_fcb_block(fcb);
	if (!fcbblock)
		return -1;

	for (i = 0; i < STRIDE_PAGES * STRIDE_COUNT; i += STRIDE_PAGES) {
		offset = i * nand_writesize;
		memcpy(buf + offset, fcbblock, nand_writesize + nand_oobsize);
	}

	free(fcbblock);
	return ret;
}

static int mx28_nand_write_dbbt(struct mx28_nand_dbbt *dbbt, char *buf)
{
	uint32_t offset;
	int i = STRIDE_PAGES * STRIDE_COUNT;

	for (; i < 2 * STRIDE_PAGES * STRIDE_COUNT; i += STRIDE_PAGES) {
		offset = i * nand_writesize;
		memcpy(buf + offset, dbbt, sizeof(struct mx28_nand_dbbt));
	}

	return 0;
}

static int mx28_nand_write_firmware(struct mx28_nand_fcb *fcb, int infd,
					char *buf)
{
	int ret;
	off_t size;
	uint32_t offset1, offset2;

	size = lseek(infd, 0, SEEK_END);
	lseek(infd, 0, SEEK_SET);

	offset1 = fcb->firmware1_starting_sector * nand_writesize;
	offset2 = fcb->firmware2_starting_sector * nand_writesize;

	ret = read(infd, buf + offset1, size);
	if (ret != size)
		return -1;

	memcpy(buf + offset2, buf + offset1, size);

	return 0;
}

void usage(void)
{
	printf(
		"Usage: mxsboot [ops] <type> <infile> <outfile>\n"
		"Augment BootStream file with a proper header for i.MX28 boot\n"
		"\n"
		"  <type>	type of image:\n"
		"                 \"nand\" for NAND image\n"
		"                 \"sd\" for SD image\n"
		"  <infile>     input file, the u-boot.sb bootstream\n"
		"  <outfile>    output file, the bootable image\n"
		"\n");
	printf(
		"For NAND boot, these options are accepted:\n"
		"  -w <size>    NAND page size\n"
		"  -o <size>    NAND OOB size\n"
		"  -e <size>    NAND erase size\n"
		"\n"
		"For SD boot, these options are accepted:\n"
		"  -p <sector>  Sector where the SGTL partition starts\n"
	);
}

static int mx28_create_nand_image(int infd, int outfd)
{
	struct mx28_nand_fcb *fcb;
	struct mx28_nand_dbbt *dbbt;
	int ret = -1;
	char *buf;
	int size;
	ssize_t wr_size;

	size = nand_writesize * 512 + 2 * MAX_BOOTSTREAM_SIZE;

	buf = malloc(size);
	if (!buf) {
		printf("Can not allocate output buffer of %d bytes\n", size);
		goto err0;
	}

	memset(buf, 0, size);

	fcb = mx28_nand_get_fcb(MAX_BOOTSTREAM_SIZE);
	if (!fcb) {
		printf("Unable to compile FCB\n");
		goto err1;
	}

	dbbt = mx28_nand_get_dbbt();
	if (!dbbt) {
		printf("Unable to compile DBBT\n");
		goto err2;
	}

	ret = mx28_nand_write_fcb(fcb, buf);
	if (ret) {
		printf("Unable to write FCB to buffer\n");
		goto err3;
	}

	ret = mx28_nand_write_dbbt(dbbt, buf);
	if (ret) {
		printf("Unable to write DBBT to buffer\n");
		goto err3;
	}

	ret = mx28_nand_write_firmware(fcb, infd, buf);
	if (ret) {
		printf("Unable to write firmware to buffer\n");
		goto err3;
	}

	wr_size = write(outfd, buf, size);
	if (wr_size != size) {
		ret = -1;
		goto err3;
	}

	ret = 0;

err3:
	free(dbbt);
err2:
	free(fcb);
err1:
	free(buf);
err0:
	return ret;
}

static int mx28_create_sd_image(int infd, int outfd)
{
	int ret = -1;
	uint32_t *buf;
	int size;
	off_t fsize;
	ssize_t wr_size;
	struct mx28_sd_config_block *cb;

	fsize = lseek(infd, 0, SEEK_END);
	lseek(infd, 0, SEEK_SET);
	size = fsize + 4 * 512;

	buf = malloc(size);
	if (!buf) {
		printf("Can not allocate output buffer of %d bytes\n", size);
		goto err0;
	}

	ret = read(infd, (uint8_t *)buf + 4 * 512, fsize);
	if (ret != fsize) {
		ret = -1;
		goto err1;
	}

	cb = (struct mx28_sd_config_block *)buf;

	cb->signature = 0x00112233;
	cb->primary_boot_tag = 0x1;
	cb->secondary_boot_tag = 0x1;
	cb->num_copies = 1;
	cb->drv_info[0].chip_num = 0x0;
	cb->drv_info[0].drive_type = 0x0;
	cb->drv_info[0].tag = 0x1;
	cb->drv_info[0].first_sector_number = sd_sector + 4;
	cb->drv_info[0].sector_count = (size - 4) / 512;

	wr_size = write(outfd, buf, size);
	if (wr_size != size) {
		ret = -1;
		goto err1;
	}

	ret = 0;

err1:
	free(buf);
err0:
	return ret;
}

int parse_ops(int argc, char **argv)
{
	int i;
	int tmp;
	char *end;
	enum param {
		PARAM_WRITE,
		PARAM_OOB,
		PARAM_ERASE,
		PARAM_PART,
		PARAM_SD,
		PARAM_NAND
	};
	int type;

	if (argc < 4)
		return -1;

	for (i = 1; i < argc; i++) {
		if (!strncmp(argv[i], "-w", 2))
			type = PARAM_WRITE;
		else if (!strncmp(argv[i], "-o", 2))
			type = PARAM_OOB;
		else if (!strncmp(argv[i], "-e", 2))
			type = PARAM_ERASE;
		else if (!strncmp(argv[i], "-p", 2))
			type = PARAM_PART;
		else	/* SD/MMC */
			break;

		tmp = strtol(argv[++i], &end, 10);
		if (tmp % 2)
			return -1;
		if (tmp <= 0)
			return -1;

		if (type == PARAM_WRITE)
			nand_writesize = tmp;
		if (type == PARAM_OOB)
			nand_oobsize = tmp;
		if (type == PARAM_ERASE)
			nand_erasesize = tmp;
		if (type == PARAM_PART)
			sd_sector = tmp;
	}

	if (strcmp(argv[i], "sd") && strcmp(argv[i], "nand"))
		return -1;

	if (i + 3 != argc)
		return -1;

	return i;
}

int main(int argc, char **argv)
{
	int infd, outfd;
	int ret = 0;
	int offset;

	offset = parse_ops(argc, argv);
	if (offset < 0) {
		usage();
		ret = 1;
		goto err1;
	}

	infd = open(argv[offset + 1], O_RDONLY);
	if (infd < 0) {
		printf("Input BootStream file can not be opened\n");
		ret = 2;
		goto err1;
	}

	outfd = open(argv[offset + 2], O_CREAT | O_TRUNC | O_WRONLY,
					S_IRUSR | S_IWUSR);
	if (outfd < 0) {
		printf("Output file can not be created\n");
		ret = 3;
		goto err2;
	}

	if (!strcmp(argv[offset], "sd"))
		ret = mx28_create_sd_image(infd, outfd);
	else if (!strcmp(argv[offset], "nand"))
		ret = mx28_create_nand_image(infd, outfd);

	close(outfd);
err2:
	close(infd);
err1:
	return ret;
}
