/*
 * (C) Copyright 2003
 * Kyle Harris, kharris@nexus-tech.net
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <malloc.h>
#include <command.h>
#include <linux/ctype.h>
#include <mmc.h>
#include <partition_table.h>
#include <emmc_partitions.h>
#include <asm/arch/cpu_sdio.h>
#include <asm/arch/sd_emmc.h>
#include <linux/sizes.h>
#include <asm/cpu_id.h>
#include <amlogic/aml_mmc.h>
#include <errno.h>
#include <part_efi.h>
#include <version.h>
#include <part.h>

#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define SD_EMMC_VDDEE_REG (*((volatile unsigned *)(0xff807000 + (0x01 << 2))))
#ifdef MMC_HS400_MODE
//#define MMC_NO_BOOT_PARTITION
/*tl1*/
static int pwm_voltage_table_ee[][2] = {
	{ 0x1c0000,  681},
	{ 0x1b0001,  691},
	{ 0x1a0002,  701},
	{ 0x190003,  711},
	{ 0x180004,  721},
	{ 0x170005,  731},
	{ 0x160006,  741},
	{ 0x150007,  751},
	{ 0x140008,  761},
	{ 0x130009,  772},
	{ 0x12000a,  782},
	{ 0x11000b,  792},
	{ 0x10000c,  802},
	{ 0x0f000d,  812},
	{ 0x0e000e,  822},
	{ 0x0d000f,  832},
	{ 0x0c0010,  842},
	{ 0x0b0011,  852},
	{ 0x0a0012,  862},
	{ 0x090013,  872},
	{ 0x080014,  882},
	{ 0x070015,  892},
	{ 0x060016,  902},
	{ 0x050017,  912},
	{ 0x040018,  922},
	{ 0x030019,  932},
	{ 0x02001a,  942},
	{ 0x01001b,  952},
	{ 0x00001c,  962}
};

/*g12b*/
//static int pwm_voltage_table_ee[][2] = {
//  { 0x1c0000,  681},
//  { 0x1b0001,  691},
//  { 0x1a0002,  701},
//  { 0x190003,  711},
//  { 0x180004,  721},
//  { 0x170005,  731},
//  { 0x160006,  741},
//  { 0x150007,  751},
//  { 0x140008,  761},
//  { 0x130009,  772},
//  { 0x12000a,  782},
//  { 0x11000b,  792},
//  { 0x10000c,  802},
//  { 0x0f000d,  812},
//  { 0x0e000e,  822},
//  { 0x0d000f,  832},
//  { 0x0c0010,  842},
//  { 0x0b0011,  852},
//  { 0x0a0012,  862},
//  { 0x090013,  872},
//  { 0x080014,  882},
//  { 0x070015,  892},
//  { 0x060016,  902},
//  { 0x050017,  912},
//  { 0x040018,  922},
//  { 0x030019,  932},
//  { 0x02001a,  942},
//  { 0x01001b,  952},
//  { 0x00001c,  962}
//};

//static int pwm_voltage_table_ee[][2] = {
//  { 0x1c0000,  681},
//  { 0x1b0001,  691},
//  { 0x1a0002,  701},
//  { 0x190003,  711},
//  { 0x180004,  721},
//  { 0x170005,  731},
//  { 0x160006,  741},
//  { 0x150007,  751},
//  { 0x140008,  761},
//  { 0x130009,  772},
//  { 0x12000a,  782},
//  { 0x11000b,  792},
//  { 0x10000c,  802},
//  { 0x0f000d,  812},
//  { 0x0e000e,  822},
//  { 0x0d000f,  832},
//  { 0x0c0010,  842},
//  { 0x0b0011,  852},
//  { 0x0a0012,  862},
//  { 0x090013,  872},
//  { 0x080014,  882},
//  { 0x070015,  892},
//  { 0x060016,  902},
//  { 0x050017,  912},
//  { 0x040018,  922},
//  { 0x030019,  932},
//  { 0x02001a,  942},
//  { 0x01001b,  952},
//  { 0x00001c,  962}
//};
/*r311
static int pwm_voltage_table_ee[][2] = {
	{ 0x1c0000,  810},
	{ 0x1b0001,  820},
	{ 0x1a0002,  830},
	{ 0x190003,  840},
	{ 0x180004,  850},
	{ 0x170005,  860},
	{ 0x160006,  870},
	{ 0x150007,  880},
	{ 0x140008,  890},
	{ 0x130009,  900},
	{ 0x12000a,  910},
	{ 0x11000b,  920},
	{ 0x10000c,  930},
	{ 0x0f000d,  940},
	{ 0x0e000e,  950},
	{ 0x0d000f,  960},
	{ 0x0c0010,  970},
	{ 0x0b0011,  980},
	{ 0x0a0012,  990},
	{ 0x090013, 1000},
	{ 0x080014, 1010},
	{ 0x070015, 1020},
	{ 0x060016, 1030},
	{ 0x050017, 1040},
	{ 0x040018, 1050},
	{ 0x030019, 1060},
	{ 0x02001a, 1070},
	{ 0x01001b, 1080},
	{ 0x00001c, 1090}
};
*/
#endif
/* info system. */
#define dtb_err(fmt, ...) printf( "%s()-%d: " fmt , \
				  __func__, __LINE__, ##__VA_ARGS__)

#define dtb_wrn(fmt, ...) printf( "%s()-%d: " fmt , \
				  __func__, __LINE__, ##__VA_ARGS__)

/* for detail debug info */
#define dtb_info(fmt, ...) printf( "%s()-%d: " fmt , \
				  __func__, __LINE__, ##__VA_ARGS__)

#define fb_err(fmt, ...)   printf("%s()-%d: " fmt , \
				__func__, __LINE__, ##__VA_ARGS__)

extern unsigned get_part_tbl_from_ept(int num, char *name);

struct aml_dtb_rsv {
	u8 data[DTB_BLK_SIZE*DTB_BLK_CNT - 4*sizeof(u32)];
	u32 magic;
	u32 version;
	u32 timestamp;
	u32 checksum;
};

struct aml_dtb_info {
	u32 stamp[2];
	u8 valid[2];
};

#define stamp_after(a,b)   ((int)(b) - (int)(a)  < 0)
/* glb dtb infos */
static struct aml_dtb_info dtb_infos = {{0, 0}, {0, 0}};

#define CONFIG_SECURITYKEY

#if !defined(CONFIG_SYS_MMC_BOOT_DEV)
	#define CONFIG_SYS_MMC_BOOT_DEV (CONFIG_SYS_MMC_ENV_DEV)
#endif

#define GXB_START_BLK   0
#define GXL_START_BLK   1

/* max 2MB for emmc in blks */
#define UBOOT_SIZE  (0x1000)

int info_disprotect = 0;

bool emmckey_is_protected (struct mmc *mmc)
{
#ifdef CONFIG_STORE_COMPATIBLE
#ifdef CONFIG_SECURITYKEY
	if (info_disprotect & DISPROTECT_KEY) {
		printf("%s(): disprotect\n", __func__);
		return 0;
	}else{
		printf("%s(): protect\n", __func__);
		return 1;
	}
#else
		return 0;
#endif
#else
#ifdef CONFIG_SECURITYKEY
		//return mmc->key_protect;
		return 0; /* fixme, */
#else
		return 0;
#endif
#endif
}

unsigned emmc_cur_partition = 0;

int mmc_read_status(struct mmc *mmc, int timeout)
{
	struct mmc_cmd cmd;
	int err, retries = 5;
	int status;

	cmd.cmdidx = MMC_CMD_SEND_STATUS;
	cmd.resp_type = MMC_RSP_R1;
	if (!mmc_host_is_spi(mmc))
		cmd.cmdarg = mmc->rca << 16;
	do {
		err = mmc_send_cmd(mmc, &cmd, NULL);
		if (!err) {
			if ((cmd.response[0] & MMC_STATUS_RDY_FOR_DATA) &&
				(cmd.response[0] & MMC_STATUS_CURR_STATE) !=
				 MMC_STATE_PRG)
				break;
			else if (cmd.response[0] & MMC_STATUS_MASK) {
				printf("Status Error: 0x%08X\n",
					cmd.response[0]);
				return COMM_ERR;
			}
		} else if (--retries < 0)
			return err;

		udelay(1000);

	} while (timeout--);

	status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9;
	printf("CURR STATE:%d, status = 0x%x\n", status, cmd.response[0]);

	if (timeout <= 0) {
		printf("read status Timeout waiting card ready\n");
		return TIMEOUT;
	}
	if (cmd.response[0] & MMC_STATUS_SWITCH_ERROR) {
		printf("mmc status switch error status =0x%x\n", status);
		return SWITCH_ERR;
	}
	return 0;
}

static int get_off_size(struct mmc * mmc, char * name, uint64_t offset, uint64_t  size, u64 * blk, u64 * cnt, u64 * sz_byte)
{
	struct partitions *part_info = NULL;
	uint64_t off = 0;
	int blk_shift = 0;

	blk_shift =  mmc->read_bl_len > 0 ? ffs(mmc->read_bl_len) - 1 : 0;
	// printf("blk_shift:%d , off:0x%llx , size:0x%llx.\n ",blk_shift,off,size );
	part_info = find_mmc_partition_by_name(name);
	if (part_info == NULL) {
			printf("get partition info failed !!\n");
			return -1;
	}
	off = part_info->offset + offset;

	// printf("part_info->offset:0x%llx , off:0x%llx , size:0x%llx.\n",part_info->offset ,off,size);

	*blk = off >>  blk_shift ;
	*cnt = size >>  blk_shift ;
	*sz_byte = size - ((*cnt) << blk_shift) ;

	// printf("get_partition_off_size : blk:0x%llx , cnt:0x%llx.\n",*blk,*cnt);
	return 0;
}

static int get_partition_size(unsigned char* name, uint64_t* addr)
{
	struct partitions *part_info = NULL;
	part_info = find_mmc_partition_by_name((char *)name);
	if (part_info == NULL) {
			printf("get partition info failed !!\n");
			return -1;
	}

	*addr = part_info->size >> 9; // unit: 512 bytes
	return 0;
}

static inline int isstring(char *p)
{
	char *endptr = p;
	while (*endptr != '\0') {
		if (!(((*endptr >= '0') && (*endptr <= '9'))
				|| ((*endptr >= 'a') && (*endptr <= 'f'))
				|| ((*endptr >= 'A') && (*endptr <= 'F'))
				|| (*endptr == 'x') || (*endptr == 'X')))
			return 1;
		endptr++;
	}

	return 0;
}

/*
	erase bootloader on user/boot0/boot1 which indicate by map.
	bit 0: user
	bit 1: boot0
	bit 2: boot1
*/
int amlmmc_erase_bootloader(int dev, int map)
{
	int ret = 0, i, count = 3;
	int blk_shift;
	unsigned long n;
	char *partname[3] = {"user", "boot0", "boot1"};
	cpu_id_t cpu_id = get_cpu_id();
	struct mmc *mmc = find_mmc_device(dev);

	/* do nothing */
	if (0 == map)
		goto _out;

	if (!mmc) {
		printf("%s() %d: not valid emmc %d\n", __func__, __LINE__, dev);
		ret = -1;
		goto _out;
	}
	/* make sure mmc is initialized! */
	ret = mmc_init(mmc);
	if (ret) {
		printf("%s() %d: emmc %d init %d\n", __func__, __LINE__, dev, ret);
		ret = -2;
		goto _out;
	}

	blk_shift =  mmc->read_bl_len > 0 ? ffs(mmc->read_bl_len) - 1 : 0;
	/* erase bootloader in user/boot0/boot1 */
	for (i = 0; i < count; i++) {
		if (map & (0x1 << i)) {
			if (!mmc_select_hwpart(dev, i)) {
				lbaint_t start = 0, blkcnt;

				blkcnt = mmc->capacity >> blk_shift;
				if (0 == i) {
					struct partitions *part_info;
					/* get info by partition */
					part_info = find_mmc_partition_by_name(MMC_BOOT_NAME);
					if (part_info == NULL) {
						printf("%s() %d: error!!\n", __func__, __LINE__);
						/* fixme, do somthing! */
						continue;
					} else {
						start = part_info->offset>> blk_shift;
						blkcnt = part_info->size>> blk_shift;
						if (cpu_id.family_id >= MESON_CPU_MAJOR_ID_GXL) {
							start = GXL_START_BLK;
							blkcnt -= GXL_START_BLK;
						}
					}
				}
/* some customer may use boot1 higher 2M as private data. */
#ifdef CONFIG_EMMC_BOOT1_TOUCH_REGION
				if (2 == i && CONFIG_EMMC_BOOT1_TOUCH_REGION <= mmc->capacity) {
					blkcnt = CONFIG_EMMC_BOOT1_TOUCH_REGION >> blk_shift;
				}
#endif/* CONFIG_EMMC_BOOT1_TOUCH_REGION */
				printf("Erasing blocks " LBAFU " to " LBAFU " @ %s\n",
				   start, blkcnt, partname[i]);
				n = mmc->block_dev.block_erase(dev, start, blkcnt);
				if (n != 0) {
					printf("mmc erase %s failed\n", partname[i]);
					ret = -3;
					break;
				}
			} else
				printf("%s() %d: switch dev %d to %s fail\n",
						__func__, __LINE__, dev, partname[i]);
		}
	}
	/* try to switch back to user. */
	mmc_select_hwpart(dev, 0);

_out:
	return ret;
}

/* dtb read&write operation with backup updates */
static u32 _calc_boot_info_checksum(struct storage_emmc_boot_info *boot_info)
{
	u32 *buffer = (u32*)boot_info;
	u32 checksum = 0;
	int i = 0;

	do {
		checksum += buffer[i];
	} while (i++ < ((EMMC_BOOT_INFO_SIZE >> 2) - 2));

	return checksum;
}

#define MAX_REACHABLE_RSV_RANGE	0x30000
static int amlmmc_boot_info_check(struct mmc *mmc, int dev)
{
	struct storage_emmc_boot_info *boot_info;
	struct virtual_partition *ddr_part;
	u64 src;
	u32 *buffer, checksum = 0;
	int i = 0, ret = -1;

	buffer = malloc(MMC_BLOCK_SIZE);
	if (!buffer)
		return -ENOMEM;

	if (mmc->block_dev.block_read(dev, 0, 1, buffer) != 1) {
		ret = -EIO;
		goto _err;
	}
	boot_info = (struct storage_emmc_boot_info *)buffer;
	ddr_part =  aml_get_virtual_partition_by_name(MMC_DDR_PARAMETER_NAME);
	if (boot_info->ddr.addr != ddr_part->offset / MMC_BLOCK_SIZE)
		goto _err;

	if (!boot_info->checksum || boot_info->version != 0x01)
		goto _err;

	src = boot_info->rsv_base_addr + boot_info->ddr.addr;
	if (!src || src == (uint64_t)(-1) || src > MAX_REACHABLE_RSV_RANGE)
		goto _err;

	do {
		checksum += buffer[i];
	} while (i++ < ((EMMC_BOOT_INFO_SIZE >> 2) - 2));

	if (!checksum)
		goto _err;

	if (checksum == boot_info->checksum)
		ret = 0;
_err:
	free(buffer);
	return ret;
}

#define GET_RSERVED_BASE_ADDR()	(_get_inherent_offset(MMC_RESERVED_NAME))
static int amlmmc_write_info_sector(struct mmc *mmc, int dev)
{
	struct storage_emmc_boot_info *boot_info;
	struct virtual_partition *ddr_part;
	u8 *buffer;
	int ret = 0;

	buffer = malloc(MMC_BLOCK_SIZE);
	if (!buffer)
		return -ENOMEM;

	memset(buffer, 0, sizeof(*boot_info));
	boot_info = (struct storage_emmc_boot_info *)buffer;
	boot_info->rsv_base_addr = GET_RSERVED_BASE_ADDR() / MMC_BLOCK_SIZE;
	ddr_part =  aml_get_virtual_partition_by_name(MMC_DDR_PARAMETER_NAME);
	boot_info->ddr.addr = ddr_part->offset / MMC_BLOCK_SIZE;
	boot_info->ddr.size = ddr_part->size / MMC_BLOCK_SIZE;
	boot_info->version = 1;
	boot_info->checksum = _calc_boot_info_checksum(boot_info);

	printf("boot_info.rsv_base_addr\t:\t%04x\n", boot_info->rsv_base_addr);
	printf("boot_info.ddr.addr\t:\t%04x\n", boot_info->ddr.addr);
	printf("boot_info.ddr.size\t:\t%04x\n", boot_info->ddr.size);
	printf("boot_info.version\t:\t%04x\n", boot_info->version);
	printf("boot_info.checksum\t:\t%04x\n", boot_info->checksum);

	if (mmc->block_dev.block_write(dev, 0, 1, buffer) != 1)
		ret = -EIO;

	free(buffer);
	return ret;
}

