rockchip: rk3399: configure the DDR secure region for BL31 image

Move the BL31 loaded base address 0x10000 to 0x1000, and configure
the the memory range 0~1MB is secure, the goal is that make sure
the BL31 image will be not modified.

Signed-off-by: Xing Zheng <zhengxing@rock-chips.com>
diff --git a/plat/rockchip/rk3399/drivers/soc/soc.c b/plat/rockchip/rk3399/drivers/soc/soc.c
index af2b205..623665c 100644
--- a/plat/rockchip/rk3399/drivers/soc/soc.c
+++ b/plat/rockchip/rk3399/drivers/soc/soc.c
@@ -29,6 +29,7 @@
  */
 
 #include <arch_helpers.h>
+#include <assert.h>
 #include <debug.h>
 #include <delay_timer.h>
 #include <dfs.h>
@@ -101,10 +102,6 @@
 		      SGRF_SLV_S_WMSK | SGRF_SLV_S_ALL_NS);
 	mmio_write_32(SGRF_BASE + SGRF_SLV_SECURE_CON0_4(4),
 		      SGRF_SLV_S_WMSK | SGRF_SLV_S_ALL_NS);
-
-	/* security config for ddr memery */
-	mmio_write_32(SGRF_BASE + SGRF_DDRRGN_CON0_16(16),
-		      SGRF_DDR_RGN_BYPS);
 }
 
 static void dma_secure_cfg(uint32_t secure)
@@ -215,6 +212,77 @@
 		      WMSK_BIT(PCLK_WDT_CM0_GATE_SHIFT));
 }
 
+static void sgrf_ddr_rgn_global_bypass(uint32_t bypass)
+{
+	if (bypass)
+		/* set bypass (non-secure regions) for whole ddr regions */
+		mmio_write_32(SGRF_BASE + SGRF_DDRRGN_CON0_16(16),
+			      SGRF_DDR_RGN_BYPS);
+	else
+		/* cancel bypass for whole ddr regions */
+		mmio_write_32(SGRF_BASE + SGRF_DDRRGN_CON0_16(16),
+			      SGRF_DDR_RGN_NO_BYPS);
+}
+
+/**
+ * There are 8 + 1 regions for DDR secure control:
+ * DDR_RGN_0 ~ DDR_RGN_7: Per DDR_RGNs grain size is 1MB
+ * DDR_RGN_X - the memories of exclude DDR_RGN_0 ~ DDR_RGN_7
+ *
+ * DDR_RGN_0 - start address of the RGN0
+ * DDR_RGN_8 - end address of the RGN0
+ * DDR_RGN_1 - start address of the RGN1
+ * DDR_RGN_9 - end address of the RGN1
+ * ...
+ * DDR_RGN_7 - start address of the RGN7
+ * DDR_RGN_15 - end address of the RGN7
+ * DDR_RGN_16 - bit 0 ~ 7 is bitmap for RGN0~7 secure,0: disable, 1: enable
+ *              bit 8 is setting for RGNx, the rest of the memory and region
+ *                which excludes RGN0~7, 0: disable, 1: enable
+ *              bit 9, the global secure configuration via bypass, 0: disable
+ *                bypass, 1: enable bypass
+ *
+ * @rgn - the DDR regions 0 ~ 7 which are can be configured.
+ * The @st_mb and @ed_mb indicate the start and end addresses for which to set
+ * the security, and the unit is megabyte. When the st_mb == 0, ed_mb == 0, the
+ * address range 0x0 ~ 0xfffff is secure.
+ *
+ * For example, if we would like to set the range [0, 32MB) is security via
+ * DDR_RGN0, then rgn == 0, st_mb == 0, ed_mb == 31.
+ */
+static void sgrf_ddr_rgn_config(uint32_t rgn,
+				uintptr_t st, uintptr_t ed)
+{
+	uintptr_t st_mb, ed_mb;
+
+	assert(rgn <= 7);
+	assert(st < ed);
+
+	/* check aligned 1MB */
+	assert(st % SIZE_M(1) == 0);
+	assert(ed % SIZE_M(1) == 0);
+
+	st_mb = st / SIZE_M(1);
+	ed_mb = ed / SIZE_M(1);
+
+	/* set ddr region addr start */
+	mmio_write_32(SGRF_BASE + SGRF_DDRRGN_CON0_16(rgn),
+		      BITS_WITH_WMASK(st_mb, SGRF_DDR_RGN_0_16_WMSK, 0));
+
+	/* set ddr region addr end */
+	mmio_write_32(SGRF_BASE + SGRF_DDRRGN_CON0_16(rgn + 8),
+		      BITS_WITH_WMASK((ed_mb - 1), SGRF_DDR_RGN_0_16_WMSK, 0));
+
+	mmio_write_32(SGRF_BASE + SGRF_DDRRGN_CON0_16(16),
+		      BIT_WITH_WMSK(rgn));
+}
+
+static void secure_sgrf_ddr_rgn_init(void)
+{
+	sgrf_ddr_rgn_config(0, TZRAM_BASE, TZRAM_SIZE);
+	sgrf_ddr_rgn_global_bypass(0);
+}
+
 static void set_pll_slow_mode(uint32_t pll_id)
 {
 	if (pll_id == PPLL_ID)
@@ -461,6 +529,7 @@
 	secure_timer_init();
 	dma_secure_cfg(0);
 	sgrf_init();
+	secure_sgrf_ddr_rgn_init();
 	soc_global_soft_reset_init();
 	plat_rockchip_gpio_init();
 	m0_init();
diff --git a/plat/rockchip/rk3399/drivers/soc/soc.h b/plat/rockchip/rk3399/drivers/soc/soc.h
index 3718894..03da025 100644
--- a/plat/rockchip/rk3399/drivers/soc/soc.h
+++ b/plat/rockchip/rk3399/drivers/soc/soc.h
@@ -273,9 +273,13 @@
 #define SGRF_PMU_SLV_CON1_CFG		(SGRF_SLV_S_WMSK | \
 					SGRF_PMUSRAM_S)
 /* ddr region */
