Merge pull request #1223 from vchong/poplar_bl1loadsfip

poplar: Enable emmc and recovery build support
diff --git a/plat/hisilicon/poplar/bl1_plat_setup.c b/plat/hisilicon/poplar/bl1_plat_setup.c
index c65e29e..7d6f10c 100644
--- a/plat/hisilicon/poplar/bl1_plat_setup.c
+++ b/plat/hisilicon/poplar/bl1_plat_setup.c
@@ -9,6 +9,8 @@
 #include <bl_common.h>
 #include <console.h>
 #include <debug.h>
+#include <dw_mmc.h>
+#include <emmc.h>
 #include <errno.h>
 #include <generic_delay_timer.h>
 #include <mmio.h>
@@ -71,6 +73,9 @@
 void bl1_platform_setup(void)
 {
 	int i;
+#if !POPLAR_RECOVERY
+	dw_mmc_params_t params = EMMC_INIT_PARAMS(POPLAR_EMMC_DESC_BASE);
+#endif
 
 	generic_delay_timer_init();
 
@@ -78,6 +83,12 @@
 	for (i = 0; i < GPIO_MAX; i++)
 		pl061_gpio_register(GPIO_BASE(i), i);
 
+#if !POPLAR_RECOVERY
+	/* SoC-specific emmc register are initialized/configured by bootrom */
+	INFO("BL1: initializing emmc\n");
+	dw_mmc_init(&params);
+#endif
+
 	plat_io_setup();
 }
 
diff --git a/plat/hisilicon/poplar/bl2_plat_setup.c b/plat/hisilicon/poplar/bl2_plat_setup.c
index db507c3..7edfab7 100644
--- a/plat/hisilicon/poplar/bl2_plat_setup.c
+++ b/plat/hisilicon/poplar/bl2_plat_setup.c
@@ -9,6 +9,8 @@
 #include <bl_common.h>
 #include <console.h>
 #include <debug.h>
+#include <dw_mmc.h>
+#include <emmc.h>
 #include <errno.h>
 #include <generic_delay_timer.h>
 #include <mmio.h>
@@ -181,12 +183,24 @@
 
 void bl2_early_platform_setup(meminfo_t *mem_layout)
 {
+#if !POPLAR_RECOVERY
+	dw_mmc_params_t params = EMMC_INIT_PARAMS(POPLAR_EMMC_DESC_BASE);
+#endif
+
 	console_init(PL011_UART0_BASE, PL011_UART0_CLK_IN_HZ, PL011_BAUDRATE);
 
 	/* Enable arch timer */
 	generic_delay_timer_init();
 
 	bl2_tzram_layout = *mem_layout;
+
+#if !POPLAR_RECOVERY
+	/* SoC-specific emmc register are initialized/configured by bootrom */
+	INFO("BL2: initializing emmc\n");
+	dw_mmc_init(&params);
+#endif
+
+	plat_io_setup();
 }
 
 void bl2_plat_arch_setup(void)
@@ -201,7 +215,6 @@
 
 void bl2_platform_setup(void)
 {
-	plat_io_setup();
 }
 
 unsigned long plat_get_ns_image_entrypoint(void)
diff --git a/plat/hisilicon/poplar/include/hi3798cv200.h b/plat/hisilicon/poplar/include/hi3798cv200.h
index 540d0aa..125b048 100644
--- a/plat/hisilicon/poplar/include/hi3798cv200.h
+++ b/plat/hisilicon/poplar/include/hi3798cv200.h
@@ -7,6 +7,8 @@
 #ifndef __HI3798cv200_H__
 #define __HI3798cv200_H__
 
+#include <utils_def.h>
+
 /* PL011 */
 #define PL011_UART0_BASE		(0xF8B00000)
 #define PL011_BAUDRATE			(115200)
@@ -63,11 +65,11 @@
 #define EMMC_CLK_50M			(1 << 8)
 #define EMMC_CLK_25M			(2 << 8)
 
