rcar_gen3: plat: Add initial D3 support

Add R-Car D3 SoC platform specifics. Driver, PFC, QoS, DDR init code
will be added separately.

Signed-off-by: Marek Vasut <marek.vasut+renesas@gmail.com>
diff --git a/plat/renesas/rcar/bl2_cpg_init.c b/plat/renesas/rcar/bl2_cpg_init.c
index 1dff690..6732172 100644
--- a/plat/renesas/rcar/bl2_cpg_init.c
+++ b/plat/renesas/rcar/bl2_cpg_init.c
@@ -33,6 +33,11 @@
 static void bl2_system_cpg_init_e3(void);
 #endif
 
+#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_D3)
+static void bl2_realtime_cpg_init_d3(void);
+static void bl2_system_cpg_init_d3(void);
+#endif
+
 typedef struct {
 	uintptr_t adr;
 	uint32_t val;
@@ -41,21 +46,39 @@
 static void bl2_secure_cpg_init(void)
 {
 	uint32_t stop_cr2, reset_cr2;
+	uint32_t stop_cr4, reset_cr4;
+	uint32_t stop_cr5, reset_cr5;
 
-#if (RCAR_LSI == RCAR_E3)
+#if (RCAR_LSI == RCAR_D3)
+	reset_cr2 = 0x00000000U;
+	stop_cr2 = 0xFFFFFFFFU;
+#elif (RCAR_LSI == RCAR_E3)
 	reset_cr2 = 0x10000000U;
 	stop_cr2 = 0xEFFFFFFFU;
 #else
 	reset_cr2 = 0x14000000U;
 	stop_cr2 = 0xEBFFFFFFU;
 #endif
+
+#if (RCAR_LSI == RCAR_D3)
+	reset_cr4 = 0x00000000U;
+	stop_cr4 = 0xFFFFFFFFU;
+	reset_cr5 = 0x00000000U;
+	stop_cr5 = 0xFFFFFFFFU;
+#else
+	reset_cr4 = 0x80000003U;
+	stop_cr4 = 0x7FFFFFFFU;
+	reset_cr5 = 0x40000000U;
+	stop_cr5 = 0xBFFFFFFFU;
+#endif
+
 	/** Secure Module Stop Control Registers */
 	cpg_write(SCMSTPCR0, 0xFFFFFFFFU);
 	cpg_write(SCMSTPCR1, 0xFFFFFFFFU);
 	cpg_write(SCMSTPCR2, stop_cr2);
 	cpg_write(SCMSTPCR3, 0xFFFFFFFFU);
-	cpg_write(SCMSTPCR4, 0x7FFFFFFFU);
-	cpg_write(SCMSTPCR5, 0xBFFFFFFFU);
+	cpg_write(SCMSTPCR4, stop_cr4);
+	cpg_write(SCMSTPCR5, stop_cr5);
 	cpg_write(SCMSTPCR6, 0xFFFFFFFFU);
 	cpg_write(SCMSTPCR7, 0xFFFFFFFFU);
 	cpg_write(SCMSTPCR8, 0xFFFFFFFFU);
@@ -68,8 +91,8 @@
 	cpg_write(SCSRSTECR1, 0x00000000U);
 	cpg_write(SCSRSTECR2, reset_cr2);
 	cpg_write(SCSRSTECR3, 0x00000000U);
-	cpg_write(SCSRSTECR4, 0x80000003U);
-	cpg_write(SCSRSTECR5, 0x40000000U);
+	cpg_write(SCSRSTECR4, reset_cr4);
+	cpg_write(SCSRSTECR5, reset_cr5);
 	cpg_write(SCSRSTECR6, 0x00000000U);
 	cpg_write(SCSRSTECR7, 0x00000000U);
 	cpg_write(SCSRSTECR8, 0x00000000U);
@@ -229,6 +252,42 @@
 }
 #endif
 
+#if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_D3)
+static void bl2_realtime_cpg_init_d3(void)
+{
+	/* Realtime Module Stop Control Registers */
+	cpg_write(RMSTPCR0, 0x00010000U);
+	cpg_write(RMSTPCR1, 0xFFFFFFFFU);
+	cpg_write(RMSTPCR2, 0x00060FDCU);
+	cpg_write(RMSTPCR3, 0xFFFFFFDFU);
+	cpg_write(RMSTPCR4, 0x80000184U);
+	cpg_write(RMSTPCR5, 0x83FFFFFFU);
+	cpg_write(RMSTPCR6, 0xFFFFFFFFU);
+	cpg_write(RMSTPCR7, 0xFFFFFFFFU);
+	cpg_write(RMSTPCR8, 0x00F1FFF7U);
+	cpg_write(RMSTPCR9, 0xF3F5E016U);
+	cpg_write(RMSTPCR10, 0xFFFEFFE0U);
+	cpg_write(RMSTPCR11, 0x000000B7U);
+}
+
+static void bl2_system_cpg_init_d3(void)
+{
+	/* System Module Stop Control Registers */
+	cpg_write(SMSTPCR0, 0x00010000U);
+	cpg_write(SMSTPCR1, 0xFFFFFFFFU);
+	cpg_write(SMSTPCR2, 0x00060FDCU);
+	cpg_write(SMSTPCR3, 0xFFFFFBDFU);
+	cpg_write(SMSTPCR4, 0x00000084U);
+	cpg_write(SMSTPCR5, 0x83FFFFFFU);
+	cpg_write(SMSTPCR6, 0xFFFFFFFFU);
+	cpg_write(SMSTPCR7, 0xFFFFFFFFU);
+	cpg_write(SMSTPCR8, 0x00F1FFF7U);
+	cpg_write(SMSTPCR9, 0xF3F5E016U);
+	cpg_write(SMSTPCR10, 0xFFFEFFE0U);
+	cpg_write(SMSTPCR11, 0x000000B7U);
+}
+#endif
+
 void bl2_cpg_init(void)
 {
 	uint32_t boot_cpu = mmio_read_32(RCAR_MODEMR) & MODEMR_BOOT_CPU_MASK;
@@ -254,6 +313,9 @@
 		case RCAR_PRODUCT_E3:
 			bl2_realtime_cpg_init_e3();
 			break;
+		case RCAR_PRODUCT_D3:
+			bl2_realtime_cpg_init_d3();
+			break;
 		default:
 			panic();
 			break;
@@ -266,6 +328,8 @@
 		bl2_realtime_cpg_init_m3n();
 #elif RCAR_LSI == RCAR_E3
 		bl2_realtime_cpg_init_e3();
+#elif RCAR_LSI == RCAR_D3
+		bl2_realtime_cpg_init_d3();
 #else
 #error "Don't have CPG initialize routine(unknown)."
 #endif
@@ -290,6 +354,9 @@
 	case RCAR_PRODUCT_E3:
 		bl2_system_cpg_init_e3();
 		break;
+	case RCAR_PRODUCT_D3:
+		bl2_system_cpg_init_d3();
+		break;
 	default:
 		panic();
 		break;
@@ -302,6 +369,8 @@
 	bl2_system_cpg_init_m3n();
 #elif RCAR_LSI == RCAR_E3
 	bl2_system_cpg_init_e3();
+#elif RCAR_LSI == RCAR_D3
+	bl2_system_cpg_init_d3();
 #else
 #error "Don't have CPG initialize routine(unknown)."
 #endif
diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c
index 7442942..d21ddf5 100644
--- a/plat/renesas/rcar/bl2_plat_setup.c
+++ b/plat/renesas/rcar/bl2_plat_setup.c
@@ -76,6 +76,9 @@
 #elif RCAR_LSI == RCAR_E3
 #define TARGET_PRODUCT			RCAR_PRODUCT_E3
 #define TARGET_NAME			"R-Car E3"
+#elif RCAR_LSI == RCAR_D3
+#define TARGET_PRODUCT			RCAR_PRODUCT_D3
+#define TARGET_NAME			"R-Car D3"
 #elif RCAR_LSI == RCAR_AUTO
 #define TARGET_NAME			"R-Car H3/M3/M3N"
 #endif
@@ -242,6 +245,9 @@
 	if (product == RCAR_PRODUCT_H3 && RCAR_CUT_VER20 > cut)
 		goto tlb;
 
+	if (product == RCAR_PRODUCT_D3)
+		goto tlb;
+
 	/* Disable MFIS write protection */
 	mmio_write_32(MFISWPCNTR, MFISWPCNTR_PASSWORD | 1);
 
@@ -430,6 +436,10 @@
 		ret = fdt_setprop_string(fdt, 0, "compatible",
 					 "renesas,ebisu");
 		break;
+	case BOARD_DRAAK:
+		ret = fdt_setprop_string(fdt, 0, "compatible",
+					 "renesas,draak");
+		break;
 	default:
 		NOTICE("BL2: Cannot set compatible string, board unsupported\n");
 		panic();
@@ -458,6 +468,10 @@
 		ret = fdt_appendprop_string(fdt, 0, "compatible",
 					    "renesas,r8a77990");
 		break;
+	case RCAR_PRODUCT_D3:
+		ret = fdt_appendprop_string(fdt, 0, "compatible",
+					    "renesas,r8a77995");
+		break;
 	default:
 		NOTICE("BL2: Cannot set compatible string, SoC unsupported\n");
 		panic();
@@ -598,6 +612,11 @@
 		dram_config[1] = 0x100000000ULL;
 #endif /* RCAR_DRAM_DDR3L_MEMCONF == 0 */
 		break;
+
+	case RCAR_PRODUCT_D3:
+		/* 512MB */
+		dram_config[1] = 0x20000000ULL;
+		break;
 	}
 
 	bl2_advertise_dram_entries(dram_config);
@@ -617,6 +636,7 @@
 	const char *product_h3 = "H3";
 	const char *product_m3 = "M3";
 	const char *product_e3 = "E3";
+	const char *product_d3 = "D3";
 	const char *lcs_secure = "SE";
 	const char *lcs_cm = "CM";
 	const char *lcs_dm = "DM";
@@ -629,7 +649,7 @@
 	const char *boot_qspi80 = "QSPI Flash(80MHz)";
 	const char *boot_emmc25x1 = "eMMC(25MHz x1)";
 	const char *boot_emmc50x8 = "eMMC(50MHz x8)";
-#if RCAR_LSI == RCAR_E3
+#if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3)
 	const char *boot_hyper160 = "HyperFlash(150MHz)";
 #else
 	const char *boot_hyper160 = "HyperFlash(160MHz)";
@@ -696,6 +716,9 @@
 	case RCAR_PRODUCT_E3:
 		str = product_e3;
 		break;
+	case RCAR_PRODUCT_D3:
+		str = product_d3;
+		break;
 	default:
 		str = unknown;
 		break;
@@ -736,6 +759,7 @@
 	case BOARD_EBISU:
 	case BOARD_STARTER_KIT_PRE:
 	case BOARD_EBISU_4D:
+	case BOARD_DRAAK:
 		break;
 	default:
 		type = BOARD_UNKNOWN;
@@ -774,9 +798,17 @@
 		str = boot_qspi80;
 		break;
 	case MODEMR_BOOT_DEV_EMMC_25X1:
+#if RCAR_LSI == RCAR_D3
+		ERROR("BL2: Failed to Initialize. eMMC is not supported.\n");
+		panic();
+#endif
 		str = boot_emmc25x1;
 		break;
 	case MODEMR_BOOT_DEV_EMMC_50X8:
+#if RCAR_LSI == RCAR_D3
+		ERROR("BL2: Failed to Initialize. eMMC is not supported.\n");
+		panic();
+#endif
 		str = boot_emmc50x8;
 		break;
 	default:
@@ -940,7 +972,9 @@
 
 static void bl2_init_generic_timer(void)
 {
-#if RCAR_LSI == RCAR_E3
+#if RCAR_LSI == RCAR_D3
+	uint32_t reg_cntfid = EXTAL_DRAAK;
+#elif RCAR_LSI == RCAR_E3
 	uint32_t reg_cntfid = EXTAL_EBISU;
 #else /* RCAR_LSI == RCAR_E3 */
 	uint32_t reg;
diff --git a/plat/renesas/rcar/bl2_secure_setting.c b/plat/renesas/rcar/bl2_secure_setting.c
index cbda1eb..7473df5 100644
--- a/plat/renesas/rcar/bl2_secure_setting.c
+++ b/plat/renesas/rcar/bl2_secure_setting.c
@@ -52,7 +52,7 @@
 	    /*        1: Reserved[R-Car E3]                                 */
 	    /* Bit10: SCEG Secure Core slave ports                          */
 	    /*        0: registers accessed from secure resource only       */
-#if RCAR_LSI == RCAR_E3
+#if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3)
 	{
 	SEC_SEL6, 0xFFFFFBFFU},
 #else
diff --git a/plat/renesas/rcar/bl31_plat_setup.c b/plat/renesas/rcar/bl31_plat_setup.c
index 4e08b5a..add3e34 100644
--- a/plat/renesas/rcar/bl31_plat_setup.c
+++ b/plat/renesas/rcar/bl31_plat_setup.c
@@ -85,10 +85,12 @@
 
 	NOTICE("BL3-1 : Rev.%s\n", version_of_renesas);
 
+#if RCAR_LSI != RCAR_D3
 	if (RCAR_CLUSTER_A53A57 == rcar_pwrc_get_cluster()) {
 		plat_cci_init();
 		plat_cci_enable();
 	}
+#endif
 }
 
 void bl31_plat_arch_setup(void)
diff --git a/plat/renesas/rcar/include/platform_def.h b/plat/renesas/rcar/include/platform_def.h
index 934b2dc..9f071bc 100644
--- a/plat/renesas/rcar/include/platform_def.h
+++ b/plat/renesas/rcar/include/platform_def.h
@@ -103,14 +103,14 @@
 /* Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug
  * size plus a little space for growth. */
 #define RCAR_SYSRAM_BASE		U(0xE6300000)
-#if RCAR_LSI == RCAR_E3
+#if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3)
 #define BL2_LIMIT			U(0xE6320000)
 #else
 #define BL2_LIMIT			U(0xE6360000)
 #endif
 
 #define BL2_BASE			U(0xE6304000)
-#if RCAR_LSI == RCAR_E3
+#if (RCAR_LSI == RCAR_E3) || (RCAR_LSI == RCAR_D3)
 #define BL2_IMAGE_LIMIT			U(0xE6318000)
 #else
 #define BL2_IMAGE_LIMIT			U(0xE632E800)
diff --git a/plat/renesas/rcar/include/rcar_def.h b/plat/renesas/rcar/include/rcar_def.h
index 6bbd6fa..9bf418f 100644
--- a/plat/renesas/rcar/include/rcar_def.h
+++ b/plat/renesas/rcar/include/rcar_def.h
@@ -153,6 +153,7 @@
 #define RCAR_PRODUCT_M3			U(0x00005200)
 #define RCAR_PRODUCT_M3N		U(0x00005500)
 #define RCAR_PRODUCT_E3			U(0x00005700)
+#define RCAR_PRODUCT_D3			U(0x00005800)
 #define RCAR_CUT_VER10			U(0x00000000)
 #define RCAR_CUT_VER11			U(0x00000001)	/* H3/M3N/E3 Ver.1.1 */
 #define RCAR_M3_CUT_VER11		U(0x00000010)	/* M3 Ver.1.1/Ver.1.2 */
@@ -205,6 +206,7 @@
 #define	EXTAL_MD14_MD13_TYPE_3		U(16666600)	/* MD14=1 MD13=1 */
 #define	EXTAL_SALVATOR_XS		U(8320000)	/* Salvator-XS */
 #define EXTAL_EBISU			U(24000000)	/* Ebisu */
+#define EXTAL_DRAAK			U(24000000)	/* Draak */
 /* CPG write protect registers 	*/
 #define	CPGWPR_PASSWORD			(0x5A5AFFFFU)
 #define	CPGWPCR_PASSWORD		(0xA5A50000U)
diff --git a/plat/renesas/rcar/plat_pm.c b/plat/renesas/rcar/plat_pm.c
index 47eda9a..f41c172 100644
--- a/plat/renesas/rcar/plat_pm.c
+++ b/plat/renesas/rcar/plat_pm.c
@@ -92,18 +92,22 @@
 
 static void rcar_pwr_domain_off(const psci_power_state_t *target_state)
 {
+#if RCAR_LSI != RCAR_D3
 	uint32_t cluster_type = rcar_pwrc_get_cluster();
+#endif
 	unsigned long mpidr = read_mpidr_el1();
 
 	gicv2_cpuif_disable();
 	rcar_pwrc_cpuoff(mpidr);
 
+#if RCAR_LSI != RCAR_D3
 	if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) {
 		if (cluster_type == RCAR_CLUSTER_A53A57)
 			plat_cci_disable();
 
 		rcar_pwrc_clusteroff(mpidr);
 	}
+#endif
 }
 
 static void rcar_pwr_domain_suspend(const psci_power_state_t *target_state)
diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk
index 715b8ae..5eb20fc 100644
--- a/plat/renesas/rcar/platform.mk
+++ b/plat/renesas/rcar/platform.mk
@@ -29,12 +29,14 @@
 RCAR_M3N:=2
 RCAR_E3:=3
 RCAR_H3N:=4
+RCAR_D3:=5
 RCAR_AUTO:=99
 $(eval $(call add_define,RCAR_H3))
 $(eval $(call add_define,RCAR_M3))
 $(eval $(call add_define,RCAR_M3N))
 $(eval $(call add_define,RCAR_E3))
 $(eval $(call add_define,RCAR_H3N))
+$(eval $(call add_define,RCAR_D3))
 $(eval $(call add_define,RCAR_AUTO))
 RCAR_CUT_10:=0
 RCAR_CUT_11:=1
@@ -143,6 +145,21 @@
       endif
       $(eval $(call add_define,RCAR_LSI_CUT))
     endif
+  else ifeq (${LSI},D3)
+    RCAR_LSI:=${RCAR_D3}
+    ifndef LSI_CUT
+      # enable compatible function.
+      RCAR_LSI_CUT_COMPAT := 1
+      $(eval $(call add_define,RCAR_LSI_CUT_COMPAT))
+    else
+      # disable compatible function.
+      ifeq (${LSI_CUT},10)
+        RCAR_LSI_CUT:=0
+      else
+        $(error "Error: ${LSI_CUT} is not supported.")
+      endif
+      $(eval $(call add_define,RCAR_LSI_CUT))
+    endif
   else
     $(error "Error: ${LSI} is not supported.")
   endif