int amlmmc_check_and_update_boot_info(void)
{
	struct mmc *mmc;
	int ret = 0, i;

	mmc = find_mmc_device(CONFIG_SYS_MMC_BOOT_DEV);
	if (!mmc)
		return -ENODEV;
	ret = mmc_init(mmc);
	if (ret)
		return -ENODEV;

	for (i = 1; i < 3; i++) {
		if (mmc_select_hwpart(CONFIG_SYS_MMC_BOOT_DEV, i)) {
			printf("switch dev %d to boot%d fail\n",
				CONFIG_SYS_MMC_BOOT_DEV, i - 1);
			continue;
		}
		if (!amlmmc_boot_info_check(mmc, CONFIG_SYS_MMC_BOOT_DEV))
			break;
		ret = amlmmc_write_info_sector(mmc, CONFIG_SYS_MMC_BOOT_DEV);
		if (ret)
			return -EIO;
	}
	mmc_select_hwpart(CONFIG_SYS_MMC_BOOT_DEV, 0);
	return ret;
}

/*
	write bootloader on user/boot0/boot1 which indicate by map.
	bit 0: user
	bit 1: boot0
	bit 2: boot1
*/
int amlmmc_write_bootloader(int dev, int map, unsigned int size, const void *src)
{
	int ret = 0, i, count = 3;
	unsigned long n;
	char *partname[3] = {"user", "boot0", "boot1"};
	struct mmc *mmc = find_mmc_device(dev);
	lbaint_t start = GXB_START_BLK, blkcnt;
	cpu_id_t cpu_id = get_cpu_id();

	/* do nothing */
	if (0 == map)
		goto _out;

	if (!mmc) {
		printf("%s() %d: not valid emmc %d\n", __func__, __LINE__, dev);
		ret = -1;
		goto _out;
	}
	/* make sure mmc is initialized! */
	ret = mmc_init(mmc);
	if (ret) {
		printf("%s() %d: emmc %d init %d\n", __func__, __LINE__, dev, ret);
		ret = -2;
		goto _out;
	}
	printf("%s() %d: map 0x%x\n", __func__, __LINE__, map);
	if (cpu_id.family_id >= MESON_CPU_MAJOR_ID_GXL)
		start = GXL_START_BLK;
	blkcnt = (size + mmc->read_bl_len - 1) / mmc->read_bl_len;

	/* erase bootloader in user/boot0/boot1 */
	for (i = 0; i < count; i++) {
		if (map & (0x1 << i)) {
			if (!mmc_select_hwpart(dev, i)) {
/* some customer may use boot1 higher 2M as private data. */
#ifdef CONFIG_EMMC_BOOT1_TOUCH_REGION
				if (2 == i && CONFIG_EMMC_BOOT1_TOUCH_REGION <= size) {
					printf("%s(), size %d exceeds TOUCH_REGION %d, skip\n",
						__func__, size, CONFIG_EMMC_BOOT1_TOUCH_REGION);
					break;
				}
#endif /* CONFIG_EMMC_BOOT1_TOUCH_REGION */
				printf("Writing blocks " LBAFU " to " LBAFU " @ %s\n",
				   start, blkcnt, partname[i]);
				if (i != 0)
					amlmmc_write_info_sector(mmc, dev);
				n = mmc->block_dev.block_write(dev, start, blkcnt, src);
				if (n != blkcnt) {
					printf("mmc write %s failed\n", partname[i]);
					ret = -3;
					break;
				}
			} else
				printf("%s() %d: switch dev %d to %s fail\n",
						__func__, __LINE__, dev, partname[i]);
		}
	}
	/* try to switch back to user. */
	mmc_select_hwpart(dev, 0);

_out:
	return ret;
}

static int amlmmc_erase_in_dev(int argc, char *const argv[])
{
	int dev = 0;
	u64 cnt = 0, blk = 0, n = 0;
	struct mmc *mmc;

	dev = simple_strtoul(argv[2], NULL, 10);
	blk = simple_strtoull(argv[3], NULL, 16);
	cnt = simple_strtoull(argv[4], NULL, 16);

	if (dev < 0) {
		printf("Cannot find dev.\n");
		return 1;
	}

	mmc = find_mmc_device(dev);

	if (!mmc)
		return 1;

	printf("MMC erase: dev # %d, start_erase_address(in block) # %#llx,\
			several blocks  # %lld will be erased ...\n ",
			dev, blk, cnt);

	mmc_init(mmc);

	if (cnt != 0)
		n = mmc->block_dev.block_erase(dev, blk, cnt);

	printf("dev # %d, %s, several blocks erased %s\n",
				dev, " ", (n == 0) ? "OK" : "ERROR");

	return (n == 0) ? 0 : 1;
}

static int amlmmc_erase_in_card(int argc, char *const argv[])
{
	int dev = 0;
	u64 cnt = 0, blk = 0, n = 0;
	/*sz_byte =0;*/
	char *name = NULL;
	u64 offset_addr = 0, size = 0;
	struct mmc *mmc;
	int tmp_shift;

	name = argv[2];
	dev = find_dev_num_by_partition_name (name);
	if (dev < 0) {
		printf("Cannot find dev.\n");
		return 1;
	}
	offset_addr = simple_strtoull(argv[3], NULL, 16);
	size = simple_strtoull(argv[4], NULL, 16);
	mmc = find_mmc_device(dev);
	if (!mmc)
		return 1;

	tmp_shift =  mmc->read_bl_len > 0 ? ffs(mmc->read_bl_len) - 1 : 0;
	cnt = size >> tmp_shift;
	blk = offset_addr >> tmp_shift;
	/* sz_byte = size - (cnt<<tmp_shift); */

	printf("MMC erase: dev # %d, start_erase_address(in block) # %#llx,\
			several blocks  # %lld will be erased ...\n ",
			dev, blk, cnt);

	mmc_init(mmc);

	if (cnt != 0)
		n = mmc->block_dev.block_erase(dev, blk, cnt);

	printf("dev # %d, %s, several blocks erased %s\n",
				dev, argv[2], (n == 0) ? "OK" : "ERROR");

	return (n == 0) ? 0 : 1;
}

static int amlmmc_erase_in_part(int argc, char *const argv[])
{
	int dev = 0;
	u64 cnt = 0, blk = 0, n = 0, sz_byte =0;
	char *name = NULL;
	u64 offset_addr = 0, size = 0;
	struct mmc *mmc;
	struct partitions *part_info;

	name = argv[2];
	dev = find_dev_num_by_partition_name (name);
	offset_addr = simple_strtoull(argv[3], NULL, 16);
	size = simple_strtoull(argv[4], NULL, 16);
	part_info = find_mmc_partition_by_name(name);
	if (!part_info)
		return -ENODEV;
	mmc = find_mmc_device(dev);
	if (!mmc)
		 return -ENODEV;

	if (offset_addr >= part_info->size) {
		printf("Start address out #%s# partition'address region,(addr_byte < 0x%llx)\n",
						name, part_info->size);
		return 1;
	}
	if ((offset_addr+size) > part_info->size) {
		printf("End address exceeds #%s# partition,(offset = 0x%llx,size = 0x%llx)\n",
						name, part_info->offset,part_info->size);
		return 1;
	}
	get_off_size(mmc, name, offset_addr, size, &blk, &cnt, &sz_byte);

	if (dev < 0) {
		printf("Cannot find dev.\n");
		return 1;
	}

	printf("MMC erase: dev # %d, start_erase_address(in block) # %#llx,\
			several blocks  # %lld will be erased ...\n ",
			dev, blk, cnt);

	mmc_init(mmc);

	if (cnt != 0)
		n = mmc->block_dev.block_erase(dev, blk, cnt);

	printf("dev # %d, %s, several blocks erased %s\n",
				dev, argv[2], (n == 0) ? "OK" : "ERROR");

	return (n == 0) ? 0 : 1;
}

static int amlmmc_erase_by_add(int argc, char *const argv[])
{
	int ret = 0;

	if (argc != 5)
		return CMD_RET_USAGE;

	if (isdigit(argv[2][0]))
		ret = amlmmc_erase_in_dev(argc, argv);
	else if (strcmp(argv[2], "card") == 0)
		ret = amlmmc_erase_in_card(argc, argv);
	else if (isstring(argv[2]))
		ret = amlmmc_erase_in_part(argc, argv);

	return ret;
}

static int _amlmmc_erase_single_part(int dev, struct mmc *mmc, char *name)
{
	u32 n = 0;
	int blk_shift;
	u64 cnt = 0, blk = 0;
	struct partitions *part_info;

	blk_shift =  mmc->read_bl_len > 0 ? ffs(mmc->read_bl_len) - 1 : 0;
	part_info = find_mmc_partition_by_name(name);
	if (part_info == NULL)
		return 1;

	blk = part_info->offset >> blk_shift;
	if (emmc_cur_partition && !strncmp(name, "bootloader", strlen("bootloader")))
		cnt = mmc->boot_size >> blk_shift;
	else
		cnt = part_info->size >> blk_shift;

	if (cnt == 0) {
		printf("%-10s partition size is 0\n", name);
		return 0;
	}

	n = mmc->block_dev.block_erase(dev, blk, cnt);

	return (n == 0) ? 0 : 1;
}

static int _amlmmc_erase_partition(int dev, struct mmc *mmc, char *exclude_name)
{
	int num = 0;
	unsigned protect_mask = MMC_PARTITION_PROTECT_MASK;
	unsigned protect_key;
	u32 n = 0;
	int ret = 0;
	unsigned mask_flags;
	char name[MAX_PART_NAME_LEN];
	protect_key = emmckey_is_protected(mmc);

	if (!protect_key && !strcmp(exclude_name, "none")) {
		n = mmc->block_dev.block_erase(dev, 0, 0);
		return (n == 0) ? 0 : 1;
	}

	while (get_part_tbl_from_ept(num, name) != -1) {
		mask_flags = get_part_tbl_from_ept(num, name);
		if ((mask_flags & protect_mask) && protect_key)
			printf("%-10s partition is protected\n", name);
		else if (!strcmp(name, exclude_name))
			printf("%-10s partition is keeped\n", name);
		else if (protect_key && !strcmp(name, MMC_RESERVED_NAME))
			printf("%-10s partition is protected\n", name);
		else {
			printf("%-10s partition is erased: ", name);
			ret |= _amlmmc_erase_single_part(dev, mmc, name);
		}
		num++;
	}

	return ret;
}

static int amlmmc_erase_non_loader(int dev, struct mmc *mmc)
{
	return _amlmmc_erase_partition(dev, mmc, MMC_BOOT_NAME);
}

static int amlmmc_erase_single_part(int dev, struct mmc *mmc, char *name)
{
	return _amlmmc_erase_single_part(dev, mmc, name);
}

static int amlmmc_erase_whole(int dev, struct mmc *mmc)
{
	int ret = 0;

	ret = _amlmmc_erase_partition(dev, mmc, "none");

	if (ret == 0)
		ret = amlmmc_erase_bootloader(dev, AML_BL_BOOT);
	if (ret)
		printf("erase bootloader in boot partition failed\n");

	return (ret == 0) ? 0 : 1;
}

static int amlmmc_erase_non_cache(int dev, struct mmc *mmc)
{
	u32 ret = 0;

	ret = _amlmmc_erase_partition(dev, mmc, MMC_CACHE_NAME);

	if (ret == 0)
		ret = amlmmc_erase_bootloader(dev, AML_BL_BOOT);
	if (ret)
			printf("erase bootloader in boot partition failed\n");

	return (ret == 0) ? 0 : 1;
}

static int amlmmc_erase_dev(int dev, struct mmc *mmc)
{
	return amlmmc_erase_whole(dev, mmc);
}

static int amlmmc_erase_allbootloader(int dev, struct mmc *mmc)
{
	return amlmmc_erase_bootloader(dev, AML_BL_ALL);
}

static int amlmmc_erase_by_part(int argc, char *const argv[])
{
	int ret = CMD_RET_USAGE;
	struct mmc *mmc;
	int dev = CONFIG_SYS_MMC_BOOT_DEV;

	if (argc != 3)
		return ret;

	mmc = find_mmc_device(dev);
	if (!mmc)
		return 1;
	mmc_init(mmc);

	if (isdigit(argv[2][0]))
		ret = amlmmc_erase_dev(dev, mmc);
	else if (strcmp(argv[2], "whole") == 0)
		ret = amlmmc_erase_whole(dev, mmc);
	else if (strcmp(argv[2], "non_cache") == 0)
		ret = amlmmc_erase_non_cache(dev, mmc);
	else if (strcmp(argv[2], "non_loader") == 0)
		ret = amlmmc_erase_non_loader(dev, mmc);
	else if (strcmp(argv[2], "allbootloader") == 0)
		ret = amlmmc_erase_allbootloader(dev, mmc);
	else
		ret = amlmmc_erase_single_part(dev, mmc, argv[2]);

	return ret;
}

static int do_amlmmc_erase(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
	int ret = CMD_RET_USAGE;

	if (argc == 3)
		ret = amlmmc_erase_by_part(argc, argv);
	else if (argc == 5)
		ret = amlmmc_erase_by_add(argc, argv);

	return ret;
}

static int amlmmc_write_in_part(int argc, char *const argv[])
{
	int dev, ret;
	void *addr = NULL;
	u64 cnt = 0, n = 0, blk = 0, sz_byte = 0;
	char *name = NULL;
	u64 offset = 0, size = 0;
	struct mmc *mmc;
#ifdef MMC_BOOT_PARTITION_SUPPORT
	int map = AML_BL_ALL;
#else
	int map = AML_BL_USER;
#endif

	name = argv[2];
	if (strcmp(name, "bootloader") == 0)
		dev = CONFIG_SYS_MMC_BOOT_DEV;
	else
		dev = find_dev_num_by_partition_name (name);
	addr = (void *)simple_strtoul(argv[3], NULL, 16);
	offset  = simple_strtoull(argv[4], NULL, 16);
	size = simple_strtoull(argv[5], NULL, 16);
	if (dev < 0) {
		printf("Cannot find dev.\n");
		return 1;
	}
	mmc = find_mmc_device(dev);
	if (!mmc)
		return 1;

	mmc_init(mmc);

	if (strcmp(name, "bootloader") == 0) {
	#ifdef CONFIG_EMMC_KEEP_BOOT1
		if (get_cpu_id().family_id != MESON_CPU_MAJOR_ID_TM2) {
			printf("WRONG CONFIG_EMMC_KEEP_BOOT1 enabled!\n");
			return -1;
		}
		if (get_cpu_id().chip_rev == 0xA)
			map &= ~AML_BL_BOOT1;
	#endif
		ret = amlmmc_write_bootloader(dev, map, size, addr);
		return ret;
	} else
		get_off_size(mmc, name, offset, size, &blk, &cnt, &sz_byte);

	n = mmc->block_dev.block_write(dev, blk, cnt, addr);
	//write sz_byte bytes
	if ((n == cnt) && (sz_byte != 0)) {
		// printf("sz_byte=%#llx bytes\n",sz_byte);
		void *addr_tmp = malloc(mmc->write_bl_len);
		void *addr_byte = (void*)(addr+cnt*(mmc->write_bl_len));
		ulong start_blk = blk+cnt;

		if (addr_tmp == NULL) {
			printf("mmc write: malloc fail\n");
			return 1;
		}

		if (mmc->block_dev.block_read(dev, start_blk, 1, addr_tmp) != 1) { // read 1 block
			free(addr_tmp);
			printf("mmc read 1 block fail\n");
			return 1;
		}

		memcpy(addr_tmp, addr_byte, sz_byte);
		if (mmc->block_dev.block_write(dev, start_blk, 1, addr_tmp) != 1) { // write 1 block
			free(addr_tmp);
			printf("mmc write 1 block fail\n");
			return 1;
		}
		free(addr_tmp);
	}
	//printf("%#llx blocks , %#llx bytes written: %s\n", n, sz_byte, (n==cnt) ? "OK" : "ERROR");
	return (n == cnt) ? 0 : 1;
}

