Browse Source

dram: starfive: jh7110: Add ddr4 support

Add ddr4 tuning support (sync from devkits)

Signed-off-by: Samin Guo <samin.guo@starfivetech.com>
Samin Guo 10 months ago
parent
commit
0779dddc23

+ 185 - 53
drivers/ram/starfive/ddrcsr_boot.c

@@ -12,7 +12,100 @@
 
 #define REGOFFSET(offset)	((offset) / 4)
 
-static struct ddr_reg_cfg ddr_csr_cfg[] = {
+static struct ddr_reg_cfg ddr4_csr_cfg[] = {
+	{0x0,		0x0,	0x00000405,	REGSETALL},
+	{0xf00,		0x0,	0x40000010,	(OFFSET_SEL | REGSETALL)},
+	{0xf04,		0x0,	0x04800001,	(OFFSET_SEL | REGSETALL)},
+	{0xf10,		0x0,	0x00400000,	(OFFSET_SEL | REGSETALL)},
+	{0xf14,		0x0,	0x043fffff,	(OFFSET_SEL | REGSETALL)},
+	{0xf18,		0x0,	0x00000000,	(OFFSET_SEL | REGSETALL)},
+	{0xf30,		0x0,	0x1f001041,	(OFFSET_SEL | REGSETALL)},
+	{0x110,		0x0,	0xc0000001,	(OFFSET_SEL | REGSETALL)},
+	{0x114,		0x0,	0xffffffff,	(OFFSET_SEL | REGSETALL)},
+	{0x10c,		0x0,	0x00000f0f,	REGSETALL},
+	{0x11c,		0x0,	0x00000000,	REGSETALL},
+	{0x500,		0x0,	0x00000201,	REGSETALL},
+	{0x514,		0x0,	0x00000100,	REGSETALL},
+	{0x6a8,		0x0,	0x00040000,	REGSETALL},
+	{0xea8,		0x0,	0x00040000,	REGSETALL},
+	{0x504,		0x0,	0x40000000,	REGSETALL}
+};
+
+static struct ddr_reg_cfg ddr4_csr_cfg1[] = {
+	{0x310,		0x0,	0x00020000,	REGSETALL},
+	{0x310,		0x0,	0x00020001,	REGSETALL},
+	{0x600,		0x0,	0x00170176,	REGSETALL},
+	{0x604,		0x0,	0x000b00bb,	REGSETALL},
+	{0x608,		0x0,	0x0005005d,	REGSETALL},
+	{0x60c,		0x0,	0x0002002e,	REGSETALL},
+	{0x678,		0x0,	0x00000019,	REGSETALL},
+	{0x100,		0x0,	0x00000008,	REGSETALL},
+	{0x620,		0x0,	0x0b000f0f,	REGSETALL},
+	{0x624,		0x0,	0x06070b07,	REGSETALL},
+	{0x628,		0x0,	0x3123088f,	REGSETALL},
+	{0x62c,		0x0,	0x23160620,	REGSETALL},
+	{0x630,		0x0,	0x1900140f,	REGSETALL},
+	{0x634,		0x0,	0x800b0208,	REGSETALL},
+	{0x638,		0x0,	0x001c1c00,	REGSETALL},
+	{0x63c,		0x0,	0x1a000a06,	REGSETALL},
+	{0x640,		0x0,	0x025600ff,	REGSETALL},
+	{0x644,		0x0,	0x124b024b,	REGSETALL},
+	{0x648,		0x0,	0x40012000,	REGSETALL},
+	{0x64c,		0x0,	0x00082310,	REGSETALL},
+	{0x6c0,		0x0,	0x001b0706,	REGSETALL},
+	{0x6c4,		0x0,	0x0000181c,	REGSETALL},
+	{0x650,		0x0,	0x00000000,	REGSETALL},
+	{0x654,		0x0,	0x00000000,	REGSETALL},
+	{0x658,		0x0,	0x00000060,	REGSETALL},
+	{0x65c,		0x0,	0x00800200,	REGSETALL},
+	{0x660,		0x0,	0x00000000,	REGSETALL},
+	{0x680,		0x0,	0x0f000410,	REGSETALL},
+	{0x684,		0x0,	0x08000b03,	REGSETALL},
+	{0x688,		0x0,	0x04080415,	REGSETALL},
+	{0x68c,		0x0,	0x20002520,	REGSETALL},
+	{0x690,		0x0,	0x00140000,	REGSETALL},
+	{0x69c,		0x0,	0x01240074,	REGSETALL},
+	{0x6a0,		0x0,	0x00000000,	REGSETALL},
+	{0x6a4,		0x0,	0x20250c00,	REGSETALL},
+	{0x6a8,		0x0,	0x00040000,	REGSETALL},
+	{0x4,		0x0,	0x10030000,	REGSETALL},
+	{0xc,		0x0,	0x00000002,	REGSETALL},
+	{0x4,		0x0,	0x1006081e,	REGSETALL},
+	{0xc,		0x0,	0x00000002,	REGSETALL},
+	{0x4,		0x0,	0x10050441,	REGSETALL},
+	{0xc,		0x0,	0x00000002,	REGSETALL},
+	{0x4,		0x0,	0x10040000,	REGSETALL},
+	{0xc,		0x0,	0x00000002,	REGSETALL},
+	{0x4,		0x0,	0x10020010,	REGSETALL},
+	{0xc,		0x0,	0x00000002,	REGSETALL},
+	{0x4,		0x0,	0x10010001,	REGSETALL},
+	{0xc,		0x0,	0x00000002,	REGSETALL},
+	{0x4,		0x0,	0x10000734,	REGSETALL},
+	{0xc,		0x0,	0x00000002,	REGSETALL},
+	{0x10,		0x0,	0x00000011,	REGSETALL},
+	{0x14,		0x0,	0x00000001,	REGSETALL},
+};
+
+static struct ddr_reg_cfg ddr4_csr_cfg3[] = {
+	{0x410,		0x0,	0x00101010,	REGSETALL},
+	{0x420,		0x0,	0x0c181006,	REGSETALL},
+	{0x424,		0x0,	0x20200820,	REGSETALL},
+	{0x428,		0x0,	0x80000020,	REGSETALL},
+	{0x0,		0x0,	0x00000005,	REGSETALL},
+	{0x108,		0x0,	0x00001000,	REGSETALL},
+	{0x704,		0x0,	0x00000007,	REGSETALL | OFFSET_SEL},
+	{0x330,		0x0,	0x09311fff,	REGSETALL},
+	{0x508,		0x0,	0x00000003,	REGSETALL},
+	{0x324,		0x0,	0x00002000,	REGSETALL},
+	{0x104,		0x0,	0x80000000,	REGSETALL},
+	{0x510,		0x0,	0x00000100,	REGSETALL},
+	{0x514,		0x0,	0x00000000,	REGSETALL},
+	{0x700,		0x0,	0x00000003,	REGSETALL | OFFSET_SEL},
+	{0x514,		0x0,	0x00000600,	REGSETALL},
+	{0x20,		0x0,	0x00000001,	REGSETALL},
+};
+
+static struct ddr_reg_cfg lpddr4_csr_cfg[] = {
 	{0x0,		0x0,	0x00000001,	REGSETALL},
 	{0xf00,		0x0,	0x40001030,	(OFFSET_SEL | F_SET | REG4G | REG8G)},
 	{0xf00,		0x0,	0x40001010,	(OFFSET_SEL | F_SET | REG2G)},
@@ -36,7 +129,7 @@ static struct ddr_reg_cfg ddr_csr_cfg[] = {
 	{0x504,		0x0,	0x40000000,	REGSETALL}
 };
 
-static struct ddr_reg_cfg ddr_csr_cfg1[] = {
+static struct ddr_reg_cfg lpddr4_csr_cfg1[] = {
 	{0x310,		0x0,	0x00020000,	REGSETALL},
 	{0x310,		0x0,	0x00020001,	REGSETALL},
 	{0x600,		0x0,	0x002e0176,	REGSETALL},
@@ -126,7 +219,7 @@ static struct ddr_reg_cfg ddr_csr_cfg2[] = {
 	{0x2e8,		0xffffffff,		0x300,		REGCLRSETALL},
 };
 
-static struct ddr_reg_cfg ddr_csr_cfg3[] = {
+static struct ddr_reg_cfg lpddr4_csr_cfg3[] = {
 	{0x100,		0x0,	0x000000e0,	REGSETALL},
 	{0x620,		0x0,	0x04041417,	REGSETALL},
 	{0x624,		0x0,	0x09110609,	REGSETALL},
@@ -217,6 +310,8 @@ void ddrcsr_boot(u32 *csrreg, u32 *secreg, u32 *phyreg, enum ddr_size_t size)
 	u32 len;
 	u32 val;
 	u32 mask;
+	bool ddr4flag;
+	struct ddr_reg_cfg *data;
 
 	switch (size) {
 	case DDR_SIZE_1G:
@@ -240,8 +335,27 @@ void ddrcsr_boot(u32 *csrreg, u32 *secreg, u32 *phyreg, enum ddr_size_t size)
 		return;
 	};
 
-	len = sizeof(ddr_csr_cfg)/sizeof(struct ddr_reg_cfg);
-	ddr_csr_set(csrreg, secreg, ddr_csr_cfg, len, mask);
+	switch (starfive_ddr_type) {
+	case DDR_TYPE_DDR4:
+		ddr4flag = true;
+		break;
+	case DDR_TYPE_LPDDR4:
+		ddr4flag = false;
+		break;
+	case DDR_TYPE_LPDDR3:
+	case DDR_TYPE_DDR3:
+	default:
+		return;
+	}
+
+	if (ddr4flag) {
+		len = sizeof(ddr4_csr_cfg) / sizeof(struct ddr_reg_cfg);
+		data = ddr4_csr_cfg;
+	} else {
+		len = sizeof(lpddr4_csr_cfg) / sizeof(struct ddr_reg_cfg);
+		data = lpddr4_csr_cfg;
+	}
+	ddr_csr_set(csrreg, secreg, data, len, mask);
 
 	do {
 		udelay(1);
@@ -270,28 +384,34 @@ void ddrcsr_boot(u32 *csrreg, u32 *secreg, u32 *phyreg, enum ddr_size_t size)
 	out_le32(csrreg + REGOFFSET(0x14), 0x00000001);
 	udelay(4);
 
-	len = sizeof(ddr_csr_cfg1)/sizeof(struct ddr_reg_cfg);
-	ddr_csr_set(csrreg, secreg, ddr_csr_cfg1, len, mask);
-
-	udelay(4);
-	out_le32(csrreg + REGOFFSET(0x10), 0x00000011);
-	out_le32(csrreg + REGOFFSET(0x14), 0x00000001);
+	if (ddr4flag) {
+		len = sizeof(ddr4_csr_cfg1) / sizeof(struct ddr_reg_cfg);
+		ddr_csr_set(csrreg, secreg, ddr4_csr_cfg1, len, mask);
+		udelay(1);
+	} else {
+		len = sizeof(lpddr4_csr_cfg1) / sizeof(struct ddr_reg_cfg);
+		ddr_csr_set(csrreg, secreg, lpddr4_csr_cfg1, len, mask);
 
-	switch (size) {
-	case DDR_SIZE_4G:
-	case DDR_SIZE_8G:
-		out_le32(csrreg + REGOFFSET(0x10), 0x00000020);
-		out_le32(csrreg + REGOFFSET(0x14), 0x00000001);
 		udelay(4);
-		out_le32(csrreg + REGOFFSET(0x10), 0x00000021);
+		out_le32(csrreg + REGOFFSET(0x10), 0x00000011);
 		out_le32(csrreg + REGOFFSET(0x14), 0x00000001);
-		break;
-	case DDR_SIZE_1G:
-	case DDR_SIZE_2G:
-	case DDR_SIZE_16G:
-	default:
-		break;
-	};
+
+		switch (size) {
+		case DDR_SIZE_4G:
+		case DDR_SIZE_8G:
+			out_le32(csrreg + REGOFFSET(0x10), 0x00000020);
+			out_le32(csrreg + REGOFFSET(0x14), 0x00000001);
+			udelay(4);
+			out_le32(csrreg + REGOFFSET(0x10), 0x00000021);
+			out_le32(csrreg + REGOFFSET(0x14), 0x00000001);
+			break;
+		case DDR_SIZE_1G:
+		case DDR_SIZE_2G:
+		case DDR_SIZE_16G:
+		default:
+			break;
+		};
+	}
 	out_le32(csrreg + REGOFFSET(0x514), 0x00000000);
 
 	do {
@@ -299,41 +419,53 @@ void ddrcsr_boot(u32 *csrreg, u32 *secreg, u32 *phyreg, enum ddr_size_t size)
 		val = in_le32(csrreg + REGOFFSET(0x518));
 	} while ((val & 0x2) != 0x2);
 
-	val = in_le32(csrreg + REGOFFSET(0x518));
-	while ((val & 0x2) != 0x0) {
-		val = in_le32(phyreg + 1);
-		if ((val & 0x20) == 0x20) {
-			switch (val & 0x0000001f) {
-			case 0: //ddrc_clock=12M
-				DDR_REG_SET(BUS, DDR_BUS_OSC_DIV2);
-				break;
-			case 1: //ddrc_clock=200M
-				DDR_REG_SET(BUS, DDR_BUS_PLL1_DIV8);
-				break;
-			case 2: //ddrc_clock=800M
-				DDR_REG_SET(BUS, DDR_BUS_PLL1_DIV2);
-				break;
-			default:
-				break;
-			};
-
-			out_le32((phyreg + 2), 0x1);
-			do {
-				udelay(2);
-				val = in_le32(phyreg + 2);
-			} while ((val & 0x00000001) != 0x00000000);
-		}
-		udelay(1);
+	if (ddr4flag) {
+		do {
+			udelay(1);
+			val = in_le32(csrreg + REGOFFSET(0x518));
+		} while (val & 0x2);
+	} else {
 		val = in_le32(csrreg + REGOFFSET(0x518));
-	};
+		while (val & 0x2) {
+			val = in_le32(phyreg + 1);
+			if (val & 0x20) {
+				switch (val & 0x0000001f) {
+				case 0: //ddrc_clock=12M
+					DDR_REG_SET(BUS, DDR_BUS_OSC_DIV2);
+					break;
+				case 1: //ddrc_clock=200M
+					DDR_REG_SET(BUS, DDR_BUS_PLL1_DIV8);
+					break;
+				case 2: //ddrc_clock=800M
+					DDR_REG_SET(BUS, DDR_BUS_PLL1_DIV2);
+					break;
+				default:
+					break;
+				};
 
+				out_le32((phyreg + 2), 0x1);
+				do {
+					udelay(2);
+					val = in_le32(phyreg + 2);
+				} while ((val & 0x00000001) != 0x00000000);
+			}
+			udelay(1);
+			val = in_le32(csrreg + REGOFFSET(0x518));
+		};
+	}
 	val = in_le32(phyreg + 2048 + 83);
 	val = in_le32(phyreg + 2048 + 84);
 	out_le32((phyreg + 2048 + 84), val & 0xF8000000);
 
-	len = sizeof(ddr_csr_cfg2)/sizeof(struct ddr_reg_cfg);
+	len = sizeof(ddr_csr_cfg2) / sizeof(struct ddr_reg_cfg);
 	ddr_csr_set((phyreg + PHY_BASE_ADDR), secreg, ddr_csr_cfg2, len, mask);
 
-	len = sizeof(ddr_csr_cfg3)/sizeof(struct ddr_reg_cfg);
-	ddr_csr_set(csrreg, secreg, ddr_csr_cfg3, len, mask);
+	if (ddr4flag) {
+		len = sizeof(ddr4_csr_cfg3) / sizeof(struct ddr_reg_cfg);
+		data = ddr4_csr_cfg3;
+	} else {
+		len = sizeof(lpddr4_csr_cfg3) / sizeof(struct ddr_reg_cfg);
+		data = lpddr4_csr_cfg3;
+	}
+	ddr_csr_set(csrreg, secreg, data, len, mask);
 }

+ 127 - 3
drivers/ram/starfive/ddrphy_start.c

@@ -9,7 +9,116 @@
 
 #include "starfive_ddr.h"
 
-static struct ddr_reg_cfg ddr_start_cfg[] = {
+static struct ddr_reg_cfg ddr4_start_cfg[] = {
+	{67,	0xffe0ffff,	0x00010000,	REGCLRSETALL},
+	{67,	0xe0ffffff,	0x01000000,	REGCLRSETALL},
+	{179,	0xff80ffff,	0x001c0000,	REGCLRSETALL},
+	{179,	0x80ffffff,	0x1c000000,	REGCLRSETALL},
+	{182,	0xff80ffff,	0x001c0000,	REGCLRSETALL},
+	{182,	0x80ffffff,	0x1c000000,	REGCLRSETALL},
+	{185,	0xff80ffff,	0x001c0000,	REGCLRSETALL},
+	{185,	0x80ffffff,	0x1c000000,	REGCLRSETALL},
+	{0,	0xffffffff,	0x01,		REGCLRSETALL},
+	{11,	0xfffffff0,	0x1,		REGCLRSETALL},
+	{96,	0x0,		0x300,		(OFFSET_SEL | REGADDSETALL)},
+	{352,	0x0,		0x300,		(OFFSET_SEL | REGADDSETALL)},
+	{608,	0x0,		0x300,		(OFFSET_SEL | REGADDSETALL)},
+	{864,	0x0,		0x300,		(OFFSET_SEL | REGADDSETALL)},
+	{96,	0xff00ffff,	0x00120000,	(OFFSET_SEL | REGCLRSETALL)},
+	{352,	0xff00ffff,	0x00120000,	(OFFSET_SEL | REGCLRSETALL)},
+	{608,	0xff00ffff,	0x00120000,	(OFFSET_SEL | REGCLRSETALL)},
+	{864,	0xff00ffff,	0x00120000,	(OFFSET_SEL | REGCLRSETALL)},
+	{33,	0xffffff00,	0x0040,		(OFFSET_SEL | REGCLRSETALL)},
+	{289,	0xffffff00,	0x0040,		(OFFSET_SEL | REGCLRSETALL)},
+	{545,	0xffffff00,	0x0040,		(OFFSET_SEL | REGCLRSETALL)},
+	{801,	0xffffff00,	0x0040,		(OFFSET_SEL | REGCLRSETALL)},
+	{180,	0xffffffff,	0x0100,		REGCLRSETALL},
+	{183,	0xffffffff,	0x0100,		REGCLRSETALL},
+	{186,	0xffffffff,	0x0100,		REGCLRSETALL},
+	{83,	0xffc0ffff,	0x70000,	(OFFSET_SEL | REGCLRSETALL)},
+	{339,	0xffc0ffff,	0x70000,	(OFFSET_SEL | REGCLRSETALL)},
+	{595,	0xffc0ffff,	0x70000,	(OFFSET_SEL | REGCLRSETALL)},
+	{851,	0xffc0ffff,	0x70000,	(OFFSET_SEL | REGCLRSETALL)},
+	{1062,	0xf800ffff,	0x70000,	(OFFSET_SEL | REGCLRSETALL)},
+	{1318,	0xf800ffff,	0x70000,	(OFFSET_SEL | REGCLRSETALL)},
+	{1574,	0xf800ffff,	0x70000,	(OFFSET_SEL | REGCLRSETALL)},
+	{1892,	0xfffc0000,	0x0a287,	(OFFSET_SEL | REGCLRSETALL)},
+	{1864,	0xffffff00,	0x34,		(OFFSET_SEL | REGCLRSETALL)},
+	{1893,	0xfffc0000,	0x7,		(OFFSET_SEL | REGCLRSETALL)},
+	{1852,	0xffffe000,	0x058,		(OFFSET_SEL | REGCLRSETALL)},
+	{1822,	0xffffffff,	0xFF,		(OFFSET_SEL | REGCLRSETALL)},
+	{1896,	0xfffffc00,	0x02ca,		(OFFSET_SEL | REGCLRSETALL)},
+	{91,	0xfc00ffff,	0x02ed0000,	(OFFSET_SEL | REGCLRSETALL)},
+	{347,	0xfc00ffff,	0x02ed0000,	(OFFSET_SEL | REGCLRSETALL)},
+	{603,	0xfc00ffff,	0x02ed0000,	(OFFSET_SEL | REGCLRSETALL)},
+	{859,	0xfc00ffff,	0x02ed0000,	(OFFSET_SEL | REGCLRSETALL)},
+	{1912,	0x0,		0xcc2bfc7,	(OFFSET_SEL | REGSETALL)},
+	{1913,	0x0,		0xff8f,		(OFFSET_SEL | REGSETALL)},
+	{1914,	0x0,		0x33f077f,	(OFFSET_SEL | REGSETALL)},
+	{1915,	0x0,		0xc3c377f,	(OFFSET_SEL | REGSETALL)},
+	{1916,	0x0,		0x1fff7f30,	(OFFSET_SEL | REGSETALL)},
+	{1917,	0x0,		0x2ec010,	(OFFSET_SEL | REGSETALL)},
+	{1918,	0x0,		0x3fc77ffb,	(OFFSET_SEL | REGSETALL)},
+	{1919,	0x0,		0xe10,		(OFFSET_SEL | REGSETALL)},
+	{1920,	0x0,		0x1fff7fff,	(OFFSET_SEL | REGSETALL)},
+	{1921,	0x0,		0x188411,	(OFFSET_SEL | REGSETALL)},
+	{1922,	0x0,		0x1fff7fff,	(OFFSET_SEL | REGSETALL)},
+	{1923,	0x0,		0x180400,	(OFFSET_SEL | REGSETALL)},
+	{1924,	0x0,		0x1fff7fff,	(OFFSET_SEL | REGSETALL)},
+	{1925,	0x0,		0x180400,	(OFFSET_SEL | REGSETALL)},
+	{1926,	0x0,		0x07ff7ffb,	(OFFSET_SEL | REGSETALL)},
+	{1927,	0x0,		0x188400,	(OFFSET_SEL | REGSETALL)},
+	{1928,	0x0,		0x1fff7fff,	(OFFSET_SEL | REGSETALL)},
+	{1929,	0x0,		0x4188411,	(OFFSET_SEL | REGSETALL)},
+	{1837,	0x0,		0x24410,	(OFFSET_SEL | REGSETALL)},
+	{1840,	0x0,		0x24410,	(OFFSET_SEL | REGSETALL)},
+	{1842,	0x0,		0x2ffff,	(OFFSET_SEL | REGSETALL)},
+	{76,	0xff0000f8,	0x00f7ff07,	(OFFSET_SEL | REGCLRSETALL)},
+	{332,	0xff0000f8,	0x00f7ff07,	(OFFSET_SEL | REGCLRSETALL)},
+	{588,	0xff0000f8,	0x00f7ff07,	(OFFSET_SEL | REGCLRSETALL)},
+	{844,	0xff0000f8,	0x00f7ff07,	(OFFSET_SEL | REGCLRSETALL)},
+	{77,	0xffff0000,	0xfcff,		(OFFSET_SEL | REGCLRSETALL)},
+	{333,	0xffff0000,	0xfcff,		(OFFSET_SEL | REGCLRSETALL)},
+	{589,	0xffff0000,	0xfcff,		(OFFSET_SEL | REGCLRSETALL)},
+	{845,	0xffff0000,	0xfcff,		(OFFSET_SEL | REGCLRSETALL)},
+	{1062,	0xffffff00,	0xbb,		(OFFSET_SEL | REGCLRSETALL)},
+	{1318,	0xffffff00,	0xbb,		(OFFSET_SEL | REGCLRSETALL)},
+	{1574,	0xffffff00,	0xbb,		(OFFSET_SEL | REGCLRSETALL)},
+	{1028,	0xffffffff,	0x1000000,	(OFFSET_SEL | REGCLRSETALL)},
+	{1284,	0xffffffff,	0x1000000,	(OFFSET_SEL | REGCLRSETALL)},
+	{1540,	0xffffffff,	0x1000000,	(OFFSET_SEL | REGCLRSETALL)},
+	{1848,	0x0,		0x3cf07f8,	(OFFSET_SEL | REGSETALL)},
+	{1849,	0x0,		0x3f,		(OFFSET_SEL | REGSETALL)},
+	{1850,	0x0,		0x1dffff,	(OFFSET_SEL | REGSETALL)},
+	{1851,	0x0,		0x190000,	(OFFSET_SEL | REGSETALL)},
+	{130,	0x0000ffff,	0xffff0000,	(OFFSET_SEL | REGCLRSETALL)},
+	{386,	0x0000ffff,	0xffff0000,	(OFFSET_SEL | REGCLRSETALL)},
+	{642,	0x0000ffff,	0xffff0000,	(OFFSET_SEL | REGCLRSETALL)},
+	{898,	0x0000ffff,	0xffff0000,	(OFFSET_SEL | REGCLRSETALL)},
+	{131,	0xfffffff0,	0xf,		(OFFSET_SEL | REGCLRSETALL)},
+	{387,	0xfffffff0,	0xf,		(OFFSET_SEL | REGCLRSETALL)},
+	{643,	0xfffffff0,	0xf,		(OFFSET_SEL | REGCLRSETALL)},
+	{899,	0xfffffff0,	0xf,		(OFFSET_SEL | REGCLRSETALL)},
+	{29,	0xc0ffffff,	0x10000000,	(OFFSET_SEL | REGCLRSETALL)},
+	{285,	0xc0ffffff,	0x10000000,	(OFFSET_SEL | REGCLRSETALL)},
+	{541,	0xc0ffffff,	0x10000000,	(OFFSET_SEL | REGCLRSETALL)},
+	{797,	0xc0ffffff,	0x10000000,	(OFFSET_SEL | REGCLRSETALL)},
+	{30,	0xffffffff,	0x00080000,	(OFFSET_SEL | REGCLRSETALL)},
+	{286,	0xffffffff,	0x00080000,	(OFFSET_SEL | REGCLRSETALL)},
+	{542,	0xffffffff,	0x00080000,	(OFFSET_SEL | REGCLRSETALL)},
+	{798,	0xffffffff,	0x00080000,	(OFFSET_SEL | REGCLRSETALL)},
+	{31,	0xffffffc0,	0x00000010,	(OFFSET_SEL | REGCLRSETALL)},
+	{287,	0xffffffc0,	0x00000010,	(OFFSET_SEL | REGCLRSETALL)},
+	{543,	0xffffffc0,	0x00000010,	(OFFSET_SEL | REGCLRSETALL)},
+	{799,	0xffffffc0,	0x00000010,	(OFFSET_SEL | REGCLRSETALL)},
+	{1071,	0xfffffff0,	0x00000008,	(OFFSET_SEL | REGCLRSETALL)},
+	{1327,	0xfffffff0,	0x00000008,	(OFFSET_SEL | REGCLRSETALL)},
+	{1583,	0xfffffff0,	0x00000008,	(OFFSET_SEL | REGCLRSETALL)},
+	{1808,	0xfffffff0,	0x00000008,	(OFFSET_SEL | REGCLRSETALL)},
+	{1896,	0xfff0ffff,	0x00080000,	(OFFSET_SEL | REGCLRSETALL)},
+};
+
+static struct ddr_reg_cfg lpddr4_start_cfg[] = {
 	{89,	0xffffff00,	0x00000051,	(OFFSET_SEL | REGCLRSETALL)},
 	{78,	0xfffffcff,	0x0,		(OFFSET_SEL | REGCLRSETALL)},
 	{345,	0xffffff00,	0x00000051,	(OFFSET_SEL | REGCLRSETALL)},
@@ -254,6 +363,7 @@ void ddr_phy_start(u32 *phyreg, enum ddr_size_t size)
 {
 	u32 len;
 	u32 mask;
+	struct ddr_reg_cfg *data;
 
 	switch (size) {
 	case DDR_SIZE_1G:
@@ -277,7 +387,21 @@ void ddr_phy_start(u32 *phyreg, enum ddr_size_t size)
 		return;
 	};
 
-	len = sizeof(ddr_start_cfg) / sizeof(struct ddr_reg_cfg);
-	ddr_reg_set(phyreg, ddr_start_cfg, len, mask);
+	switch (starfive_ddr_type) {
+	case DDR_TYPE_DDR4:
+		len = sizeof(ddr4_start_cfg) / sizeof(struct ddr_reg_cfg);
+		data = ddr4_start_cfg;
+		break;
+	case DDR_TYPE_LPDDR4:
+		len = sizeof(lpddr4_start_cfg) / sizeof(struct ddr_reg_cfg);
+		data = lpddr4_start_cfg;
+		break;
+	case DDR_TYPE_LPDDR3:
+	case DDR_TYPE_DDR3:
+	default:
+		return;
+	}
+
+	ddr_reg_set(phyreg, data, len, mask);
 	out_le32(phyreg, 0x01);
 }

+ 387 - 3
drivers/ram/starfive/ddrphy_train.c

@@ -8,7 +8,376 @@
 #include <common.h>
 #include <asm/io.h>
 
-static u32 ddr_train_data[] = {
+#include "starfive_ddr.h"
+
+static u32 ddr4_train_data[] = {
+	0xa00,
+	0x101,
+	0x640000,
+	0x1,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x1,
+	0x7,
+	0x10000,
+	0x10003,
+	0x1,
+	0x5,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x280d0000,
+	0x0,
+	0x1,
+	0x32000003,
+	0x0,
+	0x0,
+	0x60602,
+	0x1,
+	0x0,
+	0x0,
+	0x0,
+	0x55,
+	0xaa,
+	0xad,
+	0x52,
+	0x6a,
+	0x95,
+	0x95,
+	0xad,
+	0x1000000,
+	0x1000000,
+	0x0,
+	0x3030000,
+	0x14,
+	0x7d0,
+	0x300,
+	0x0,
+	0x0,
+	0x1000000,
+	0x10101,
+	0x0,
+	0x30000,
+	0x10100,
+	0x1703,
+	0x0,
+	0x0,
+	0x0,
+	0xa140a01,
+	0x204010a,
+	0x2080510,
+	0x40400,
+	0x101,
+	0x10100,
+	0x2040300,
+	0x34000000,
+	0x0,
+	0x0,
+	0x1000000,
+	0x0,
+	0x0,
+	0x0,
+	0x6,
+	0x100,
+	0x40000,
+	0x2000200,
+	0x1000100,
+	0x1000000,
+	0x2000200,
+	0x200,
+	0x0,
+	0x0,
+	0x0,
+	0xe000003,
+	0xc0d100f,
+	0xa09080b,
+	0x2010000,
+	0x80103,
+	0x10200,
+	0x0,
+	0x3000000,
+	0xd6,
+	0x216,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x30100,
+	0x1010001,
+	0x10200,
+	0x4000103,
+	0x1050001,
+	0x10600,
+	0x107,
+	0x0,
+	0x0,
+	0x10000,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x10000,
+	0x4,
+	0x0,
+	0x0,
+	0x0,
+	0xa000a0,
+	0x1a1a00a0,
+	0x1a,
+	0x35,
+	0x35,
+	0x40035,
+	0x4000400,
+	0xca04000b,
+	0x4000b20,
+	0xb20ca,
+	0x20ca04,
+	0x24b,
+	0x207b,
+	0x24b,
+	0x207b,
+	0x24b,
+	0x400207b,
+	0x1010404,
+	0x1801,
+	0x180018,
+	0x10e010e,
+	0x10e,
+	0x0,
+	0x5000000,
+	0x1010505,
+	0x1010101,
+	0x191919,
+	0x0,
+	0x0,
+	0x11000000,
+	0xc0c1111,
+	0x303030c,
+	0xc0034,
+	0xc0034,
+	0xc0034,
+	0x0,
+	0x0,
+	0xa,
+	0xa,
+	0x100000a,
+	0x0,
+	0x100,
+	0x1000000,
+	0x0,
+	0x1e1a1e1a,
+	0x1011e1a,
+	0x100b0801,
+	0x100b080f,
+	0x100b080f,
+	0xc00f,
+	0xc01000,
+	0xc01000,
+	0x191000,
+	0x19010b,
+	0x19010b,
+	0x101010b,
+	0x1f01,
+	0x1e1a0055,
+	0x7000001,
+	0x1f0c11,
+	0x1e1a0055,
+	0x7000001,
+	0x1f0c11,
+	0x1e1a0055,
+	0x7000001,
+	0xc11,
+	0xf0f0800,
+	0x100806,
+	0x2301071c,
+	0x8002000,
+	0x1d1d190b,
+	0x60f0f08,
+	0x1008,
+	0x2301071c,
+	0x8002000,
+	0x1d1d190b,
+	0x60f0f08,
+	0x1008,
+	0x2301071c,
+	0x8002000,
+	0x1d1d190b,
+	0x40f6,
+	0x2899c,
+	0x40f6,
+	0x2899c,
+	0x40f6,
+	0x2899c,
+	0x3000300,
+	0x3030300,
+	0x30003,
+	0x3000300,
+	0xb,
+	0x0,
+	0x0,
+	0x0,
+	0x256,
+	0xb,
+	0x0,
+	0x0,
+	0x0,
+	0x256,
+	0xb,
+	0x0,
+	0x0,
+	0x0,
+	0x2000256,
+	0x80,
+	0x20000,
+	0x80,
+	0x20000,
+	0x80,
+	0x0,
+	0x0,
+	0x2020202,
+	0x2040108,
+	0x8010402,
+	0x67676767,
+	0x67676767,
+	0x67676767,
+	0x67676767,
+	0x1010101,
+	0x0,
+	0x0,
+	0x0,
+	0x0,
+	0x5500,
+	0x5a00,
+	0x55003c,
+	0x0,
+	0x3c00005a,
+	0x5500,
+	0x5a00,
+	0x55003c,
+	0x0,
+	0x3c00005a,
+	0x18171615,
+	0x14131211,
+	0x7060504,
+	0x3020100,
+	0x0,
+	0x0,
+	0x0,
+	0x1000000,
+	0x4020201,
+	0x80804,
+	0x634,
+	0x201,
+	0x10,
+	0x200,
+	0x0,
+	0x481,
+	0x800,
+	0x4d4d,
+	0x634,
+	0x201,
+	0x10,
+	0x200,
+	0x0,
+	0x481,
+	0x800,
+	0x4d4d,
+	0x634,
+	0x201,
+	0x10,
+	0x200,
+	0x0,
+	0x481,
+	0x800,
+	0x4d4d,
+	0x634,
+	0x201,
+	0x10,
+	0x200,
+	0x0,
+	0x481,
+	0x800,
+	0x4d4d,
+	0x634,
+	0x201,
+	0x10,
+	0x200,
+	0x0,
+	0x481,
+	0x800,
+	0x4d4d,
+	0x634,
+	0x201,
+	0x10,
+	0x200,
+	0x0,
+	0x481,
+	0x800,
+	0x4d4d,
+	0x634,
+	0x201,
+	0x10,
+	0x200,
+	0x0,
+	0x481,
+	0x800,
+	0x4d4d,
+	0x634,
+	0x201,
+	0x10,
+	0x200,
+	0x0,
+	0x481,
+	0x800,
+	0x4d4d,
+	0x634,
+	0x201,
+	0x10,
+	0x200,
+	0x0,
+	0x481,
+	0x800,
+	0x4d4d,
+	0x634,
+	0x201,
+	0x10,
+	0x200,
+	0x0,
+	0x481,
+	0x800,
+	0x4d4d,
+	0x634,
+	0x201,
+	0x10,
+	0x200,
+	0x0,
+	0x481,
+	0x800,
+	0x4d4d,
+	0x634,
+	0x201,
+	0x10,
+	0x200,
+	0x0,
+	0x481,
+	0x800,
+	0x4d4d,
+
+};
+
+static u32 lpddr4_train_data[] = {
 	0xb00,
 	0x101,
 	0x640000,
@@ -377,9 +746,24 @@ static u32 ddr_train_data[] = {
 void ddr_phy_train(u32 *phyreg)
 {
 	u32 i, len;
+	u32 *data;
+
+	switch (starfive_ddr_type) {
+	case DDR_TYPE_DDR4:
+		len = sizeof(ddr4_train_data) / sizeof(u32);
+		data = ddr4_train_data;
+		break;
+	case DDR_TYPE_LPDDR4:
+		len = sizeof(lpddr4_train_data) / sizeof(u32);
+		data = lpddr4_train_data;
+		break;
+	case DDR_TYPE_LPDDR3:
+	case DDR_TYPE_DDR3:
+	default:
+		return;
+	}
 
-	len = sizeof(ddr_train_data) / sizeof(u32);
 	for (i = 0; i < len; i++)
-		out_le32(phyreg + i, ddr_train_data[i]);
+		out_le32(phyreg + i, data[i]);
 }
 

File diff suppressed because it is too large
+ 1938 - 1
drivers/ram/starfive/ddrphy_utils.c


+ 38 - 3
drivers/ram/starfive/starfive_ddr.c

@@ -33,9 +33,17 @@ struct starfive_ddr_priv {
 	u32	fre;
 };
 
+enum ddr_type_t starfive_ddr_type;
+
+__weak int starfive_get_ddr_type(void)
+{
+	return -EINVAL;
+}
+
 static int starfive_ddr_setup(struct udevice *dev, struct starfive_ddr_priv *priv)
 {
 	enum ddr_size_t size;
+	int ret;
 
 	switch (priv->info.size) {
 	case 0x40000000:
@@ -56,11 +64,35 @@ static int starfive_ddr_setup(struct udevice *dev, struct starfive_ddr_priv *pri
 		return -1;
 	}
 
+	starfive_ddr_type = DDR_TYPE_LPDDR4;	/*set default ddr type */
+	ret = starfive_get_ddr_type();
+	if (ret >= 0) {
+		switch (ret) {
+		case 0x0:
+			starfive_ddr_type = DDR_TYPE_LPDDR4;
+			break;
+		case 0x1:
+			starfive_ddr_type = DDR_TYPE_DDR4;
+			break;
+		case 0x2:
+			starfive_ddr_type = DDR_TYPE_LPDDR3;
+			break;
+		case 0x3:
+			starfive_ddr_type = DDR_TYPE_DDR3;
+			break;
+		default:
+			pr_err("unsupport ddr type %d\n", ret);
+			return -EINVAL;
+		}
+	}
+
 	ddr_phy_train(priv->phyreg + (PHY_BASE_ADDR << 2));
 	ddr_phy_util(priv->phyreg + (PHY_AC_BASE_ADDR << 2));
 	ddr_phy_start(priv->phyreg, size);
 
-	DDR_REG_SET(BUS, DDR_BUS_OSC_DIV2);
+	if (starfive_ddr_type == DDR_TYPE_LPDDR4)
+		DDR_REG_SET(BUS, DDR_BUS_OSC_DIV2);
+
 	ddrcsr_boot(priv->ctrlreg, priv->ctrlreg + SEC_CTRL_ADDR,
 		   priv->phyreg, size);
 
@@ -124,8 +156,11 @@ static int starfive_ddr_probe(struct udevice *dev)
 	reset_deassert(&priv->rst_axi);
 
 	ret = starfive_ddr_setup(dev, priv);
-	printf("DDR: %ldG version: g8ad50857.\n", priv->info.size/1024/1024/1024);
-		goto init_end;
+	printf("%sDDR4: %ldG version: g8ad50857.\n",
+		starfive_ddr_type == DDR_TYPE_LPDDR4 ? "LP":"",
+		priv->info.size/1024/1024/1024);
+	goto init_end;
+
 err_osc:
 	reset_free(&priv->rst_osc);
 err_axi:

+ 10 - 0
drivers/ram/starfive/starfive_ddr.h

@@ -54,6 +54,16 @@ enum ddr_size_t {
 	DDR_SIZE_16G,
 };
 
+enum ddr_type_t {
+	DDR_TYPE_LPDDR4,
+	DDR_TYPE_DDR4,
+	DDR_TYPE_LPDDR3,
+	DDR_TYPE_DDR3,
+	DDR_TYPE_UNKNOWN,
+};
+
+extern enum ddr_type_t starfive_ddr_type;
+
 void ddr_phy_train(u32 *phyreg);
 void ddr_phy_util(u32 *phyreg);
 void ddr_phy_start(u32 *phyreg, enum ddr_size_t size);

Some files were not shown because too many files changed in this diff