ram: starfive: add ddr driver

Add driver for StarFive JH7110 to support ddr initialization in SPL.

Signed-off-by: Yanhong Wang <yanhong.wang@starfivetech.com>
Tested-by: Conor Dooley <conor.dooley@microchip.com>
diff --git a/drivers/ram/starfive/ddrphy_start.c b/drivers/ram/starfive/ddrphy_start.c
new file mode 100644
index 0000000..479b6ef
--- /dev/null
+++ b/drivers/ram/starfive/ddrphy_start.c
@@ -0,0 +1,279 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2022 StarFive Technology Co., Ltd.
+ * Author: Yanhong Wang<yanhong.wang@starfivetech.com>
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+#include "starfive_ddr.h"
+
+static const struct ddr_reg_cfg ddr_start_cfg[] = {
+	{89,	0xffffff00,	0x00000051,	(OFFSET_SEL | REGCLRSETALL)},
+	{78,	0xfffffcff,	0x0,		(OFFSET_SEL | REGCLRSETALL)},
+	{345,	0xffffff00,	0x00000051,	(OFFSET_SEL | REGCLRSETALL)},
+	{334,	0xfffffcff,	0x0,		(OFFSET_SEL | REGCLRSETALL)},
+	{601,	0xffffff00,	0x00000051,	(OFFSET_SEL | REGCLRSETALL)},
+	{590,	0xfffffcff,	0x0,		(OFFSET_SEL | REGCLRSETALL)},
+	{857,	0xffffff00,	0x00000051,	(OFFSET_SEL | REGCLRSETALL)},
+	{846,	0xfffffcff,	0x0,		(OFFSET_SEL | REGCLRSETALL)},
+	{1793,	0xfffffeff,	0x0,		(OFFSET_SEL | REGCLRSETALL)},
+	{1793,	0xfffcffff,	0x0,		(OFFSET_SEL | REGCLRSETALL)},
+	{125,	0xfff0ffff,	0x00010000,	(OFFSET_SEL | REGCLRSETALL)},
+	{102,	0xfffffffc,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
+	{105,	0xffffffe0,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
+	{92,	0xfffffffe,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
+	{94,	0xffffe0ff,	0x00000200,	(OFFSET_SEL | REGCLRSETALL)},
+	{96,	0xfffff0ff,	0x00000400,	(OFFSET_SEL | REGCLRSETALL)},
+	{89,	0xffffff00,	0x00000051,	(OFFSET_SEL | REGCLRSETALL)},
+	{381,	0xfff0ffff,	0x00010000,	(OFFSET_SEL | REGCLRSETALL)},
+	{358,	0xfffffffc,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
+	{361,	0xffffffe0,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
+	{348,	0xfffffffe,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
+	{350,	0xffffe0ff,	0x00000200,	(OFFSET_SEL | REGCLRSETALL)},
+	{352,	0xfffff0ff,	0x00000400,	(OFFSET_SEL | REGCLRSETALL)},
+	{345,	0xffffff00,	0x00000051,	(OFFSET_SEL | REGCLRSETALL)},
+	{637,	0xfff0ffff,	0x00010000,	(OFFSET_SEL | REGCLRSETALL)},
+	{614,	0xfffffffc,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
+	{617,	0xffffffe0,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
+	{604,	0xfffffffe,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
+	{606,	0xffffe0ff,	0x00000200,	(OFFSET_SEL | REGCLRSETALL)},
+	{608,	0xfffff0ff,	0x00000400,	(OFFSET_SEL | REGCLRSETALL)},
+	{601,	0xffffff00,	0x00000051,	(OFFSET_SEL | REGCLRSETALL)},
+	{893,	0xfff0ffff,	0x00010000,	(OFFSET_SEL | REGCLRSETALL)},
+	{870,	0xfffffffc,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
+	{873,	0xffffffe0,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
+	{860,	0xfffffffe,	0x00000001,	(OFFSET_SEL | REGCLRSETALL)},
+	{862,	0xffffe0ff,	0x00000200,	(OFFSET_SEL | REGCLRSETALL)},
+	{864,	0xfffff0ff,	0x00000400,	(OFFSET_SEL | REGCLRSETALL)},
+	{857,	0xffffff00,	0x00000051,	(OFFSET_SEL | REGCLRSETALL)},
+	{1895,	0xffffe000,	0x00001342,	(OFFSET_SEL | REGCLRSETALL)},
+	{1835,	0xfffff0ff,	0x00000200,	(OFFSET_SEL | REGCLRSETALL)},
+	{1793,	0xfffffeff,	0x00000100,	(OFFSET_SEL | REGCLRSETALL)},
+	{62,	0xfffffeff,	0x0,		REGCLRSETALL},
+	{66,	0xfffffeff,	0x0,		REGCLRSETALL},
+	{166,	0xffffff80,	0x00000001,	REGCLRSETALL},
+	{62,	0xfff0ffff,	0x00010000,	REGCLRSETALL},
+	{62,	0xf0ffffff,	0x01000000,	REGCLRSETALL},
+	{166,	0xffff80ff,	0x00000100,	REGCLRSETALL},
+	{179,	0xff80ffff,	0x00010000,	REGCLRSETALL},
+	{67,	0xffe0ffff,	0x00010000,	REGCLRSETALL},
+	{67,	0xe0ffffff,	0x01000000,	REGCLRSETALL},
+	{179,	0x80ffffff,	0x01000000,	REGCLRSETALL},
+	{166,	0xff80ffff,	0x00010000,	REGCLRSETALL},
+	{62,	0xfff0ffff,	0x00010000,	REGCLRSETALL},
+	{62,	0xf0ffffff,	0x01000000,	REGCLRSETALL},
+	{166,	0x80ffffff,	0x01000000,	REGCLRSETALL},
+	{182,	0xff80ffff,	0x00010000,	REGCLRSETALL},
+	{67,	0xffe0ffff,	0x00010000,	REGCLRSETALL},
+	{67,	0xe0ffffff,	0x01000000,	REGCLRSETALL},
+	{182,	0x80ffffff,	0x01000000,	REGCLRSETALL},
+	{167,	0xffffff80,	0x00000017,	REGCLRSETALL},
+	{62,	0xfff0ffff,	0x00010000,	REGCLRSETALL},
+	{62,	0xf0ffffff,	0x01000000,	REGCLRSETALL},
+	{167,	0xffff80ff,	0x00001700,	REGCLRSETALL},
+	{185,	0xff80ffff,	0x00200000,	REGCLRSETALL},
+	{67,	0xffe0ffff,	0x00010000,	REGCLRSETALL},
+	{67,	0xe0ffffff,	0x01000000,	REGCLRSETALL},
+	{185,	0x80ffffff,	0x20000000,	REGCLRSETALL},
+	{10,	0xffffffe0,	0x00000002,	REGCLRSETALL},
+	{0,	0xfffffffe,	0x00000001,	REGCLRSETALL},
+	{11,	0xfffffff0,	0x00000005,	(F_CLRSET | REG2G)},
+	{247,	0xffffffff,	0x00000008,	REGCLRSETALL},
+	{249,	0xffffffff,	0x00000800,	REGCLRSETALL},
+	{252,	0xffffffff,	0x00000008,	REGCLRSETALL},
+	{254,	0xffffffff,	0x00000800,	REGCLRSETALL},
+	{281,	0xffffffff,	0x33000000,	REGCLRSETALL},
+	{305,	0xffffffff,	0x33000000,	REGCLRSETALL},
+	{329,	0xffffffff,	0x33000000,	REGCLRSETALL},
+	{353,	0xffffffff,	0x33000000,	REGCLRSETALL},
+	{289,	0xffffffff,	0x36000000,	(F_CLRSET | REG8G)},
+	{313,	0xffffffff,	0x36000000,	(F_CLRSET | REG8G)},
+	{337,	0xffffffff,	0x36000000,	(F_CLRSET | REG8G)},
+	{361,	0xffffffff,	0x36000000,	(F_CLRSET | REG8G)},
+	{289,	0xffffffff,	0x66000000,	(F_CLRSET | REG2G | REG4G)},
+	{313,	0xffffffff,	0x66000000,	(F_CLRSET | REG2G | REG4G)},
+	{337,	0xffffffff,	0x66000000,	(F_CLRSET | REG2G | REG4G)},
+	{361,	0xffffffff,	0x66000000,	(F_CLRSET | REG2G | REG4G)},
+	{282,	0xffffffff,	0x00160000,	REGCLRSETALL},
+	{306,	0xffffffff,	0x00160000,	REGCLRSETALL},
+	{330,	0xffffffff,	0x00160000,	REGCLRSETALL},
+	{354,	0xffffffff,	0x00160000,	REGCLRSETALL},
+	{290,	0xffffffff,	0x00160000,	REGCLRSETALL},
+	{314,	0xffffffff,	0x00160000,	REGCLRSETALL},
+	{338,	0xffffffff,	0x00160000,	REGCLRSETALL},
+	{362,	0xffffffff,	0x00160000,	REGCLRSETALL},
+	{282,	0xffffff00,	0x17,		REGCLRSETALL},
+	{306,	0xffffff00,	0x17,		REGCLRSETALL},
+	{330,	0xffffff00,	0x17,		REGCLRSETALL},
+	{354,	0xffffff00,	0x17,		REGCLRSETALL},
+	{290,	0xffffff00,	0x17,		REGCLRSETALL},
+	{314,	0xffffff00,	0x17,		REGCLRSETALL},
+	{338,	0xffffff00,	0x17,		REGCLRSETALL},
+	{362,	0xffffff00,	0x17,		REGCLRSETALL},
+	{282,	0xffff00ff,	0x2000,		REGCLRSETALL},
+	{306,	0xffff00ff,	0x2000,		REGCLRSETALL},
+	{330,	0xffff00ff,	0x2000,		REGCLRSETALL},
+	{354,	0xffff00ff,	0x2000,		REGCLRSETALL},
+	{290,	0xffff00ff,	0x2000,		REGCLRSETALL},
+	{314,	0xffff00ff,	0x2000,		REGCLRSETALL},
+	{338,	0xffff00ff,	0x2000,		REGCLRSETALL},
+	{362,	0xffff00ff,	0x2000,		REGCLRSETALL},
+	{65,	0xffffffff,	0x00000100,	(OFFSET_SEL | REGCLRSETALL)},
+	{321,	0xffffffff,	0x00000100,	(OFFSET_SEL | REGCLRSETALL)},
+	{577,	0xffffffff,	0x00000100,	(OFFSET_SEL | REGCLRSETALL)},
+	{833,	0xffffffff,	0x00000100,	(OFFSET_SEL | 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)},
+	{1038,	0xfcffffff,	0x03000000,	(OFFSET_SEL | REGCLRSETALL)},
+	{1294,	0xfcffffff,	0x03000000,	(OFFSET_SEL | REGCLRSETALL)},
+	{1550,	0xfcffffff,	0x03000000,	(OFFSET_SEL | 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,	0x15547,	(OFFSET_SEL | REGCLRSETALL)},
+	{1893,	0xfffc0000,	0x7,		(OFFSET_SEL | REGCLRSETALL)},
+	{1852,	0xffffe000,	0x07a,		(OFFSET_SEL | REGCLRSETALL)},
+	{1853,	0xffffffff,	0x0100,		(OFFSET_SEL | REGCLRSETALL)},
+	{1822,	0xffffffff,	0xFF,		(OFFSET_SEL | REGCLRSETALL)},
+	{1896,	0xfffffc00,	0x03d5,		(OFFSET_SEL | REGCLRSETALL)},
+	{91,	0xfc00ffff,	0x03d50000,	(OFFSET_SEL | REGCLRSETALL)},
+	{347,	0xfc00ffff,	0x03d50000,	(OFFSET_SEL | REGCLRSETALL)},
+	{603,	0xfc00ffff,	0x03d50000,	(OFFSET_SEL | REGCLRSETALL)},
+	{859,	0xfc00ffff,	0x03d50000,	(OFFSET_SEL | REGCLRSETALL)},
+	{1912,	0x0,		0xcc3bfc7,	(OFFSET_SEL | REGSETALL)},
+	{1913,	0x0,		0xff8f,		(OFFSET_SEL | REGSETALL)},
+	{1914,	0x0,		0x33f07ff,	(OFFSET_SEL | REGSETALL)},
+	{1915,	0x0,		0xc3c37ff,	(OFFSET_SEL | REGSETALL)},
+	{1916,	0x0,		0x1fffff10,	(OFFSET_SEL | REGSETALL)},
+	{1917,	0x0,		0x230070,	(OFFSET_SEL | REGSETALL)},
+	{1918,	0x0,		0x3ff7ffff,	(OFFSET_SEL | REG4G | REG2G | F_SET)},
+	{1918,	0x0,		0x3ff7ffff,	(OFFSET_SEL | REG8G | F_SET)},
+	{1919,	0x0,		0xe10,		(OFFSET_SEL | REGSETALL)},
+	{1920,	0x0,		0x1fffffff,	(OFFSET_SEL | REGSETALL)},
+	{1921,	0x0,		0x188411,	(OFFSET_SEL | REGSETALL)},
+	{1922,	0x0,		0x1fffffff,	(OFFSET_SEL | REGSETALL)},
+	{1923,	0x0,		0x180400,	(OFFSET_SEL | REGSETALL)},
+	{1924,	0x0,		0x1fffffff,	(OFFSET_SEL | REGSETALL)},
+	{1925,	0x0,		0x180400,	(OFFSET_SEL | REGSETALL)},
+	{1926,	0x0,		0x1fffffcf,	(OFFSET_SEL | REGSETALL)},
+	{1927,	0x0,		0x188400,	(OFFSET_SEL | REGSETALL)},
+	{1928,	0x0,		0x1fffffff,	(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,	0x00ff8f07,	(OFFSET_SEL | REGCLRSETALL)},
+	{332,	0xff0000f8,	0x00ff8f07,	(OFFSET_SEL | REGCLRSETALL)},
+	{588,	0xff0000f8,	0x00ff8f07,	(OFFSET_SEL | REGCLRSETALL)},
+	{844,	0xff0000f8,	0x00ff8f07,	(OFFSET_SEL | REGCLRSETALL)},
+	{77,	0xffff0000,	0xff8f,		(OFFSET_SEL | REGCLRSETALL)},
+	{333,	0xffff0000,	0xff8f,		(OFFSET_SEL | REGCLRSETALL)},
+	{589,	0xffff0000,	0xff8f,		(OFFSET_SEL | REGCLRSETALL)},
+	{845,	0xffff0000,	0xff8f,		(OFFSET_SEL | REGCLRSETALL)},
+	{1062,	0xffffff00,	0xff,		(OFFSET_SEL | REG4G | REG2G | F_CLRSET)},
+	{1318,	0xffffff00,	0xff,		(OFFSET_SEL | REG4G | REG2G | F_CLRSET)},
+	{1574,	0xffffff00,	0xff,		(OFFSET_SEL | REG4G | REG2G | F_CLRSET)},
+	{1062,	0xffffff00,	0xfb,		(OFFSET_SEL | REG8G | F_CLRSET)},
+	{1318,	0xffffff00,	0xfb,		(OFFSET_SEL | REG8G | F_CLRSET)},
+	{1574,	0xffffff00,	0xfb,		(OFFSET_SEL | REG8G | F_CLRSET)},
+	{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,		0x1fffff,	(OFFSET_SEL | REGSETALL)},
+	{1851,	0x0,		0x060000,	(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)},
+};
+
+void ddr_reg_set(u32 *reg, const struct ddr_reg_cfg *data,
+		 u32 len, u32 mask)
+{
+	u32 *addr;
+	u32 i;
+
+	for (i = 0; i < len; i++) {
+		if (!(data[i].flag & mask))
+			continue;
+
+		if (data[i].flag & OFFSET_SEL)
+			addr = reg + PHY_AC_BASE_ADDR + data[i].offset;
+		else
+			addr = reg + PHY_BASE_ADDR + data[i].offset;
+
+		if (data[i].flag & F_CLRSET)
+			DDR_REG_TRIGGER(addr, data[i].mask, data[i].val);
+		else if (data[i].flag & F_SET)
+			out_le32(addr, data[i].val);
+		else
+			out_le32(addr, in_le32(addr) + data[i].val);
+	}
+}
+
+void ddr_phy_start(u32 *phyreg, enum ddr_size_t size)
+{
+	u32 len;
+	u32 mask;
+
+	switch (size) {
+	case DDR_SIZE_2G:
+		mask = REG2G;
+		break;
+
+	case DDR_SIZE_4G:
+		mask = REG4G;
+		break;
+
+	case DDR_SIZE_8G:
+		mask = REG8G;
+		break;
+
+	case DDR_SIZE_16G:
+	default:
+		return;
+	};
+
+	len = ARRAY_SIZE(ddr_start_cfg);
+	ddr_reg_set(phyreg, ddr_start_cfg, len, mask);
+	out_le32(phyreg, 0x01);
+}