static int amlmmc_write_in_card(int argc, char *const argv[])
{
	int dev;
	void *addr = NULL;
	u64 cnt = 0, n = 0, blk = 0, sz_byte = 0;
	char *name = NULL;
	u64 offset = 0, size = 0;
	struct mmc *mmc;
	int blk_shift;

	name = argv[2];
	dev = find_dev_num_by_partition_name (name);
	addr = (void *)simple_strtoul(argv[3], NULL, 16);
	offset  = simple_strtoull(argv[4], NULL, 16);
	size = simple_strtoull(argv[5], NULL, 16);
	if (dev < 0) {
		printf("Cannot find dev.\n");
		return 1;
	}
	mmc = find_mmc_device(dev);
	if (!mmc)
		return 1;

	blk_shift = mmc->read_bl_len > 0 ? ffs(mmc->read_bl_len) - 1 : 0;
	cnt = size >> blk_shift;
	blk = offset >> blk_shift;
	sz_byte = size - (cnt<<blk_shift);
	 mmc_init(mmc);

	n = mmc->block_dev.block_write(dev, blk, cnt, addr);

	//write sz_byte bytes
	if ((n == cnt) && (sz_byte != 0)) {
		// printf("sz_byte=%#llx bytes\n",sz_byte);
		void *addr_tmp = malloc(mmc->write_bl_len);
		void *addr_byte = (void*)(addr+cnt*(mmc->write_bl_len));
		ulong start_blk = blk+cnt;

		if (addr_tmp == NULL) {
			printf("mmc write: malloc fail\n");
			return 1;
		}

		if (mmc->block_dev.block_read(dev, start_blk, 1, addr_tmp) != 1) { // read 1 block
			free(addr_tmp);
			printf("mmc read 1 block fail\n");
			return 1;
		}

		memcpy(addr_tmp, addr_byte, sz_byte);
		if (mmc->block_dev.block_write(dev, start_blk, 1, addr_tmp) != 1) { // write 1 block
			free(addr_tmp);
			printf("mmc write 1 block fail\n");
			return 1;
		}
		free(addr_tmp);
	}
	//printf("%#llx blocks , %#llx bytes written: %s\n", n, sz_byte, (n==cnt) ? "OK" : "ERROR");
	return (n == cnt) ? 0 : 1;
}

static int amlmmc_write_in_dev(int argc, char *const argv[])
{
	int dev;
	void *addr = NULL;
	u64 cnt = 0, n = 0, blk = 0;
	struct mmc *mmc;
	dev = simple_strtoul(argv[2], NULL, 10);
	addr = (void *)simple_strtoul(argv[3], NULL, 16);
	blk = simple_strtoull(argv[4], NULL, 16);
	cnt = simple_strtoull(argv[5], NULL, 16);
	if (dev < 0) {
		printf("Cannot find dev.\n");
		return 1;
	}
	mmc = find_mmc_device(dev);
	if (!mmc)
		return 1;

	 //printf("MMC write: dev # %d, block # %#llx, count # %#llx ... ",
	 //dev, blk, cnt);

	mmc_init(mmc);

	n = mmc->block_dev.block_write(dev, blk, cnt, addr);
	return (n == cnt) ? 0 : 1;
}

static int do_amlmmc_write(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
	int ret = 0;
	if (argc != 6)
		return CMD_RET_USAGE;

	if (isdigit(argv[2][0]))
		ret = amlmmc_write_in_dev(argc, argv);
	else if (strcmp(argv[2], "card") == 0)
		ret = amlmmc_write_in_card(argc, argv);
	else if (isstring(argv[2]))
		ret = amlmmc_write_in_part(argc, argv);

	return ret;
}

static int amlmmc_read_in_dev(int argc, char *const argv[])
{
	int dev;
	void *addr = NULL;
	u64 cnt =0, n = 0, blk = 0;
	struct mmc *mmc;

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

	if (dev < 0) {
		printf("Cannot find dev.\n");
		return 1;
	}

	mmc = find_mmc_device(dev);
	if (!mmc)
		return 1;
	n = mmc->block_dev.block_read(dev, blk, cnt, addr);
	return (n == cnt) ? 0 : 1;
}

static int amlmmc_read_in_card(int argc, char *const argv[])
{
	int dev;
	void *addr = NULL;
	//u32 flag =0;
	u64 cnt =0, n = 0, blk = 0, sz_byte = 0;
	char *name = NULL;
	u64 offset = 0, size = 0;
	int blk_shift;
	struct mmc *mmc;
	void *addr_tmp;
	void *addr_byte;
	ulong start_blk;

	name = argv[2];
	dev = find_dev_num_by_partition_name (name);
	addr = (void *)simple_strtoul(argv[3], NULL, 16);
	size = simple_strtoull(argv[5], NULL, 16);
	offset = simple_strtoull(argv[4], NULL, 16);

	if (dev < 0) {
		printf("Cannot find dev.\n");
		return 1;
	}

	mmc = find_mmc_device(dev);
	if (!mmc)
		return 1;

	blk_shift = mmc->read_bl_len > 0 ? ffs(mmc->read_bl_len) - 1 : 0;
	cnt = size >> blk_shift;
	blk = offset >> blk_shift;
	sz_byte = size - (cnt<<blk_shift);

	mmc_init(mmc);
	n = mmc->block_dev.block_read(dev, blk, cnt, addr);

	//read sz_byte bytes
	if ((n == cnt) && (sz_byte != 0)) {
	   addr_tmp = malloc(mmc->read_bl_len);
	   addr_byte = (void *)(addr+cnt*(mmc->read_bl_len));
	   start_blk = blk+cnt;
	   if (addr_tmp == NULL) {
		   printf("mmc read: malloc fail\n");
		   return 1;
	   }
	   if (mmc->block_dev.block_read(dev, start_blk, 1, addr_tmp) != 1) { // read 1 block
		   free(addr_tmp);
		   printf("mmc read 1 block fail\n");
		   return 1;
	   }
	   memcpy(addr_byte, addr_tmp, sz_byte);
	   free(addr_tmp);
	}
	return (n == cnt) ? 0 : 1;
}

static int amlmmc_read_in_part(int argc, char *const argv[])
{
	int dev;
	void *addr = NULL;
	u64 cnt = 0, n = 0, blk = 0, sz_byte = 0;
	char *name = NULL;
	u64 offset = 0, size = 0;
	struct mmc *mmc;
	void *addr_tmp;
	void *addr_byte;
	ulong start_blk;
#ifdef CONFIG_AML_GPT
	block_dev_desc_t *dev_desc;
	gpt_entry *gpt_pte = NULL;
	char	str[128];
	int ret;
	bool switch_boot = false;
#endif

	name = argv[2];

	if (strcmp(name, "bootloader") == 0)
		dev = CONFIG_SYS_MMC_BOOT_DEV;
	else
		dev = find_dev_num_by_partition_name(name);

	addr = (void *)simple_strtoul(argv[3], NULL, 16);
	offset = simple_strtoull(argv[4], NULL, 16);
	size = simple_strtoull(argv[5], NULL, 16);

	mmc = find_mmc_device(1);
	if (!mmc)
		return 1;

#ifdef CONFIG_AML_GPT
	dev_desc = &mmc->block_dev;
	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);

	/* This function validates AND fills in the GPT header and PTE */
	if (strcmp(name, "bootloader") == 0 && (is_gpt_valid(dev_desc,
				GPT_PRIMARY_PARTITION_TABLE_LBA, gpt_head, &gpt_pte) == 1)) {
		sprintf(str, "amlmmc switch 1 boot0");
		ret = run_command(str, 0);
		if (ret == -1)
			return 1;
		switch_boot = true;
	}
#endif

	get_off_size(mmc, name, offset, size, &blk, &cnt, &sz_byte);
	mmc_init(mmc);
	n = mmc->block_dev.block_read(dev, blk, cnt, addr);

	//read sz_byte bytes
	if ((n == cnt) && (sz_byte != 0)) {
	   /*printf("sz_byte=%#llx bytes\n",sz_byte);*/
	   addr_tmp = malloc(mmc->read_bl_len);
	   addr_byte = (void *)(addr+cnt*(mmc->read_bl_len));
	   start_blk = blk+cnt;

	   if (addr_tmp == NULL) {
		   printf("mmc read: malloc fail\n");
		   return 1;
	   }

	   if (mmc->block_dev.block_read(dev, start_blk, 1, addr_tmp) != 1) { // read 1 block
		   free(addr_tmp);
		   printf("mmc read 1 block fail\n");
		   return 1;
	   }

	   memcpy(addr_byte, addr_tmp, sz_byte);
	   free(addr_tmp);
	}

#ifdef CONFIG_AML_GPT
	if (switch_boot) {
		sprintf(str, "amlmmc switch 1 user");
		ret = run_command(str, 0);
		if (ret != 0) {
			printf("amlmmc cmd failed\n");
			return 1;
		}
	}
#endif

	return (n == cnt) ? 0 : 1;
}

static int do_amlmmc_read(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
	int ret = 0;

	if (argc != 6)
		return CMD_RET_USAGE;

	if (isdigit(argv[2][0]))
		ret = amlmmc_read_in_dev(argc, argv);
	else if (strcmp(argv[2], "card") == 0)
		ret = amlmmc_read_in_card(argc, argv);
	else if (isstring(argv[2]))
		ret = amlmmc_read_in_part(argc, argv);

	return ret;
}

static int do_amlmmc_env(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
	printf("herh\n");
	env_relocate();
	return 0;
}

static int do_amlmmc_list(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
	print_mmc_devices('\n');
	return 0;
}

static int do_amlmmc_size(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
	char *name;
	uint64_t* addr = NULL;
	int dev;
	struct mmc *mmc = NULL;

	if (argc != 4)
		return CMD_RET_USAGE;

	name = argv[2];
	addr = (uint64_t *)simple_strtoul(argv[3], NULL, 16);
	if (!strcmp(name, "wholeDev")) {
		dev = CONFIG_SYS_MMC_BOOT_DEV;
		mmc = find_mmc_device(dev);
		if (!mmc) {
			puts("no mmc devices available\n");
			return 1;
		}
		mmc_init(mmc);

		*addr = mmc->capacity >> 9; // unit: 512 bytes
		return 0;
	}
	return get_partition_size((unsigned char *)name, addr);
}

static int amlmmc_get_ext_csd(int argc, char *const argv[])
{
	int ret= 0;
	u8 ext_csd[512] = {0};
	int dev, byte;
	struct mmc *mmc;

	if (argc != 4)
		return CMD_RET_USAGE;

	dev = simple_strtoul(argv[2], NULL, 10);
	byte = simple_strtoul(argv[3], NULL, 10);
	mmc = find_mmc_device(dev);

	if (!mmc) {
		puts("no mmc devices available\n");
		return 1;
	}
	mmc_init(mmc);
	ret = mmc_get_ext_csd(mmc, ext_csd);
	printf("read EXT_CSD byte[%d] val[0x%x] %s\n",
			byte, ext_csd[byte], (ret == 0) ? "ok" : "fail");
	return ret;
}

static int amlmmc_set_ext_csd(int argc, char *const argv[])
{
	int ret = 0;
	int dev, byte;
	struct mmc *mmc;
	int val;

	if (argc != 5)
		return CMD_RET_USAGE;

	dev = simple_strtoul(argv[2], NULL, 10);
	byte = simple_strtoul(argv[3], NULL, 10);
	val = simple_strtoul(argv[4], NULL, 16);
	if ((byte > 191) || (byte < 0)) {
		printf("byte is not able to write!\n");
		return 1;
	}

	mmc = find_mmc_device(dev);

	if (!mmc) {
		puts("no mmc devices available\n");
		return 1;
	}

	mmc_init(mmc);

	ret = mmc_set_ext_csd(mmc, byte, val);
	printf("write EXT_CSD byte[%d] val[0x%x] %s\n",
			byte, val, (ret == 0) ? "ok" : "fail");
	return ret;
}

static int do_amlmmc_ext_csd(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
	int ret = CMD_RET_USAGE;

	if (argc == 4)
		ret = amlmmc_get_ext_csd(argc,argv);
	else if (argc == 5)
		ret = amlmmc_set_ext_csd(argc,argv);

	return ret;
}

static int do_amlmmc_switch(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
	int rc = 0;
	int dev;
	struct mmc *mmc;

	if (argc != 4)
		return CMD_RET_USAGE;

	dev = simple_strtoul(argv[2], NULL, 10);
	mmc = find_mmc_device(dev);

	if (!mmc) {
		puts("no mmc devices available\n");
		return 1;
	}

	mmc_init(mmc);
	printf("mmc switch to ");

	if (strcmp(argv[3], "boot0") == 0) {
		rc = mmc_switch_part(dev, 1);
		if (rc == 0) {
			emmc_cur_partition = 1;
			printf("boot0 success\n");
		} else {
			printf("boot0 failed\n");
		}
	}
	else if(strcmp(argv[3], "boot1") == 0) {
		rc = mmc_switch_part(dev, 2);
		if (rc == 0) {
			emmc_cur_partition = 2;
			printf("boot1 success\n");
		} else {
			printf("boot1 failed\n");
		}
	}
	else if(strcmp(argv[3], "user") == 0) {
		rc = mmc_switch_part(dev, 0);
		if (rc == 0) {
			emmc_cur_partition = 0;
			printf("user success\n");
		} else {
			printf("user failed\n");
	   }
	}
#ifdef CONFIG_SUPPORT_EMMC_RPMB
	else if(strcmp(argv[3], "rpmb") == 0) {
		rc = mmc_switch_part(dev, 3);
		if (rc == 0) {
			emmc_cur_partition = 3;
			printf("rpmb success\n");
		} else {
			printf("rpmb failed\n");
		}
	}
#endif
	else
		printf("%s failed\n", argv[3]);
	return rc;
}

static int do_amlmmc_controller(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
	int dev;
	struct mmc *mmc;
	struct aml_card_sd_info *aml_priv;
	struct sd_emmc_global_regs *sd_emmc_reg;

	if (argc != 3)
		return CMD_RET_USAGE;

	dev = simple_strtoul(argv[2], NULL, 10);

	if (dev < 0) {
		printf("Cannot find dev.\n");
		return 1;
	}

	mmc = find_mmc_device(dev);

	if (!mmc)
		return 1;

	aml_priv = mmc->priv;
	sd_emmc_reg = aml_priv->sd_emmc_reg;

	printf("sd_emmc_reg->gclock = 0x%x\n", sd_emmc_reg->gclock);
	printf("sd_emmc_reg->gdelay = 0x%x\n", sd_emmc_reg->gdelay);
	printf("sd_emmc_reg->gadjust = 0x%x\n", sd_emmc_reg->gadjust);
	printf("sd_emmc_reg->gcalout = 0x%x\n", sd_emmc_reg->gcalout);
	if (!mmc->has_init) {
		printf("mmc dev %d has not been initialed\n", dev);
		return 1;
	}
	printf("sd_emmc_reg->gstart = 0x%x\n", sd_emmc_reg->gstart);
	printf("sd_emmc_reg->gcfg = 0x%x\n", sd_emmc_reg->gcfg);
	printf("sd_emmc_reg->gstatus = 0x%x\n", sd_emmc_reg->gstatus);
	printf("sd_emmc_reg->girq_en = 0x%x\n", sd_emmc_reg->girq_en);
	printf("sd_emmc_reg->gcmd_cfg = 0x%x\n", sd_emmc_reg->gcmd_cfg);
	printf("sd_emmc_reg->gcmd_arg = 0x%x\n", sd_emmc_reg->gcmd_arg);
	printf("sd_emmc_reg->gcmd_dat = 0x%x\n", sd_emmc_reg->gcmd_dat);
	printf("sd_emmc_reg->gcmd_rsp0 = 0x%x\n", sd_emmc_reg->gcmd_rsp0);
	printf("sd_emmc_reg->gcmd_rsp1 = 0x%x\n", sd_emmc_reg->gcmd_rsp1);
	printf("sd_emmc_reg->gcmd_rsp2 = 0x%x\n", sd_emmc_reg->gcmd_rsp2);
	printf("sd_emmc_reg->gcmd_rsp3 = 0x%x\n", sd_emmc_reg->gcmd_rsp3);
	return 0;
}

static int do_amlmmc_response(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
	int dev;
	struct mmc *mmc;
	struct aml_card_sd_info *aml_priv;
	struct sd_emmc_global_regs *sd_emmc_reg;

	if (argc != 3)
		return CMD_RET_USAGE;

	dev = simple_strtoul(argv[2], NULL, 10);

	if (dev < 0) {
		printf("Cannot find dev.\n");
		return 1;
	}

	mmc = find_mmc_device(dev);

	if (!mmc)
		return 1;
	if (!mmc->has_init) {
		printf("mmc dev %d has not been initialed\n", dev);
		return 1;
	}

	aml_priv = mmc->priv;
	sd_emmc_reg = aml_priv->sd_emmc_reg;

	printf("last cmd = %d, response0 = 0x%x\n",
		(sd_emmc_reg->gcmd_cfg & 0x3f), sd_emmc_reg->gcmd_rsp0);
	return 0;
}

