/*
 * Copyright 2013 Freescale Semiconductor, Inc.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <mmc.h>
#include <malloc.h>

/*
 * The environment variables are written to just after the u-boot image
 * on SDCard, so we must read the MBR to get the start address and code
 * length of the u-boot image, then calculate the address of the env.
 */
#define ESDHC_BOOT_IMAGE_SIZE	0x48
#define ESDHC_BOOT_IMAGE_ADDR	0x50
#define MBRDBR_BOOT_SIG_55	0x1fe
#define MBRDBR_BOOT_SIG_AA	0x1ff
#define CONFIG_CFG_DATA_SECTOR	0

/*
 * The main entry for mmc booting. It's necessary that SDRAM is already
 * configured and available since this code loads the main U-Boot image
 * from mmc into SDRAM and starts it from there.
 */

void __noreturn mmc_boot(void)
{
	__attribute__((noreturn)) void (*uboot)(void);
	uint blk_start, blk_cnt, err;
	u32 blklen;
	uchar *tmp_buf;
	uchar val;
	uint i, byte_num;
	u32 offset, code_len;
	struct mmc *mmc;

	mmc = find_mmc_device(0);
	if (!mmc) {
		puts("spl: mmc device not found!!\n");
		hang();
	}

	blklen = mmc->read_bl_len;
	tmp_buf = malloc(blklen);
	if (!tmp_buf) {
		puts("spl: malloc memory failed!!\n");
		hang();
	}
	memset(tmp_buf, 0, blklen);

	/*
	* Read source addr from sd card
	*/
	err = mmc->block_dev.block_read(0, CONFIG_CFG_DATA_SECTOR, 1, tmp_buf);
	if (err != 1) {
		puts("spl: mmc read failed!!\n");
		free(tmp_buf);
		hang();
	}

	val = *(tmp_buf + MBRDBR_BOOT_SIG_55);
	if (0x55 != val) {
		puts("spl: mmc signature is not valid!!\n");
		free(tmp_buf);
		hang();
	}
	val = *(tmp_buf + MBRDBR_BOOT_SIG_AA);
	if (0xAA != val) {
		puts("spl: mmc signature is not valid!!\n");
		free(tmp_buf);
		hang();
	}

	byte_num = 4;
	offset = 0;
	for (i = 0; i < byte_num; i++) {
		val = *(tmp_buf + ESDHC_BOOT_IMAGE_ADDR + i);
		offset = (offset << 8) + val;
	}
	offset += CONFIG_SYS_MMC_U_BOOT_OFFS;
	/* Get the code size from offset 0x48 */
	byte_num = 4;
	code_len = 0;
	for (i = 0; i < byte_num; i++) {
		val = *(tmp_buf + ESDHC_BOOT_IMAGE_SIZE + i);
		code_len = (code_len << 8) + val;
	}
	code_len -= CONFIG_SYS_MMC_U_BOOT_OFFS;
	/*
	* Load U-Boot image from mmc into RAM
	*/
	blk_start = ALIGN(offset, mmc->read_bl_len) / mmc->read_bl_len;
	blk_cnt = ALIGN(code_len, mmc->read_bl_len) / mmc->read_bl_len;
	err = mmc->block_dev.block_read(0, blk_start, blk_cnt,
					(uchar *)CONFIG_SYS_MMC_U_BOOT_DST);
	if (err != blk_cnt) {
		puts("spl: mmc read failed!!\n");
		free(tmp_buf);
		hang();
	}

	/*
	* Clean d-cache and invalidate i-cache, to
	* make sure that no stale data is executed.
	*/
	flush_cache(CONFIG_SYS_MMC_U_BOOT_DST, CONFIG_SYS_MMC_U_BOOT_SIZE);

	/*
	* Jump to U-Boot image
	*/
	uboot = (void *)CONFIG_SYS_MMC_U_BOOT_START;
	(*uboot)();
}