-#define EMMC_DESC_SIZE			(0xF0000)
+#define EMMC_DESC_SIZE			U(0x00100000) /* 1MB */
 #define EMMC_INIT_PARAMS(base)				\
 	{	.bus_width = EMMC_BUS_WIDTH_8,		\
 		.clk_rate = 25 * 1000 * 1000,		\
-		.desc_base = (base) - EMMC_DESC_SIZE,	\
+		.desc_base = (base),	\
 		.desc_size = EMMC_DESC_SIZE,		\
 		.flags =  EMMC_FLAG_CMD23,		\
 		.reg_base = REG_BASE_MCI,		\
diff --git a/plat/hisilicon/poplar/include/platform_def.h b/plat/hisilicon/poplar/include/platform_def.h
index 3d1ad9b..c0f8371 100644
--- a/plat/hisilicon/poplar/include/platform_def.h
+++ b/plat/hisilicon/poplar/include/platform_def.h
@@ -12,6 +12,7 @@
 #include <gic_common.h>
 #include <interrupt_props.h>
 #include <tbbr/tbbr_img_def.h>
+#include <utils_def.h>
 #include "hi3798cv200.h"
 #include "poplar_layout.h"		/* BL memory region sizes, etc */
 
@@ -53,13 +54,12 @@
 #define POPLAR_DRAM_ID	1
 
 /*
- * DDR for OP-TEE (28MB from 0x02200000 -0x04000000) is divided in several
+ * DDR for OP-TEE (26MB from 0x02400000 -0x04000000) is divided in several
  * regions:
  *   - Secure DDR (default is the top 16MB) used by OP-TEE
  *   - Non-secure DDR (4MB) reserved for OP-TEE's future use
  *   - Secure DDR (4MB aligned on 4MB) for OP-TEE's "Secure Data Path" feature
  *   - Non-secure DDR used by OP-TEE (shared memory and padding) (4MB)
- *   - Non-secure DDR (2MB) reserved for OP-TEE's future use
  */
 #define DDR_SEC_SIZE			0x01000000
 #define DDR_SEC_BASE			0x03000000
@@ -96,6 +96,11 @@
 #endif /* SPD_none */
 #endif
 
+#define POPLAR_EMMC_DATA_BASE U(0x02200000)
+#define POPLAR_EMMC_DATA_SIZE EMMC_DESC_SIZE
+#define POPLAR_EMMC_DESC_BASE (POPLAR_EMMC_DATA_BASE + POPLAR_EMMC_DATA_SIZE)
+#define POPLAR_EMMC_DESC_SIZE EMMC_DESC_SIZE
+
 #define PLAT_POPLAR_NS_IMAGE_OFFSET	0x37000000
 
 /* Page table and MMU setup constants */
diff --git a/plat/hisilicon/poplar/include/poplar_layout.h b/plat/hisilicon/poplar/include/poplar_layout.h
index e0b5618..9ce0434 100644
--- a/plat/hisilicon/poplar/include/poplar_layout.h
+++ b/plat/hisilicon/poplar/include/poplar_layout.h
@@ -12,8 +12,8 @@
  */
 
 /*
- * When Poplar is powered on, boot ROM loads the initial content of
- * boot media into low memory, verifies it, and begins executing it
+ * When Poplar is powered on, boot ROM verifies the initial content of
+ * boot media, loads it into low memory, and begins executing it
  * in 32-bit mode.  The image loaded is "l-loader.bin", which contains
  * a small amount code along with an embedded ARM Trusted Firmware
  * BL1 image.  The main purpose of "l-loader" is to prepare the
@@ -78,12 +78,36 @@
 #define BL1_OFFSET			0x0000D000	/* page multiple */
 #define FIP_BASE			0x02040000
 
+/*
+ * FIP_BASE_EMMC = 0x40000 - 0x1000
+ * = fip.bin offset - l-loader text offset
+ * in l-loader.bin
+ */
+#define FIP_BASE_EMMC			0x0003f000
+
 #define BL1_RO_SIZE			0x00008000	/* page multiple */
 #define BL1_RW_SIZE			0x00008000	/* page multiple */
 #define BL1_SIZE			(BL1_RO_SIZE + BL1_RW_SIZE)
 #define BL2_SIZE			0x0000c000	/* page multiple */
 #define BL31_SIZE			0x00014000
+#if !POPLAR_RECOVERY
+/*
+ * emmc partition1 4096KB
+ * - l-loader.bin 1984KB
+ * |- l-loader + bl1.bin 256KB
+ * |- fip.bin 1728KB (0x001b0000)
+ * - u-boot persistent data 64KB
+ * - uefi persistent data 2048KB
+ */
+#define FIP_SIZE			0x001b0000  /* absolute max */
+#else
+/*
+ * same as above, but bootrom can only load an image (l-loader.bin) of
+ * 1024KB max, so after deducting the size of l-loader + bl1.bin (256KB),
+ * that leaves 768KB (0x000c0000) for fip.bin
+ */
 #define FIP_SIZE			0x000c0000  /* absolute max */
+#endif
 
      /* BL1_OFFSET */			/* (Defined above) */
 #define BL1_BASE			(LLOADER_TEXT_BASE + BL1_OFFSET)
diff --git a/plat/hisilicon/poplar/plat_storage.c b/plat/hisilicon/poplar/plat_storage.c
index ab94cba..468e229 100644
--- a/plat/hisilicon/poplar/plat_storage.c
+++ b/plat/hisilicon/poplar/plat_storage.c
@@ -7,6 +7,7 @@
 #include <arch_helpers.h>
 #include <assert.h>
 #include <debug.h>
+#include <emmc.h>
 #include <firmware_image_package.h>
 #include <io_block.h>
 #include <io_driver.h>
@@ -21,19 +22,41 @@
 #include <utils.h>
 #include "platform_def.h"
 
-static const io_dev_connector_t *mmap_dev_con;
-static const io_dev_connector_t *fip_dev_con;
+#if !POPLAR_RECOVERY
+static const io_dev_connector_t *emmc_dev_con;
+static uintptr_t emmc_dev_handle;
+static int open_emmc(const uintptr_t spec);
 
-static uintptr_t mmap_dev_handle;
-static uintptr_t fip_dev_handle;
+static const io_block_spec_t emmc_fip_spec = {
+	.offset		= FIP_BASE_EMMC,
+	.length		= FIP_SIZE
+};
 
+static const io_block_dev_spec_t emmc_dev_spec = {
+	.buffer		= {
+		.offset	= POPLAR_EMMC_DATA_BASE,
+		.length	= POPLAR_EMMC_DATA_SIZE,
+	},
+	.ops		= {
+		.read	= emmc_read_blocks,
+		.write	= emmc_write_blocks,
+	},
+	.block_size	= EMMC_BLOCK_SIZE,
+};
+#else
+static const io_dev_connector_t *mmap_dev_con;
+static uintptr_t mmap_dev_handle;
 static int open_mmap(const uintptr_t spec);
-static int open_fip(const uintptr_t spec);
 
 static const io_block_spec_t loader_fip_spec = {
 	.offset		= FIP_BASE,
 	.length		= FIP_SIZE
 };
+#endif
+
+static const io_dev_connector_t *fip_dev_con;
+static uintptr_t fip_dev_handle;
+static int open_fip(const uintptr_t spec);
 
 static const io_uuid_spec_t bl2_uuid_spec = {
 	.uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2,
@@ -58,11 +81,19 @@
 };
 
 static const struct plat_io_policy policies[] = {
+#if !POPLAR_RECOVERY
+	[FIP_IMAGE_ID] = {
+		&emmc_dev_handle,
+		(uintptr_t)&emmc_fip_spec,
+		open_emmc
+	},
+#else
 	[FIP_IMAGE_ID] = {
 		&mmap_dev_handle,
 		(uintptr_t)&loader_fip_spec,
 		open_mmap
 	},
+#endif
 	[BL2_IMAGE_ID] = {
 		&fip_dev_handle,
 		(uintptr_t)&bl2_uuid_spec,
@@ -85,6 +116,28 @@
 	},
 };
 
+#if !POPLAR_RECOVERY
+static int open_emmc(const uintptr_t spec)
+{
+	int result;
+	uintptr_t local_image_handle;
+
+	result = io_dev_init(emmc_dev_handle, (uintptr_t)NULL);
+	if (result == 0) {
+		result = io_open(emmc_dev_handle, spec, &local_image_handle);
+		if (result == 0) {
+			INFO("Using eMMC\n");
+			io_close(local_image_handle);
+		} else {
+			ERROR("error opening emmc\n");
+		}
+	} else {
+		ERROR("error initializing emmc\n");
+	}
+
+	return result;
+}
+#else
 static int open_mmap(const uintptr_t spec)
 {
 	int result;
@@ -94,11 +147,18 @@
 	if (result == 0) {
 		result = io_open(mmap_dev_handle, spec, &local_image_handle);
 		if (result == 0) {
+			INFO("Using mmap\n");
 			io_close(local_image_handle);
+		} else {
+			ERROR("error opening mmap\n");
 		}
+	} else {
+		ERROR("error initializing mmap\n");
 	}
+
 	return result;
 }
+#endif
 
 static int open_fip(const uintptr_t spec)
 {
@@ -109,12 +169,13 @@
 	if (result == 0) {
 		result = io_open(fip_dev_handle, spec, &local_image_handle);
 		if (result == 0) {
+			INFO("Using FIP\n");
 			io_close(local_image_handle);
 		} else {
-			VERBOSE("error opening fip\n");
+			ERROR("error opening fip\n");
 		}
 	} else {
-		VERBOSE("error initializing fip\n");
+		ERROR("error initializing fip\n");
 	}
 
 	return result;
@@ -142,17 +203,31 @@
 {
 	int result;
 
+#if !POPLAR_RECOVERY
+	result = register_io_dev_block(&emmc_dev_con);
+#else
 	result = register_io_dev_memmap(&mmap_dev_con);
+#endif
 	assert(result == 0);
 
 	result = register_io_dev_fip(&fip_dev_con);
 	assert(result == 0);
 
+#if !POPLAR_RECOVERY
+	result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
+				&fip_dev_handle);
+#else
 	result = io_dev_open(fip_dev_con, (uintptr_t)&loader_fip_spec,
 				&fip_dev_handle);
+#endif
 	assert(result == 0);
 
+#if !POPLAR_RECOVERY
+	result = io_dev_open(emmc_dev_con, (uintptr_t)&emmc_dev_spec,
+				&emmc_dev_handle);
+#else
 	result = io_dev_open(mmap_dev_con, (uintptr_t)NULL, &mmap_dev_handle);
+#endif
 	assert(result == 0);
 
 	(void) result;
diff --git a/plat/hisilicon/poplar/platform.mk b/plat/hisilicon/poplar/platform.mk
index 818e311..2dbbac6 100644
--- a/plat/hisilicon/poplar/platform.mk
+++ b/plat/hisilicon/poplar/platform.mk
@@ -15,6 +15,9 @@
 endif
 $(eval $(call add_define,POPLAR_TSP_RAM_LOCATION_ID))
 
+POPLAR_RECOVERY		:= 0
+$(eval $(call add_define,POPLAR_RECOVERY))
+
 NEED_BL33			:= yes
 
 COLD_BOOT_SINGLE_CPU		:= 1
@@ -36,6 +39,7 @@
 			-Iinclude/plat/arm/common/		\
 			-Iplat/hisilicon/poplar			\
 			-Iinclude/common/tbbr			\
+			-Iinclude/drivers/synopsys		\
 			-Iinclude/drivers/io
 
 PLAT_BL_COMMON_SOURCES	:=						\
@@ -54,6 +58,8 @@
 BL1_SOURCES	+=							\
 		lib/cpus/aarch64/cortex_a53.S				\
 		drivers/arm/pl061/pl061_gpio.c				\
+		drivers/emmc/emmc.c					\
+		drivers/synopsys/emmc/dw_mmc.c				\
 		drivers/io/io_storage.c					\
 		drivers/io/io_block.c					\
 		drivers/gpio/gpio.c					\
@@ -65,6 +71,8 @@
 
 BL2_SOURCES	+=      						\
 		drivers/arm/pl061/pl061_gpio.c				\
+		drivers/emmc/emmc.c					\
+		drivers/synopsys/emmc/dw_mmc.c				\
 		drivers/io/io_storage.c					\
 		drivers/io/io_block.c					\
 		drivers/io/io_fip.c					\