static int do_amlmmc_status(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
	int rc = 0;
	int dev;
	struct mmc *mmc;

	if (argc != 3)
		return CMD_RET_USAGE;

	dev = simple_strtoul(argv[2], NULL, 10);

	if (dev < 0) {
		printf("Cannot find dev.\n");
		return 1;
	}
	mmc = find_mmc_device(dev);

	if (!mmc)
		return 1;
	if (!mmc->has_init) {
		printf("mmc dev %d has not been initialed\n", dev);
		return 1;
	}
	rc = mmc_read_status(mmc, 1000);
	if (rc)
		return 1;
	else
		return 0;
}

static int do_amlmmc_part(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	int dev;
	block_dev_desc_t *mmc_dev;
	struct mmc *mmc;

	if (argc != 3)
		return CMD_RET_USAGE;

	dev = simple_strtoul(argv[2], NULL, 10);
	mmc = find_mmc_device(dev);

	if (!mmc) {
		puts("no mmc devices available\n");
		return 1;
	}
	mmc_init(mmc);
	mmc_dev = mmc_get_dev(dev);
	if (mmc_dev != NULL &&
		mmc_dev->type != DEV_TYPE_UNKNOWN) {
		print_part(mmc_dev);
		return 0;
	}
	puts("get mmc type error!\n");
	return 1;
}

static int do_amlmmc_rescan(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	int dev;
	struct mmc *mmc;

	if (argc != 3)
		return CMD_RET_USAGE;

	dev = simple_strtoul(argv[2], NULL, 10);

	if (dev < 0) {
		printf("Cannot find dev.\n");
		return 1;
	}

	mmc = find_mmc_device(dev);

	if (!mmc)
			return 1;

	return mmc_init(mmc);
}

#ifdef CONFIG_SECURITYKEY
static int do_amlmmc_key(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
	struct mmc *mmc;
	int dev;

	//char *name = "logo";
	dev = CONFIG_SYS_MMC_BOOT_DEV;
	mmc = find_mmc_device(dev);
	if (!mmc) {
		printf("device %d is invalid\n",dev);
		return 1;
	}
	//mmc->key_protect = 0;
#ifdef CONFIG_STORE_COMPATIBLE
	info_disprotect |= DISPROTECT_KEY;  //disprotect
	printf("emmc disprotect key\n");
#endif
	return 0;
}
#endif

static int set_write_prot(struct mmc *mmc, u64 start)
{
	struct mmc_cmd cmd;
	int err;

	cmd.cmdidx = MMC_CMD_SET_WRITE_PROTECT;
	cmd.cmdarg = start;
	cmd.resp_type = MMC_RSP_R1b;

	err = mmc_send_cmd(mmc, &cmd, NULL);
	if (err)
		goto err_out;

	return 0;

err_out:
	puts("Failed: mmc write protect failed\n");
	return err;
}

static int set_us_wp_en(struct mmc *mmc, u8 *ext_csd, u8 wp_enable_type)
{
	u8 index = EXT_CSD_USER_WP;
	u8 user_wp = ext_csd[index];
	user_wp = user_wp & (~WP_ENABLE_MASK);
	user_wp = user_wp | wp_enable_type;
	int err = 0;
	err = mmc_set_ext_csd(mmc, index, user_wp);
	if (err)
		printf("Failed: set write protect enable failed\n");
	return err;
}

static int mmc_set_us_perm_wp_dis(struct mmc *mmc, u8 *ext_csd)
{
	u8 usr_wp = ext_csd[EXT_CSD_USER_WP];
	u8 perm_disable_bit = US_PERM_WP_DIS_BIT;

	int err;
	if (usr_wp & perm_disable_bit)
		return 0;

	usr_wp = usr_wp | perm_disable_bit;
	err = mmc_set_ext_csd(mmc, EXT_CSD_USER_WP, usr_wp);
	if (err) {
		printf("Failed: set permanent write protect disable failed\n");
		return 1;
	}
	return 0;
}

static int mmc_is_us_pwr_wp_dis(u8 user_wp)
{
   return user_wp & US_PWR_WP_DIS_BIT;
}

static int mmc_is_us_perm_wp_dis(u8 user_wp)
{
   return user_wp & US_PERM_WP_DIS_BIT;
}

static int check_wp_type(u8 *addr, u8 wp_type, u64 set_protect_cnt)
{
	u8 type_mask = WP_TYPE_MASK;
	u64 cnt = set_protect_cnt;
	u8 times = 0;
	u8 index = 7;
	u8 cur_group_wp_type = addr[index];

	while (cnt != 0) {
		if (wp_type != ((type_mask)&(cur_group_wp_type))) {
			return 1;
		}
		if (times == 3) {
			times = 0;
			index--;
			cur_group_wp_type = addr[index];
		}
		else {
			cur_group_wp_type = cur_group_wp_type >> 2;
			times++;
		}
		cnt--;
	}
	return 0;
}

static int set_register_to_temporary(struct mmc *mmc, u8 *ext_csd)
{
	int err;
	u8 wp_enable_type = WP_TEMPORARY_EN_BIT;
	err = set_us_wp_en(mmc, ext_csd, wp_enable_type);
	if (err)
		printf("Failed: set temporary write protect failed\n");
	return err;
}

static int set_register_to_pwr(struct mmc *mmc, u8 *ext_csd)
{
	int err;
	u8 user_wp = ext_csd[EXT_CSD_USER_WP];
	u8 wp_enable_type = WP_POWER_ON_EN_BIT;
	if (mmc_is_us_pwr_wp_dis(user_wp)) {
		printf("Failed: power on protection had been disabled\n");
		return 1;
	}

	err = mmc_set_us_perm_wp_dis(mmc, ext_csd);
	if (err) {
		printf("Failed: set permanent protection disable failed\n");
		return 1;
	}

	err = set_us_wp_en(mmc, ext_csd, wp_enable_type);
	if (err) {
		printf("Failed: set power on write protect enable failed\n");
		return 1;
	}
	return 0;
}

static int set_register_to_perm(struct mmc *mmc, u8 *ext_csd)
{
	int err;
	u8 wp_enable_type = WP_PERM_EN_BIT;
	u8 user_wp = ext_csd[EXT_CSD_USER_WP];

	if (mmc_is_us_perm_wp_dis(user_wp)) {
		printf("Failed: Permanent protection had been disabled\n");
		return 1;
	}

	err = set_us_wp_en(mmc, ext_csd, wp_enable_type);
	if (err) {
		printf("Failed: set permanent write protect enable failed\n");
		return 1;
	}
	return 0;
}

static int set_wp_register(struct mmc *mmc, u8 *ext_csd, u8 wp_type)
{
	int ret = 1;
	if (wp_type == WP_POWER_ON_TYPE)
		ret = set_register_to_pwr(mmc, ext_csd);
	else if (wp_type == WP_PERMANENT_TYPE)
		ret = set_register_to_perm(mmc, ext_csd);
	else if (wp_type == WP_TEMPORARY_TYPE)
		ret = set_register_to_temporary(mmc, ext_csd);
	return ret;
}

static u64 write_protect_group_size(struct mmc *mmc, u8 *ext_csd)
{
	int erase_group_def = ext_csd[EXT_CSD_ERASE_GROUP_DEF];
	u64 write_protect_group_size;
	int wp_grp_size = mmc->csd[2] & WP_GRP_SIZE_MASK;
	int hc_wp_grp_size = ext_csd[EXT_CSD_HC_WP_GRP_SIZE];

	if (erase_group_def == 0)
		write_protect_group_size = (u64)(wp_grp_size + 1) * mmc->erase_grp_size;
	else
		write_protect_group_size = (u64)hc_wp_grp_size * mmc->erase_grp_size;

	return write_protect_group_size;
}

int is_write_protect_valid(u8 *ext_csd)
{
	u8 class_6_ctrl = ext_csd[EXT_CSD_CLASS_6_CTRL];
	if (class_6_ctrl == 0)
		return 1;
	return 0;
}

static int compute_write_protect_range(struct mmc *mmc, char *name,
		u8 *ext_csd, u64 *wp_grp_size_addr, u64 *start_addr, u64 *end)
{
	int blk_shift;
	struct partitions *part_info;
	u64 cnt;
	u64 start;
	u64 align_start;
	u64 wp_grp_size;
	u64 group_num ;
	u64 partition_end;

	wp_grp_size = write_protect_group_size(mmc, ext_csd);

	blk_shift = mmc->read_bl_len > 0 ? ffs(mmc->read_bl_len) - 1 : 0;

	part_info = find_mmc_partition_by_name(name);
	if (part_info == NULL)
		return 1;

	start = part_info->offset >> blk_shift;
	if ((start % wp_grp_size)) {
		align_start = (start + wp_grp_size - 1) / wp_grp_size * wp_grp_size;
		printf("Caution! The partition start address isn't' aligned"
				"to group size\n"
			   "the start address is change from 0x%llx to 0x%llx\n",
			   start, align_start);
	} else {
		align_start = start;
	}
	if (emmc_cur_partition && !strncmp(name, "bootloader", strlen("bootloader")))
		cnt = mmc->boot_size >> blk_shift;
	else
		cnt = part_info->size >> blk_shift;
	if (cnt < wp_grp_size) {
		printf("Caution: The partition size is 0x%llx sector smaller than "
				"the group size 0x%llx sector, \n"
				"so the partition can't be protect\n", cnt, wp_grp_size);
		return 1;
	}

	*start_addr = align_start;
	*wp_grp_size_addr = wp_grp_size;
	partition_end = start + cnt - 1;
	group_num = (cnt - (align_start - start)) / wp_grp_size;
	*end = align_start + group_num * wp_grp_size - 1;

	if (partition_end != *end) {
		printf("Caution! The boundary of partition isn't aligned with write "
				"protected group,\n"
				"so the write protected boundary of the "
				"partition is 0x%llx, rather than 0x%llx\n",
				*end, partition_end);
	}

	printf("write_protect group size is 0x%llx sector\n", wp_grp_size);
	printf("The %s partition write protect group number is %lld\n", name, group_num);
#ifdef WP_DEBUG
	printf("the start address is 0x%llx, group size is 0x%llx, end is 0x%llx\n",
		   *start_addr, *wp_grp_size_addr, *end);
#endif
	return 0;
}

static int send_wp_prot_type(struct mmc *mmc, void *dst, u64 blk)
{
	struct mmc_cmd cmd;
	int err;
	struct mmc_data data;

	cmd.cmdidx = MMC_CMD_SEND_WRITE_PROT_TYPE;
	cmd.cmdarg = blk;
	cmd.resp_type = MMC_RSP_R1;

	data.dest = dst;
	data.blocks = 1;
	data.blocksize = 8;
	data.flags = MMC_DATA_READ;

	err = mmc_send_cmd(mmc, &cmd, &data);
	if (err)
		goto err_out;

	return 0;

err_out:
	puts("Failed: mmc send write protect type failed\n");
	return err;
}

static int is_wp_set_failed(struct mmc *mmc, u8 wp_type, u64 start, u64 group_cnt)
{
	u8 *addr = NULL;
	u8 err = 0;

	addr = malloc(sizeof(u64));
	if (addr == NULL) {
		printf("Failed: malloc failed\n");
		return 1;
	}

	err = send_wp_prot_type(mmc, addr, start);
	if (err)
		goto err_out;

#ifdef WP_DEBUG
	int  i;
	for (i = 0; i < 8; i++)
		printf("write_protect status is %x\n", ((u8 *)addr)[i]);
#endif
	if (check_wp_type(addr, wp_type, group_cnt)) {
		printf("Failed: Write Protection set failed\n");
		goto err_out;
	}
	return 0;

err_out:
	free(addr);
	return 1;
}

static int send_part_wp_type(struct mmc *mmc, char *name)
{
	int err = 0;
	u8 ext_csd[512] = {0};
	u64 wp_grp_size, start, part_end;
	u64 group_start;
	void *addr = NULL;
	int i;
	int ret;

	ret = mmc_get_ext_csd(mmc, ext_csd);
	if (ret) {
		printf("Failed: get ext_csd failed\n");
		return 1;
	}

	if (!is_write_protect_valid(ext_csd)) {
		printf("Failed: CLASS_6_CTRL isn't '0' "
				"write protect process is invalid\n");
		return 1;
	}

	addr = malloc(sizeof(u64));
	if (addr == NULL) {
		printf("Failed: malloc failed\n");
		return 1;
	}

	err = compute_write_protect_range(mmc, name, ext_csd,
			&wp_grp_size, &start, &part_end);
	if (err)
		goto _out;

	group_start = start;

	while ((group_start + wp_grp_size - 1) <= part_end) {
		err = send_wp_prot_type(mmc, addr, group_start);
		if (err)
			goto _out;
		printf("The write protect type for the 32 groups after 0x%llx is: \n0x",
				group_start);
		for (i = 0; i < 8; i++)
			printf("%02x", ((u8*)addr)[i]);
		printf("\n");
		group_start += 32 * wp_grp_size;
	}
_out:
	free(addr);
	return 0;
}

static int send_add_wp_type(struct mmc *mmc, u64 start, u64 cnt)
{
	u8 ext_csd[512] = {0};
	u64 wp_grp_size = 0;
	u64 part_end = 0;
	u64 group_start;
	u64 mmc_boundary;
	int blk_shift;
	void *addr = NULL;
	int i;
	int ret;

	ret = mmc_get_ext_csd(mmc, ext_csd);
	if (ret) {
		printf("Failed: get ext_csd failed\n");
		return 1;
	}

	if (!is_write_protect_valid(ext_csd)) {
		printf("Failed: CLASS_6_CTRL isn't '0' "
				"write protect process is invalid\n");
		return 1;
	}

	addr = malloc(sizeof(u64));
	if (addr == NULL) {
		printf("Failed: malloc failed\n");
		return 1;
	}

	wp_grp_size = write_protect_group_size(mmc, ext_csd);

   if ((start % wp_grp_size)) {
		group_start = (start + wp_grp_size - 1) / wp_grp_size * wp_grp_size;
		printf("Caution! The partition start address isn't' aligned"
				"to group size\n"
			   "the start address is change from 0x%llx to 0x%llx\n",
			   start, group_start);
		part_end = group_start + (cnt - 1) * wp_grp_size - 1;
		printf("The write protect group number is 0x%llx, rather than 0x%lld\n",
				cnt - 1, cnt);
	} else {
		group_start = start;
		part_end = group_start + cnt * wp_grp_size - 1;
	}

	blk_shift = mmc->read_bl_len > 0 ? ffs(mmc->read_bl_len) - 1 : 0;
	mmc_boundary = mmc->capacity>>blk_shift;

	if ((part_end + 1) > mmc_boundary) {
		printf("Error: the operation cross the boundary of mmc\n");
		free(addr);
		return 1;
	}

	while ((group_start + wp_grp_size - 1) <= part_end) {
		ret = send_wp_prot_type(mmc, addr, group_start);
		if (ret) {
			free(addr);
			return 1;
		}
		printf("The write protect type for the 32 groups after 0x%llx is: \n0x",
				group_start);
		for (i = 0; i < 8; i++)
			printf("%02x", ((u8*)addr)[i]);
		printf("\n");
		group_start += 32 * wp_grp_size;
	}
	free(addr);
	return 0;
}

static int set_part_write_protect(struct mmc *mmc, u8 wp_type, char *name)
{
	int err = 0;
	u8 ext_csd[512] = {0};
	u8 group_num  = 32;
	u64 wp_grp_size, start, part_end;
	u64 group_start;
	u64 check_group_start;
	u64 set_protect_cnt = 0;

	err = mmc_get_ext_csd(mmc, ext_csd);
	if (err) {
		printf("Failed: get ext_csd failed\n");
		return 1;
	}

	if (!is_write_protect_valid(ext_csd)) {
		printf("Failed: CLASS_6_CTRL isn't '0' "
				"write protect process is invalid\n");
		return 1;
	}

	err = compute_write_protect_range(mmc, name, ext_csd,
			&wp_grp_size, &start, &part_end);
	if (err)
		return 1;

	group_start = start;
	err = set_wp_register(mmc, ext_csd, wp_type);
	if (err)
		return 1;
	while ((group_start + wp_grp_size - 1) <= part_end) {
		err = set_write_prot(mmc, group_start);
		if (err)
			return 1;
		group_start += wp_grp_size;
		set_protect_cnt++;
//check write protect type every 32 group
		if (set_protect_cnt % 32 == 0) {
			check_group_start = group_start -  group_num * wp_grp_size;
			err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num);
			if (err)
				return 1;
		}
	}

	group_num = set_protect_cnt % 32;
	check_group_start = group_start - group_num * wp_grp_size;

	if (group_num) {
		err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num);
		if (err)
			return 1;
	}

	return 0;
}

