drivers: Add emmc driver for Broadcom platforms

Add emmc driver for Broadcom platforms

Change-Id: I126a6dfccd41062cb0b856f2c2fb1f724730b95e
Signed-off-by: Sheetal Tigadoli <sheetal.tigadoli@broadcom.com>
diff --git a/plat/brcm/board/common/board_common.mk b/plat/brcm/board/common/board_common.mk
index a0112c5..2a7ebdf 100644
--- a/plat/brcm/board/common/board_common.mk
+++ b/plat/brcm/board/common/board_common.mk
@@ -28,6 +28,10 @@
 $(eval $(call add_define,SYSCNT_FREQ))
 endif
 
+ifeq (${DRIVER_EMMC_ENABLE},)
+DRIVER_EMMC_ENABLE :=1
+endif
+
 # By default, Trusted Watchdog is always enabled unless SPIN_ON_BL1_EXIT is set
 ifeq (${BRCM_DISABLE_TRUSTED_WDOG},)
 BRCM_DISABLE_TRUSTED_WDOG	:=	0
@@ -89,6 +93,14 @@
 $(eval $(call add_define,USE_CRMU_SRAM))
 endif
 
+# Use PIO mode if DDR is not used
+ifeq (${USE_DDR},yes)
+EMMC_USE_DMA	:=	1
+else
+EMMC_USE_DMA	:=	0
+endif
+$(eval $(call add_define,EMMC_USE_DMA))
+
 # On BRCM platforms, separate the code and read-only data sections to allow
 # mapping the former as executable and the latter as execute-never.
 SEPARATE_CODE_AND_RODATA	:=	1
@@ -97,7 +109,8 @@
 USE_TBBR_DEFS			:=	1
 
 PLAT_INCLUDES		+=	-Iplat/brcm/board/common \
-				-Iinclude/drivers/brcm
+				-Iinclude/drivers/brcm \
+				-Iinclude/drivers/brcm/emmc
 
 PLAT_BL_COMMON_SOURCES	+=	plat/brcm/common/brcm_common.c \
 				plat/brcm/board/common/cmn_sec.c \
@@ -116,6 +129,22 @@
 				plat/brcm/board/common/sbl_util.c \
 				drivers/arm/sp805/sp805.c
 
+# Add eMMC driver
+ifeq (${DRIVER_EMMC_ENABLE},1)
+$(eval $(call add_define,DRIVER_EMMC_ENABLE))
+
+EMMC_SOURCES		+=	drivers/brcm/emmc/emmc_chal_sd.c \
+				drivers/brcm/emmc/emmc_csl_sdcard.c \
+				drivers/brcm/emmc/emmc_csl_sdcmd.c \
+				drivers/brcm/emmc/emmc_pboot_hal_memory_drv.c
+
+PLAT_BL_COMMON_SOURCES += ${EMMC_SOURCES}
+
+ifeq (${DRIVER_EMMC_ENABLE_DATA_WIDTH_8BIT},)
+$(eval $(call add_define,DRIVER_EMMC_ENABLE_DATA_WIDTH_8BIT))
+endif
+endif
+
 BL2_SOURCES		+=	plat/brcm/common/brcm_bl2_mem_params_desc.c \
 				plat/brcm/common/brcm_image_load.c \
 				common/desc_image_load.c
