/*
 * Copyright (C) 2015-2016 Freescale Semiconductor, Inc.
 * Copyright 2017 NXP
 *
 * SPDX-License-Identifier:     GPL-2.0+
 */

#include <fsl_fastboot.h>
#include <linux/stat.h>
#include <linux/types.h>
#include <common.h>
#include <g_dnl.h>
#include <mmc.h>
#include "bcb.h"
#define ALIGN_BYTES 64 /*armv7 cache line need 64 bytes aligned */

static ulong get_block_size(char *ifname, int dev)
{
	struct blk_desc *dev_desc = NULL;

	dev_desc = blk_get_dev(ifname, dev);
	if (dev_desc == NULL) {
		printf("Block device %s %d not supported\n", ifname, dev);
		return 0;
	}

	return dev_desc->blksz;
}

static int do_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	char *ep;
	struct blk_desc *dev_desc = NULL;
	int dev;
	int part = 0;
	disk_partition_t part_info;
	ulong offset = 0u;
	ulong limit = 0u;
	void *addr;
	uint blk;
	uint cnt;

	if (argc != 6) {
		cmd_usage(cmdtp);
		return 1;
	}

	dev = (int)simple_strtoul(argv[2], &ep, 16);
	if (*ep) {
		if (*ep != ':') {
			printf("Invalid block device %s\n", argv[2]);
			return 1;
		}
		part = (int)simple_strtoul(++ep, NULL, 16);
	}

	dev_desc = blk_get_dev(argv[1], dev);
	if (dev_desc == NULL) {
		printf("Block device %s %d not supported\n", argv[1], dev);
		return 1;
	}

	addr = (void *)simple_strtoul(argv[3], NULL, 16);
	blk = simple_strtoul(argv[4], NULL, 16);
	cnt = simple_strtoul(argv[5], NULL, 16);

	if (part != 0) {
		if (part_get_info(dev_desc, part, &part_info)) {
			printf("Cannot find partition %d\n", part);
			return 1;
		}
		offset = part_info.start;
		limit = part_info.size;
	} else {
		/* Largest address not available in block_dev_desc_t. */
		limit = ~0;
	}

	if (cnt + blk > limit) {
		printf("Write out of range\n");
		return 1;
	}

	if (dev_desc->block_write(dev_desc, offset + blk, cnt, addr) != cnt) {
		printf("Error writing blocks\n");
		return 1;
	}

	return 0;
}

U_BOOT_CMD(
	write,	6,	0,	do_write,
	"write binary data to a partition",
	"<interface> <dev[:part]> addr blk# cnt"
);

int bcb_rw_block(bool bread, char **ppblock,
		uint *pblksize, char *pblock_write, uint offset, uint size)
{
	int ret;
	char *argv[6];
	char addr_str[20];
	char cnt_str[8];
	char devpart_str[8];
	char block_begin_str[8];
	ulong blk_size = 0;
	uint blk_begin = 0;
	uint blk_end = 0;
	uint block_cnt = 0;
	char *p_block = NULL;
	unsigned int mmc_id;

	if (bread && ((ppblock == NULL) || (pblksize == NULL)))
		return -1;

	if (!bread && (pblock_write == NULL))
		return -1;

	mmc_id = mmc_get_env_dev();
	blk_size = get_block_size("mmc", mmc_id);
	if (blk_size == 0) {
		printf("bcb_rw_block, get_block_size return 0\n");
		return -1;
	}

	blk_begin = offset/blk_size;
	blk_end = (offset + size)/blk_size;
	block_cnt = 1 + (blk_end - blk_begin);

	sprintf(devpart_str, "0x%x:0x%x", mmc_id,
			fastboot_flash_find_index(FASTBOOT_PARTITION_MISC));
	sprintf(block_begin_str, "0x%x", blk_begin);
	sprintf(cnt_str, "0x%x", block_cnt);

	argv[0] = "rw"; /* not care */
	argv[1] = "mmc";
	argv[2] = devpart_str;
	argv[3] = addr_str;
	argv[4] = block_begin_str;
	argv[5] = cnt_str;

	if (bread) {
		p_block = (char *)memalign(ALIGN_BYTES, blk_size * block_cnt);
		if (NULL == p_block) {
			printf("bcb_rw_block, memalign %d bytes failed\n",
			(int)(blk_size * block_cnt));
			return -1;
		}
		sprintf(addr_str, "0x%x", (unsigned int)(uintptr_t)p_block);
		ret = do_raw_read(NULL, 0, 6, argv);
		if (ret) {
			free(p_block);
			printf("do_raw_read failed, ret %d\n", ret);
			return -1;
		}

		*ppblock = p_block;
		*pblksize = (uint)blk_size;
	} else {
		sprintf(addr_str, "0x%x", (unsigned int)(uintptr_t)pblock_write);
		ret = do_write(NULL, 0, 6, argv);
		if (ret) {
			printf("do_write failed, ret %d\n", ret);
			return -1;
		}
	}
	return 0;
}