static int set_add_write_protect(struct mmc *mmc, u8 wp_type, u64 start, u64 cnt)
{
	int err = 0;
	u8 ext_csd[512] = {0};
	int group_num = 32;
	u64 wp_grp_size, part_end;
	u64 group_start;
	u64 check_group_start;
	u64 set_protect_cnt = 0;
	u64 mmc_boundary = 0;
	int blk_shift;
	err = mmc_get_ext_csd(mmc, ext_csd);

	if (err) {
		printf("Failed: get ext_csd failed\n");
		return 1;
	}

	if (!is_write_protect_valid(ext_csd)) {
		printf("Failed: CLASS_6_CTRL isn't '0' "
				"write protect process is invalid\n");
		return 1;
	}

	wp_grp_size = write_protect_group_size(mmc, ext_csd);

	if ((start % wp_grp_size)) {
	  group_start = (start + wp_grp_size - 1) / wp_grp_size * wp_grp_size;
	  printf("Caution! The partition start address isn't' aligned"
			  "to group size\n"
			 "the start address is change from 0x%llx to 0x%llx\n",
			 start, group_start);
	  part_end = group_start + (cnt - 1) * wp_grp_size - 1;
	  printf("The write protect group number is 0x%llx, rather than 0x%lld\n",
			  cnt - 1, cnt);
	} else {
	  group_start = start;
	  part_end = group_start + cnt * wp_grp_size - 1;
	}

	blk_shift = mmc->read_bl_len > 0 ? ffs(mmc->read_bl_len) - 1 : 0;
	mmc_boundary = mmc->capacity>>blk_shift;

	if ((part_end + 1) > mmc_boundary) {
		printf("Error: the operation cross the boundary of mmc\n");
		return 1;
	}

	err = set_wp_register(mmc, ext_csd, wp_type);
	if (err)
		return 1;

	while ((group_start + wp_grp_size - 1) <= part_end) {
		err = set_write_prot(mmc, group_start);
		if (err)
			return 1;
		group_start += wp_grp_size;
		set_protect_cnt++;
//check write protect type every 32 group
		if (set_protect_cnt % 32 == 0) {
			check_group_start = group_start -  group_num * wp_grp_size;
			err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num);
			if (err)
				return 1;
		}
	}

	group_num = set_protect_cnt % 32;
	check_group_start = group_start - group_num * wp_grp_size;

	if (group_num) {
		err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num);
		if (err)
			return 1;
	}

	return 0;
}

static int do_amlmmc_write_protect(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
	int ret = CMD_RET_USAGE;
	struct mmc *mmc;
	int dev = 1;
	char *name = NULL;
	char *wp_type_str = NULL;
	u8 write_protect_type;
	u64 start, cnt;

	if (argc > 5 || argc < 4)
		return ret;

	if (argc == 4) {
		name = argv[2];
		wp_type_str = argv[3];
		dev = find_dev_num_by_partition_name(name);
		if (dev < 0) {
			printf("Error: Cannot find dev.\n");
			return CMD_RET_USAGE;
		}
	} else {
		start = simple_strtoull(argv[2], NULL, 16);
		cnt = simple_strtoull(argv[3], NULL, 0);
		wp_type_str = argv[4];
	}

	mmc = find_mmc_device(dev);
	if (!mmc)
		return 1;

	if (IS_SD(mmc)) {
		mmc = find_mmc_device(~dev);
		if (!mmc)
			return 1;
		if (IS_SD(mmc)) {
			printf("SD card can not be write protect\n");
			return 1;
		}
	}

	mmc_init(mmc);

	if (strcmp(wp_type_str, "temporary") == 0)
		write_protect_type = WP_TEMPORARY_TYPE;
	else if (strcmp(wp_type_str, "power_on") == 0)
		write_protect_type = WP_POWER_ON_TYPE;
	else if (strcmp(wp_type_str, "permanent") == 0)
		write_protect_type = WP_PERMANENT_TYPE;
	else
		return ret;

	if (argc == 4)
		ret = set_part_write_protect(mmc, write_protect_type, name);
	else
		ret = set_add_write_protect(mmc, write_protect_type, start, cnt);

	return ret;
}

static int do_amlmmc_boot_wp(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
	int ret = CMD_RET_USAGE;
	u8 ext_csd[512] = {0};
	char *name = NULL;
	char *type = NULL;
	struct mmc *mmc;
	int dev = 1;
	u8 boot_wp = 0;
	u8 boot_wp_status = 0;
	u8 perm_dis = 0;
	u8 perm_en = 0;

	if (argc != 4)
		return ret;

	name = argv[2];
	type = argv[3];
	mmc = find_mmc_device(dev);
	if (!mmc)
		return 1;

	if (IS_SD(mmc)) {
		mmc = find_mmc_device(~dev);
		if (!mmc)
			return 1;
		if (IS_SD(mmc)) {
			printf("SD card can not be write protect\n");
			return 1;
		}
	}

	mmc_init(mmc);

	ret = mmc_get_ext_csd(mmc, ext_csd);
	if (ret)
		printf("get ext_csd failed\n");

	boot_wp = ext_csd[EXT_CSD_BOOT_WP];
	boot_wp_status = ext_csd[EXT_CSD_BOOT_WP_STATUS];

	perm_dis = boot_wp & 0x10;
	perm_en = boot_wp & 0x4;

	if (!strcmp(type, "permanent") && perm_dis == 0) {
		if (!strcmp(name, "both"))
			boot_wp = 0x4;
		else if (!strcmp(name, "boot0"))
			boot_wp = 0x84;
		else if (!strcmp(name, "boot1"))
			boot_wp = 0x8c;
		else
			return -1;
	}

	if (!strcmp(type, "poweron")) {
		if (!strcmp(name, "both") && perm_en == 0) {
			boot_wp |= 0x1;
		} else if (!strcmp(name, "boot0")) {
			boot_wp |= 0x81;
			boot_wp |= boot_wp_status & 0x8;
		} else if (!strcmp(name, "boot1")) {
			boot_wp |= 0x83;
		} else {
			return -1;
		}
	}

	printf("boot_wp is 0x%x\n", boot_wp);

	ret = mmc_set_ext_csd(mmc, EXT_CSD_BOOT_WP, boot_wp);
	if (ret) {
		printf("set ext_csd boot_wp field failed\n");
		return ret;
	}

	return ret;
}

static int do_amlmmc_boot_wp_status(cmd_tbl_t *cmdtp,
		int flag, int argc, char *const argv[])
{
	int ret = CMD_RET_USAGE;
	u8 ext_csd[512] = {0};
	u8 boot_wp_status;
	struct mmc *mmc;
	int dev = 1;

	if (argc != 2)
		return ret;

	mmc = find_mmc_device(dev);
	if (!mmc)
		return ret;

	if (IS_SD(mmc)) {
		mmc = find_mmc_device(~dev);
		if (!mmc)
			return ret;
		if (IS_SD(mmc)) {
			printf("SD card can not be write protect\n");
			return 1;
		}
	}

	mmc_init(mmc);
	ret = mmc_get_ext_csd(mmc, ext_csd);
	if (ret)
		printf("get ext_csd failed\n");
	boot_wp_status =  ext_csd[EXT_CSD_BOOT_WP_STATUS];

	if ((boot_wp_status & 0x3) == 0)
		printf("boot0 is not protected\n");
	else if ((boot_wp_status & 0x3) == 1)
		printf("boot0 is power on protected\n");
	else if ((boot_wp_status & 0x3) == 2)
		printf("boot0 is permanently protected\n");

	if ((boot_wp_status & 0xc) == 0)
		printf("boot1 is not protected\n");
	else if ((boot_wp_status & 0xc) == 4)
		printf("boot1 is power on protected\n");
	else if ((boot_wp_status & 0xc) == 8)
		printf("boot1 is permanently protected\n");

	return ret;
}

static int clear_write_prot_per_group(struct mmc *mmc, u64 blk)
{
	struct mmc_cmd cmd;
	int err;

	cmd.cmdidx = MMC_CMD_CLR_WRITE_PROT;
	cmd.cmdarg = blk;
	cmd.resp_type = MMC_RSP_R1b;

	err = mmc_send_cmd(mmc, &cmd, NULL);

	return err;
}

static int set_part_clear_wp(struct mmc *mmc, char *name)
{
	int err = 0;
	u8 ext_csd[512] = {0};
	u8 group_num  = 32;
	u64 wp_grp_size, start, part_end;
	u64 group_start;
	u64 check_group_start;
	u64 set_protect_cnt = 0;
	u8 wp_type = WP_CLEAR_TYPE;

	err = mmc_get_ext_csd(mmc, ext_csd);
	if (err) {
		printf("get ext_csd failed\n");
		return 1;
	}

	if (!is_write_protect_valid(ext_csd)) {
		printf("CLASS_6_CTRL isn't '0' write protect process is invalid\n");
		return 1;
	}

	err = compute_write_protect_range(mmc, name, ext_csd,
			&wp_grp_size, &start, &part_end);
	if (err)
		return 1;

	group_start = start;
/*
	if (!is_wp_type_temporary(ext_csd)) {
		printf("The write protect can't be clear\n");
		return 1;
	}
*/
	while ((group_start + wp_grp_size - 1) <= part_end) {
		err = clear_write_prot_per_group(mmc, group_start);
		if (err) {
			printf("Error: The write protect can't be clear\n");
			return 1;
		}
		group_start += wp_grp_size;
		set_protect_cnt++;
//check write protect type every 32 group
		if (set_protect_cnt % 32 == 0) {
			check_group_start = group_start -  group_num * wp_grp_size;
			err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num);
			if (err)
				return 1;
		}
	}

	group_num = set_protect_cnt % 32;
	check_group_start = group_start - group_num * wp_grp_size;

	if (group_num) {
		err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num);
		if (err)
			return 1;
	}

	return 0;
}

static int set_add_clear_wp(struct mmc *mmc, u64 start, u64 cnt)
{
	int err = 0;
	u8 ext_csd[512] = {0};
	u8 group_num  = 32;
	u64 wp_grp_size, part_end;
	u64 group_start;
	u64 check_group_start;
	u64 set_protect_cnt = 0;
	u8 wp_type = WP_CLEAR_TYPE;
	int blk_shift;
	u64 mmc_boundary;

	err = mmc_get_ext_csd(mmc, ext_csd);
	if (err) {
		printf("get ext_csd failed\n");
		return 1;
	}

	if (!is_write_protect_valid(ext_csd)) {
		printf("CLASS_6_CTRL isn't '0' write protect process is invalid\n");
		return 1;
	}

	wp_grp_size = write_protect_group_size(mmc, ext_csd);

	if ((start % wp_grp_size)) {
		group_start = (start + wp_grp_size - 1) / wp_grp_size * wp_grp_size;
		printf("Caution! The partition start address isn't' aligned"
				 "to group size\n"
				"the start address is change from 0x%llx to 0x%llx\n",
				start, group_start);
		part_end = group_start + (cnt - 1) * wp_grp_size - 1;
		printf("The write protect group number is 0x%llx, rather than 0x%lld\n",
				 cnt - 1, cnt);
	} else {
		group_start = start;
		part_end = group_start + cnt * wp_grp_size - 1;
	}

	blk_shift = mmc->read_bl_len > 0 ? ffs(mmc->read_bl_len) - 1 : 0;
	mmc_boundary = mmc->capacity>>blk_shift;

	if ((part_end + 1) > mmc_boundary) {
		printf("Error: the operation cross the boundary of mmc\n");
		return 1;
	}

	while ((group_start + wp_grp_size - 1) <= part_end) {
		err = clear_write_prot_per_group(mmc, group_start);
		if (err) {
			printf("Error: The write protect can't be clear\n");
			return 1;
		}
		group_start += wp_grp_size;
		set_protect_cnt++;
//check write protect type every 32 group
		if (set_protect_cnt % 32 == 0) {
			check_group_start = group_start -  group_num * wp_grp_size;
			err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num);
			if (err)
				return 1;
		}
	}

	group_num = set_protect_cnt % 32;
	check_group_start = group_start - group_num * wp_grp_size;

	if (group_num) {
		err = is_wp_set_failed(mmc, wp_type, check_group_start, group_num);
		if (err)
			return 1;
	}

	return 0;
}