diff --git a/plat/brcm/board/stingray/driver/plat_emmc.c b/plat/brcm/board/stingray/driver/plat_emmc.c
new file mode 100644
index 0000000..82085e1
--- /dev/null
+++ b/plat/brcm/board/stingray/driver/plat_emmc.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2016 - 2020, Broadcom
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdint.h>
+
+#include <lib/mmio.h>
+
+#include <platform_def.h>
+
+#define ICFG_IPROC_IOPAD_CTRL_4 (IPROC_ROOT + 0x9c0)
+#define ICFG_IPROC_IOPAD_CTRL_5 (IPROC_ROOT + 0x9c4)
+#define ICFG_IPROC_IOPAD_CTRL_6 (IPROC_ROOT + 0x9c8)
+#define ICFG_IPROC_IOPAD_CTRL_7 (IPROC_ROOT + 0x9cc)
+
+#define IOPAD_CTRL4_SDIO0_CD_IND_R 30
+#define IOPAD_CTRL4_SDIO0_CD_SRC_R 31
+#define IOPAD_CTRL4_SDIO0_CD_HYS_R 29
+#define IOPAD_CTRL4_SDIO0_CD_PULL_R 28
+#define IOPAD_CTRL4_SDIO0_CD_DRIVE_R 24
+#define IOPAD_CTRL4_SDIO0_CLK_SDCARD_SRC_R 23
+#define IOPAD_CTRL4_SDIO0_CLK_SDCARD_HYS_R 21
+#define IOPAD_CTRL4_SDIO0_CLK_SDCARD_DRIVE_R 17
+
+#define IOPAD_CTRL4_SDIO0_DATA0_SRC_R 15
+#define IOPAD_CTRL4_SDIO0_DATA0_HYS_R 13
+#define IOPAD_CTRL4_SDIO0_DATA0_DRIVE_R 9
+#define IOPAD_CTRL4_SDIO0_DATA1_SRC_R 7
+#define IOPAD_CTRL4_SDIO0_DATA1_HYS_R 5
+#define IOPAD_CTRL4_SDIO0_DATA1_DRIVE_R 1
+
+#define IOPAD_CTRL5_SDIO0_DATA2_SRC_R 31
+#define IOPAD_CTRL5_SDIO0_DATA2_HYS_R 29
+#define IOPAD_CTRL5_SDIO0_DATA2_DRIVE_R 25
+#define IOPAD_CTRL5_SDIO0_DATA3_SRC_R 23
+#define IOPAD_CTRL5_SDIO0_DATA3_IND_R 22
+#define IOPAD_CTRL5_SDIO0_DATA3_HYS_R 21
+#define IOPAD_CTRL5_SDIO0_DATA3_DRIVE_R 17
+#define IOPAD_CTRL5_SDIO0_DATA4_SRC_R 15
+#define IOPAD_CTRL5_SDIO0_DATA4_HYS_R 13
+#define IOPAD_CTRL5_SDIO0_DATA4_DRIVE_R 9
+#define IOPAD_CTRL5_SDIO0_DATA5_SRC_R 7
+#define IOPAD_CTRL5_SDIO0_DATA5_HYS_R 5
+#define IOPAD_CTRL5_SDIO0_DATA5_DRIVE_R 1
+
+#define IOPAD_CTRL6_SDIO0_DATA6_SRC_R 31
+#define IOPAD_CTRL6_SDIO0_DATA6_HYS_R 29
+#define IOPAD_CTRL6_SDIO0_DATA6_DRIVE_R 25
+#define IOPAD_CTRL6_SDIO0_DATA7_SRC_R 23
+#define IOPAD_CTRL6_SDIO0_DATA7_HYS_R 21
+#define IOPAD_CTRL6_SDIO0_DATA7_DRIVE_R 17
+
+void emmc_soft_reset(void)
+{
+	uint32_t val = 0;
+
+	val = (BIT(IOPAD_CTRL6_SDIO0_DATA7_SRC_R) |
+	       BIT(IOPAD_CTRL6_SDIO0_DATA7_HYS_R) |
+	       BIT(IOPAD_CTRL6_SDIO0_DATA7_DRIVE_R) |
+	       BIT(IOPAD_CTRL6_SDIO0_DATA6_SRC_R) |
+	       BIT(IOPAD_CTRL6_SDIO0_DATA6_HYS_R) |
+	       BIT(IOPAD_CTRL6_SDIO0_DATA6_DRIVE_R));
+
+	mmio_write_32(ICFG_IPROC_IOPAD_CTRL_6, val);
+
+	val = (BIT(IOPAD_CTRL5_SDIO0_DATA3_SRC_R) |
+	       BIT(IOPAD_CTRL5_SDIO0_DATA3_HYS_R) |
+	       BIT(IOPAD_CTRL5_SDIO0_DATA3_DRIVE_R) |
+	       BIT(IOPAD_CTRL5_SDIO0_DATA4_SRC_R) |
+	       BIT(IOPAD_CTRL5_SDIO0_DATA4_HYS_R) |
+	       BIT(IOPAD_CTRL5_SDIO0_DATA4_DRIVE_R) |
+	       BIT(IOPAD_CTRL5_SDIO0_DATA5_SRC_R) |
+	       BIT(IOPAD_CTRL5_SDIO0_DATA5_HYS_R) |
+	       BIT(IOPAD_CTRL5_SDIO0_DATA5_DRIVE_R));
+
+	mmio_write_32(ICFG_IPROC_IOPAD_CTRL_5, val);
+
+	val = (BIT(IOPAD_CTRL4_SDIO0_DATA0_SRC_R) |
+	       BIT(IOPAD_CTRL4_SDIO0_DATA0_HYS_R) |
+	       BIT(IOPAD_CTRL4_SDIO0_DATA0_DRIVE_R) |
+	       BIT(IOPAD_CTRL4_SDIO0_DATA1_SRC_R) |
+	       BIT(IOPAD_CTRL4_SDIO0_DATA1_HYS_R) |
+	       BIT(IOPAD_CTRL4_SDIO0_DATA1_DRIVE_R) |
+	       BIT(IOPAD_CTRL5_SDIO0_DATA2_SRC_R) |
+	       BIT(IOPAD_CTRL5_SDIO0_DATA2_HYS_R) |
+	       BIT(IOPAD_CTRL5_SDIO0_DATA2_DRIVE_R));
+
+	mmio_write_32(ICFG_IPROC_IOPAD_CTRL_6, val);
+
+	val = (BIT(IOPAD_CTRL4_SDIO0_CLK_SDCARD_SRC_R) |
+	       BIT(IOPAD_CTRL4_SDIO0_CLK_SDCARD_HYS_R) |
+	       BIT(IOPAD_CTRL4_SDIO0_CLK_SDCARD_DRIVE_R) |
+	       BIT(IOPAD_CTRL4_SDIO0_CD_SRC_R) |
+	       BIT(IOPAD_CTRL4_SDIO0_CD_HYS_R));
+
+	/*
+	 * set pull-down, clear pull-up=0
+	 * bit 12: pull-down  bit 11: pull-up
+	 * Note:  In emulation, this pull-down setting was not
+	 * sufficient.  Board design likely requires pull down on
+	 * this pin for eMMC.
+	 */
+
+	val |= BIT(IOPAD_CTRL4_SDIO0_CD_PULL_R);
+
+	mmio_write_32(ICFG_IPROC_IOPAD_CTRL_4, val);
+}
diff --git a/plat/brcm/board/stingray/platform.mk b/plat/brcm/board/stingray/platform.mk
index cc7ae53..8d2119d 100644
--- a/plat/brcm/board/stingray/platform.mk
+++ b/plat/brcm/board/stingray/platform.mk
@@ -24,6 +24,13 @@
 DRIVER_CC_ENABLE := 1
 $(eval $(call add_define,DRIVER_CC_ENABLE))
 