+#define SGRF_DDR_RGN_0_16_WMSK		0x0fff 	/* DDR RGN 0~16 size mask */
+
 #define SGRF_DDR_RGN_DPLL_CLK	BIT_WITH_WMSK(15) /* DDR PLL output clock */
 #define SGRF_DDR_RGN_RTC_CLK	BIT_WITH_WMSK(14) /* 32K clock for DDR PLL */
 #define SGRF_DDR_RGN_BYPS	BIT_WITH_WMSK(9) /* All of ddr rgn  is ns */
+/* All security of the DDR RGNs are not bypass  */
+#define SGRF_DDR_RGN_NO_BYPS	WMSK_BIT(9)
 
 /* The MST access the ddr rgn n with secure attribution */
 #define SGRF_L_MST_S_DDR_RGN(n)	BIT_WITH_WMSK((n))
diff --git a/plat/rockchip/rk3399/include/platform_def.h b/plat/rockchip/rk3399/include/platform_def.h
index 6fb9d98..b83b891 100644
--- a/plat/rockchip/rk3399/include/platform_def.h
+++ b/plat/rockchip/rk3399/include/platform_def.h
@@ -91,9 +91,9 @@
 /*******************************************************************************
  * Platform memory map related constants
  ******************************************************************************/
-/* TF txet, ro, rw, Size: 512KB */
+/* TF text, ro, rw, Size: 1MB */
 #define TZRAM_BASE		(0x0)
-#define TZRAM_SIZE		(0x80000)
+#define TZRAM_SIZE		(0x100000)
 
 /*******************************************************************************
  * BL31 specific defines.
@@ -101,7 +101,7 @@
 /*
  * Put BL3-1 at the top of the Trusted RAM
  */
-#define BL31_BASE		(TZRAM_BASE + 0x10000)
+#define BL31_BASE		(TZRAM_BASE + 0x1000)
 #define BL31_LIMIT	(TZRAM_BASE + TZRAM_SIZE)
 
 /*******************************************************************************