static int do_amlmmc_clear_wp(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
{
	int ret = CMD_RET_USAGE;
	struct mmc *mmc;
	int dev = 1;
	char *name = NULL;
	u64 start, cnt;

	if (argc < 3 || argc > 4)
		return ret;

	if (argc == 3) {
		 name = argv[2];
		 dev = find_dev_num_by_partition_name(name);
		 if (dev < 0) {
			 printf("Error: Cannot find dev.\n");
			 return CMD_RET_USAGE;
		 }
	 } else {
		 start = simple_strtoull(argv[2], NULL, 16);
		 cnt = simple_strtoull(argv[3], NULL, 10);
	 }

	mmc = find_mmc_device(dev);
	if (!mmc)
		return 1;

	if (IS_SD(mmc)) {
		mmc = find_mmc_device(~dev);
		if (!mmc)
			return 1;
		if (IS_SD(mmc)) {
			printf("SD card can not be write protect\n");
			return 1;
		}
	}

	mmc_init(mmc);

	if (argc == 3)
		ret = set_part_clear_wp(mmc, name);
	else
		ret = set_add_clear_wp(mmc, start, cnt);

	return ret;
}

static int send_write_prot_status_group(struct mmc *mmc, u64 blk)
{
	struct mmc_cmd cmd;
	struct mmc_data data;
	int err;
	void *addr = NULL;
	int i = 0;
	addr = malloc(4*sizeof(u8));

	if (addr == NULL) {
		printf("Failed: malloc failed\n");
		return 1;
	}

	cmd.cmdidx = MMC_CMD_SEND_WRITE_PROT;
	cmd.cmdarg = blk;
	cmd.resp_type = MMC_RSP_R1;

	data.dest = addr;
	data.blocks = 1;
	data.blocksize = 4;
	data.flags = MMC_DATA_READ;

	err = mmc_send_cmd(mmc, &cmd, &data);
	if (err)
		goto err_out;

	printf("The write protect type for the 32 groups after 0x%llx is:\n0x",
			blk);
	for (i = 0 ; i < 4; i++)
		printf("%02x", ((u8 *)addr)[i]);
	printf("\n");

	free(addr);
	return 0;
err_out:
	free(addr);
	return 1;
}

static int send_part_wp_status(struct mmc *mmc, char *name)
{
	int err = 0;
	u8 ext_csd[512] = {0};
	u64 wp_grp_size, start, part_end;
	u64 group_start;

	err = mmc_get_ext_csd(mmc, ext_csd);
	if (err) {
		printf("Failed: get ext_csd failed\n");
		return 1;
	}

	if (!is_write_protect_valid(ext_csd)) {
		printf("Failed: CLASS_6_CTRL isn't '0' "
				"write protect process is invalid\n");
		return 1;
	}

	err = compute_write_protect_range(mmc, name, ext_csd,
			&wp_grp_size, &start, &part_end);
	if (err)
		return 1;

	group_start = start;

	while ((group_start + wp_grp_size - 1) <= part_end) {
		err = send_write_prot_status_group(mmc, group_start);
		if (err)
			return 1;
		group_start += 32 * wp_grp_size;
	}

	return 0;
}

static int send_add_wp_status(struct mmc *mmc, u64 start, u64 cnt)
{
	int err = 0;
	u8 ext_csd[512] = {0};
	u64 wp_grp_size, part_end;
	u64 group_start;
	int blk_shift;
	u64 mmc_boundary;
	err = mmc_get_ext_csd(mmc, ext_csd);
	if (err) {
		printf("Failed: get ext_csd failed\n");
		return 1;
	}

	if (!is_write_protect_valid(ext_csd)) {
		printf("Failed: CLASS_6_CTRL isn't '0' "
				"write protect process is invalid\n");
		return 1;
	}

	wp_grp_size = write_protect_group_size(mmc, ext_csd);

	if ((start % wp_grp_size)) {
		 group_start = (start + wp_grp_size - 1) / wp_grp_size * wp_grp_size;
		 printf("Caution! The partition start address isn't' aligned"
				 "to group size\n"
				"the start address is change from 0x%llx to 0x%llx\n",
				start, group_start);
		 part_end = group_start + (cnt - 1) * wp_grp_size - 1;
		 printf("The write protect group number is 0x%llx, rather than 0x%lld\n",
				 cnt - 1, cnt);
	 } else {
		 group_start = start;
		 part_end = group_start + cnt * wp_grp_size - 1;
	 }

	blk_shift = mmc->read_bl_len > 0 ? ffs(mmc->read_bl_len) - 1 : 0;
	mmc_boundary = mmc->capacity>>blk_shift;

	if ((part_end + 1) > mmc_boundary) {
		printf("Error: the operation cross the boundary of mmc\n");
		return 1;
	}

	while ((group_start + wp_grp_size - 1) <= part_end) {
		err = send_write_prot_status_group(mmc, group_start);
		if (err)
			return 1;
		group_start += 32 * wp_grp_size;
	}

	return 0;
}

static int do_amlmmc_send_wp_status(cmd_tbl_t *cmdtp,
		int flag, int argc, char *const argv[])
{
	int ret = CMD_RET_USAGE;
	struct mmc *mmc;
	int dev = 1;
	char *name = NULL;
	u64 start, cnt;

	if (argc < 3 || argc > 4)
		return ret;

	if (argc == 3) {
		name = argv[2];
		dev = find_dev_num_by_partition_name(name);
		if (dev < 0) {
			printf("Error: Cannot find dev.\n");
			return 1;
		}
	} else {
		start = simple_strtoull(argv[2], NULL, 16);
		cnt = simple_strtoull(argv[3], NULL, 0);
	}

	mmc = find_mmc_device(dev);
	if (!mmc)
		return ret;

	if (IS_SD(mmc)) {
		mmc = find_mmc_device(~dev);
		if (!mmc)
			return ret;
		if (IS_SD(mmc)) {
			printf("SD card can not be write protect\n");
			return 1;
		}
	}

	mmc_init(mmc);

	if (argc == 3)
		ret = send_part_wp_status(mmc, name);
	else
		ret = send_add_wp_status(mmc, start, cnt);

	if (ret) {
		printf("Failed: send partition write protect status failed\n");
	}

	return ret;
}

static int do_amlmmc_send_wp_type(cmd_tbl_t *cmdtp,
		int flag, int argc, char *const argv[])
{
	int ret = CMD_RET_USAGE;
	struct mmc *mmc;
	int dev = 1;
	char *name = NULL;
	u64 start, cnt;

	if (argc < 3 || argc > 4)
		return ret;

	if (argc == 3) {
		name = argv[2];
		dev = find_dev_num_by_partition_name(name);
		if (dev < 0) {
			printf("Error: Cannot find dev.\n");
			return 1;
		}
	} else {
		start = simple_strtoull(argv[2], NULL, 16);
		cnt = simple_strtoull(argv[3], NULL, 0);
	}

	mmc = find_mmc_device(dev);
	if (!mmc)
		return 1;

	if (IS_SD(mmc)) {
		mmc = find_mmc_device(~dev);
		if (!mmc)
			return 1;
		if (IS_SD(mmc)) {
			printf("SD card can not be write protect\n");
			return 1;
		}
	}

	mmc_init(mmc);

	if (argc == 3)
		ret = send_part_wp_type(mmc, name);
	else
		ret = send_add_wp_type(mmc, start, cnt);

	if (ret) {
		printf("Failed: send partition write protect type failed\n");
	}

	return ret;
}

static int set_driver_strength(struct mmc *mmc, int strength)
{
	int ret = 0;
	u8 ext_csd[512] = {0};
	u8 strength_type = 0;
	u8 driver_strength;
	u8 hs_timing = 0;
	ret = mmc_get_ext_csd(mmc, ext_csd);
	if (ret) {
		printf("get ext_csd failed\n");
		return ret;
	}
	strength_type = 1 << strength;
	driver_strength = ext_csd[EXT_CSD_DRIVER_STRENGTH];
	if (0 == (strength_type & driver_strength)) {
		printf("Failed: This device didn't support strength type %d\n", strength);
		return 1;
	}

	hs_timing = ext_csd[EXT_CSD_HS_TIMING];
	if ((hs_timing >> 4) > 0) {
		printf("Failed: The driver strength has been set already, \
			  please reset the device\n");
		return 1;
	}

	hs_timing = hs_timing | (strength << 4);

	ret = mmc_set_ext_csd(mmc, EXT_CSD_HS_TIMING, hs_timing);
	if (ret) {
		printf("set ext_csd hs_timing field failed\n");
		return ret;
	}
	ret = mmc_get_ext_csd(mmc, ext_csd);
	if (ret) {
		printf("get ext_csd failed\n");
		return ret;
	}
	printf("The ext_csd[HS_TIMING] has been set to 0x%x\n",
		  ext_csd[EXT_CSD_HS_TIMING]);
	return ret;
}

static int get_driver_strength(struct mmc *mmc)
{
	int ret = 0;
	u8 ext_csd[512] = {0};
	u8 support_ds_type = 0;
	u8 cur_driver_strength;
	u8 hs_timing = 0;
	ret = mmc_get_ext_csd(mmc, ext_csd);
	if (ret) {
		printf("get ext_csd failed\n");
		return ret;
	}

	support_ds_type = ext_csd[EXT_CSD_DRIVER_STRENGTH];

	hs_timing = ext_csd[EXT_CSD_HS_TIMING];
	cur_driver_strength = hs_timing >> 4;

	printf("current strength type is: ");
	int strength_type = 0;
	while (support_ds_type) {
		if (support_ds_type & 1) {
			if (cur_driver_strength == strength_type)
				printf("[%d] ", strength_type);
			else
				printf("%d ", strength_type);
		}
		strength_type++;
		support_ds_type = support_ds_type >> 1;
	}
	printf("\n");
	return ret;
}

static int amlmmc_set_driver_strength(int argc, char *const argv[])
{
	int ret = CMD_RET_USAGE;
	int dev, strength;
	struct mmc *mmc;

	if (argc != 4)
		return CMD_RET_USAGE;

	dev = simple_strtoul(argv[2], NULL, 10);
	strength = simple_strtoul(argv[3], NULL, 10);
	mmc = find_mmc_device(dev);
	if (!mmc) {
		puts("no mmc devices available\n");
		return 1;
	}
	mmc_init(mmc);

	ret = set_driver_strength(mmc, strength);

	return ret;
}

static int amlmmc_get_driver_strength(int argc, char *const argv[])
{
	int ret = CMD_RET_USAGE;
	int dev;
	struct mmc *mmc;

	if (argc != 3)
		return CMD_RET_USAGE;

	dev = simple_strtoul(argv[2], NULL, 10);
	mmc = find_mmc_device(dev);
	if (!mmc) {
		puts("no mmc devices available\n");
		return 1;
	}
	mmc_init(mmc);

	ret = get_driver_strength(mmc);

	return ret;
}

static int do_amlmmc_driver_strength(cmd_tbl_t *cmdtp,
		int flag, int argc, char *const argv[])
{
	int ret = CMD_RET_USAGE;

	if (argc == 3)
		ret = amlmmc_get_driver_strength(argc,argv);
	else if (argc == 4)
		ret = amlmmc_set_driver_strength(argc,argv);

	return ret;
}

#ifdef MMC_HS400_MODE
static int do_amlmmc_reset_delay(cmd_tbl_t *cmdtp, int flag,
		int argc, char * const argv[])
{
	struct mmc *mmc;
	int dev;

	struct aml_card_sd_info *aml_priv;
	struct sd_emmc_global_regs *sd_emmc_regs;

	if (argc != 3)
		return CMD_RET_USAGE;

	dev = simple_strtoul(argv[2], NULL, 10);
	mmc = find_mmc_device(dev);
	if (!mmc) {
		puts("no mmc devices available\n");
		return 1;
	}
	mmc_init(mmc);
	if (!mmc)
		return 1;

	aml_priv = mmc->priv;
	sd_emmc_regs = aml_priv->sd_emmc_reg;

	sd_emmc_regs->gdelay = 0;
	sd_emmc_regs->gdelay1 = 0;

	return CMD_RET_SUCCESS;

}

static int do_amlmmc_clktest(cmd_tbl_t *cmdtp, int flag,
		int argc, char * const argv[])
{
	struct mmc *mmc;
	int dev;

	if (argc != 3)
		return CMD_RET_USAGE;
	dev = simple_strtoul(argv[2], NULL, 10);

	if (dev < 0) {
		printf("Cannot find dev.\n");
		return 1;
	}
	mmc  = find_mmc_device(dev);

	if (!mmc) {
		puts("no mmc devices available\n");
		return 1;
	}

	mmc_init(mmc);
	if (!mmc)
		return 1;

	aml_sd_emmc_clktest(mmc);
	return CMD_RET_SUCCESS;
}

static int do_amlmmc_set_rxdelay(cmd_tbl_t *cmdtp, int flag,
		int argc, char * const argv[])
{
	struct mmc *mmc;
	int dev;
	u32 delay1, delay2;

	if (argc != 5)
		return CMD_RET_USAGE;
	dev = simple_strtoul(argv[2], NULL, 10);
	delay1 = simple_strtoul(argv[3], NULL, 16);
	delay2 = simple_strtoul(argv[4], NULL, 16);

	if (dev < 0) {
		printf("Cannot find dev.\n");
		return 1;
	}
	mmc  = find_mmc_device(dev);

	if (!mmc) {
		puts("no mmc devices available\n");
		return 1;
	}

	mmc_init(mmc);
	if (!mmc)
		return 1;

	struct aml_card_sd_info *aml_priv = mmc->priv;
	struct sd_emmc_global_regs *sd_emmc_regs = aml_priv->sd_emmc_reg;

	sd_emmc_regs->gdelay = delay1;
	sd_emmc_regs->gdelay1 = delay2;

	update_all_line_eyetest(mmc);

	return CMD_RET_SUCCESS;
}

static int do_amlmmc_set_txdelay(cmd_tbl_t *cmdtp, int flag,
		int argc, char * const argv[])
{
	struct mmc *mmc;
	u32 delay;
	u32 mask;
	int dev;

	if (argc != 4)
		return CMD_RET_USAGE;
	dev = simple_strtoul(argv[2], NULL, 10);
	delay = simple_strtoul(argv[3], NULL, 16);

	if (dev < 0) {
		printf("Cannot find dev.\n");
		return 1;
	}
	mmc  = find_mmc_device(dev);

	if (!mmc) {
		puts("no mmc devices available\n");
		return 1;
	}

	mmc_init(mmc);
	if (!mmc)
		return 1;

	if (delay < 0 || delay > 63) {
		printf("error: tx delay is out of range\n");
		return CMD_RET_USAGE;
	}

	struct aml_card_sd_info *aml_priv = mmc->priv;
	struct sd_emmc_global_regs *sd_emmc_regs = aml_priv->sd_emmc_reg;

	mask = ~(0x3f<<16);
	sd_emmc_regs->gclock = sd_emmc_regs->gclock & mask;
	sd_emmc_regs->gclock |= delay << 16;

	update_all_line_eyetest(mmc);
	return CMD_RET_SUCCESS;
}

static void set_vddee_voltage(unsigned int target_voltage)
{
	unsigned int to;

	for (to = 0; to < ARRAY_SIZE(pwm_voltage_table_ee); to++) {
		if (pwm_voltage_table_ee[to][1] >= target_voltage) {
			break;
		}
	}

	if (to >= ARRAY_SIZE(pwm_voltage_table_ee)) {
		to = ARRAY_SIZE(pwm_voltage_table_ee) - 1;
	}

	SD_EMMC_VDDEE_REG = pwm_voltage_table_ee[to][0];
}

static int send_vddee_voltage(unsigned int target_voltage)
{
	unsigned int to;
	int vddee;

	for (to = 0; to < ARRAY_SIZE(pwm_voltage_table_ee); to++) {
		if (pwm_voltage_table_ee[to][0] <= target_voltage) {
			break;
		}
	}

	if (to >= ARRAY_SIZE(pwm_voltage_table_ee)) {
		to = ARRAY_SIZE(pwm_voltage_table_ee) - 1;
	}

	vddee = pwm_voltage_table_ee[to][1];

	return vddee;
}

static int do_amlmmc_set_vddee(cmd_tbl_t *cmdtp, int flag,
		int argc, char * const argv[])
{
	unsigned int vddee;
	struct mmc *mmc;
	int dev;

	if (argc != 4)
		return CMD_RET_USAGE;
	dev = simple_strtoul(argv[2], NULL, 10);
	vddee = simple_strtoul(argv[3], NULL, 10);

	if (dev < 0) {
		printf("Cannot find dev.\n");
		return 1;
	}

	mmc  = find_mmc_device(dev);

	if (!mmc) {
		puts("no mmc devices available\n");
		return 1;
	}

	mmc_init(mmc);
	if (!mmc)
		return 1;

	set_vddee_voltage(vddee);
	return CMD_RET_SUCCESS;

}

static int do_amlmmc_show_vddee(cmd_tbl_t *cmdtp, int flag,
		int argc, char * const argv[])
{
	int vddee;
	unsigned int vddee_reg;
	struct mmc *mmc;
	int dev;

	if (argc != 3)
		return CMD_RET_USAGE;
	dev = simple_strtoul(argv[2], NULL, 10);

	if (dev < 0) {
		printf("Cannot find dev.\n");
		return 1;
	}

	mmc  = find_mmc_device(dev);

	if (!mmc) {
		puts("no mmc devices available\n");
		return 1;
	}

	mmc_init(mmc);
	if (!mmc)
		return 1;

	vddee_reg = SD_EMMC_VDDEE_REG;

	vddee = send_vddee_voltage(vddee_reg);

	printf("meson-mmc: emmc: vddee is %d mv\n", vddee);

	return CMD_RET_SUCCESS;

}

static int do_amlmmc_refix(cmd_tbl_t *cmdtp, int flag,
		int argc, char * const argv[])
{
	int err;
	struct mmc *mmc;
	int dev;

	if (argc != 3)
		return CMD_RET_USAGE;
	dev = simple_strtoul(argv[2], NULL, 10);

	if (dev < 0) {
		printf("Cannot find dev.\n");
		return 1;
	}

	mmc  = find_mmc_device(dev);

	if (!mmc) {
		puts("no mmc devices available\n");
		return 1;
	}

	mmc_init(mmc);
	if (!mmc)
		return 1;

	err = aml_emmc_refix(mmc);
	if (err)
		printf("refix failed\n");
	return err;

}

static int do_amlmmc_move_all_delay(cmd_tbl_t *cmdtp, int flag,
		int argc, char * const argv[])
{
	struct mmc *mmc;
	u32 delay1, delay2;
	u8 count;
	int dev;

	if (argc != 4)
		return CMD_RET_USAGE;
	dev = simple_strtoul(argv[2], NULL, 10);
	count = simple_strtoul(argv[3], NULL, 16);
	if (dev < 0) {
		printf("Cannot find dev.\n");
		return 1;
	}

	mmc  = find_mmc_device(dev);

	if (!mmc) {
		puts("no mmc devices available\n");
		return 1;
	}

	mmc_init(mmc);
	if (!mmc)
		return 1;

	struct aml_card_sd_info *aml_priv = mmc->priv;
	struct sd_emmc_global_regs *sd_emmc_regs = aml_priv->sd_emmc_reg;

	delay1 = sd_emmc_regs->gdelay;
	delay2 = sd_emmc_regs->gdelay1;

	delay1 += (count<<0)|(count<<6)|(count<<12)|(count<<18)|(count<<24);
	delay2 += (count<<0)|(count<<6)|(count<<12);

	sd_emmc_regs->gdelay = delay1;
	sd_emmc_regs->gdelay1 = delay2;

	update_all_line_eyetest(mmc);
	return CMD_RET_SUCCESS;
}

static int do_amlmmc_move_sig_delay(cmd_tbl_t *cmdtp, int flag,
		int argc, char * const argv[])
{
	struct mmc *mmc;
	u32 delay1, delay2;
	u8 line, count;
	int dev;

	if (argc != 5)
		return CMD_RET_USAGE;

	dev = simple_strtoul(argv[2], NULL, 10);
	line = simple_strtoul(argv[3], NULL, 10);
	count = simple_strtoul(argv[4], NULL, 10);

	if (dev < 0) {
		printf("Cannot find dev.\n");
		return 1;
	}

	mmc  = find_mmc_device(dev);

	if (!mmc) {
		puts("no mmc devices available\n");
		return 1;
	}

	mmc_init(mmc);
	if (!mmc)
		return 1;

	if (line > 9 || line < 0) {
		printf("error: data line out of range\n");
		return CMD_RET_USAGE;
	}

	struct aml_card_sd_info *aml_priv = mmc->priv;
	struct sd_emmc_global_regs *sd_emmc_regs = aml_priv->sd_emmc_reg;

	delay1 = sd_emmc_regs->gdelay;
	delay2 = sd_emmc_regs->gdelay1;

	if (line < 5) {
		delay1 += (count<<(6*line));
		sd_emmc_regs->gdelay = delay1;
	} else {
		delay2 += (count<<(6 * (line - 5)));
		sd_emmc_regs->gdelay1 = delay2;
	}

	update_all_line_eyetest(mmc);
	return CMD_RET_SUCCESS;
}

static int do_amlmmc_line_eyetest(cmd_tbl_t *cmdtp, int flag,
		int argc, char * const argv[])
{
	struct mmc *mmc;
	u32 delay1, delay2;
	u8 line, count;
	int dev;
	u32 mask = 0x3f;

	if (argc != 4)
		return CMD_RET_USAGE;

	dev = simple_strtoul(argv[2], NULL, 10);
	line = simple_strtoul(argv[3], NULL, 10);

	if (dev < 0) {
		printf("Cannot find dev.\n");
		return 1;
	}

	mmc  = find_mmc_device(dev);

	if (!mmc) {
		puts("no mmc devices available\n");
		return 1;
	}

	mmc_init(mmc);
	if (!mmc)
		return 1;

	if (line > 9 || line < 0) {
		printf("error: data line out of range\n");
		return CMD_RET_USAGE;
	}

	struct aml_card_sd_info *aml_priv = mmc->priv;
	struct sd_emmc_global_regs *sd_emmc_regs = aml_priv->sd_emmc_reg;

	delay1 = sd_emmc_regs->gdelay;
	delay2 = sd_emmc_regs->gdelay1;

	if (line < 5)
		delay1 &= ~(mask << (6 * line));
	else
		delay2 &= ~(mask << (6 * (line - 5)));

	for (count = 0; count < 64; count++) {
		if (line < 5) {
			delay1 &= ~(mask << (6 * line));
			delay1 |= (count << (6 * line));
			sd_emmc_regs->gdelay = delay1;
		} else {
			delay2 &= ~(mask << (6 * (line - 5)));
			delay2 |= (count << (6 * line));
			sd_emmc_regs->gdelay1 = delay2;
		}
		emmc_eyetest_log(mmc, line);
	}
	return CMD_RET_SUCCESS;
}
#endif
static cmd_tbl_t cmd_amlmmc[] = {
	U_BOOT_CMD_MKENT(read,          6, 0, do_amlmmc_read,          "", ""),
	U_BOOT_CMD_MKENT(write,         6, 0, do_amlmmc_write,         "", ""),
	U_BOOT_CMD_MKENT(erase,         5, 0, do_amlmmc_erase,         "", ""),
	U_BOOT_CMD_MKENT(rescan,        3, 0, do_amlmmc_rescan,        "", ""),
	U_BOOT_CMD_MKENT(part,          3, 0, do_amlmmc_part,          "", ""),
	U_BOOT_CMD_MKENT(list,          2, 0, do_amlmmc_list,          "", ""),
	U_BOOT_CMD_MKENT(switch,        4, 0, do_amlmmc_switch,        "", ""),
	U_BOOT_CMD_MKENT(status,        3, 0, do_amlmmc_status,        "", ""),
	U_BOOT_CMD_MKENT(ext_csd,       5, 0, do_amlmmc_ext_csd,       "", ""),
	U_BOOT_CMD_MKENT(response,      3, 0, do_amlmmc_response,      "", ""),
	U_BOOT_CMD_MKENT(controller,    3, 0, do_amlmmc_controller,    "", ""),
	U_BOOT_CMD_MKENT(size,          4, 0, do_amlmmc_size,          "", ""),
	U_BOOT_CMD_MKENT(env,           2, 0, do_amlmmc_env,           "", ""),
	U_BOOT_CMD_MKENT(write_protect, 5, 0, do_amlmmc_write_protect,   "", ""),
	U_BOOT_CMD_MKENT(send_wp_status, 4, 0, do_amlmmc_send_wp_status, "", ""),
	U_BOOT_CMD_MKENT(send_wp_type,   4, 0, do_amlmmc_send_wp_type,   "", ""),
	U_BOOT_CMD_MKENT(clear_wp,       4, 0, do_amlmmc_clear_wp,       "", ""),
	U_BOOT_CMD_MKENT(boot_wp,        4, 0, do_amlmmc_boot_wp,        "", ""),
	U_BOOT_CMD_MKENT(boot_wp_status, 2, 0, do_amlmmc_boot_wp_status, "", ""),
	U_BOOT_CMD_MKENT(ds,            4, 0, do_amlmmc_driver_strength, "", ""),
#ifdef CONFIG_SECURITYKEY
	U_BOOT_CMD_MKENT(key,           2, 0, do_amlmmc_key,           "", ""),
#endif
#ifdef MMC_HS400_MODE
	U_BOOT_CMD_MKENT(clktest,    3, 0, do_amlmmc_clktest,    "", ""),
	U_BOOT_CMD_MKENT(refix,    3, 0, do_amlmmc_refix,    "", ""),
	U_BOOT_CMD_MKENT(move_all, 4, 0, do_amlmmc_move_all_delay, "", ""),
	U_BOOT_CMD_MKENT(move_single, 5, 0, do_amlmmc_move_sig_delay, "", ""),
	U_BOOT_CMD_MKENT(set_rxdly, 5, 0, do_amlmmc_set_rxdelay, "", ""),
	U_BOOT_CMD_MKENT(set_txdly, 4, 0, do_amlmmc_set_txdelay, "", ""),
	U_BOOT_CMD_MKENT(set_vddee, 4, 0, do_amlmmc_set_vddee, "", ""),
	U_BOOT_CMD_MKENT(show_vddee, 3, 0, do_amlmmc_show_vddee, "", ""),
	U_BOOT_CMD_MKENT(reset_dly, 3, 0, do_amlmmc_reset_delay, "", ""),
	U_BOOT_CMD_MKENT(line_eyetest, 4, 0, do_amlmmc_line_eyetest, "", ""),
#endif
};

static int do_amlmmcops(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	cmd_tbl_t *cp;

	cp = find_cmd_tbl(argv[1], cmd_amlmmc, ARRAY_SIZE(cmd_amlmmc));

	if (cp == NULL || argc > cp->maxargs)
		return CMD_RET_USAGE;

	if (flag == CMD_FLAG_REPEAT && !cp->repeatable)
		return CMD_RET_SUCCESS;

	return cp->cmd(cmdtp, flag, argc, argv);
}

U_BOOT_CMD(
	amlmmc, 6, 1, do_amlmmcops,
	"AMLMMC sub system",
	"read  <partition_name> ram_addr addr_byte# cnt_byte\n"
	"amlmmc write <partition_name> ram_addr addr_byte# cnt_byte\n"
	"amlmmc erase <partition_name> addr_byte# cnt_byte\n"
	"amlmmc erase <partition_name>/<device num>\n"
	"amlmmc rescan <device_num>\n"
	"amlmmc part <device_num> - show partition information of mmc\n"
	"amlmmc list - lists available devices\n"
	"amlmmc env -  display env partition offset\n"
	"amlmmc switch <device_num> <part name> - part name : boot0, boot1, user\n"
	"amlmmc status <device_num> - read sd/emmc device status\n"
	"amlmmc ext_csd <device_num> <byte> - read sd/emmc device EXT_CSD [byte]\n"
	"amlmmc ext_csd <device_num> <byte> <value> - write sd/emmc device EXT_CSD [byte] value\n"
	"amlmmc response <device_num> - read sd/emmc last command response\n"
	"amlmmc controller <device_num> - read sd/emmc controller register\n"
	"amlmmc write_protect <partition_name> <write_protect_type>\n"
	"        - set write protect on partition through power_on or temporary\n"
	"amlmmc write_protect <addr_base16> <cnt_base10> <write_protect_type>\n"
	"        - set write protect on specified address through power_on or temporary\n"
	"amlmmc send_wp_status <partition_name> send protect status of partition\n"
	"amlmmc send_wp_status <addr_base16> <cnt_base10> send protect status on specified address\n"
	"amlmmc send_wp_type <partition_name> send protect type of partition\n"
	"amlmmc send_wp_type <addr_base16> <cnt_base10> send protect type on specified address\n"
	"amlmmc clear_wp <partition_name> clear write protect of partition\n"
	"amlmmc clear_wp <addr_base16> <cnt_base10> clear write protect on specified address\n"
	"amlmmc boot_wp <boot number> <write protect type> boot0/boot1/both, /poweron/permanent\n"
	"amlmmc boot_wp_status send boot write protect status\n"
	"amlmmc ds <dev_num> <val> set driver strength\n"
#ifdef CONFIG_SECURITYKEY
	"amlmmc key - disprotect key partition\n"
#endif
#ifdef MMC_HS400_MODE
	"amlmmc clktest <dev> - display info of delaycell and count\n"
	"amlmmc reset_dly <dev> - reset all delay register\n"
	"amlmmc set_rxdly <dev> <0xdelay1> <0xdelay2> - manually set rx delay value\n"
	"amlmmc set_txdly <dev> <0xdelay> - manually set tx delay\n"
	"amlmmc refix <dev> - fix adj\n"
	"amlmmc move_all <dev> <count> - move all data delay line <count> steps\n"
	"amlmmc move_single <dev> <line> <count> - move <line> <count> steps\n"
	"amlmmc set_vddee <dev> <value> - set vddee\n"
	"amlmmc show_vddee <dev> -show current vddee\n"
	"amlmmc line_eyetest <dev> <line> single line eyetest\n"
#endif
);

static u32 _calc_dtb_checksum(struct aml_dtb_rsv * dtb)
{
	int i = 0;
	int size = sizeof(struct aml_dtb_rsv) - sizeof(u32);
	u32 * buffer;
	u32 checksum = 0;

	if ((u64)dtb % 4 != 0) {
		BUG();
	}

	size = size >> 2;
	buffer = (u32*) dtb;
	while (i < size)
		checksum += buffer[i++];

	return checksum;
}

static int _verify_dtb_checksum(struct aml_dtb_rsv * dtb)
{
	u32 checksum;

	checksum = _calc_dtb_checksum(dtb);
	dtb_info("calc %x, store %x\n", checksum, dtb->checksum);

	return !(checksum == dtb->checksum);
}

static int _dtb_read(struct mmc *mmc, u64 blk, u64 cnt, void * addr)
{
	int dev = EMMC_DTB_DEV;
	u64 n;
	n = mmc->block_dev.block_read(dev, blk, cnt, addr);
	if (n != cnt) {
		dtb_err("%s: dev # %d, block # %#llx, count # %#llx ERROR!\n",
				__func__, dev, blk, cnt);
	}

	return (n != cnt);
}

static int _dtb_write(struct mmc *mmc, u64 blk, u64 cnt, void * addr)
{
	int dev = EMMC_DTB_DEV;
	u64 n;
	n = mmc->block_dev.block_write(dev, blk, cnt, addr);
	if (n != cnt) {
		dtb_err("%s: dev # %d, block # %#llx, count # %#llx ERROR!\n",
				__func__, dev, blk, cnt);
	}

	return (n != cnt);
}

static struct mmc *_dtb_init(void)
{
	struct mmc *mmc = find_mmc_device(EMMC_DTB_DEV);
	if (!mmc) {
		dtb_err("not find mmc\n");
		return NULL;
	}

	if (mmc_init(mmc)) {
		dtb_err("mmc init failed\n");
		return NULL;
	}
	return mmc;
}

static int dtb_read_shortcut(struct mmc * mmc, void *addr)
{
	u64 blk, cnt, dtb_glb_offset;
	int dev = EMMC_DTB_DEV;
	struct aml_dtb_info *info = &dtb_infos;
	struct partitions * part = NULL;
	struct virtual_partition *vpart = NULL;
	vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME);
	part = aml_get_partition_by_name(MMC_RESERVED_NAME);
	dtb_glb_offset = part->offset + vpart->offset;
	/* short cut */
	if (info->valid[0]) {
		dtb_info("short cut in...\n");
		blk = dtb_glb_offset / mmc->read_bl_len;
		cnt = vpart->size / mmc->read_bl_len;
		if (_dtb_read(mmc, blk, cnt, addr)) {
			dtb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n",
					__func__, dev, blk, cnt);
			/*try dtb2 if it's valid */
			if (info->valid[1]) {
				blk = (dtb_glb_offset + vpart->size) / mmc->read_bl_len;
				cnt = vpart->size / mmc->read_bl_len;
				if (_dtb_read(mmc, blk, cnt, addr)) {
					dtb_err("%s: dev # %d, block # %#llx, cnt # %#llx ERROR!\n",
						__func__, dev, blk, cnt);
					return -1;
				}
			}
		}
		return 0;
	}
	return -2;
}