+# Enable to erase eMMC
+INCLUDE_EMMC_DRIVER_ERASE_CODE := 0
+
+ifeq (${INCLUDE_EMMC_DRIVER_ERASE_CODE},1)
+$(eval $(call add_define,INCLUDE_EMMC_DRIVER_ERASE_CODE))
+endif
+
 # BL31 is in DRAM
 ARM_BL31_IN_DRAM	:=	1
 
@@ -178,6 +185,7 @@
 				drivers/ti/uart/aarch64/16550_console.S \
 				plat/${SOC_DIR}/src/tz_sec.c \
 				drivers/arm/tzc/tzc400.c \
+				plat/${SOC_DIR}/driver/plat_emmc.c \
 				plat/${SOC_DIR}/src/topology.c
 
 ifeq (${USE_CHIMP},yes)
diff --git a/plat/brcm/board/stingray/src/bl2_setup.c b/plat/brcm/board/stingray/src/bl2_setup.c
index 0b0a3ff..9a79744 100644
--- a/plat/brcm/board/stingray/src/bl2_setup.c
+++ b/plat/brcm/board/stingray/src/bl2_setup.c
@@ -15,6 +15,7 @@
 #include <chip_id.h>
 #include <cmn_plat_util.h>
 #include <dmu.h>
+#include <emmc_api.h>
 #include <fru.h>
 #ifdef USE_GPIO
 #include <drivers/gpio.h>