/*
 * 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


void mmc_spl_load_image(uint32_t offs, unsigned int size, void *vdst)
{
	uint blk_start, blk_cnt, err;

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

	if (mmc_init(mmc)) {
		puts("MMC init failed\n");
		return;
	}

	blk_start = ALIGN(offs, mmc->read_bl_len) / mmc->read_bl_len;
	blk_cnt = ALIGN(size, mmc->read_bl_len) / mmc->read_bl_len;

	err = mmc->block_dev.block_read(0, blk_start, blk_cnt, vdst);
	if (err != blk_cnt) {
		puts("spl: mmc read failed!!\n");
		hang();
	}
}

/*
 * 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;
#ifndef CONFIG_FSL_CORENET
	uchar *tmp_buf;
	u32 blklen;
	uchar val;
	uint i, byte_num;
#endif
	u32 offset, code_len;
	struct mmc *mmc;

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

#ifdef CONFIG_FSL_CORENET
	offset = CONFIG_SYS_MMC_U_BOOT_OFFS;
	code_len = CONFIG_SYS_MMC_U_BOOT_SIZE;
#else
	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
	*/
#endif
	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");
#ifndef CONFIG_FSL_CORENET
		free(tmp_buf);
#endif
		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)();
}