static int update_dtb_info(struct mmc *mmc, void *addr)
{
	int ret = 0, dev = EMMC_DTB_DEV;
	u64 blk, cnt, dtb_glb_offset;
	struct aml_dtb_rsv * dtb = (struct aml_dtb_rsv *) addr;
	struct aml_dtb_info *info = &dtb_infos;
	int cpy = 1, valid = 0;
	struct partitions * part = NULL;
	struct virtual_partition *vpart = NULL;
	vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME);
	part = aml_get_partition_by_name(MMC_RESERVED_NAME);
	dtb_glb_offset = part->offset + vpart->offset;

	while (cpy >= 0) {
		blk = (dtb_glb_offset + cpy * (vpart->size)) / mmc->read_bl_len;
		cnt = vpart->size / mmc->read_bl_len;
		ret = _dtb_read(mmc, blk, cnt, addr);
		if (ret) {
			dtb_err("%s: dev # %d, block # %#llx, cnt # %#llx ERROR!\n",
				__func__, dev, blk, cnt);
		} else {
			ret = _verify_dtb_checksum(dtb);
			/* check magic avoid whole 0 issue */
			if (!ret && (dtb->magic != 0)) {
				info->stamp[cpy] = dtb->timestamp;
				info->valid[cpy] = 1;
			}
			else
				dtb_wrn("cpy %d is not valid\n", cpy);
		}
		valid += info->valid[cpy];
		cpy --;
	}
	return valid;
}

static int update_invalid_dtb(struct mmc *mmc, void *addr)
{
	int ret = 0, dev = EMMC_DTB_DEV;
	u64 blk, cnt, dtb_glb_offset;
	struct aml_dtb_rsv * dtb = (struct aml_dtb_rsv *) addr;
	struct aml_dtb_info *info = &dtb_infos;
	struct partitions * part = NULL;
	struct virtual_partition *vpart = NULL;
	vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME);
	part = aml_get_partition_by_name(MMC_RESERVED_NAME);
	dtb_glb_offset = part->offset + vpart->offset;
	cnt = vpart->size / mmc->read_bl_len;

	if (info->valid[1]) {
		blk = (dtb_glb_offset + vpart->size) / mmc->read_bl_len;
		if (_dtb_read(mmc, blk, cnt, addr)) {
		dtb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n",
				__func__, dev, blk, cnt);
			ret = -2;
		}
		/* fixme, update the invalid one - dtb1 */
		blk = (dtb_glb_offset) / mmc->read_bl_len;
		if (_dtb_write(mmc, blk, cnt, addr)) {
			dtb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n",
				__func__, dev, blk, cnt);
			ret = -4;
		}
		info->valid[0] = 1;
		info->stamp[0] = dtb->timestamp;
	} else {
		dtb_info("update dtb2");
		blk = (dtb_glb_offset + vpart->size) / mmc->read_bl_len;
		if (_dtb_write(mmc, blk, cnt, addr)) {
			dtb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n",
				__func__, dev, blk, cnt);
			ret = -2;
		}
		info->valid[1] = 1;
		info->stamp[1] = dtb->timestamp;
	}
	return ret;
}

int update_old_dtb(struct mmc *mmc, void *addr)
{
	int ret = 0, dev = EMMC_DTB_DEV;
	u64 blk, cnt, dtb_glb_offset;
	struct aml_dtb_rsv * dtb = (struct aml_dtb_rsv *) addr;
	struct aml_dtb_info *info = &dtb_infos;
	struct partitions * part = NULL;
	struct virtual_partition *vpart = NULL;
	vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME);
	part = aml_get_partition_by_name(MMC_RESERVED_NAME);
	dtb_glb_offset = part->offset + vpart->offset;
	cnt = vpart->size / mmc->read_bl_len;
	if (stamp_after(info->stamp[1], info->stamp[0])) {
		blk = (dtb_glb_offset + vpart->size) / mmc->read_bl_len;
		if (_dtb_read(mmc, blk, cnt, addr)) {
			dtb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n",
					__func__, dev, blk, cnt);
			ret = -3;
		}
		/*update dtb1*/
		blk = dtb_glb_offset / mmc->read_bl_len;
		if (_dtb_write(mmc, blk, cnt, addr)) {
			dtb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n",
					__func__, dev, blk, cnt);
			ret = -3;
		}
		info->stamp[0] = dtb->timestamp;
	} else if (stamp_after(info->stamp[0], info->stamp[1])) {
		/*update dtb2*/
		blk = (dtb_glb_offset + vpart->size) / mmc->read_bl_len;
		if (_dtb_write(mmc, blk, cnt, addr)) {
			dtb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n",
					__func__, dev, blk, cnt);
			ret = -3;
		}
		info->stamp[1] = dtb->timestamp;
	} else {
		dtb_info("do nothing\n");
	}
	return ret;
}

int dtb_read(void *addr)
{
	int ret = 0;
	int valid = 0;
	struct mmc *mmc;

	mmc = _dtb_init();
	if (mmc == NULL)
		return -10;

	if (dtb_read_shortcut(mmc, addr) == 0)
		return ret;

	valid = update_dtb_info(mmc, addr);
	dtb_info("total valid %d\n", valid);
	/* check valid */
	switch (valid) {
		/* none is valid, using the 1st one for compatibility*/
		case 0:
			ret = -1;
			goto _out;
		break;
		/* only 1 is valid, using the valid one */
		case 1:
			update_invalid_dtb(mmc, addr);
		break;
		/* both are valid, pickup new one. */
		case 2:
			update_old_dtb(mmc, addr);
		break;
		default:
			dtb_err("impossible valid values.\n");
			BUG();
		break;
	}
_out:
	return ret;
}


int dtb_write(void *addr)
{
	int ret = 0;
	struct aml_dtb_rsv * dtb = (struct aml_dtb_rsv *) addr;
	struct aml_dtb_info *info = &dtb_infos;
	u64 blk, cnt, dtb_glb_offset;
	int cpy, valid;
	struct mmc * mmc;
	struct partitions * part = NULL;
	struct virtual_partition *vpart = NULL;
	vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME);
	part = aml_get_partition_by_name(MMC_RESERVED_NAME);
	dtb_glb_offset = part->offset + vpart->offset;

	mmc = _dtb_init();
	if (NULL == mmc)
		return -10;

	/* stamp */
	valid = info->valid[0] + info->valid[1];
	dtb_info("valid %d\n", valid);
	if (0 == valid)
		dtb->timestamp = 0;
	else if (1 == valid) {
		dtb->timestamp = 1 + info->stamp[info->valid[0]?0:1];
	} else {
		/* both are valid */
		if (info->stamp[0] != info->stamp[1]) {
			dtb_wrn("timestamp are not same %d:%d\n",
				info->stamp[0], info->stamp[1]);
			dtb->timestamp = 1 + ((info->stamp[1] > info->stamp[0]) ?
				info->stamp[1]:info->stamp[0]);
		} else
			dtb->timestamp = 1 + info->stamp[0];
	}
	/*setting version and magic*/
	dtb->version = 1; /* base version */
	dtb->magic = 0x00447e41; /*A~D\0*/
	dtb->checksum = _calc_dtb_checksum(dtb);
	dtb_info("new stamp %d, checksum 0x%x, version %d, magic %s\n",
		dtb->timestamp, dtb->checksum, dtb->version, (char *)&dtb->magic);

	for (cpy = 0; cpy < DTB_COPIES; cpy++) {
		blk = (dtb_glb_offset + cpy * (vpart->size)) / mmc->read_bl_len;
		cnt = vpart->size / mmc->read_bl_len;
		ret |= _dtb_write(mmc, blk, cnt, addr);
		info->valid[cpy] = 1;
		info->stamp[cpy] = dtb->timestamp;
	}

	return ret;
}

extern int check_valid_dts(unsigned char *buffer, unsigned char **dts);
int renew_partition_tbl(unsigned char *buffer)
{
	int ret = 0;
	unsigned char *temp = NULL;

	if (!buffer)
		return 1;
	temp = malloc (AML_DTB_IMG_MAX_SZ);
	if (!temp)
		return 1;
	memcpy(temp, buffer, AML_DTB_IMG_MAX_SZ);
	/* todo, check new dts imcoming.... */
	ret = check_valid_dts(temp, NULL);
	free(temp);

	/* only the dts new is valid */
	if (!ret) {
		free_partitions();
		ret = get_partition_from_dts(buffer);
		if (ret == -1)
			goto _out;

		if (0 == mmc_device_init(_dtb_init())) {
			printf("partition table success\n");
			ret = 0;
			goto _out;
		}
		printf("partition table error\n");
		ret = 1;
	}

_out:
	return ret;
}

int do_amlmmc_dtb_key(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	int dev, ret = 0;
	void *addr = NULL;
	u64 cnt = 0, n = 0, blk = 0;
	//u64 size;
	struct partitions *part = NULL;
	struct virtual_partition *vpart = NULL;
	vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME);
	part = aml_get_partition_by_name(MMC_RESERVED_NAME);

	switch (argc) {
		case 3:
			if (strcmp(argv[1], "erase") == 0) {
				if (strcmp(argv[2], "dtb") == 0) {
					printf("start erase dtb......\n");
					dev = EMMC_DTB_DEV;
					struct mmc *mmc = find_mmc_device(dev);
					if (!mmc) {
						printf("not find mmc\n");
						return 1;
					}
					blk = (part->offset + vpart->offset) / mmc->read_bl_len;
					cnt = (vpart->size * 2) / mmc->read_bl_len;
					if (cnt != 0)
						n = mmc->block_dev.block_erase(dev, blk, cnt);
					printf("dev # %d, %s, several blocks erased %s\n",
							dev, (flag == 0) ? " ":(argv[2]),(n == 0) ? "OK" : "ERROR");
					return (n == 0) ? 0 : 1;
				}else if (strcmp(argv[2], "key") == 0){
					printf("start erase key......\n");
					dev = 1;
					struct mmc *mmc = find_mmc_device(dev);
					if (!mmc) {
						printf("not find mmc\n");
						return 1;
					}
					n = mmc_key_erase();
					printf("dev # %d, %s, several blocks erased %s\n",
							dev, (flag == 0) ? " ":(argv[2]),(n == 0) ? "OK" : "ERROR");
					return (n == 0) ? 0 : 1;
				}
			} else if (strcmp(argv[1], "cali_pattern") == 0) {

				if (strcmp(argv[2], "write") == 0) {
					dev = EMMC_DTB_DEV;
					struct mmc *mmc = find_mmc_device(dev);
					if (!mmc) {
						printf("not find mmc\n");
						return 1;
					}
					vpart = aml_get_virtual_partition_by_name(MMC_PATTERN_NAME);
					part = aml_get_partition_by_name(MMC_RESERVED_NAME);
					addr = (void *)malloc(vpart->size);
					if (addr == NULL) {
						printf("cali_pattern malloc fail\n");
						return 1;
					}
					mmc_write_cali_mattern(addr);
					blk = (part->offset + vpart->offset) / mmc->read_bl_len;
					cnt = vpart->size / mmc->read_bl_len;
					if (cnt != 0)
						n = mmc->block_dev.block_write(dev, blk, cnt, addr);
					printf("dev # %d, %s, several calibration pattern blocks write %s\n",
							dev, (flag == 0) ? " ":(argv[2]),(n == cnt) ? "OK" : "ERROR");
					free(addr);
					return (n == cnt) ? 0 : 1;
				}
			}
			return 0;
		case 4:
			addr = (void *)simple_strtoul(argv[2], NULL, 16);
			if (strcmp(argv[1], "dtb_read") == 0) {
				/* fixme, */
				ret = dtb_read(addr);
				return 0;

			} else if (strcmp(argv[1], "dtb_write") == 0) {
				/* fixme, should we check the return value? */
				ret = dtb_write(addr);
				ret |= renew_partition_tbl(addr);
				return ret;
			}
			return 0;
		default:
			break;
	}
	return 1;
}

/* update partition table in reserved partition. */
__weak int emmc_update_ept(unsigned char *buffer)
{
	int ret = 0;

#ifndef DTB_BIND_KERNEL
	dtb_write(buffer);
#endif
	ret = renew_partition_tbl(buffer);
	return ret;
}

/* fixme, should use renew_partition_tbl here! */
__weak int emmc_update_mbr(unsigned char *buffer)
{
	int ret = 0;
	cpu_id_t cpu_id = get_cpu_id();

	if (cpu_id.family_id < MESON_CPU_MAJOR_ID_GXL) {
		ret = -1;
		printf("MBR not support, try dtb\n");
		goto _out;
	}
#ifndef DTB_BIND_KERNEL
	dtb_write(buffer);
#endif
	ret = get_partition_from_dts(buffer);
	if (ret) {
		printf("Fail to get partition table from dts\n");
		goto _out;
	}
	ret = mmc_device_init(_dtb_init());
	printf("%s: update mbr %s\n", __func__, ret?"Fail":"Success");
_out:
	return ret;
}

int do_emmc_erase(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	int dev;
	u64 cnt = 0, n = 0, blk = 0;
	//u64 size;
	struct partitions *part = NULL;
	struct virtual_partition *vpart = NULL;
	struct mmc *mmc;
	if (argc != 3)
		return CMD_RET_USAGE;

	vpart = aml_get_virtual_partition_by_name(MMC_DTB_NAME);
	part = aml_get_partition_by_name(MMC_RESERVED_NAME);
	if (strcmp(argv[2], "dtb") == 0) {
		printf("start erase dtb......\n");
		dev = EMMC_DTB_DEV;
		mmc = find_mmc_device(dev);
		if (!mmc) {
			printf("not find mmc\n");
			return 1;
		}
		blk = (part->offset + vpart->offset) / mmc->read_bl_len;
		cnt = (vpart->size * 2) / mmc->read_bl_len;
		if (cnt != 0)
			n = mmc->block_dev.block_erase(dev, blk, cnt);
		printf("dev # %d, %s, several blocks erased %s\n",
				dev, (flag == 0) ? " ":(argv[2]),(n == 0) ? "OK" : "ERROR");
		return (n == 0) ? 0 : 1;
	} else if (strcmp(argv[2], "key") == 0) {
		printf("start erase key......\n");
		dev = 1;
		mmc = find_mmc_device(dev);
		if (!mmc) {
			printf("not find mmc\n");
			return 1;
		}
		n = mmc_key_erase();
		printf("dev # %d, %s, several blocks erased %s\n",
				dev, (flag == 0) ? " ":(argv[2]),(n == 0) ? "OK" : "ERROR");
		return (n == 0) ? 0 : 1;
	}
	return 1;
}

int do_emmc_dtb_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	int ret = 0;
	void *addr = NULL;

	if (argc != 4)
		return CMD_RET_USAGE;

	addr = (void *)simple_strtoul(argv[2], NULL, 16);
	ret = dtb_read(addr);
	return ret;
}

int do_emmc_dtb_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	int ret = 0;
	void *addr = NULL;

	if (argc != 4)
		return CMD_RET_USAGE;

	addr = (void *)simple_strtoul(argv[2], NULL, 16);
	ret = dtb_write(addr);
	ret |= renew_partition_tbl(addr);
	return ret;
}

static int _fastboot_context_read(struct mmc *mmc, u64 blk,
		u64 cnt, void *addr)
{
	int dev = EMMC_FASTBOOT_CONTEXT_DEV;
	u64 n;

	n = mmc->block_dev.block_read(dev, blk, cnt, addr);
	if (n != cnt) {
		fb_err("%s: dev # %d, block # %#llx, count # %#llx ERROR!\n",
			__func__, dev, blk, cnt);
	}

	return n != cnt;
}

int fastboot_context_read(void *buf, size_t size)
{
	uint32_t crc_result;
	struct mmc *mmc;
	struct FastbootContext *fb_cont;
	int fb_size = sizeof(struct FastbootContext);
	u64 blk, cnt, fb_glb_offset;
	int dev = EMMC_FASTBOOT_CONTEXT_DEV;
	struct partitions *part = NULL;
	struct virtual_partition *vpart = NULL;

	mmc = find_mmc_device(dev);
	if (!mmc) {
		puts("no mmc devices available\n");
		return 1;
	}

	if (mmc_init(mmc)) {
		printf("%s() %d: emmc init failed\n", __func__, __LINE__);
		return 1;
	}

	vpart = aml_get_virtual_partition_by_name(MMC_FASTBOOT_CONTEXT_NAME);
	part = aml_get_partition_by_name(MMC_RESERVED_NAME);
	fb_glb_offset = part->offset + vpart->offset;

	blk = fb_glb_offset / mmc->read_bl_len;
	cnt = size / mmc->read_bl_len;

	if (_fastboot_context_read(mmc, blk, cnt, buf))
		return 1;

	fb_cont = (struct FastbootContext *)buf;
	crc_result = crc32(0, buf, fb_size - 4);

	if (crc_result != fb_cont->crc32) {
		printf("%s %d: crc checksum ERROR!\n", __func__, __LINE__);
		return 1;
	}
	return 0;
}


int do_emmc_fb_read(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	int ret = 0;
	void *addr = NULL;
	u64 size;

	if (argc != 4)
		return CMD_RET_USAGE;

	addr = (void *)simple_strtoul(argv[2], NULL, 16);
	size = simple_strtoull(argv[3], NULL, 16);
	ret = fastboot_context_read(addr, size);
	return ret;
}

static int _fastboot_context_write(struct mmc *mmc, u64 blk,
		u64 cnt, void *addr)
{
	int dev = EMMC_FASTBOOT_CONTEXT_DEV;
	int n;

	n = mmc->block_dev.block_write(dev, blk, cnt, addr);

	if (n != cnt) {
		fb_err("%s: dev # %d, block # %#llx,cnt # %#llx ERROR!\n",
			__func__, dev, blk, cnt);
	}

	return n != cnt;
}

int fastboot_context_write(void *buf, size_t size)
{
	int ret = 0;
	struct FastbootContext *fb_cont = (struct FastbootContext *)buf;
	u64 blk, cnt, fb_glb_offset;
	struct mmc *mmc;
	struct partitions *part = NULL;
	struct virtual_partition *vpart = NULL;
	int dev = EMMC_FASTBOOT_CONTEXT_DEV;
	int fb_size = sizeof(struct FastbootContext);

	mmc = find_mmc_device(dev);
	if (!mmc) {
		puts("no mmc devices available\n");
		return 1;
	}

	ret = mmc_init(mmc);
	if (ret) {
		printf("%s() %d: emmc init failed\n", __func__, __LINE__);
		return 1;
	}

	vpart = aml_get_virtual_partition_by_name(MMC_FASTBOOT_CONTEXT_NAME);
	part = aml_get_partition_by_name(MMC_RESERVED_NAME);
	fb_glb_offset = part->offset + vpart->offset;
	fb_cont->crc32 = crc32(0, buf, fb_size - 4);
	blk = fb_glb_offset / mmc->read_bl_len;
	cnt = size / mmc->read_bl_len;
	ret = _fastboot_context_write(mmc, blk, cnt, buf);

	return ret;
}

int do_emmc_fb_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	int ret = 0;
	void *addr = NULL;
	u64 size;

	if (argc != 4)
		return CMD_RET_USAGE;

	addr = (void *)simple_strtoul(argv[2], NULL, 16);
	size = simple_strtoull(argv[3], NULL, 16);
	ret = fastboot_context_write(addr, size);
	return ret;
}


static cmd_tbl_t cmd_emmc[] = {
	U_BOOT_CMD_MKENT(dtb_read,  4, 0, do_emmc_dtb_read,  "", ""),
	U_BOOT_CMD_MKENT(dtb_write, 4, 0, do_emmc_dtb_write, "", ""),
	U_BOOT_CMD_MKENT(erase,     3, 0, do_emmc_erase,     "", ""),
	U_BOOT_CMD_MKENT(fastboot_read, 4, 0, do_emmc_fb_read, "", ""),
	U_BOOT_CMD_MKENT(fastboot_write, 4, 0, do_emmc_fb_write, "", ""),
};

static int do_emmc_dtb_key(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
	cmd_tbl_t *cp;

	cp = find_cmd_tbl(argv[1], cmd_emmc, ARRAY_SIZE(cmd_emmc));

	if (cp == NULL || argc > cp->maxargs)
		return CMD_RET_USAGE;
	if (flag == CMD_FLAG_REPEAT && !cp->repeatable)
		return CMD_RET_SUCCESS;
	return cp->cmd(cmdtp, flag, argc, argv);
}


U_BOOT_CMD(
	emmc, 4, 1, do_emmc_dtb_key,
	"EMMC sub system",
	"dtb_read addr size\n"
	"emmc dtb_write addr size\n"
	"emmc erase dtb\n"
	"emmc erase key\n"
	"emmc fastboot_read addr size\n"
	"emmc fastboot_write addr size\n");

