All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH]  arm: add initial support for the Phytium Pomelo Board
@ 2021-06-16  6:16 nicholas_zheng
  0 siblings, 0 replies; 12+ messages in thread
From: nicholas_zheng @ 2021-06-16  6:16 UTC (permalink / raw)
  To: trini, bharat.gooty, rayagonda.kokatanur
  Cc: jagan, kever.yang, andre.przywara, festevam, patrick.delaunay,
	tharvey, pbrobinson, hs, lokeshvutla, d-gerlach, u-boot,
	weichangzheng

From: weichangzheng <nicholas_zheng@outlook.com>

 This adds platform code and the device tree for the Phytium Pomelo Board.
 The initial support comprises the UART and the PCIE.

Signed-off-by: weichangzheng <nicholas_zheng@outlook.com>
---
 arch/arm/Kconfig                 |   8 ++
 arch/arm/dts/Makefile            |   1 +
 arch/arm/dts/phytium-pomelo.dts  | 103 +++++++++++++++++++
 board/phytium/pomelo/Kconfig     |  12 +++
 board/phytium/pomelo/MAINTAINERS |   8 ++
 board/phytium/pomelo/Makefile    |  14 +++
 board/phytium/pomelo/cpu.h       |  73 ++++++++++++++
 board/phytium/pomelo/ddr.c       | 164 +++++++++++++++++++++++++++++++
 board/phytium/pomelo/pcie.c      |  61 ++++++++++++
 board/phytium/pomelo/pll.c       |  75 ++++++++++++++
 board/phytium/pomelo/pomelo.c    | 120 ++++++++++++++++++++++
 board/phytium/pomelo/sec.c       |  40 ++++++++
 configs/pomelo_defconfig         |  36 +++++++
 include/configs/pomelo.h         |  45 +++++++++
 14 files changed, 760 insertions(+)
 create mode 100644 arch/arm/dts/phytium-pomelo.dts
 create mode 100644 board/phytium/pomelo/Kconfig
 create mode 100644 board/phytium/pomelo/MAINTAINERS
 create mode 100644 board/phytium/pomelo/Makefile
 create mode 100644 board/phytium/pomelo/cpu.h
 create mode 100644 board/phytium/pomelo/ddr.c
 create mode 100644 board/phytium/pomelo/pcie.c
 create mode 100644 board/phytium/pomelo/pll.c
 create mode 100644 board/phytium/pomelo/pomelo.c
 create mode 100644 board/phytium/pomelo/sec.c
 create mode 100644 configs/pomelo_defconfig
 create mode 100644 include/configs/pomelo.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 31d687ea01..6110fcddad 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1800,6 +1800,13 @@ config TARGET_DURIAN
 	  Support for durian platform.
 	  It has 2GB Sdram, uart and pcie.
 
+config TARGET_POMELO
+	bool "Support Phytium Pomelo Platform"
+	select ARM64
+	help
+		Support for pomelo platform.
+		It has 2GB Sdram, uart and pcie.
+
 config TARGET_PRESIDIO_ASIC
 	bool "Support Cortina Presidio ASIC Platform"
 	select ARM64
@@ -2019,6 +2026,7 @@ source "board/toradex/colibri_pxa270/Kconfig"
 source "board/variscite/dart_6ul/Kconfig"
 source "board/vscom/baltos/Kconfig"
 source "board/phytium/durian/Kconfig"
+source "board/phytium/pomelo/Kconfig"
 source "board/xen/xenguest_arm64/Kconfig"
 source "board/keymile/Kconfig"
 
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 096068261d..c26692c17e 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1098,6 +1098,7 @@ dtb-$(CONFIG_TARGET_MX53PPD) += imx53-ppd.dtb
 dtb-$(CONFIG_TARGET_TOTAL_COMPUTE) += total_compute.dtb
 
 dtb-$(CONFIG_TARGET_DURIAN) += phytium-durian.dtb
+dtb-$(CONFIG_TARGET_POMELO) += phytium-pomelo.dtb
 
 dtb-$(CONFIG_TARGET_PRESIDIO_ASIC) += ca-presidio-engboard.dtb
 
diff --git a/arch/arm/dts/phytium-pomelo.dts b/arch/arm/dts/phytium-pomelo.dts
new file mode 100644
index 0000000000..4961682058
--- /dev/null
+++ b/arch/arm/dts/phytium-pomelo.dts
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Phytium Pomelo board
+ * Copyright (C) 2021, Phytium Ltd.
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+/dts-v1/;
+
+/memreserve/	0x0000000080000000 0x0000000000100000;
+/ {
+	model = "Phytium Pomelo";
+	compatible = "phytium,pomelo";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <0x2>;
+		#size-cells = <0x0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu4: cpu@4 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x100>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu5: cpu@5 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x101>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu8: cpu@8 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x200>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu9: cpu@9 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x201>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu12: cpu@12 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x300>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu13: cpu@13 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x301>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+	};
+
+	pcie-controller@40000000 {
+		compatible = "pci-host-ecam-generic";
+		device_type = "pci";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		reg = <0x0 0x40000000 0x0 0x10000000>;
+		bus-range = <0x0 0xff>;
+		ranges = <0x01000000 0x00 0x00000000 0x0  0x50000000 0x0  0x00F00000>,
+			 <0x02000000 0x00 0x58000000 0x0  0x58000000 0x0  0x28000000>,
+			 <0x43000000 0x10 0x00000000 0x10 0x00000000 0x10  0x00000000>;
+	};
+
+	uart@28001000 {
+		compatible = "arm,pl011";
+		reg = <0x0 0x28001000 0x0 0x1000>;
+		clock = <48000000>;
+	};
+};
diff --git a/board/phytium/pomelo/Kconfig b/board/phytium/pomelo/Kconfig
new file mode 100644
index 0000000000..281aa8feff
--- /dev/null
+++ b/board/phytium/pomelo/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_POMELO
+
+config SYS_BOARD
+	default "pomelo"
+
+config SYS_VENDOR
+	default "phytium"
+
+config SYS_CONFIG_NAME
+	default "pomelo"
+
+endif
diff --git a/board/phytium/pomelo/MAINTAINERS b/board/phytium/pomelo/MAINTAINERS
new file mode 100644
index 0000000000..950449392b
--- /dev/null
+++ b/board/phytium/pomelo/MAINTAINERS
@@ -0,0 +1,8 @@
+POMELO BOARD
+M:	lixinde <lixinde@phytium.com.cn>
+M:	weichangzheng <weichangzheng@phytium.com.cn>
+S:	Maintained
+F:	board/phytium/pomelo/*
+F:	include/configs/pomelo.h
+F:	configs/pomelo_defconfig
+
diff --git a/board/phytium/pomelo/Makefile b/board/phytium/pomelo/Makefile
new file mode 100644
index 0000000000..b9cb3609bd
--- /dev/null
+++ b/board/phytium/pomelo/Makefile
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2021
+# lixinde         <lixinde@phytium.com.cn>
+# weichangzheng   <weichangzheng@phytium.com.cn>
+#
+
+obj-y += pomelo.o
+obj-y += pll.o
+obj-y += pcie.o
+obj-y += ddr.o
+obj-y += sec.o
+
+
diff --git a/board/phytium/pomelo/cpu.h b/board/phytium/pomelo/cpu.h
new file mode 100644
index 0000000000..e15917609b
--- /dev/null
+++ b/board/phytium/pomelo/cpu.h
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2021
+ * Phytium Technology Ltd <www.phytium.com>
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#ifndef _FT_POMELO_H
+#define _FT_POMELO_H
+
+/* SMCCC ID */
+#define CPU_SVC_VERSION			0xC2000F00
+#define CPU_GET_RST_SOURCE		0xC2000F01
+#define CPU_INIT_PLL			0xC2000F02
+#define CPU_INIT_PCIE			0xC2000F03
+#define CPU_INIT_MEM			0xC2000F04
+#define CPU_INIT_SEC_SVC		0xC2000F05
+
+/*CPU RESET*/
+#define CPU_RESET_POWER_ON		0x1
+#define CPU_RESET_PLL			0x4
+#define CPU_RESET_WATCH_DOG		0x8
+
+/* PLL */
+#define PARAMETER_PLL_MAGIC		0x54460010
+
+/* PCIE */
+#define PARAMETER_PCIE_MAGIC		0x54460011
+#define CONFIG_INDEPENDENT_TREE		0x0
+#define PCI_PEU0			0x1
+#define PCI_PEU1			0x1
+#define PEU1_OFFSET			16
+#define PEU_C_OFFSET_MODE		16
+#define PEU_C_OFFSET_SPEED		0
+#define RC_MODE				0x1
+#define X8X8				0x1
+#define GEN3				3
+
+/* DDR */
+#define PARAMETER_MCU_MAGIC		0x54460014
+#define PARAM_MCU_VERSION		0x1
+#define PARAM_MCU_SIZE			0x100
+#define PARAM_CH_ENABLE			0x3
+#define PARAM_ECC_ENABLE		0x3
+#define PARAM_FORCE_SPD_DISABLE		0x0
+#define PARAM_MCU_MISC_ENABLE		0x0
+
+#define UDIMM_TYPE			0x2
+#define DIMM_X8				0x1
+#define NO_MIRROR			0x0
+#define NO_ECC_TYPE			0
+#define DDR4_TYPE			0xC
+
+/* SEC */
+#define PARAMETER_COMMON_MAGIC		0x54460013
+
+/* FLUSH L3 CASHE */
+#define HNF_COUNT			0x8
+#define HNF_PSTATE_REQ			(HNF_BASE + 0x10)
+#define HNF_PSTATE_STAT			(HNF_BASE + 0x18)
+#define HNF_PSTATE_OFF			0x0
+#define HNF_PSTATE_SFONLY		0x1
+#define HNF_PSTATE_HALF			0x2
+#define HNF_PSTATE_FULL			0x3
+#define HNF_STRIDE			0x10000
+#define HNF_BASE			(unsigned long)(0x3A200000)
+void ddr_init(void);
+void sec_init(void);
+void check_reset(void);
+void pcie_init(void);
+
+#endif /* _FT_POMELO_H */
diff --git a/board/phytium/pomelo/ddr.c b/board/phytium/pomelo/ddr.c
new file mode 100644
index 0000000000..88756f5fc1
--- /dev/null
+++ b/board/phytium/pomelo/ddr.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct ddr_spd {
+	/******************* read from spd *****************/
+	unsigned char  dimm_type;	/* 1: RDIMM;2: UDIMM;3: SODIMM;4: LRDIMM */
+	unsigned char  data_width;	/* 0: x4; 1: x8; 2: x16 */
+	unsigned char  mirror_type;	/* 0: stardard; 1: mirror */
+	unsigned char  ecc_type;	/* 0: no-ecc; 1:ecc */
+	unsigned char  dram_type;	/* 0xB: DDR3; 0xC: DDR4 */
+	unsigned char  rank_num;
+	unsigned char  row_num;
+	unsigned char  col_num;
+
+	unsigned char  bg_num;	/*only DDR4*/
+	unsigned char  bank_num;
+	unsigned short int module_manufacturer_id;
+	unsigned short int taamin;
+	unsigned short int trcdmin;
+
+	unsigned short int trpmin;
+	unsigned short int trasmin;
+	unsigned short int trcmin;
+	unsigned short int tfawmin;
+
+	unsigned short int trrd_smin;	/*only DDR4*/
+	unsigned short int trrd_lmin;	/*only DDR4*/
+	unsigned short int tccd_lmin;	/*only DDR4*/
+	unsigned short int twrmin;
+
+	unsigned short int twtr_smin;	/*only DDR4*/
+	unsigned short int twtr_lmin;	/*only DDR4*/
+	unsigned short int twtrmin;	/*only DDR3*/
+	unsigned short int trrdmin;	/*only DDR3*/
+
+	/******************* RCD control words *****************/
+	unsigned char  f0rc03; /*bit[3:2]:CS		bit[1:0]:CA  */
+	unsigned char  f0rc04; /*bit[3:2]:ODT		bit[1:0]:CKE */
+	unsigned char  f0rc05; /*bit[3:2]:CLK-A side	bit[1:0]:CLK-B side */
+	unsigned char  bc00;
+	unsigned char  bc01;
+	unsigned char  bc02;
+	unsigned char  bc03;
+	unsigned char  bc04;
+
+	unsigned char  bc05;
+	unsigned char  f5bc5x;
+	unsigned char  f5bc6x;
+	/******************* LRDIMM special *****************/
+	unsigned char  vrefdq_pr0;
+	unsigned char  vrefdq_mdram;
+	unsigned char  rtt_mdram_1866;
+	unsigned char  rtt_mdram_2400;
+	unsigned char  rtt_mdram_3200;
+
+	unsigned char  drive_dram;
+	unsigned char  odt_dram_1866;
+	unsigned char  odt_dram_2400;
+	unsigned char  odt_dram_3200;
+	unsigned char  park_dram_1866;
+	unsigned char  park_dram_2400;
+	unsigned char  park_dram_3200;
+	unsigned char  rcd_num;
+} __attribute((aligned(4)));
+
+struct mcu_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+
+	unsigned char ch_enable;
+	unsigned char misc1_enable;
+	unsigned char misc2_enable;
+	unsigned char force_spd_enable;
+	unsigned char misc3_enable;
+	unsigned char train_debug;
+	unsigned char train_recover;
+	unsigned char rev2[9];
+
+	struct ddr_spd ddr_spd_info[2];
+} __attribute((aligned(4)));
+
+static void get_mcu_up_info_default(struct mcu_config *pm)
+{
+	pm->magic		= PARAMETER_MCU_MAGIC;
+	pm->version		= PARAM_MCU_VERSION;
+	pm->size		= PARAM_MCU_SIZE;
+	pm->ch_enable		= PARAM_CH_ENABLE;
+	pm->misc1_enable	= PARAM_ECC_ENABLE;
+	pm->force_spd_enable	= PARAM_FORCE_SPD_DISABLE;
+	pm->misc3_enable	= PARAM_MCU_MISC_ENABLE;
+	pm->train_recover	= 0x0;
+}
+
+static unsigned char init_dimm_param(unsigned char ch, struct mcu_config *pm)
+{
+	printf("manual config dimm info...\n");
+	pm->ddr_spd_info[ch].dimm_type = UDIMM_TYPE;
+	pm->ddr_spd_info[ch].data_width = DIMM_X8;
+	pm->ddr_spd_info[ch].mirror_type = NO_MIRROR;
+	pm->ddr_spd_info[ch].ecc_type = NO_ECC_TYPE;
+	pm->ddr_spd_info[ch].dram_type = DDR4_TYPE;
+	pm->ddr_spd_info[ch].rank_num = 1;
+	pm->ddr_spd_info[ch].row_num  = 16;
+	pm->ddr_spd_info[ch].col_num = 10;
+	pm->ddr_spd_info[ch].bg_num = 4;
+	pm->ddr_spd_info[ch].bank_num = 4;
+	pm->ddr_spd_info[ch].taamin = 13750;
+	pm->ddr_spd_info[ch].trcdmin = 13750;
+
+	pm->ddr_spd_info[ch].trpmin = 13750;
+	pm->ddr_spd_info[ch].trasmin = 32000;
+	pm->ddr_spd_info[ch].trcmin =  45750;
+	pm->ddr_spd_info[ch].tfawmin = 21000;
+
+	pm->ddr_spd_info[ch].trrd_smin = 3000;
+	pm->ddr_spd_info[ch].trrd_lmin = 4900;
+	pm->ddr_spd_info[ch].tccd_lmin = 5000;
+	pm->ddr_spd_info[ch].twrmin = 15000;
+
+	pm->ddr_spd_info[ch].twtr_smin = 2500;
+	pm->ddr_spd_info[ch].twtr_lmin = 7500;
+
+	return 0;
+}
+
+void get_default_mcu_info(unsigned char *data)
+{
+	get_mcu_up_info_default((struct mcu_config *)data);
+}
+
+void fix_mcu_info(unsigned char *data)
+{
+	unsigned char ch;
+	struct mcu_config *mcu_info = (struct mcu_config *)data;
+
+	for (ch = 0; ch < 2; ch++)
+		init_dimm_param(ch, mcu_info);
+}
+
+void ddr_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	get_default_mcu_info(buffer);
+	fix_mcu_info(buffer);
+
+	arm_smccc_smc(CPU_INIT_MEM, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+	if (res.a0 != 0) {
+		printf("error x0: 0x%lx, x1: 0x%lx\n", res.a0, res.a1);
+		while (true)
+			;
+	}
+}
diff --git a/board/phytium/pomelo/pcie.c b/board/phytium/pomelo/pcie.c
new file mode 100644
index 0000000000..3754d8eb9b
--- /dev/null
+++ b/board/phytium/pomelo/pcie.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct pcu_ctr {
+	unsigned int base_config[3];
+	unsigned int equalization[3];
+	unsigned char rev[80];
+} __attribute((aligned(4)));
+
+struct pcu_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+	unsigned int independent_tree;
+	unsigned int base_cfg;
+	unsigned char rev2[16];
+	struct pcu_ctr ctr_cfg[2];
+} __attribute((aligned(4)));
+
+struct pcu_config const peu_base_info = {
+	.magic = PARAMETER_PCIE_MAGIC,
+	.version = 0x2,
+	.size = 0x100,
+	.independent_tree = CONFIG_INDEPENDENT_TREE,
+	.base_cfg = ((PCI_PEU1 | (X8X8 << 1)) << PEU1_OFFSET | (PCI_PEU0 | (X8X8 << 1))),
+	.ctr_cfg[0].base_config[0] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[0].base_config[1] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[0].base_config[2] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[1].base_config[0] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[1].base_config[1] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[1].base_config[2] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[0].equalization[0] = 0x7,
+	.ctr_cfg[0].equalization[1] = 0x7,
+	.ctr_cfg[0].equalization[2] = 0x7,
+	.ctr_cfg[1].equalization[0] = 0x7,
+	.ctr_cfg[1].equalization[1] = 0x7,
+	.ctr_cfg[1].equalization[2] = 0x7,
+};
+
+void pcie_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	memcpy(buffer, &peu_base_info, sizeof(peu_base_info));
+	arm_smccc_smc(CPU_INIT_PCIE, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+	if (res.a0 != 0) {
+		while (true)
+			;
+	}
+}
diff --git a/board/phytium/pomelo/pll.c b/board/phytium/pomelo/pll.c
new file mode 100644
index 0000000000..1227b7dd80
--- /dev/null
+++ b/board/phytium/pomelo/pll.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <asm/io.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct pll_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+	unsigned int core_pll;
+	unsigned int res1;
+	unsigned int lmu_pll;
+	unsigned int res2;
+	unsigned int res3;
+	unsigned int res4;
+	unsigned int res5;
+} __attribute((aligned(4)));
+
+struct pll_config const pll_base_info = {
+	.magic = PARAMETER_PLL_MAGIC,
+	.version = 0x1,
+	.size = 0x30,
+	.core_pll = 2300,	/*MHz*/
+	.lmu_pll = 667,		/*MHz*/
+};
+
+unsigned int get_reset_source(void)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(CPU_GET_RST_SOURCE, 0, 0, 0, 0, 0, 0, 0, &res);
+	return res.a0;
+}
+
+void pll_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	memcpy(buffer, &pll_base_info, sizeof(pll_base_info));
+	arm_smccc_smc(CPU_INIT_PLL, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+	if (res.a0 != 0) {
+		while (true)
+			;
+	}
+}
+
+void check_reset(void)
+{
+	unsigned int rst;
+
+	rst = get_reset_source();
+
+	switch (rst) {
+	case CPU_RESET_POWER_ON:
+		pll_init();
+		break;
+	case CPU_RESET_PLL:
+		break;
+	case CPU_RESET_WATCH_DOG:
+		break;
+	default:
+		while (true)
+			;
+	}
+}
diff --git a/board/phytium/pomelo/pomelo.c b/board/phytium/pomelo/pomelo.c
new file mode 100644
index 0000000000..693e891d20
--- /dev/null
+++ b/board/phytium/pomelo/pomelo.c
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <command.h>
+#include <init.h>
+#include <asm/armv8/mmu.h>
+#include <asm/io.h>
+#include <linux/arm-smccc.h>
+#include <scsi.h>
+#include "cpu.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+	gd->mem_clk = 0;
+	gd->ram_size = PHYS_SDRAM_1_SIZE;
+
+	printf("Phytium ddr init\n");
+
+	ddr_init();
+	sec_init();
+	printf("PBF relocate done\n");
+
+	return 0;
+}
+
+int board_init(void)
+{
+	return 0;
+}
+
+void reset_cpu(void)
+{
+	struct arm_smccc_res res;
+
+	printf("run in reset cpu\n");
+	arm_smccc_smc(0x84000009, 0, 0, 0, 0, 0, 0, 0, &res);
+	printf("reset cpu error, %lx\n", res.a0);
+}
+
+int mach_cpu_init(void)
+{
+	check_reset();
+	return 0;
+}
+
+int board_early_init_f(void)
+{
+	pcie_init();
+	return 0;
+}
+
+int board_early_init_r(void)
+{
+	return 0;
+}
+
+static struct mm_region pomelo_mem_map[] = {
+	{
+		.virt = 0x0UL,
+		.phys = 0x0UL,
+		.size = 0x80000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+				 PTE_BLOCK_NON_SHARE |
+				 PTE_BLOCK_PXN |
+				 PTE_BLOCK_UXN
+	},
+	{
+		.virt = (u64)PHYS_SDRAM_1,
+		.phys = (u64)PHYS_SDRAM_1,
+		.size = (u64)PHYS_SDRAM_1_SIZE,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+				 PTE_BLOCK_NS |
+				 PTE_BLOCK_INNER_SHARE
+	},
+	{
+		0,
+	}
+};
+
+struct mm_region *mem_map = pomelo_mem_map;
+
+int __asm_flush_l3_dcache(void)
+{
+	int i, pstate;
+
+	for (i = 0; i < HNF_COUNT; i++)
+		writeq(HNF_PSTATE_SFONLY, HNF_PSTATE_REQ + i * HNF_STRIDE);
+	for (i = 0; i < HNF_COUNT; i++) {
+		do {
+			pstate = readq(HNF_PSTATE_STAT + i * HNF_STRIDE);
+		} while ((pstate & 0xf) != (HNF_PSTATE_SFONLY << 2));
+	}
+
+	for (i = 0; i < HNF_COUNT; i++)
+		writeq(HNF_PSTATE_FULL, HNF_PSTATE_REQ + i * HNF_STRIDE);
+
+	return 0;
+}
+
+int last_stage_init(void)
+{
+	int ret;
+
+	/* pci e */
+	pci_init();
+	/* scsi scan */
+	ret = scsi_scan(true);
+	if (ret) {
+		printf("scsi scan failed\n");
+		return CMD_RET_FAILURE;
+	}
+	return ret;
+}
diff --git a/board/phytium/pomelo/sec.c b/board/phytium/pomelo/sec.c
new file mode 100644
index 0000000000..8ec0fa797b
--- /dev/null
+++ b/board/phytium/pomelo/sec.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct common_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+	unsigned long long  core_bit_map;
+} __attribute((aligned(4)));
+
+struct common_config const common_base_info = {
+	.magic = PARAMETER_COMMON_MAGIC,
+	.version = 0x1,
+	.core_bit_map = 0x3333,
+};
+
+void sec_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	memcpy(buffer, &common_base_info, sizeof(common_base_info));
+	arm_smccc_smc(CPU_INIT_SEC_SVC, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+
+	if (res.a0 != 0) {
+		printf("error ret %lx\n", res.a0);
+		while (true)
+			;
+	}
+}
diff --git a/configs/pomelo_defconfig b/configs/pomelo_defconfig
new file mode 100644
index 0000000000..3e6c18196d
--- /dev/null
+++ b/configs/pomelo_defconfig
@@ -0,0 +1,36 @@
+CONFIG_ARM=y
+CONFIG_ARM_SMCCC=y
+CONFIG_TARGET_POMELO=y
+CONFIG_SYS_TEXT_BASE=0x180000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x1000
+# CONFIG_PSCI_RESET is not set
+CONFIG_DEFAULT_DEVICE_TREE="phytium-pomelo"
+CONFIG_AHCI=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyAMA0,115200 earlycon=pl011,0x28001000 root=/dev/sda2 rw"
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_LAST_STAGE_INIT=y
+CONFIG_SYS_PROMPT="pomelo#"
+# CONFIG_CMD_LZMADEC is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_PCI=y
+CONFIG_OF_CONTROL=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+# CONFIG_NET is not set
+CONFIG_DM=y
+CONFIG_SCSI_AHCI=y
+CONFIG_AHCI_PCI=y
+CONFIG_BLK=y
+# CONFIG_MMC is not set
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
+CONFIG_PCI_PHYTIUM=y
+CONFIG_PCIE_ECAM_GENERIC=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
+CONFIG_DM_SERIAL=y
+CONFIG_PL01X_SERIAL=y
diff --git a/include/configs/pomelo.h b/include/configs/pomelo.h
new file mode 100644
index 0000000000..69c4195d86
--- /dev/null
+++ b/include/configs/pomelo.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#ifndef __POMELO_CONFIG_H__
+#define __POMELO_CONFIG_H__
+
+/* SDRAM Bank #1 start address */
+#define PHYS_SDRAM_1			0x80000000
+#define PHYS_SDRAM_1_SIZE		0x7B000000
+#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
+
+#define CONFIG_SYS_LOAD_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x10000000)
+
+/* SIZE of malloc pool */
+#define CONFIG_SYS_MALLOC_LEN		(1 * 1024 * 1024  + CONFIG_ENV_SIZE)
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_BOARD_EARLY_INIT_R
+
+#define CONFIG_SYS_INIT_SP_ADDR		(0x29800000 + 0x1a000)
+
+/* PCI CONFIG */
+#define CONFIG_SYS_PCI_64BIT		1
+#define CONFIG_PCI_SCAN_SHOW
+
+/* SCSI */
+#define CONFIG_SYS_SCSI_MAX_SCSI_ID	4
+#define CONFIG_SYS_SCSI_MAX_LUN		1
+#define CONFIG_SYS_SCSI_MAX_DEVICE	128
+#define CONFIG_SCSI_AHCI_PLAT
+#define CONFIG_SYS_SATA_MAX_DEVICE	4
+
+/*BOOT*/
+#define CONFIG_SYS_BOOTM_LEN		(60 * 1024 * 1024)
+
+#define CONFIG_EXTRA_ENV_SETTINGS	\
+	"load_kernel=ext4load scsi 0:1 0x90100000 uImage_old\0"	\
+	"load_fdt=ext4load scsi 0:1 0x95000000 ft-d2000.dtb\0"\
+	"boot_fdt=bootm 0x90100000 -:- 0x17c000\0"	\
+	"distro_bootcmd=run load_kernel; run boot_fdt"
+
+#endif
-- 
2.17.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* 回复: [PATCH]  arm: add initial support for the Phytium Pomelo Board
  2021-06-25 12:27 ` Andre Przywara
@ 2021-06-29  7:41   ` Nicholas zheng
  0 siblings, 0 replies; 12+ messages in thread
From: Nicholas zheng @ 2021-06-29  7:41 UTC (permalink / raw)
  To: Andre Przywara
  Cc: trini, bharat.gooty, rayagonda.kokatanur, jagan, festevam,
	patrick.delaunay, tharvey, pbrobinson, hs, lokeshvutla,
	d-gerlach, u-boot, Rob Herring


Is this some internal board? Or something China only? Google couldn't
find any useful hits about the platform.

This board corresponds to Phytium D2000. The name of the public edition has not been announced.
For other questions, I will submit a new patch after modifying it. thanks.
________________________________
发件人: Andre Przywara <andre.przywara@arm.com>
发送时间: 2021年6月25日 20:27
收件人: nicholas_zheng@outlook.com <nicholas_zheng@outlook.com>
抄送: trini@konsulko.com <trini@konsulko.com>; bharat.gooty@broadcom.com <bharat.gooty@broadcom.com>; rayagonda.kokatanur@broadcom.com <rayagonda.kokatanur@broadcom.com>; jagan@amarulasolutions.com <jagan@amarulasolutions.com>; festevam@gmail.com <festevam@gmail.com>; patrick.delaunay@foss.st.com <patrick.delaunay@foss.st.com>; tharvey@gateworks.com <tharvey@gateworks.com>; pbrobinson@gmail.com <pbrobinson@gmail.com>; hs@denx.de <hs@denx.de>; lokeshvutla@ti.com <lokeshvutla@ti.com>; d-gerlach@ti.com <d-gerlach@ti.com>; u-boot@lists.denx.de <u-boot@lists.denx.de>; Rob Herring <robh+dt@kernel.org>
主题: Re: [PATCH] arm: add initial support for the Phytium Pomelo Board

On Thu, 24 Jun 2021 09:02:45 +0800
nicholas_zheng@outlook.com wrote:

Hi,

this is some revised version, isn't it? Can you please start putting
patch version numbers into the subject: "[PATCH v4] arm: ..."? It's hard
to see what's outdated and find the latest version otherwise.

> From: weichangzheng <nicholas_zheng@outlook.com>
>
>  This adds platform code and the device tree for the Phytium Pomelo Board.
>  The initial support comprises the UART and the PCIE.

Is this some internal board? Or something China only? Google couldn't
find any useful hits about the platform.

>
> Signed-off-by: weichangzheng <nicholas_zheng@outlook.com>
> ---
>  arch/arm/Kconfig                 |   8 ++
>  arch/arm/dts/Makefile            |   1 +
>  arch/arm/dts/phytium-pomelo.dts  | 103 +++++++++++++++++++
>  board/phytium/pomelo/Kconfig     |  12 +++
>  board/phytium/pomelo/MAINTAINERS |   8 ++
>  board/phytium/pomelo/Makefile    |  14 +++
>  board/phytium/pomelo/cpu.h       |  73 ++++++++++++++
>  board/phytium/pomelo/ddr.c       | 164 +++++++++++++++++++++++++++++++
>  board/phytium/pomelo/pcie.c      |  61 ++++++++++++
>  board/phytium/pomelo/pll.c       |  75 ++++++++++++++
>  board/phytium/pomelo/pomelo.c    | 120 ++++++++++++++++++++++
>  board/phytium/pomelo/sec.c       |  40 ++++++++
>  configs/pomelo_defconfig         |  36 +++++++
>  include/configs/pomelo.h         |  45 +++++++++
>  14 files changed, 760 insertions(+)
>  create mode 100644 arch/arm/dts/phytium-pomelo.dts
>  create mode 100644 board/phytium/pomelo/Kconfig
>  create mode 100644 board/phytium/pomelo/MAINTAINERS
>  create mode 100644 board/phytium/pomelo/Makefile
>  create mode 100644 board/phytium/pomelo/cpu.h
>  create mode 100644 board/phytium/pomelo/ddr.c
>  create mode 100644 board/phytium/pomelo/pcie.c
>  create mode 100644 board/phytium/pomelo/pll.c
>  create mode 100644 board/phytium/pomelo/pomelo.c
>  create mode 100644 board/phytium/pomelo/sec.c
>  create mode 100644 configs/pomelo_defconfig
>  create mode 100644 include/configs/pomelo.h
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 31d687ea01..6110fcddad 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1800,6 +1800,13 @@ config TARGET_DURIAN
>          Support for durian platform.
>          It has 2GB Sdram, uart and pcie.
>
> +config TARGET_POMELO
> +     bool "Support Phytium Pomelo Platform"
> +     select ARM64
> +     help
> +             Support for pomelo platform.
> +             It has 2GB Sdram, uart and pcie.
> +
>  config TARGET_PRESIDIO_ASIC
>        bool "Support Cortina Presidio ASIC Platform"
>        select ARM64
> @@ -2019,6 +2026,7 @@ source "board/toradex/colibri_pxa270/Kconfig"
>  source "board/variscite/dart_6ul/Kconfig"
>  source "board/vscom/baltos/Kconfig"
>  source "board/phytium/durian/Kconfig"
> +source "board/phytium/pomelo/Kconfig"
>  source "board/xen/xenguest_arm64/Kconfig"
>  source "board/keymile/Kconfig"
>
> diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
> index 096068261d..c26692c17e 100644
> --- a/arch/arm/dts/Makefile
> +++ b/arch/arm/dts/Makefile
> @@ -1098,6 +1098,7 @@ dtb-$(CONFIG_TARGET_MX53PPD) += imx53-ppd.dtb
>  dtb-$(CONFIG_TARGET_TOTAL_COMPUTE) += total_compute.dtb
>
>  dtb-$(CONFIG_TARGET_DURIAN) += phytium-durian.dtb
> +dtb-$(CONFIG_TARGET_POMELO) += phytium-pomelo.dtb
>
>  dtb-$(CONFIG_TARGET_PRESIDIO_ASIC) += ca-presidio-engboard.dtb
>
> diff --git a/arch/arm/dts/phytium-pomelo.dts b/arch/arm/dts/phytium-pomelo.dts
> new file mode 100644
> index 0000000000..4961682058
> --- /dev/null
> +++ b/arch/arm/dts/phytium-pomelo.dts
> @@ -0,0 +1,103 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * dts file for Phytium Pomelo board
> + * Copyright (C) 2021, Phytium Ltd.
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */

I think this file should be reviewed by Linux DT people, they have much
more experience with this (CC:ing Rob)
It looks simple enough to remain stable, so the U-Boot DT could
actually be the only source for the DTB, but it should still go through
Linux' review machinery.

> +/dts-v1/;
> +
> +/memreserve/ 0x0000000080000000 0x0000000000100000;

I think /memreserve/ is somewhat deprecated now. It has the
disadvantage of allowing the kernel to still map the memory, so the CPU
can speculate into there, which might cause problems if this is
configured secure-only.
(I guess this is where the secure firmware/PSCI provider/TF-A lives?)

The better alternative is
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
and using the "nomap;" property.

> +/ {
> +     model = "Phytium Pomelo";
> +     compatible = "phytium,pomelo";
> +     #address-cells = <2>;
> +     #size-cells = <2>;
> +

Please have a chosen node with a stdout-path property pointing to the
UART. And possibly an aliases node with serial0 entry.
Then you can use just "earlycon" on the command line, and in general DT
users will find the console automatically.

> +     cpus {
> +             #address-cells = <0x2>;
> +             #size-cells = <0x0>;
> +
> +             cpu0: cpu@0 {
> +                     device_type = "cpu";
> +                     compatible = "arm,armv8";

This generic name is now deprecated (reserved for the AEM fastmodel),
we use the actual core name now.

> +                     reg = <0x0 0x0>;
> +                     enable-method = "psci";
> +                     numa-node-id = <0>;
> +             };
> +
> +             cpu1: cpu@1 {
> +                     device_type = "cpu";
> +                     compatible = "arm,armv8";
> +                     reg = <0x0 0x1>;
> +                     enable-method = "psci";
> +                     numa-node-id = <0>;
> +             };
> +
> +             cpu4: cpu@4 {

The cpu label should just increase monotonically, so this would be
cpu2. The address behind the "@" must match the reg property:
                cpu2: cpu@100 {
(same for the rest)

> +                     device_type = "cpu";
> +                     compatible = "arm,armv8";
> +                     reg = <0x0 0x100>;
> +                     enable-method = "psci";
> +                     numa-node-id = <0>;
> +             };
> +
> +             cpu5: cpu@5 {
> +                     device_type = "cpu";
> +                     compatible = "arm,armv8";
> +                     reg = <0x0 0x101>;
> +                     enable-method = "psci";
> +                     numa-node-id = <0>;
> +             };
> +
> +             cpu8: cpu@8 {
> +                     device_type = "cpu";
> +                     compatible = "arm,armv8";
> +                     reg = <0x0 0x200>;
> +                     enable-method = "psci";
> +                     numa-node-id = <0>;
> +             };
> +
> +             cpu9: cpu@9 {
> +                     device_type = "cpu";
> +                     compatible = "arm,armv8";
> +                     reg = <0x0 0x201>;
> +                     enable-method = "psci";
> +                     numa-node-id = <0>;
> +             };
> +
> +             cpu12: cpu@12 {
> +                     device_type = "cpu";
> +                     compatible = "arm,armv8";
> +                     reg = <0x0 0x300>;
> +                     enable-method = "psci";
> +                     numa-node-id = <0>;
> +             };
> +
> +             cpu13: cpu@13 {
> +                     device_type = "cpu";
> +                     compatible = "arm,armv8";
> +                     reg = <0x0 0x301>;
> +                     enable-method = "psci";
> +                     numa-node-id = <0>;
> +             };
> +     };
> +
> +     pcie-controller@40000000 {
> +             compatible = "pci-host-ecam-generic";
> +             device_type = "pci";
> +             #address-cells = <3>;
> +             #size-cells = <2>;
> +             reg = <0x0 0x40000000 0x0 0x10000000>;
> +             bus-range = <0x0 0xff>;
> +             ranges = <0x01000000 0x00 0x00000000 0x0  0x50000000 0x0  0x00F00000>,
> +                      <0x02000000 0x00 0x58000000 0x0  0x58000000 0x0  0x28000000>,
> +                      <0x43000000 0x10 0x00000000 0x10 0x00000000 0x10  0x00000000>;
> +     };

If this works you deserve a price for shipping a working and standards
compliant PCIe controller ;-)

Read: all fine, well done:
- full 256MB config space!
- generous MMIO32 area!
- even more generous MMIO64 area!

> +
> +     uart@28001000 {
> +             compatible = "arm,pl011";
> +             reg = <0x0 0x28001000 0x0 0x1000>;
> +             clock = <48000000>;

I think this is a non-standard property?
Please have a fixed-clock with 48 MHz, and refer to that from here. If
you need the UART before the DT is parsed, you can set the base
frequency somewhere in the config or some header file.

Didn't look at the rest too closely, can't check much of this anyway.

Cheers,
Andre

> +     };
> +};
> diff --git a/board/phytium/pomelo/Kconfig b/board/phytium/pomelo/Kconfig
> new file mode 100644
> index 0000000000..281aa8feff
> --- /dev/null
> +++ b/board/phytium/pomelo/Kconfig
> @@ -0,0 +1,12 @@
> +if TARGET_POMELO
> +
> +config SYS_BOARD
> +     default "pomelo"
> +
> +config SYS_VENDOR
> +     default "phytium"
> +
> +config SYS_CONFIG_NAME
> +     default "pomelo"
> +
> +endif
> diff --git a/board/phytium/pomelo/MAINTAINERS b/board/phytium/pomelo/MAINTAINERS
> new file mode 100644
> index 0000000000..950449392b
> --- /dev/null
> +++ b/board/phytium/pomelo/MAINTAINERS
> @@ -0,0 +1,8 @@
> +POMELO BOARD
> +M:   lixinde <lixinde@phytium.com.cn>
> +M:   weichangzheng <weichangzheng@phytium.com.cn>
> +S:   Maintained
> +F:   board/phytium/pomelo/*
> +F:   include/configs/pomelo.h
> +F:   configs/pomelo_defconfig
> +
> diff --git a/board/phytium/pomelo/Makefile b/board/phytium/pomelo/Makefile
> new file mode 100644
> index 0000000000..b9cb3609bd
> --- /dev/null
> +++ b/board/phytium/pomelo/Makefile
> @@ -0,0 +1,14 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +#
> +# Copyright (C) 2021
> +# lixinde         <lixinde@phytium.com.cn>
> +# weichangzheng   <weichangzheng@phytium.com.cn>
> +#
> +
> +obj-y += pomelo.o
> +obj-y += pll.o
> +obj-y += pcie.o
> +obj-y += ddr.o
> +obj-y += sec.o
> +
> +
> diff --git a/board/phytium/pomelo/cpu.h b/board/phytium/pomelo/cpu.h
> new file mode 100644
> index 0000000000..e15917609b
> --- /dev/null
> +++ b/board/phytium/pomelo/cpu.h
> @@ -0,0 +1,73 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * (C) Copyright 2021
> + * Phytium Technology Ltd <www.phytium.com<http://www.phytium.com>>
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */
> +
> +#ifndef _FT_POMELO_H
> +#define _FT_POMELO_H
> +
> +/* SMCCC ID */
> +#define CPU_SVC_VERSION                      0xC2000F00
> +#define CPU_GET_RST_SOURCE           0xC2000F01
> +#define CPU_INIT_PLL                 0xC2000F02
> +#define CPU_INIT_PCIE                        0xC2000F03
> +#define CPU_INIT_MEM                 0xC2000F04
> +#define CPU_INIT_SEC_SVC             0xC2000F05
> +
> +/*CPU RESET*/
> +#define CPU_RESET_POWER_ON           0x1
> +#define CPU_RESET_PLL                        0x4
> +#define CPU_RESET_WATCH_DOG          0x8
> +
> +/* PLL */
> +#define PARAMETER_PLL_MAGIC          0x54460010
> +
> +/* PCIE */
> +#define PARAMETER_PCIE_MAGIC         0x54460011
> +#define CONFIG_INDEPENDENT_TREE              0x0
> +#define PCI_PEU0                     0x1
> +#define PCI_PEU1                     0x1
> +#define PEU1_OFFSET                  16
> +#define PEU_C_OFFSET_MODE            16
> +#define PEU_C_OFFSET_SPEED           0
> +#define RC_MODE                              0x1
> +#define X8X8                         0x1
> +#define GEN3                         3
> +
> +/* DDR */
> +#define PARAMETER_MCU_MAGIC          0x54460014
> +#define PARAM_MCU_VERSION            0x1
> +#define PARAM_MCU_SIZE                       0x100
> +#define PARAM_CH_ENABLE                      0x3
> +#define PARAM_ECC_ENABLE             0x3
> +#define PARAM_FORCE_SPD_DISABLE              0x0
> +#define PARAM_MCU_MISC_ENABLE                0x0
> +
> +#define UDIMM_TYPE                   0x2
> +#define DIMM_X8                              0x1
> +#define NO_MIRROR                    0x0
> +#define NO_ECC_TYPE                  0
> +#define DDR4_TYPE                    0xC
> +
> +/* SEC */
> +#define PARAMETER_COMMON_MAGIC               0x54460013
> +
> +/* FLUSH L3 CASHE */
> +#define HNF_COUNT                    0x8
> +#define HNF_PSTATE_REQ                       (HNF_BASE + 0x10)
> +#define HNF_PSTATE_STAT                      (HNF_BASE + 0x18)
> +#define HNF_PSTATE_OFF                       0x0
> +#define HNF_PSTATE_SFONLY            0x1
> +#define HNF_PSTATE_HALF                      0x2
> +#define HNF_PSTATE_FULL                      0x3
> +#define HNF_STRIDE                   0x10000
> +#define HNF_BASE                     (unsigned long)(0x3A200000)
> +void ddr_init(void);
> +void sec_init(void);
> +void check_reset(void);
> +void pcie_init(void);
> +
> +#endif /* _FT_POMELO_H */
> diff --git a/board/phytium/pomelo/ddr.c b/board/phytium/pomelo/ddr.c
> new file mode 100644
> index 0000000000..88756f5fc1
> --- /dev/null
> +++ b/board/phytium/pomelo/ddr.c
> @@ -0,0 +1,164 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */
> +
> +#include <stdio.h>
> +#include <linux/arm-smccc.h>
> +#include "cpu.h"
> +
> +struct ddr_spd {
> +     /******************* read from spd *****************/
> +     unsigned char  dimm_type;       /* 1: RDIMM;2: UDIMM;3: SODIMM;4: LRDIMM */
> +     unsigned char  data_width;      /* 0: x4; 1: x8; 2: x16 */
> +     unsigned char  mirror_type;     /* 0: stardard; 1: mirror */
> +     unsigned char  ecc_type;        /* 0: no-ecc; 1:ecc */
> +     unsigned char  dram_type;       /* 0xB: DDR3; 0xC: DDR4 */
> +     unsigned char  rank_num;
> +     unsigned char  row_num;
> +     unsigned char  col_num;
> +
> +     unsigned char  bg_num;  /*only DDR4*/
> +     unsigned char  bank_num;
> +     unsigned short int module_manufacturer_id;
> +     unsigned short int taamin;
> +     unsigned short int trcdmin;
> +
> +     unsigned short int trpmin;
> +     unsigned short int trasmin;
> +     unsigned short int trcmin;
> +     unsigned short int tfawmin;
> +
> +     unsigned short int trrd_smin;   /*only DDR4*/
> +     unsigned short int trrd_lmin;   /*only DDR4*/
> +     unsigned short int tccd_lmin;   /*only DDR4*/
> +     unsigned short int twrmin;
> +
> +     unsigned short int twtr_smin;   /*only DDR4*/
> +     unsigned short int twtr_lmin;   /*only DDR4*/
> +     unsigned short int twtrmin;     /*only DDR3*/
> +     unsigned short int trrdmin;     /*only DDR3*/
> +
> +     /******************* RCD control words *****************/
> +     unsigned char  f0rc03; /*bit[3:2]:CS            bit[1:0]:CA  */
> +     unsigned char  f0rc04; /*bit[3:2]:ODT           bit[1:0]:CKE */
> +     unsigned char  f0rc05; /*bit[3:2]:CLK-A side    bit[1:0]:CLK-B side */
> +     unsigned char  bc00;
> +     unsigned char  bc01;
> +     unsigned char  bc02;
> +     unsigned char  bc03;
> +     unsigned char  bc04;
> +
> +     unsigned char  bc05;
> +     unsigned char  f5bc5x;
> +     unsigned char  f5bc6x;
> +     /******************* LRDIMM special *****************/
> +     unsigned char  vrefdq_pr0;
> +     unsigned char  vrefdq_mdram;
> +     unsigned char  rtt_mdram_1866;
> +     unsigned char  rtt_mdram_2400;
> +     unsigned char  rtt_mdram_3200;
> +
> +     unsigned char  drive_dram;
> +     unsigned char  odt_dram_1866;
> +     unsigned char  odt_dram_2400;
> +     unsigned char  odt_dram_3200;
> +     unsigned char  park_dram_1866;
> +     unsigned char  park_dram_2400;
> +     unsigned char  park_dram_3200;
> +     unsigned char  rcd_num;
> +} __attribute((aligned(4)));
> +
> +struct mcu_config {
> +     unsigned int magic;
> +     unsigned int version;
> +     unsigned int size;
> +     unsigned char rev1[4];
> +
> +     unsigned char ch_enable;
> +     unsigned char misc1_enable;
> +     unsigned char misc2_enable;
> +     unsigned char force_spd_enable;
> +     unsigned char misc3_enable;
> +     unsigned char train_debug;
> +     unsigned char train_recover;
> +     unsigned char rev2[9];
> +
> +     struct ddr_spd ddr_spd_info[2];
> +} __attribute((aligned(4)));
> +
> +static void get_mcu_up_info_default(struct mcu_config *pm)
> +{
> +     pm->magic               = PARAMETER_MCU_MAGIC;
> +     pm->version             = PARAM_MCU_VERSION;
> +     pm->size                = PARAM_MCU_SIZE;
> +     pm->ch_enable           = PARAM_CH_ENABLE;
> +     pm->misc1_enable        = PARAM_ECC_ENABLE;
> +     pm->force_spd_enable    = PARAM_FORCE_SPD_DISABLE;
> +     pm->misc3_enable        = PARAM_MCU_MISC_ENABLE;
> +     pm->train_recover       = 0x0;
> +}
> +
> +static unsigned char init_dimm_param(unsigned char ch, struct mcu_config *pm)
> +{
> +     printf("manual config dimm info...\n");
> +     pm->ddr_spd_info[ch].dimm_type = UDIMM_TYPE;
> +     pm->ddr_spd_info[ch].data_width = DIMM_X8;
> +     pm->ddr_spd_info[ch].mirror_type = NO_MIRROR;
> +     pm->ddr_spd_info[ch].ecc_type = NO_ECC_TYPE;
> +     pm->ddr_spd_info[ch].dram_type = DDR4_TYPE;
> +     pm->ddr_spd_info[ch].rank_num = 1;
> +     pm->ddr_spd_info[ch].row_num  = 16;
> +     pm->ddr_spd_info[ch].col_num = 10;
> +     pm->ddr_spd_info[ch].bg_num = 4;
> +     pm->ddr_spd_info[ch].bank_num = 4;
> +     pm->ddr_spd_info[ch].taamin = 13750;
> +     pm->ddr_spd_info[ch].trcdmin = 13750;
> +
> +     pm->ddr_spd_info[ch].trpmin = 13750;
> +     pm->ddr_spd_info[ch].trasmin = 32000;
> +     pm->ddr_spd_info[ch].trcmin =  45750;
> +     pm->ddr_spd_info[ch].tfawmin = 21000;
> +
> +     pm->ddr_spd_info[ch].trrd_smin = 3000;
> +     pm->ddr_spd_info[ch].trrd_lmin = 4900;
> +     pm->ddr_spd_info[ch].tccd_lmin = 5000;
> +     pm->ddr_spd_info[ch].twrmin = 15000;
> +
> +     pm->ddr_spd_info[ch].twtr_smin = 2500;
> +     pm->ddr_spd_info[ch].twtr_lmin = 7500;
> +
> +     return 0;
> +}
> +
> +void get_default_mcu_info(unsigned char *data)
> +{
> +     get_mcu_up_info_default((struct mcu_config *)data);
> +}
> +
> +void fix_mcu_info(unsigned char *data)
> +{
> +     unsigned char ch;
> +     struct mcu_config *mcu_info = (struct mcu_config *)data;
> +
> +     for (ch = 0; ch < 2; ch++)
> +             init_dimm_param(ch, mcu_info);
> +}
> +
> +void ddr_init(void)
> +{
> +     unsigned char buffer[0x100];
> +     struct arm_smccc_res res;
> +
> +     get_default_mcu_info(buffer);
> +     fix_mcu_info(buffer);
> +
> +     arm_smccc_smc(CPU_INIT_MEM, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
> +     if (res.a0 != 0) {
> +             printf("error x0: 0x%lx, x1: 0x%lx\n", res.a0, res.a1);
> +             while (true)
> +                     ;
> +     }
> +}
> diff --git a/board/phytium/pomelo/pcie.c b/board/phytium/pomelo/pcie.c
> new file mode 100644
> index 0000000000..3754d8eb9b
> --- /dev/null
> +++ b/board/phytium/pomelo/pcie.c
> @@ -0,0 +1,61 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */
> +
> +#include <stdio.h>
> +#include <string.h>
> +#include <linux/arm-smccc.h>
> +#include "cpu.h"
> +
> +struct pcu_ctr {
> +     unsigned int base_config[3];
> +     unsigned int equalization[3];
> +     unsigned char rev[80];
> +} __attribute((aligned(4)));
> +
> +struct pcu_config {
> +     unsigned int magic;
> +     unsigned int version;
> +     unsigned int size;
> +     unsigned char rev1[4];
> +     unsigned int independent_tree;
> +     unsigned int base_cfg;
> +     unsigned char rev2[16];
> +     struct pcu_ctr ctr_cfg[2];
> +} __attribute((aligned(4)));
> +
> +struct pcu_config const peu_base_info = {
> +     .magic = PARAMETER_PCIE_MAGIC,
> +     .version = 0x2,
> +     .size = 0x100,
> +     .independent_tree = CONFIG_INDEPENDENT_TREE,
> +     .base_cfg = ((PCI_PEU1 | (X8X8 << 1)) << PEU1_OFFSET | (PCI_PEU0 | (X8X8 << 1))),
> +     .ctr_cfg[0].base_config[0] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
> +     .ctr_cfg[0].base_config[1] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
> +     .ctr_cfg[0].base_config[2] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
> +     .ctr_cfg[1].base_config[0] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
> +     .ctr_cfg[1].base_config[1] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
> +     .ctr_cfg[1].base_config[2] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
> +     .ctr_cfg[0].equalization[0] = 0x7,
> +     .ctr_cfg[0].equalization[1] = 0x7,
> +     .ctr_cfg[0].equalization[2] = 0x7,
> +     .ctr_cfg[1].equalization[0] = 0x7,
> +     .ctr_cfg[1].equalization[1] = 0x7,
> +     .ctr_cfg[1].equalization[2] = 0x7,
> +};
> +
> +void pcie_init(void)
> +{
> +     unsigned char buffer[0x100];
> +     struct arm_smccc_res res;
> +
> +     memcpy(buffer, &peu_base_info, sizeof(peu_base_info));
> +     arm_smccc_smc(CPU_INIT_PCIE, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
> +     if (res.a0 != 0) {
> +             while (true)
> +                     ;
> +     }
> +}
> diff --git a/board/phytium/pomelo/pll.c b/board/phytium/pomelo/pll.c
> new file mode 100644
> index 0000000000..1227b7dd80
> --- /dev/null
> +++ b/board/phytium/pomelo/pll.c
> @@ -0,0 +1,75 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */
> +
> +#include <stdio.h>
> +#include <string.h>
> +#include <asm/io.h>
> +#include <linux/arm-smccc.h>
> +#include "cpu.h"
> +
> +struct pll_config {
> +     unsigned int magic;
> +     unsigned int version;
> +     unsigned int size;
> +     unsigned char rev1[4];
> +     unsigned int core_pll;
> +     unsigned int res1;
> +     unsigned int lmu_pll;
> +     unsigned int res2;
> +     unsigned int res3;
> +     unsigned int res4;
> +     unsigned int res5;
> +} __attribute((aligned(4)));
> +
> +struct pll_config const pll_base_info = {
> +     .magic = PARAMETER_PLL_MAGIC,
> +     .version = 0x1,
> +     .size = 0x30,
> +     .core_pll = 2300,       /*MHz*/
> +     .lmu_pll = 667,         /*MHz*/
> +};
> +
> +unsigned int get_reset_source(void)
> +{
> +     struct arm_smccc_res res;
> +
> +     arm_smccc_smc(CPU_GET_RST_SOURCE, 0, 0, 0, 0, 0, 0, 0, &res);
> +     return res.a0;
> +}
> +
> +void pll_init(void)
> +{
> +     unsigned char buffer[0x100];
> +     struct arm_smccc_res res;
> +
> +     memcpy(buffer, &pll_base_info, sizeof(pll_base_info));
> +     arm_smccc_smc(CPU_INIT_PLL, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
> +     if (res.a0 != 0) {
> +             while (true)
> +                     ;
> +     }
> +}
> +
> +void check_reset(void)
> +{
> +     unsigned int rst;
> +
> +     rst = get_reset_source();
> +
> +     switch (rst) {
> +     case CPU_RESET_POWER_ON:
> +             pll_init();
> +             break;
> +     case CPU_RESET_PLL:
> +             break;
> +     case CPU_RESET_WATCH_DOG:
> +             break;
> +     default:
> +             while (true)
> +                     ;
> +     }
> +}
> diff --git a/board/phytium/pomelo/pomelo.c b/board/phytium/pomelo/pomelo.c
> new file mode 100644
> index 0000000000..693e891d20
> --- /dev/null
> +++ b/board/phytium/pomelo/pomelo.c
> @@ -0,0 +1,120 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */
> +
> +#include <stdio.h>
> +#include <command.h>
> +#include <init.h>
> +#include <asm/armv8/mmu.h>
> +#include <asm/io.h>
> +#include <linux/arm-smccc.h>
> +#include <scsi.h>
> +#include "cpu.h"
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +int dram_init(void)
> +{
> +     gd->mem_clk = 0;
> +     gd->ram_size = PHYS_SDRAM_1_SIZE;
> +
> +     printf("Phytium ddr init\n");
> +
> +     ddr_init();
> +     sec_init();
> +     printf("PBF relocate done\n");
> +
> +     return 0;
> +}
> +
> +int board_init(void)
> +{
> +     return 0;
> +}
> +
> +void reset_cpu(void)
> +{
> +     struct arm_smccc_res res;
> +
> +     printf("run in reset cpu\n");
> +     arm_smccc_smc(0x84000009, 0, 0, 0, 0, 0, 0, 0, &res);
> +     printf("reset cpu error, %lx\n", res.a0);
> +}
> +
> +int mach_cpu_init(void)
> +{
> +     check_reset();
> +     return 0;
> +}
> +
> +int board_early_init_f(void)
> +{
> +     pcie_init();
> +     return 0;
> +}
> +
> +int board_early_init_r(void)
> +{
> +     return 0;
> +}
> +
> +static struct mm_region pomelo_mem_map[] = {
> +     {
> +             .virt = 0x0UL,
> +             .phys = 0x0UL,
> +             .size = 0x80000000UL,
> +             .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
> +                              PTE_BLOCK_NON_SHARE |
> +                              PTE_BLOCK_PXN |
> +                              PTE_BLOCK_UXN
> +     },
> +     {
> +             .virt = (u64)PHYS_SDRAM_1,
> +             .phys = (u64)PHYS_SDRAM_1,
> +             .size = (u64)PHYS_SDRAM_1_SIZE,
> +             .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
> +                              PTE_BLOCK_NS |
> +                              PTE_BLOCK_INNER_SHARE
> +     },
> +     {
> +             0,
> +     }
> +};
> +
> +struct mm_region *mem_map = pomelo_mem_map;
> +
> +int __asm_flush_l3_dcache(void)
> +{
> +     int i, pstate;
> +
> +     for (i = 0; i < HNF_COUNT; i++)
> +             writeq(HNF_PSTATE_SFONLY, HNF_PSTATE_REQ + i * HNF_STRIDE);
> +     for (i = 0; i < HNF_COUNT; i++) {
> +             do {
> +                     pstate = readq(HNF_PSTATE_STAT + i * HNF_STRIDE);
> +             } while ((pstate & 0xf) != (HNF_PSTATE_SFONLY << 2));
> +     }
> +
> +     for (i = 0; i < HNF_COUNT; i++)
> +             writeq(HNF_PSTATE_FULL, HNF_PSTATE_REQ + i * HNF_STRIDE);
> +
> +     return 0;
> +}
> +
> +int last_stage_init(void)
> +{
> +     int ret;
> +
> +     /* pci e */
> +     pci_init();
> +     /* scsi scan */
> +     ret = scsi_scan(true);
> +     if (ret) {
> +             printf("scsi scan failed\n");
> +             return CMD_RET_FAILURE;
> +     }
> +     return ret;
> +}
> diff --git a/board/phytium/pomelo/sec.c b/board/phytium/pomelo/sec.c
> new file mode 100644
> index 0000000000..8ec0fa797b
> --- /dev/null
> +++ b/board/phytium/pomelo/sec.c
> @@ -0,0 +1,40 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */
> +
> +#include <stdio.h>
> +#include <string.h>
> +#include <linux/arm-smccc.h>
> +#include "cpu.h"
> +
> +struct common_config {
> +     unsigned int magic;
> +     unsigned int version;
> +     unsigned int size;
> +     unsigned char rev1[4];
> +     unsigned long long  core_bit_map;
> +} __attribute((aligned(4)));
> +
> +struct common_config const common_base_info = {
> +     .magic = PARAMETER_COMMON_MAGIC,
> +     .version = 0x1,
> +     .core_bit_map = 0x3333,
> +};
> +
> +void sec_init(void)
> +{
> +     unsigned char buffer[0x100];
> +     struct arm_smccc_res res;
> +
> +     memcpy(buffer, &common_base_info, sizeof(common_base_info));
> +     arm_smccc_smc(CPU_INIT_SEC_SVC, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
> +
> +     if (res.a0 != 0) {
> +             printf("error ret %lx\n", res.a0);
> +             while (true)
> +                     ;
> +     }
> +}
> diff --git a/configs/pomelo_defconfig b/configs/pomelo_defconfig
> new file mode 100644
> index 0000000000..3e6c18196d
> --- /dev/null
> +++ b/configs/pomelo_defconfig
> @@ -0,0 +1,36 @@
> +CONFIG_ARM=y
> +CONFIG_ARM_SMCCC=y
> +CONFIG_TARGET_POMELO=y
> +CONFIG_SYS_TEXT_BASE=0x180000
> +CONFIG_NR_DRAM_BANKS=1
> +CONFIG_ENV_SIZE=0x1000
> +# CONFIG_PSCI_RESET is not set
> +CONFIG_DEFAULT_DEVICE_TREE="phytium-pomelo"
> +CONFIG_AHCI=y
> +CONFIG_DISTRO_DEFAULTS=y
> +CONFIG_USE_BOOTARGS=y
> +CONFIG_BOOTARGS="console=ttyAMA0,115200 earlycon=pl011,0x28001000 root=/dev/sda2 rw"
> +# CONFIG_DISPLAY_CPUINFO is not set
> +# CONFIG_DISPLAY_BOARDINFO is not set
> +CONFIG_LAST_STAGE_INIT=y
> +CONFIG_SYS_PROMPT="pomelo#"
> +# CONFIG_CMD_LZMADEC is not set
> +# CONFIG_CMD_UNZIP is not set
> +CONFIG_CMD_PCI=y
> +CONFIG_OF_CONTROL=y
> +CONFIG_SYS_RELOC_GD_ENV_ADDR=y
> +# CONFIG_NET is not set
> +CONFIG_DM=y
> +CONFIG_SCSI_AHCI=y
> +CONFIG_AHCI_PCI=y
> +CONFIG_BLK=y
> +# CONFIG_MMC is not set
> +CONFIG_PCI=y
> +CONFIG_DM_PCI=y
> +CONFIG_DM_PCI_COMPAT=y
> +CONFIG_PCI_PHYTIUM=y
> +CONFIG_PCIE_ECAM_GENERIC=y
> +CONFIG_SCSI=y
> +CONFIG_DM_SCSI=y
> +CONFIG_DM_SERIAL=y
> +CONFIG_PL01X_SERIAL=y
> diff --git a/include/configs/pomelo.h b/include/configs/pomelo.h
> new file mode 100644
> index 0000000000..69c4195d86
> --- /dev/null
> +++ b/include/configs/pomelo.h
> @@ -0,0 +1,45 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2021
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */
> +
> +#ifndef __POMELO_CONFIG_H__
> +#define __POMELO_CONFIG_H__
> +
> +/* SDRAM Bank #1 start address */
> +#define PHYS_SDRAM_1                 0x80000000
> +#define PHYS_SDRAM_1_SIZE            0x7B000000
> +#define CONFIG_SYS_SDRAM_BASE                PHYS_SDRAM_1
> +
> +#define CONFIG_SYS_LOAD_ADDR         (CONFIG_SYS_SDRAM_BASE + 0x10000000)
> +
> +/* SIZE of malloc pool */
> +#define CONFIG_SYS_MALLOC_LEN                (1 * 1024 * 1024  + CONFIG_ENV_SIZE)
> +#define CONFIG_BOARD_EARLY_INIT_F
> +#define CONFIG_BOARD_EARLY_INIT_R
> +
> +#define CONFIG_SYS_INIT_SP_ADDR              (0x29800000 + 0x1a000)
> +
> +/* PCI CONFIG */
> +#define CONFIG_SYS_PCI_64BIT         1
> +#define CONFIG_PCI_SCAN_SHOW
> +
> +/* SCSI */
> +#define CONFIG_SYS_SCSI_MAX_SCSI_ID  4
> +#define CONFIG_SYS_SCSI_MAX_LUN              1
> +#define CONFIG_SYS_SCSI_MAX_DEVICE   128
> +#define CONFIG_SCSI_AHCI_PLAT
> +#define CONFIG_SYS_SATA_MAX_DEVICE   4
> +
> +/*BOOT*/
> +#define CONFIG_SYS_BOOTM_LEN         (60 * 1024 * 1024)
> +
> +#define CONFIG_EXTRA_ENV_SETTINGS    \
> +     "load_kernel=ext4load scsi 0:1 0x90100000 uImage_old\0" \
> +     "load_fdt=ext4load scsi 0:1 0x95000000 ft-d2000.dtb\0"\
> +     "boot_fdt=bootm 0x90100000 -:- 0x17c000\0"      \
> +     "distro_bootcmd=run load_kernel; run boot_fdt"
> +
> +#endif


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH]  arm: add initial support for the Phytium Pomelo Board
  2021-06-24  1:02 nicholas_zheng
@ 2021-06-25 12:27 ` Andre Przywara
  2021-06-29  7:41   ` 回复: " Nicholas zheng
  0 siblings, 1 reply; 12+ messages in thread
From: Andre Przywara @ 2021-06-25 12:27 UTC (permalink / raw)
  To: nicholas_zheng
  Cc: trini, bharat.gooty, rayagonda.kokatanur, jagan, festevam,
	patrick.delaunay, tharvey, pbrobinson, hs, lokeshvutla,
	d-gerlach, u-boot, Rob Herring

On Thu, 24 Jun 2021 09:02:45 +0800
nicholas_zheng@outlook.com wrote:

Hi,

this is some revised version, isn't it? Can you please start putting
patch version numbers into the subject: "[PATCH v4] arm: ..."? It's hard
to see what's outdated and find the latest version otherwise.

> From: weichangzheng <nicholas_zheng@outlook.com>
> 
>  This adds platform code and the device tree for the Phytium Pomelo Board.
>  The initial support comprises the UART and the PCIE.

Is this some internal board? Or something China only? Google couldn't
find any useful hits about the platform.

> 
> Signed-off-by: weichangzheng <nicholas_zheng@outlook.com>
> ---
>  arch/arm/Kconfig                 |   8 ++
>  arch/arm/dts/Makefile            |   1 +
>  arch/arm/dts/phytium-pomelo.dts  | 103 +++++++++++++++++++
>  board/phytium/pomelo/Kconfig     |  12 +++
>  board/phytium/pomelo/MAINTAINERS |   8 ++
>  board/phytium/pomelo/Makefile    |  14 +++
>  board/phytium/pomelo/cpu.h       |  73 ++++++++++++++
>  board/phytium/pomelo/ddr.c       | 164 +++++++++++++++++++++++++++++++
>  board/phytium/pomelo/pcie.c      |  61 ++++++++++++
>  board/phytium/pomelo/pll.c       |  75 ++++++++++++++
>  board/phytium/pomelo/pomelo.c    | 120 ++++++++++++++++++++++
>  board/phytium/pomelo/sec.c       |  40 ++++++++
>  configs/pomelo_defconfig         |  36 +++++++
>  include/configs/pomelo.h         |  45 +++++++++
>  14 files changed, 760 insertions(+)
>  create mode 100644 arch/arm/dts/phytium-pomelo.dts
>  create mode 100644 board/phytium/pomelo/Kconfig
>  create mode 100644 board/phytium/pomelo/MAINTAINERS
>  create mode 100644 board/phytium/pomelo/Makefile
>  create mode 100644 board/phytium/pomelo/cpu.h
>  create mode 100644 board/phytium/pomelo/ddr.c
>  create mode 100644 board/phytium/pomelo/pcie.c
>  create mode 100644 board/phytium/pomelo/pll.c
>  create mode 100644 board/phytium/pomelo/pomelo.c
>  create mode 100644 board/phytium/pomelo/sec.c
>  create mode 100644 configs/pomelo_defconfig
>  create mode 100644 include/configs/pomelo.h
> 
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 31d687ea01..6110fcddad 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1800,6 +1800,13 @@ config TARGET_DURIAN
>  	  Support for durian platform.
>  	  It has 2GB Sdram, uart and pcie.
>  
> +config TARGET_POMELO
> +	bool "Support Phytium Pomelo Platform"
> +	select ARM64
> +	help
> +		Support for pomelo platform.
> +		It has 2GB Sdram, uart and pcie.
> +
>  config TARGET_PRESIDIO_ASIC
>  	bool "Support Cortina Presidio ASIC Platform"
>  	select ARM64
> @@ -2019,6 +2026,7 @@ source "board/toradex/colibri_pxa270/Kconfig"
>  source "board/variscite/dart_6ul/Kconfig"
>  source "board/vscom/baltos/Kconfig"
>  source "board/phytium/durian/Kconfig"
> +source "board/phytium/pomelo/Kconfig"
>  source "board/xen/xenguest_arm64/Kconfig"
>  source "board/keymile/Kconfig"
>  
> diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
> index 096068261d..c26692c17e 100644
> --- a/arch/arm/dts/Makefile
> +++ b/arch/arm/dts/Makefile
> @@ -1098,6 +1098,7 @@ dtb-$(CONFIG_TARGET_MX53PPD) += imx53-ppd.dtb
>  dtb-$(CONFIG_TARGET_TOTAL_COMPUTE) += total_compute.dtb
>  
>  dtb-$(CONFIG_TARGET_DURIAN) += phytium-durian.dtb
> +dtb-$(CONFIG_TARGET_POMELO) += phytium-pomelo.dtb
>  
>  dtb-$(CONFIG_TARGET_PRESIDIO_ASIC) += ca-presidio-engboard.dtb
>  
> diff --git a/arch/arm/dts/phytium-pomelo.dts b/arch/arm/dts/phytium-pomelo.dts
> new file mode 100644
> index 0000000000..4961682058
> --- /dev/null
> +++ b/arch/arm/dts/phytium-pomelo.dts
> @@ -0,0 +1,103 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * dts file for Phytium Pomelo board
> + * Copyright (C) 2021, Phytium Ltd.
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */

I think this file should be reviewed by Linux DT people, they have much
more experience with this (CC:ing Rob)
It looks simple enough to remain stable, so the U-Boot DT could
actually be the only source for the DTB, but it should still go through
Linux' review machinery.

> +/dts-v1/;
> +
> +/memreserve/	0x0000000080000000 0x0000000000100000;

I think /memreserve/ is somewhat deprecated now. It has the
disadvantage of allowing the kernel to still map the memory, so the CPU
can speculate into there, which might cause problems if this is
configured secure-only.
(I guess this is where the secure firmware/PSCI provider/TF-A lives?)

The better alternative is
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt
and using the "nomap;" property.

> +/ {
> +	model = "Phytium Pomelo";
> +	compatible = "phytium,pomelo";
> +	#address-cells = <2>;
> +	#size-cells = <2>;
> +

Please have a chosen node with a stdout-path property pointing to the
UART. And possibly an aliases node with serial0 entry.
Then you can use just "earlycon" on the command line, and in general DT
users will find the console automatically.
 
> +	cpus {
> +		#address-cells = <0x2>;
> +		#size-cells = <0x0>;
> +
> +		cpu0: cpu@0 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";

This generic name is now deprecated (reserved for the AEM fastmodel),
we use the actual core name now.

> +			reg = <0x0 0x0>;
> +			enable-method = "psci";
> +			numa-node-id = <0>;
> +		};
> +
> +		cpu1: cpu@1 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";
> +			reg = <0x0 0x1>;
> +			enable-method = "psci";
> +			numa-node-id = <0>;
> +		};
> +
> +		cpu4: cpu@4 {

The cpu label should just increase monotonically, so this would be
cpu2. The address behind the "@" must match the reg property:
		cpu2: cpu@100 {
(same for the rest)

> +			device_type = "cpu";
> +			compatible = "arm,armv8";
> +			reg = <0x0 0x100>;
> +			enable-method = "psci";
> +			numa-node-id = <0>;
> +		};
> +
> +		cpu5: cpu@5 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";
> +			reg = <0x0 0x101>;
> +			enable-method = "psci";
> +			numa-node-id = <0>;
> +		};
> +
> +		cpu8: cpu@8 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";
> +			reg = <0x0 0x200>;
> +			enable-method = "psci";
> +			numa-node-id = <0>;
> +		};
> +
> +		cpu9: cpu@9 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";
> +			reg = <0x0 0x201>;
> +			enable-method = "psci";
> +			numa-node-id = <0>;
> +		};
> +
> +		cpu12: cpu@12 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";
> +			reg = <0x0 0x300>;
> +			enable-method = "psci";
> +			numa-node-id = <0>;
> +		};
> +
> +		cpu13: cpu@13 {
> +			device_type = "cpu";
> +			compatible = "arm,armv8";
> +			reg = <0x0 0x301>;
> +			enable-method = "psci";
> +			numa-node-id = <0>;
> +		};
> +	};
> +
> +	pcie-controller@40000000 {
> +		compatible = "pci-host-ecam-generic";
> +		device_type = "pci";
> +		#address-cells = <3>;
> +		#size-cells = <2>;
> +		reg = <0x0 0x40000000 0x0 0x10000000>;
> +		bus-range = <0x0 0xff>;
> +		ranges = <0x01000000 0x00 0x00000000 0x0  0x50000000 0x0  0x00F00000>,
> +			 <0x02000000 0x00 0x58000000 0x0  0x58000000 0x0  0x28000000>,
> +			 <0x43000000 0x10 0x00000000 0x10 0x00000000 0x10  0x00000000>;
> +	};

If this works you deserve a price for shipping a working and standards
compliant PCIe controller ;-)

Read: all fine, well done:
- full 256MB config space!
- generous MMIO32 area!
- even more generous MMIO64 area!

> +
> +	uart@28001000 {
> +		compatible = "arm,pl011";
> +		reg = <0x0 0x28001000 0x0 0x1000>;
> +		clock = <48000000>;

I think this is a non-standard property?
Please have a fixed-clock with 48 MHz, and refer to that from here. If
you need the UART before the DT is parsed, you can set the base
frequency somewhere in the config or some header file.

Didn't look at the rest too closely, can't check much of this anyway.

Cheers,
Andre

> +	};
> +};
> diff --git a/board/phytium/pomelo/Kconfig b/board/phytium/pomelo/Kconfig
> new file mode 100644
> index 0000000000..281aa8feff
> --- /dev/null
> +++ b/board/phytium/pomelo/Kconfig
> @@ -0,0 +1,12 @@
> +if TARGET_POMELO
> +
> +config SYS_BOARD
> +	default "pomelo"
> +
> +config SYS_VENDOR
> +	default "phytium"
> +
> +config SYS_CONFIG_NAME
> +	default "pomelo"
> +
> +endif
> diff --git a/board/phytium/pomelo/MAINTAINERS b/board/phytium/pomelo/MAINTAINERS
> new file mode 100644
> index 0000000000..950449392b
> --- /dev/null
> +++ b/board/phytium/pomelo/MAINTAINERS
> @@ -0,0 +1,8 @@
> +POMELO BOARD
> +M:	lixinde <lixinde@phytium.com.cn>
> +M:	weichangzheng <weichangzheng@phytium.com.cn>
> +S:	Maintained
> +F:	board/phytium/pomelo/*
> +F:	include/configs/pomelo.h
> +F:	configs/pomelo_defconfig
> +
> diff --git a/board/phytium/pomelo/Makefile b/board/phytium/pomelo/Makefile
> new file mode 100644
> index 0000000000..b9cb3609bd
> --- /dev/null
> +++ b/board/phytium/pomelo/Makefile
> @@ -0,0 +1,14 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +#
> +# Copyright (C) 2021
> +# lixinde         <lixinde@phytium.com.cn>
> +# weichangzheng   <weichangzheng@phytium.com.cn>
> +#
> +
> +obj-y += pomelo.o
> +obj-y += pll.o
> +obj-y += pcie.o
> +obj-y += ddr.o
> +obj-y += sec.o
> +
> +
> diff --git a/board/phytium/pomelo/cpu.h b/board/phytium/pomelo/cpu.h
> new file mode 100644
> index 0000000000..e15917609b
> --- /dev/null
> +++ b/board/phytium/pomelo/cpu.h
> @@ -0,0 +1,73 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * (C) Copyright 2021
> + * Phytium Technology Ltd <www.phytium.com>
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */
> +
> +#ifndef _FT_POMELO_H
> +#define _FT_POMELO_H
> +
> +/* SMCCC ID */
> +#define CPU_SVC_VERSION			0xC2000F00
> +#define CPU_GET_RST_SOURCE		0xC2000F01
> +#define CPU_INIT_PLL			0xC2000F02
> +#define CPU_INIT_PCIE			0xC2000F03
> +#define CPU_INIT_MEM			0xC2000F04
> +#define CPU_INIT_SEC_SVC		0xC2000F05
> +
> +/*CPU RESET*/
> +#define CPU_RESET_POWER_ON		0x1
> +#define CPU_RESET_PLL			0x4
> +#define CPU_RESET_WATCH_DOG		0x8
> +
> +/* PLL */
> +#define PARAMETER_PLL_MAGIC		0x54460010
> +
> +/* PCIE */
> +#define PARAMETER_PCIE_MAGIC		0x54460011
> +#define CONFIG_INDEPENDENT_TREE		0x0
> +#define PCI_PEU0			0x1
> +#define PCI_PEU1			0x1
> +#define PEU1_OFFSET			16
> +#define PEU_C_OFFSET_MODE		16
> +#define PEU_C_OFFSET_SPEED		0
> +#define RC_MODE				0x1
> +#define X8X8				0x1
> +#define GEN3				3
> +
> +/* DDR */
> +#define PARAMETER_MCU_MAGIC		0x54460014
> +#define PARAM_MCU_VERSION		0x1
> +#define PARAM_MCU_SIZE			0x100
> +#define PARAM_CH_ENABLE			0x3
> +#define PARAM_ECC_ENABLE		0x3
> +#define PARAM_FORCE_SPD_DISABLE		0x0
> +#define PARAM_MCU_MISC_ENABLE		0x0
> +
> +#define UDIMM_TYPE			0x2
> +#define DIMM_X8				0x1
> +#define NO_MIRROR			0x0
> +#define NO_ECC_TYPE			0
> +#define DDR4_TYPE			0xC
> +
> +/* SEC */
> +#define PARAMETER_COMMON_MAGIC		0x54460013
> +
> +/* FLUSH L3 CASHE */
> +#define HNF_COUNT			0x8
> +#define HNF_PSTATE_REQ			(HNF_BASE + 0x10)
> +#define HNF_PSTATE_STAT			(HNF_BASE + 0x18)
> +#define HNF_PSTATE_OFF			0x0
> +#define HNF_PSTATE_SFONLY		0x1
> +#define HNF_PSTATE_HALF			0x2
> +#define HNF_PSTATE_FULL			0x3
> +#define HNF_STRIDE			0x10000
> +#define HNF_BASE			(unsigned long)(0x3A200000)
> +void ddr_init(void);
> +void sec_init(void);
> +void check_reset(void);
> +void pcie_init(void);
> +
> +#endif /* _FT_POMELO_H */
> diff --git a/board/phytium/pomelo/ddr.c b/board/phytium/pomelo/ddr.c
> new file mode 100644
> index 0000000000..88756f5fc1
> --- /dev/null
> +++ b/board/phytium/pomelo/ddr.c
> @@ -0,0 +1,164 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */
> +
> +#include <stdio.h>
> +#include <linux/arm-smccc.h>
> +#include "cpu.h"
> +
> +struct ddr_spd {
> +	/******************* read from spd *****************/
> +	unsigned char  dimm_type;	/* 1: RDIMM;2: UDIMM;3: SODIMM;4: LRDIMM */
> +	unsigned char  data_width;	/* 0: x4; 1: x8; 2: x16 */
> +	unsigned char  mirror_type;	/* 0: stardard; 1: mirror */
> +	unsigned char  ecc_type;	/* 0: no-ecc; 1:ecc */
> +	unsigned char  dram_type;	/* 0xB: DDR3; 0xC: DDR4 */
> +	unsigned char  rank_num;
> +	unsigned char  row_num;
> +	unsigned char  col_num;
> +
> +	unsigned char  bg_num;	/*only DDR4*/
> +	unsigned char  bank_num;
> +	unsigned short int module_manufacturer_id;
> +	unsigned short int taamin;
> +	unsigned short int trcdmin;
> +
> +	unsigned short int trpmin;
> +	unsigned short int trasmin;
> +	unsigned short int trcmin;
> +	unsigned short int tfawmin;
> +
> +	unsigned short int trrd_smin;	/*only DDR4*/
> +	unsigned short int trrd_lmin;	/*only DDR4*/
> +	unsigned short int tccd_lmin;	/*only DDR4*/
> +	unsigned short int twrmin;
> +
> +	unsigned short int twtr_smin;	/*only DDR4*/
> +	unsigned short int twtr_lmin;	/*only DDR4*/
> +	unsigned short int twtrmin;	/*only DDR3*/
> +	unsigned short int trrdmin;	/*only DDR3*/
> +
> +	/******************* RCD control words *****************/
> +	unsigned char  f0rc03; /*bit[3:2]:CS		bit[1:0]:CA  */
> +	unsigned char  f0rc04; /*bit[3:2]:ODT		bit[1:0]:CKE */
> +	unsigned char  f0rc05; /*bit[3:2]:CLK-A side	bit[1:0]:CLK-B side */
> +	unsigned char  bc00;
> +	unsigned char  bc01;
> +	unsigned char  bc02;
> +	unsigned char  bc03;
> +	unsigned char  bc04;
> +
> +	unsigned char  bc05;
> +	unsigned char  f5bc5x;
> +	unsigned char  f5bc6x;
> +	/******************* LRDIMM special *****************/
> +	unsigned char  vrefdq_pr0;
> +	unsigned char  vrefdq_mdram;
> +	unsigned char  rtt_mdram_1866;
> +	unsigned char  rtt_mdram_2400;
> +	unsigned char  rtt_mdram_3200;
> +
> +	unsigned char  drive_dram;
> +	unsigned char  odt_dram_1866;
> +	unsigned char  odt_dram_2400;
> +	unsigned char  odt_dram_3200;
> +	unsigned char  park_dram_1866;
> +	unsigned char  park_dram_2400;
> +	unsigned char  park_dram_3200;
> +	unsigned char  rcd_num;
> +} __attribute((aligned(4)));
> +
> +struct mcu_config {
> +	unsigned int magic;
> +	unsigned int version;
> +	unsigned int size;
> +	unsigned char rev1[4];
> +
> +	unsigned char ch_enable;
> +	unsigned char misc1_enable;
> +	unsigned char misc2_enable;
> +	unsigned char force_spd_enable;
> +	unsigned char misc3_enable;
> +	unsigned char train_debug;
> +	unsigned char train_recover;
> +	unsigned char rev2[9];
> +
> +	struct ddr_spd ddr_spd_info[2];
> +} __attribute((aligned(4)));
> +
> +static void get_mcu_up_info_default(struct mcu_config *pm)
> +{
> +	pm->magic		= PARAMETER_MCU_MAGIC;
> +	pm->version		= PARAM_MCU_VERSION;
> +	pm->size		= PARAM_MCU_SIZE;
> +	pm->ch_enable		= PARAM_CH_ENABLE;
> +	pm->misc1_enable	= PARAM_ECC_ENABLE;
> +	pm->force_spd_enable	= PARAM_FORCE_SPD_DISABLE;
> +	pm->misc3_enable	= PARAM_MCU_MISC_ENABLE;
> +	pm->train_recover	= 0x0;
> +}
> +
> +static unsigned char init_dimm_param(unsigned char ch, struct mcu_config *pm)
> +{
> +	printf("manual config dimm info...\n");
> +	pm->ddr_spd_info[ch].dimm_type = UDIMM_TYPE;
> +	pm->ddr_spd_info[ch].data_width = DIMM_X8;
> +	pm->ddr_spd_info[ch].mirror_type = NO_MIRROR;
> +	pm->ddr_spd_info[ch].ecc_type = NO_ECC_TYPE;
> +	pm->ddr_spd_info[ch].dram_type = DDR4_TYPE;
> +	pm->ddr_spd_info[ch].rank_num = 1;
> +	pm->ddr_spd_info[ch].row_num  = 16;
> +	pm->ddr_spd_info[ch].col_num = 10;
> +	pm->ddr_spd_info[ch].bg_num = 4;
> +	pm->ddr_spd_info[ch].bank_num = 4;
> +	pm->ddr_spd_info[ch].taamin = 13750;
> +	pm->ddr_spd_info[ch].trcdmin = 13750;
> +
> +	pm->ddr_spd_info[ch].trpmin = 13750;
> +	pm->ddr_spd_info[ch].trasmin = 32000;
> +	pm->ddr_spd_info[ch].trcmin =  45750;
> +	pm->ddr_spd_info[ch].tfawmin = 21000;
> +
> +	pm->ddr_spd_info[ch].trrd_smin = 3000;
> +	pm->ddr_spd_info[ch].trrd_lmin = 4900;
> +	pm->ddr_spd_info[ch].tccd_lmin = 5000;
> +	pm->ddr_spd_info[ch].twrmin = 15000;
> +
> +	pm->ddr_spd_info[ch].twtr_smin = 2500;
> +	pm->ddr_spd_info[ch].twtr_lmin = 7500;
> +
> +	return 0;
> +}
> +
> +void get_default_mcu_info(unsigned char *data)
> +{
> +	get_mcu_up_info_default((struct mcu_config *)data);
> +}
> +
> +void fix_mcu_info(unsigned char *data)
> +{
> +	unsigned char ch;
> +	struct mcu_config *mcu_info = (struct mcu_config *)data;
> +
> +	for (ch = 0; ch < 2; ch++)
> +		init_dimm_param(ch, mcu_info);
> +}
> +
> +void ddr_init(void)
> +{
> +	unsigned char buffer[0x100];
> +	struct arm_smccc_res res;
> +
> +	get_default_mcu_info(buffer);
> +	fix_mcu_info(buffer);
> +
> +	arm_smccc_smc(CPU_INIT_MEM, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
> +	if (res.a0 != 0) {
> +		printf("error x0: 0x%lx, x1: 0x%lx\n", res.a0, res.a1);
> +		while (true)
> +			;
> +	}
> +}
> diff --git a/board/phytium/pomelo/pcie.c b/board/phytium/pomelo/pcie.c
> new file mode 100644
> index 0000000000..3754d8eb9b
> --- /dev/null
> +++ b/board/phytium/pomelo/pcie.c
> @@ -0,0 +1,61 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */
> +
> +#include <stdio.h>
> +#include <string.h>
> +#include <linux/arm-smccc.h>
> +#include "cpu.h"
> +
> +struct pcu_ctr {
> +	unsigned int base_config[3];
> +	unsigned int equalization[3];
> +	unsigned char rev[80];
> +} __attribute((aligned(4)));
> +
> +struct pcu_config {
> +	unsigned int magic;
> +	unsigned int version;
> +	unsigned int size;
> +	unsigned char rev1[4];
> +	unsigned int independent_tree;
> +	unsigned int base_cfg;
> +	unsigned char rev2[16];
> +	struct pcu_ctr ctr_cfg[2];
> +} __attribute((aligned(4)));
> +
> +struct pcu_config const peu_base_info = {
> +	.magic = PARAMETER_PCIE_MAGIC,
> +	.version = 0x2,
> +	.size = 0x100,
> +	.independent_tree = CONFIG_INDEPENDENT_TREE,
> +	.base_cfg = ((PCI_PEU1 | (X8X8 << 1)) << PEU1_OFFSET | (PCI_PEU0 | (X8X8 << 1))),
> +	.ctr_cfg[0].base_config[0] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
> +	.ctr_cfg[0].base_config[1] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
> +	.ctr_cfg[0].base_config[2] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
> +	.ctr_cfg[1].base_config[0] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
> +	.ctr_cfg[1].base_config[1] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
> +	.ctr_cfg[1].base_config[2] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
> +	.ctr_cfg[0].equalization[0] = 0x7,
> +	.ctr_cfg[0].equalization[1] = 0x7,
> +	.ctr_cfg[0].equalization[2] = 0x7,
> +	.ctr_cfg[1].equalization[0] = 0x7,
> +	.ctr_cfg[1].equalization[1] = 0x7,
> +	.ctr_cfg[1].equalization[2] = 0x7,
> +};
> +
> +void pcie_init(void)
> +{
> +	unsigned char buffer[0x100];
> +	struct arm_smccc_res res;
> +
> +	memcpy(buffer, &peu_base_info, sizeof(peu_base_info));
> +	arm_smccc_smc(CPU_INIT_PCIE, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
> +	if (res.a0 != 0) {
> +		while (true)
> +			;
> +	}
> +}
> diff --git a/board/phytium/pomelo/pll.c b/board/phytium/pomelo/pll.c
> new file mode 100644
> index 0000000000..1227b7dd80
> --- /dev/null
> +++ b/board/phytium/pomelo/pll.c
> @@ -0,0 +1,75 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */
> +
> +#include <stdio.h>
> +#include <string.h>
> +#include <asm/io.h>
> +#include <linux/arm-smccc.h>
> +#include "cpu.h"
> +
> +struct pll_config {
> +	unsigned int magic;
> +	unsigned int version;
> +	unsigned int size;
> +	unsigned char rev1[4];
> +	unsigned int core_pll;
> +	unsigned int res1;
> +	unsigned int lmu_pll;
> +	unsigned int res2;
> +	unsigned int res3;
> +	unsigned int res4;
> +	unsigned int res5;
> +} __attribute((aligned(4)));
> +
> +struct pll_config const pll_base_info = {
> +	.magic = PARAMETER_PLL_MAGIC,
> +	.version = 0x1,
> +	.size = 0x30,
> +	.core_pll = 2300,	/*MHz*/
> +	.lmu_pll = 667,		/*MHz*/
> +};
> +
> +unsigned int get_reset_source(void)
> +{
> +	struct arm_smccc_res res;
> +
> +	arm_smccc_smc(CPU_GET_RST_SOURCE, 0, 0, 0, 0, 0, 0, 0, &res);
> +	return res.a0;
> +}
> +
> +void pll_init(void)
> +{
> +	unsigned char buffer[0x100];
> +	struct arm_smccc_res res;
> +
> +	memcpy(buffer, &pll_base_info, sizeof(pll_base_info));
> +	arm_smccc_smc(CPU_INIT_PLL, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
> +	if (res.a0 != 0) {
> +		while (true)
> +			;
> +	}
> +}
> +
> +void check_reset(void)
> +{
> +	unsigned int rst;
> +
> +	rst = get_reset_source();
> +
> +	switch (rst) {
> +	case CPU_RESET_POWER_ON:
> +		pll_init();
> +		break;
> +	case CPU_RESET_PLL:
> +		break;
> +	case CPU_RESET_WATCH_DOG:
> +		break;
> +	default:
> +		while (true)
> +			;
> +	}
> +}
> diff --git a/board/phytium/pomelo/pomelo.c b/board/phytium/pomelo/pomelo.c
> new file mode 100644
> index 0000000000..693e891d20
> --- /dev/null
> +++ b/board/phytium/pomelo/pomelo.c
> @@ -0,0 +1,120 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */
> +
> +#include <stdio.h>
> +#include <command.h>
> +#include <init.h>
> +#include <asm/armv8/mmu.h>
> +#include <asm/io.h>
> +#include <linux/arm-smccc.h>
> +#include <scsi.h>
> +#include "cpu.h"
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +int dram_init(void)
> +{
> +	gd->mem_clk = 0;
> +	gd->ram_size = PHYS_SDRAM_1_SIZE;
> +
> +	printf("Phytium ddr init\n");
> +
> +	ddr_init();
> +	sec_init();
> +	printf("PBF relocate done\n");
> +
> +	return 0;
> +}
> +
> +int board_init(void)
> +{
> +	return 0;
> +}
> +
> +void reset_cpu(void)
> +{
> +	struct arm_smccc_res res;
> +
> +	printf("run in reset cpu\n");
> +	arm_smccc_smc(0x84000009, 0, 0, 0, 0, 0, 0, 0, &res);
> +	printf("reset cpu error, %lx\n", res.a0);
> +}
> +
> +int mach_cpu_init(void)
> +{
> +	check_reset();
> +	return 0;
> +}
> +
> +int board_early_init_f(void)
> +{
> +	pcie_init();
> +	return 0;
> +}
> +
> +int board_early_init_r(void)
> +{
> +	return 0;
> +}
> +
> +static struct mm_region pomelo_mem_map[] = {
> +	{
> +		.virt = 0x0UL,
> +		.phys = 0x0UL,
> +		.size = 0x80000000UL,
> +		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
> +				 PTE_BLOCK_NON_SHARE |
> +				 PTE_BLOCK_PXN |
> +				 PTE_BLOCK_UXN
> +	},
> +	{
> +		.virt = (u64)PHYS_SDRAM_1,
> +		.phys = (u64)PHYS_SDRAM_1,
> +		.size = (u64)PHYS_SDRAM_1_SIZE,
> +		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
> +				 PTE_BLOCK_NS |
> +				 PTE_BLOCK_INNER_SHARE
> +	},
> +	{
> +		0,
> +	}
> +};
> +
> +struct mm_region *mem_map = pomelo_mem_map;
> +
> +int __asm_flush_l3_dcache(void)
> +{
> +	int i, pstate;
> +
> +	for (i = 0; i < HNF_COUNT; i++)
> +		writeq(HNF_PSTATE_SFONLY, HNF_PSTATE_REQ + i * HNF_STRIDE);
> +	for (i = 0; i < HNF_COUNT; i++) {
> +		do {
> +			pstate = readq(HNF_PSTATE_STAT + i * HNF_STRIDE);
> +		} while ((pstate & 0xf) != (HNF_PSTATE_SFONLY << 2));
> +	}
> +
> +	for (i = 0; i < HNF_COUNT; i++)
> +		writeq(HNF_PSTATE_FULL, HNF_PSTATE_REQ + i * HNF_STRIDE);
> +
> +	return 0;
> +}
> +
> +int last_stage_init(void)
> +{
> +	int ret;
> +
> +	/* pci e */
> +	pci_init();
> +	/* scsi scan */
> +	ret = scsi_scan(true);
> +	if (ret) {
> +		printf("scsi scan failed\n");
> +		return CMD_RET_FAILURE;
> +	}
> +	return ret;
> +}
> diff --git a/board/phytium/pomelo/sec.c b/board/phytium/pomelo/sec.c
> new file mode 100644
> index 0000000000..8ec0fa797b
> --- /dev/null
> +++ b/board/phytium/pomelo/sec.c
> @@ -0,0 +1,40 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */
> +
> +#include <stdio.h>
> +#include <string.h>
> +#include <linux/arm-smccc.h>
> +#include "cpu.h"
> +
> +struct common_config {
> +	unsigned int magic;
> +	unsigned int version;
> +	unsigned int size;
> +	unsigned char rev1[4];
> +	unsigned long long  core_bit_map;
> +} __attribute((aligned(4)));
> +
> +struct common_config const common_base_info = {
> +	.magic = PARAMETER_COMMON_MAGIC,
> +	.version = 0x1,
> +	.core_bit_map = 0x3333,
> +};
> +
> +void sec_init(void)
> +{
> +	unsigned char buffer[0x100];
> +	struct arm_smccc_res res;
> +
> +	memcpy(buffer, &common_base_info, sizeof(common_base_info));
> +	arm_smccc_smc(CPU_INIT_SEC_SVC, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
> +
> +	if (res.a0 != 0) {
> +		printf("error ret %lx\n", res.a0);
> +		while (true)
> +			;
> +	}
> +}
> diff --git a/configs/pomelo_defconfig b/configs/pomelo_defconfig
> new file mode 100644
> index 0000000000..3e6c18196d
> --- /dev/null
> +++ b/configs/pomelo_defconfig
> @@ -0,0 +1,36 @@
> +CONFIG_ARM=y
> +CONFIG_ARM_SMCCC=y
> +CONFIG_TARGET_POMELO=y
> +CONFIG_SYS_TEXT_BASE=0x180000
> +CONFIG_NR_DRAM_BANKS=1
> +CONFIG_ENV_SIZE=0x1000
> +# CONFIG_PSCI_RESET is not set
> +CONFIG_DEFAULT_DEVICE_TREE="phytium-pomelo"
> +CONFIG_AHCI=y
> +CONFIG_DISTRO_DEFAULTS=y
> +CONFIG_USE_BOOTARGS=y
> +CONFIG_BOOTARGS="console=ttyAMA0,115200 earlycon=pl011,0x28001000 root=/dev/sda2 rw"
> +# CONFIG_DISPLAY_CPUINFO is not set
> +# CONFIG_DISPLAY_BOARDINFO is not set
> +CONFIG_LAST_STAGE_INIT=y
> +CONFIG_SYS_PROMPT="pomelo#"
> +# CONFIG_CMD_LZMADEC is not set
> +# CONFIG_CMD_UNZIP is not set
> +CONFIG_CMD_PCI=y
> +CONFIG_OF_CONTROL=y
> +CONFIG_SYS_RELOC_GD_ENV_ADDR=y
> +# CONFIG_NET is not set
> +CONFIG_DM=y
> +CONFIG_SCSI_AHCI=y
> +CONFIG_AHCI_PCI=y
> +CONFIG_BLK=y
> +# CONFIG_MMC is not set
> +CONFIG_PCI=y
> +CONFIG_DM_PCI=y
> +CONFIG_DM_PCI_COMPAT=y
> +CONFIG_PCI_PHYTIUM=y
> +CONFIG_PCIE_ECAM_GENERIC=y
> +CONFIG_SCSI=y
> +CONFIG_DM_SCSI=y
> +CONFIG_DM_SERIAL=y
> +CONFIG_PL01X_SERIAL=y
> diff --git a/include/configs/pomelo.h b/include/configs/pomelo.h
> new file mode 100644
> index 0000000000..69c4195d86
> --- /dev/null
> +++ b/include/configs/pomelo.h
> @@ -0,0 +1,45 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2021
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */
> +
> +#ifndef __POMELO_CONFIG_H__
> +#define __POMELO_CONFIG_H__
> +
> +/* SDRAM Bank #1 start address */
> +#define PHYS_SDRAM_1			0x80000000
> +#define PHYS_SDRAM_1_SIZE		0x7B000000
> +#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
> +
> +#define CONFIG_SYS_LOAD_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x10000000)
> +
> +/* SIZE of malloc pool */
> +#define CONFIG_SYS_MALLOC_LEN		(1 * 1024 * 1024  + CONFIG_ENV_SIZE)
> +#define CONFIG_BOARD_EARLY_INIT_F
> +#define CONFIG_BOARD_EARLY_INIT_R
> +
> +#define CONFIG_SYS_INIT_SP_ADDR		(0x29800000 + 0x1a000)
> +
> +/* PCI CONFIG */
> +#define CONFIG_SYS_PCI_64BIT		1
> +#define CONFIG_PCI_SCAN_SHOW
> +
> +/* SCSI */
> +#define CONFIG_SYS_SCSI_MAX_SCSI_ID	4
> +#define CONFIG_SYS_SCSI_MAX_LUN		1
> +#define CONFIG_SYS_SCSI_MAX_DEVICE	128
> +#define CONFIG_SCSI_AHCI_PLAT
> +#define CONFIG_SYS_SATA_MAX_DEVICE	4
> +
> +/*BOOT*/
> +#define CONFIG_SYS_BOOTM_LEN		(60 * 1024 * 1024)
> +
> +#define CONFIG_EXTRA_ENV_SETTINGS	\
> +	"load_kernel=ext4load scsi 0:1 0x90100000 uImage_old\0"	\
> +	"load_fdt=ext4load scsi 0:1 0x95000000 ft-d2000.dtb\0"\
> +	"boot_fdt=bootm 0x90100000 -:- 0x17c000\0"	\
> +	"distro_bootcmd=run load_kernel; run boot_fdt"
> +
> +#endif


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH]  arm: add initial support for the Phytium Pomelo Board
@ 2021-06-24  1:02 nicholas_zheng
  2021-06-25 12:27 ` Andre Przywara
  0 siblings, 1 reply; 12+ messages in thread
From: nicholas_zheng @ 2021-06-24  1:02 UTC (permalink / raw)
  To: trini, bharat.gooty, rayagonda.kokatanur
  Cc: jagan, andre.przywara, festevam, patrick.delaunay, tharvey,
	pbrobinson, hs, lokeshvutla, d-gerlach, u-boot, weichangzheng

From: weichangzheng <nicholas_zheng@outlook.com>

 This adds platform code and the device tree for the Phytium Pomelo Board.
 The initial support comprises the UART and the PCIE.

Signed-off-by: weichangzheng <nicholas_zheng@outlook.com>
---
 arch/arm/Kconfig                 |   8 ++
 arch/arm/dts/Makefile            |   1 +
 arch/arm/dts/phytium-pomelo.dts  | 103 +++++++++++++++++++
 board/phytium/pomelo/Kconfig     |  12 +++
 board/phytium/pomelo/MAINTAINERS |   8 ++
 board/phytium/pomelo/Makefile    |  14 +++
 board/phytium/pomelo/cpu.h       |  73 ++++++++++++++
 board/phytium/pomelo/ddr.c       | 164 +++++++++++++++++++++++++++++++
 board/phytium/pomelo/pcie.c      |  61 ++++++++++++
 board/phytium/pomelo/pll.c       |  75 ++++++++++++++
 board/phytium/pomelo/pomelo.c    | 120 ++++++++++++++++++++++
 board/phytium/pomelo/sec.c       |  40 ++++++++
 configs/pomelo_defconfig         |  36 +++++++
 include/configs/pomelo.h         |  45 +++++++++
 14 files changed, 760 insertions(+)
 create mode 100644 arch/arm/dts/phytium-pomelo.dts
 create mode 100644 board/phytium/pomelo/Kconfig
 create mode 100644 board/phytium/pomelo/MAINTAINERS
 create mode 100644 board/phytium/pomelo/Makefile
 create mode 100644 board/phytium/pomelo/cpu.h
 create mode 100644 board/phytium/pomelo/ddr.c
 create mode 100644 board/phytium/pomelo/pcie.c
 create mode 100644 board/phytium/pomelo/pll.c
 create mode 100644 board/phytium/pomelo/pomelo.c
 create mode 100644 board/phytium/pomelo/sec.c
 create mode 100644 configs/pomelo_defconfig
 create mode 100644 include/configs/pomelo.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 31d687ea01..6110fcddad 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1800,6 +1800,13 @@ config TARGET_DURIAN
 	  Support for durian platform.
 	  It has 2GB Sdram, uart and pcie.
 
+config TARGET_POMELO
+	bool "Support Phytium Pomelo Platform"
+	select ARM64
+	help
+		Support for pomelo platform.
+		It has 2GB Sdram, uart and pcie.
+
 config TARGET_PRESIDIO_ASIC
 	bool "Support Cortina Presidio ASIC Platform"
 	select ARM64
@@ -2019,6 +2026,7 @@ source "board/toradex/colibri_pxa270/Kconfig"
 source "board/variscite/dart_6ul/Kconfig"
 source "board/vscom/baltos/Kconfig"
 source "board/phytium/durian/Kconfig"
+source "board/phytium/pomelo/Kconfig"
 source "board/xen/xenguest_arm64/Kconfig"
 source "board/keymile/Kconfig"
 
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 096068261d..c26692c17e 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1098,6 +1098,7 @@ dtb-$(CONFIG_TARGET_MX53PPD) += imx53-ppd.dtb
 dtb-$(CONFIG_TARGET_TOTAL_COMPUTE) += total_compute.dtb
 
 dtb-$(CONFIG_TARGET_DURIAN) += phytium-durian.dtb
+dtb-$(CONFIG_TARGET_POMELO) += phytium-pomelo.dtb
 
 dtb-$(CONFIG_TARGET_PRESIDIO_ASIC) += ca-presidio-engboard.dtb
 
diff --git a/arch/arm/dts/phytium-pomelo.dts b/arch/arm/dts/phytium-pomelo.dts
new file mode 100644
index 0000000000..4961682058
--- /dev/null
+++ b/arch/arm/dts/phytium-pomelo.dts
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Phytium Pomelo board
+ * Copyright (C) 2021, Phytium Ltd.
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+/dts-v1/;
+
+/memreserve/	0x0000000080000000 0x0000000000100000;
+/ {
+	model = "Phytium Pomelo";
+	compatible = "phytium,pomelo";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <0x2>;
+		#size-cells = <0x0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu4: cpu@4 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x100>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu5: cpu@5 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x101>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu8: cpu@8 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x200>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu9: cpu@9 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x201>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu12: cpu@12 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x300>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu13: cpu@13 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x301>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+	};
+
+	pcie-controller@40000000 {
+		compatible = "pci-host-ecam-generic";
+		device_type = "pci";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		reg = <0x0 0x40000000 0x0 0x10000000>;
+		bus-range = <0x0 0xff>;
+		ranges = <0x01000000 0x00 0x00000000 0x0  0x50000000 0x0  0x00F00000>,
+			 <0x02000000 0x00 0x58000000 0x0  0x58000000 0x0  0x28000000>,
+			 <0x43000000 0x10 0x00000000 0x10 0x00000000 0x10  0x00000000>;
+	};
+
+	uart@28001000 {
+		compatible = "arm,pl011";
+		reg = <0x0 0x28001000 0x0 0x1000>;
+		clock = <48000000>;
+	};
+};
diff --git a/board/phytium/pomelo/Kconfig b/board/phytium/pomelo/Kconfig
new file mode 100644
index 0000000000..281aa8feff
--- /dev/null
+++ b/board/phytium/pomelo/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_POMELO
+
+config SYS_BOARD
+	default "pomelo"
+
+config SYS_VENDOR
+	default "phytium"
+
+config SYS_CONFIG_NAME
+	default "pomelo"
+
+endif
diff --git a/board/phytium/pomelo/MAINTAINERS b/board/phytium/pomelo/MAINTAINERS
new file mode 100644
index 0000000000..950449392b
--- /dev/null
+++ b/board/phytium/pomelo/MAINTAINERS
@@ -0,0 +1,8 @@
+POMELO BOARD
+M:	lixinde <lixinde@phytium.com.cn>
+M:	weichangzheng <weichangzheng@phytium.com.cn>
+S:	Maintained
+F:	board/phytium/pomelo/*
+F:	include/configs/pomelo.h
+F:	configs/pomelo_defconfig
+
diff --git a/board/phytium/pomelo/Makefile b/board/phytium/pomelo/Makefile
new file mode 100644
index 0000000000..b9cb3609bd
--- /dev/null
+++ b/board/phytium/pomelo/Makefile
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2021
+# lixinde         <lixinde@phytium.com.cn>
+# weichangzheng   <weichangzheng@phytium.com.cn>
+#
+
+obj-y += pomelo.o
+obj-y += pll.o
+obj-y += pcie.o
+obj-y += ddr.o
+obj-y += sec.o
+
+
diff --git a/board/phytium/pomelo/cpu.h b/board/phytium/pomelo/cpu.h
new file mode 100644
index 0000000000..e15917609b
--- /dev/null
+++ b/board/phytium/pomelo/cpu.h
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2021
+ * Phytium Technology Ltd <www.phytium.com>
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#ifndef _FT_POMELO_H
+#define _FT_POMELO_H
+
+/* SMCCC ID */
+#define CPU_SVC_VERSION			0xC2000F00
+#define CPU_GET_RST_SOURCE		0xC2000F01
+#define CPU_INIT_PLL			0xC2000F02
+#define CPU_INIT_PCIE			0xC2000F03
+#define CPU_INIT_MEM			0xC2000F04
+#define CPU_INIT_SEC_SVC		0xC2000F05
+
+/*CPU RESET*/
+#define CPU_RESET_POWER_ON		0x1
+#define CPU_RESET_PLL			0x4
+#define CPU_RESET_WATCH_DOG		0x8
+
+/* PLL */
+#define PARAMETER_PLL_MAGIC		0x54460010
+
+/* PCIE */
+#define PARAMETER_PCIE_MAGIC		0x54460011
+#define CONFIG_INDEPENDENT_TREE		0x0
+#define PCI_PEU0			0x1
+#define PCI_PEU1			0x1
+#define PEU1_OFFSET			16
+#define PEU_C_OFFSET_MODE		16
+#define PEU_C_OFFSET_SPEED		0
+#define RC_MODE				0x1
+#define X8X8				0x1
+#define GEN3				3
+
+/* DDR */
+#define PARAMETER_MCU_MAGIC		0x54460014
+#define PARAM_MCU_VERSION		0x1
+#define PARAM_MCU_SIZE			0x100
+#define PARAM_CH_ENABLE			0x3
+#define PARAM_ECC_ENABLE		0x3
+#define PARAM_FORCE_SPD_DISABLE		0x0
+#define PARAM_MCU_MISC_ENABLE		0x0
+
+#define UDIMM_TYPE			0x2
+#define DIMM_X8				0x1
+#define NO_MIRROR			0x0
+#define NO_ECC_TYPE			0
+#define DDR4_TYPE			0xC
+
+/* SEC */
+#define PARAMETER_COMMON_MAGIC		0x54460013
+
+/* FLUSH L3 CASHE */
+#define HNF_COUNT			0x8
+#define HNF_PSTATE_REQ			(HNF_BASE + 0x10)
+#define HNF_PSTATE_STAT			(HNF_BASE + 0x18)
+#define HNF_PSTATE_OFF			0x0
+#define HNF_PSTATE_SFONLY		0x1
+#define HNF_PSTATE_HALF			0x2
+#define HNF_PSTATE_FULL			0x3
+#define HNF_STRIDE			0x10000
+#define HNF_BASE			(unsigned long)(0x3A200000)
+void ddr_init(void);
+void sec_init(void);
+void check_reset(void);
+void pcie_init(void);
+
+#endif /* _FT_POMELO_H */
diff --git a/board/phytium/pomelo/ddr.c b/board/phytium/pomelo/ddr.c
new file mode 100644
index 0000000000..88756f5fc1
--- /dev/null
+++ b/board/phytium/pomelo/ddr.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct ddr_spd {
+	/******************* read from spd *****************/
+	unsigned char  dimm_type;	/* 1: RDIMM;2: UDIMM;3: SODIMM;4: LRDIMM */
+	unsigned char  data_width;	/* 0: x4; 1: x8; 2: x16 */
+	unsigned char  mirror_type;	/* 0: stardard; 1: mirror */
+	unsigned char  ecc_type;	/* 0: no-ecc; 1:ecc */
+	unsigned char  dram_type;	/* 0xB: DDR3; 0xC: DDR4 */
+	unsigned char  rank_num;
+	unsigned char  row_num;
+	unsigned char  col_num;
+
+	unsigned char  bg_num;	/*only DDR4*/
+	unsigned char  bank_num;
+	unsigned short int module_manufacturer_id;
+	unsigned short int taamin;
+	unsigned short int trcdmin;
+
+	unsigned short int trpmin;
+	unsigned short int trasmin;
+	unsigned short int trcmin;
+	unsigned short int tfawmin;
+
+	unsigned short int trrd_smin;	/*only DDR4*/
+	unsigned short int trrd_lmin;	/*only DDR4*/
+	unsigned short int tccd_lmin;	/*only DDR4*/
+	unsigned short int twrmin;
+
+	unsigned short int twtr_smin;	/*only DDR4*/
+	unsigned short int twtr_lmin;	/*only DDR4*/
+	unsigned short int twtrmin;	/*only DDR3*/
+	unsigned short int trrdmin;	/*only DDR3*/
+
+	/******************* RCD control words *****************/
+	unsigned char  f0rc03; /*bit[3:2]:CS		bit[1:0]:CA  */
+	unsigned char  f0rc04; /*bit[3:2]:ODT		bit[1:0]:CKE */
+	unsigned char  f0rc05; /*bit[3:2]:CLK-A side	bit[1:0]:CLK-B side */
+	unsigned char  bc00;
+	unsigned char  bc01;
+	unsigned char  bc02;
+	unsigned char  bc03;
+	unsigned char  bc04;
+
+	unsigned char  bc05;
+	unsigned char  f5bc5x;
+	unsigned char  f5bc6x;
+	/******************* LRDIMM special *****************/
+	unsigned char  vrefdq_pr0;
+	unsigned char  vrefdq_mdram;
+	unsigned char  rtt_mdram_1866;
+	unsigned char  rtt_mdram_2400;
+	unsigned char  rtt_mdram_3200;
+
+	unsigned char  drive_dram;
+	unsigned char  odt_dram_1866;
+	unsigned char  odt_dram_2400;
+	unsigned char  odt_dram_3200;
+	unsigned char  park_dram_1866;
+	unsigned char  park_dram_2400;
+	unsigned char  park_dram_3200;
+	unsigned char  rcd_num;
+} __attribute((aligned(4)));
+
+struct mcu_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+
+	unsigned char ch_enable;
+	unsigned char misc1_enable;
+	unsigned char misc2_enable;
+	unsigned char force_spd_enable;
+	unsigned char misc3_enable;
+	unsigned char train_debug;
+	unsigned char train_recover;
+	unsigned char rev2[9];
+
+	struct ddr_spd ddr_spd_info[2];
+} __attribute((aligned(4)));
+
+static void get_mcu_up_info_default(struct mcu_config *pm)
+{
+	pm->magic		= PARAMETER_MCU_MAGIC;
+	pm->version		= PARAM_MCU_VERSION;
+	pm->size		= PARAM_MCU_SIZE;
+	pm->ch_enable		= PARAM_CH_ENABLE;
+	pm->misc1_enable	= PARAM_ECC_ENABLE;
+	pm->force_spd_enable	= PARAM_FORCE_SPD_DISABLE;
+	pm->misc3_enable	= PARAM_MCU_MISC_ENABLE;
+	pm->train_recover	= 0x0;
+}
+
+static unsigned char init_dimm_param(unsigned char ch, struct mcu_config *pm)
+{
+	printf("manual config dimm info...\n");
+	pm->ddr_spd_info[ch].dimm_type = UDIMM_TYPE;
+	pm->ddr_spd_info[ch].data_width = DIMM_X8;
+	pm->ddr_spd_info[ch].mirror_type = NO_MIRROR;
+	pm->ddr_spd_info[ch].ecc_type = NO_ECC_TYPE;
+	pm->ddr_spd_info[ch].dram_type = DDR4_TYPE;
+	pm->ddr_spd_info[ch].rank_num = 1;
+	pm->ddr_spd_info[ch].row_num  = 16;
+	pm->ddr_spd_info[ch].col_num = 10;
+	pm->ddr_spd_info[ch].bg_num = 4;
+	pm->ddr_spd_info[ch].bank_num = 4;
+	pm->ddr_spd_info[ch].taamin = 13750;
+	pm->ddr_spd_info[ch].trcdmin = 13750;
+
+	pm->ddr_spd_info[ch].trpmin = 13750;
+	pm->ddr_spd_info[ch].trasmin = 32000;
+	pm->ddr_spd_info[ch].trcmin =  45750;
+	pm->ddr_spd_info[ch].tfawmin = 21000;
+
+	pm->ddr_spd_info[ch].trrd_smin = 3000;
+	pm->ddr_spd_info[ch].trrd_lmin = 4900;
+	pm->ddr_spd_info[ch].tccd_lmin = 5000;
+	pm->ddr_spd_info[ch].twrmin = 15000;
+
+	pm->ddr_spd_info[ch].twtr_smin = 2500;
+	pm->ddr_spd_info[ch].twtr_lmin = 7500;
+
+	return 0;
+}
+
+void get_default_mcu_info(unsigned char *data)
+{
+	get_mcu_up_info_default((struct mcu_config *)data);
+}
+
+void fix_mcu_info(unsigned char *data)
+{
+	unsigned char ch;
+	struct mcu_config *mcu_info = (struct mcu_config *)data;
+
+	for (ch = 0; ch < 2; ch++)
+		init_dimm_param(ch, mcu_info);
+}
+
+void ddr_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	get_default_mcu_info(buffer);
+	fix_mcu_info(buffer);
+
+	arm_smccc_smc(CPU_INIT_MEM, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+	if (res.a0 != 0) {
+		printf("error x0: 0x%lx, x1: 0x%lx\n", res.a0, res.a1);
+		while (true)
+			;
+	}
+}
diff --git a/board/phytium/pomelo/pcie.c b/board/phytium/pomelo/pcie.c
new file mode 100644
index 0000000000..3754d8eb9b
--- /dev/null
+++ b/board/phytium/pomelo/pcie.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct pcu_ctr {
+	unsigned int base_config[3];
+	unsigned int equalization[3];
+	unsigned char rev[80];
+} __attribute((aligned(4)));
+
+struct pcu_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+	unsigned int independent_tree;
+	unsigned int base_cfg;
+	unsigned char rev2[16];
+	struct pcu_ctr ctr_cfg[2];
+} __attribute((aligned(4)));
+
+struct pcu_config const peu_base_info = {
+	.magic = PARAMETER_PCIE_MAGIC,
+	.version = 0x2,
+	.size = 0x100,
+	.independent_tree = CONFIG_INDEPENDENT_TREE,
+	.base_cfg = ((PCI_PEU1 | (X8X8 << 1)) << PEU1_OFFSET | (PCI_PEU0 | (X8X8 << 1))),
+	.ctr_cfg[0].base_config[0] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[0].base_config[1] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[0].base_config[2] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[1].base_config[0] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[1].base_config[1] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[1].base_config[2] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[0].equalization[0] = 0x7,
+	.ctr_cfg[0].equalization[1] = 0x7,
+	.ctr_cfg[0].equalization[2] = 0x7,
+	.ctr_cfg[1].equalization[0] = 0x7,
+	.ctr_cfg[1].equalization[1] = 0x7,
+	.ctr_cfg[1].equalization[2] = 0x7,
+};
+
+void pcie_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	memcpy(buffer, &peu_base_info, sizeof(peu_base_info));
+	arm_smccc_smc(CPU_INIT_PCIE, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+	if (res.a0 != 0) {
+		while (true)
+			;
+	}
+}
diff --git a/board/phytium/pomelo/pll.c b/board/phytium/pomelo/pll.c
new file mode 100644
index 0000000000..1227b7dd80
--- /dev/null
+++ b/board/phytium/pomelo/pll.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <asm/io.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct pll_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+	unsigned int core_pll;
+	unsigned int res1;
+	unsigned int lmu_pll;
+	unsigned int res2;
+	unsigned int res3;
+	unsigned int res4;
+	unsigned int res5;
+} __attribute((aligned(4)));
+
+struct pll_config const pll_base_info = {
+	.magic = PARAMETER_PLL_MAGIC,
+	.version = 0x1,
+	.size = 0x30,
+	.core_pll = 2300,	/*MHz*/
+	.lmu_pll = 667,		/*MHz*/
+};
+
+unsigned int get_reset_source(void)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(CPU_GET_RST_SOURCE, 0, 0, 0, 0, 0, 0, 0, &res);
+	return res.a0;
+}
+
+void pll_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	memcpy(buffer, &pll_base_info, sizeof(pll_base_info));
+	arm_smccc_smc(CPU_INIT_PLL, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+	if (res.a0 != 0) {
+		while (true)
+			;
+	}
+}
+
+void check_reset(void)
+{
+	unsigned int rst;
+
+	rst = get_reset_source();
+
+	switch (rst) {
+	case CPU_RESET_POWER_ON:
+		pll_init();
+		break;
+	case CPU_RESET_PLL:
+		break;
+	case CPU_RESET_WATCH_DOG:
+		break;
+	default:
+		while (true)
+			;
+	}
+}
diff --git a/board/phytium/pomelo/pomelo.c b/board/phytium/pomelo/pomelo.c
new file mode 100644
index 0000000000..693e891d20
--- /dev/null
+++ b/board/phytium/pomelo/pomelo.c
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <command.h>
+#include <init.h>
+#include <asm/armv8/mmu.h>
+#include <asm/io.h>
+#include <linux/arm-smccc.h>
+#include <scsi.h>
+#include "cpu.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+	gd->mem_clk = 0;
+	gd->ram_size = PHYS_SDRAM_1_SIZE;
+
+	printf("Phytium ddr init\n");
+
+	ddr_init();
+	sec_init();
+	printf("PBF relocate done\n");
+
+	return 0;
+}
+
+int board_init(void)
+{
+	return 0;
+}
+
+void reset_cpu(void)
+{
+	struct arm_smccc_res res;
+
+	printf("run in reset cpu\n");
+	arm_smccc_smc(0x84000009, 0, 0, 0, 0, 0, 0, 0, &res);
+	printf("reset cpu error, %lx\n", res.a0);
+}
+
+int mach_cpu_init(void)
+{
+	check_reset();
+	return 0;
+}
+
+int board_early_init_f(void)
+{
+	pcie_init();
+	return 0;
+}
+
+int board_early_init_r(void)
+{
+	return 0;
+}
+
+static struct mm_region pomelo_mem_map[] = {
+	{
+		.virt = 0x0UL,
+		.phys = 0x0UL,
+		.size = 0x80000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+				 PTE_BLOCK_NON_SHARE |
+				 PTE_BLOCK_PXN |
+				 PTE_BLOCK_UXN
+	},
+	{
+		.virt = (u64)PHYS_SDRAM_1,
+		.phys = (u64)PHYS_SDRAM_1,
+		.size = (u64)PHYS_SDRAM_1_SIZE,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+				 PTE_BLOCK_NS |
+				 PTE_BLOCK_INNER_SHARE
+	},
+	{
+		0,
+	}
+};
+
+struct mm_region *mem_map = pomelo_mem_map;
+
+int __asm_flush_l3_dcache(void)
+{
+	int i, pstate;
+
+	for (i = 0; i < HNF_COUNT; i++)
+		writeq(HNF_PSTATE_SFONLY, HNF_PSTATE_REQ + i * HNF_STRIDE);
+	for (i = 0; i < HNF_COUNT; i++) {
+		do {
+			pstate = readq(HNF_PSTATE_STAT + i * HNF_STRIDE);
+		} while ((pstate & 0xf) != (HNF_PSTATE_SFONLY << 2));
+	}
+
+	for (i = 0; i < HNF_COUNT; i++)
+		writeq(HNF_PSTATE_FULL, HNF_PSTATE_REQ + i * HNF_STRIDE);
+
+	return 0;
+}
+
+int last_stage_init(void)
+{
+	int ret;
+
+	/* pci e */
+	pci_init();
+	/* scsi scan */
+	ret = scsi_scan(true);
+	if (ret) {
+		printf("scsi scan failed\n");
+		return CMD_RET_FAILURE;
+	}
+	return ret;
+}
diff --git a/board/phytium/pomelo/sec.c b/board/phytium/pomelo/sec.c
new file mode 100644
index 0000000000..8ec0fa797b
--- /dev/null
+++ b/board/phytium/pomelo/sec.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct common_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+	unsigned long long  core_bit_map;
+} __attribute((aligned(4)));
+
+struct common_config const common_base_info = {
+	.magic = PARAMETER_COMMON_MAGIC,
+	.version = 0x1,
+	.core_bit_map = 0x3333,
+};
+
+void sec_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	memcpy(buffer, &common_base_info, sizeof(common_base_info));
+	arm_smccc_smc(CPU_INIT_SEC_SVC, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+
+	if (res.a0 != 0) {
+		printf("error ret %lx\n", res.a0);
+		while (true)
+			;
+	}
+}
diff --git a/configs/pomelo_defconfig b/configs/pomelo_defconfig
new file mode 100644
index 0000000000..3e6c18196d
--- /dev/null
+++ b/configs/pomelo_defconfig
@@ -0,0 +1,36 @@
+CONFIG_ARM=y
+CONFIG_ARM_SMCCC=y
+CONFIG_TARGET_POMELO=y
+CONFIG_SYS_TEXT_BASE=0x180000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x1000
+# CONFIG_PSCI_RESET is not set
+CONFIG_DEFAULT_DEVICE_TREE="phytium-pomelo"
+CONFIG_AHCI=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyAMA0,115200 earlycon=pl011,0x28001000 root=/dev/sda2 rw"
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_LAST_STAGE_INIT=y
+CONFIG_SYS_PROMPT="pomelo#"
+# CONFIG_CMD_LZMADEC is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_PCI=y
+CONFIG_OF_CONTROL=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+# CONFIG_NET is not set
+CONFIG_DM=y
+CONFIG_SCSI_AHCI=y
+CONFIG_AHCI_PCI=y
+CONFIG_BLK=y
+# CONFIG_MMC is not set
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
+CONFIG_PCI_PHYTIUM=y
+CONFIG_PCIE_ECAM_GENERIC=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
+CONFIG_DM_SERIAL=y
+CONFIG_PL01X_SERIAL=y
diff --git a/include/configs/pomelo.h b/include/configs/pomelo.h
new file mode 100644
index 0000000000..69c4195d86
--- /dev/null
+++ b/include/configs/pomelo.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#ifndef __POMELO_CONFIG_H__
+#define __POMELO_CONFIG_H__
+
+/* SDRAM Bank #1 start address */
+#define PHYS_SDRAM_1			0x80000000
+#define PHYS_SDRAM_1_SIZE		0x7B000000
+#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
+
+#define CONFIG_SYS_LOAD_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x10000000)
+
+/* SIZE of malloc pool */
+#define CONFIG_SYS_MALLOC_LEN		(1 * 1024 * 1024  + CONFIG_ENV_SIZE)
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_BOARD_EARLY_INIT_R
+
+#define CONFIG_SYS_INIT_SP_ADDR		(0x29800000 + 0x1a000)
+
+/* PCI CONFIG */
+#define CONFIG_SYS_PCI_64BIT		1
+#define CONFIG_PCI_SCAN_SHOW
+
+/* SCSI */
+#define CONFIG_SYS_SCSI_MAX_SCSI_ID	4
+#define CONFIG_SYS_SCSI_MAX_LUN		1
+#define CONFIG_SYS_SCSI_MAX_DEVICE	128
+#define CONFIG_SCSI_AHCI_PLAT
+#define CONFIG_SYS_SATA_MAX_DEVICE	4
+
+/*BOOT*/
+#define CONFIG_SYS_BOOTM_LEN		(60 * 1024 * 1024)
+
+#define CONFIG_EXTRA_ENV_SETTINGS	\
+	"load_kernel=ext4load scsi 0:1 0x90100000 uImage_old\0"	\
+	"load_fdt=ext4load scsi 0:1 0x95000000 ft-d2000.dtb\0"\
+	"boot_fdt=bootm 0x90100000 -:- 0x17c000\0"	\
+	"distro_bootcmd=run load_kernel; run boot_fdt"
+
+#endif
-- 
2.17.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH]  arm: add initial support for the Phytium Pomelo Board
@ 2021-06-21  8:36 nicholas_zheng
  0 siblings, 0 replies; 12+ messages in thread
From: nicholas_zheng @ 2021-06-21  8:36 UTC (permalink / raw)
  To: trini, bharat.gooty, rayagonda.kokatanur
  Cc: jagan, andre.przywara, festevam, patrick.delaunay, tharvey,
	pbrobinson, hs, lokeshvutla, d-gerlach, u-boot, weichangzheng

From: weichangzheng <nicholas_zheng@outlook.com>

 This adds platform code and the device tree for the Phytium Pomelo Board.
 The initial support comprises the UART and the PCIE.

Signed-off-by: weichangzheng <nicholas_zheng@outlook.com>
---
 arch/arm/Kconfig                 |   8 ++
 arch/arm/dts/Makefile            |   1 +
 arch/arm/dts/phytium-pomelo.dts  | 103 +++++++++++++++++++
 board/phytium/pomelo/Kconfig     |  12 +++
 board/phytium/pomelo/MAINTAINERS |   8 ++
 board/phytium/pomelo/Makefile    |  14 +++
 board/phytium/pomelo/cpu.h       |  73 ++++++++++++++
 board/phytium/pomelo/ddr.c       | 164 +++++++++++++++++++++++++++++++
 board/phytium/pomelo/pcie.c      |  61 ++++++++++++
 board/phytium/pomelo/pll.c       |  75 ++++++++++++++
 board/phytium/pomelo/pomelo.c    | 120 ++++++++++++++++++++++
 board/phytium/pomelo/sec.c       |  40 ++++++++
 configs/pomelo_defconfig         |  36 +++++++
 include/configs/pomelo.h         |  45 +++++++++
 14 files changed, 760 insertions(+)
 create mode 100644 arch/arm/dts/phytium-pomelo.dts
 create mode 100644 board/phytium/pomelo/Kconfig
 create mode 100644 board/phytium/pomelo/MAINTAINERS
 create mode 100644 board/phytium/pomelo/Makefile
 create mode 100644 board/phytium/pomelo/cpu.h
 create mode 100644 board/phytium/pomelo/ddr.c
 create mode 100644 board/phytium/pomelo/pcie.c
 create mode 100644 board/phytium/pomelo/pll.c
 create mode 100644 board/phytium/pomelo/pomelo.c
 create mode 100644 board/phytium/pomelo/sec.c
 create mode 100644 configs/pomelo_defconfig
 create mode 100644 include/configs/pomelo.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 31d687ea01..6110fcddad 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1800,6 +1800,13 @@ config TARGET_DURIAN
 	  Support for durian platform.
 	  It has 2GB Sdram, uart and pcie.
 
+config TARGET_POMELO
+	bool "Support Phytium Pomelo Platform"
+	select ARM64
+	help
+		Support for pomelo platform.
+		It has 2GB Sdram, uart and pcie.
+
 config TARGET_PRESIDIO_ASIC
 	bool "Support Cortina Presidio ASIC Platform"
 	select ARM64
@@ -2019,6 +2026,7 @@ source "board/toradex/colibri_pxa270/Kconfig"
 source "board/variscite/dart_6ul/Kconfig"
 source "board/vscom/baltos/Kconfig"
 source "board/phytium/durian/Kconfig"
+source "board/phytium/pomelo/Kconfig"
 source "board/xen/xenguest_arm64/Kconfig"
 source "board/keymile/Kconfig"
 
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 096068261d..c26692c17e 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1098,6 +1098,7 @@ dtb-$(CONFIG_TARGET_MX53PPD) += imx53-ppd.dtb
 dtb-$(CONFIG_TARGET_TOTAL_COMPUTE) += total_compute.dtb
 
 dtb-$(CONFIG_TARGET_DURIAN) += phytium-durian.dtb
+dtb-$(CONFIG_TARGET_POMELO) += phytium-pomelo.dtb
 
 dtb-$(CONFIG_TARGET_PRESIDIO_ASIC) += ca-presidio-engboard.dtb
 
diff --git a/arch/arm/dts/phytium-pomelo.dts b/arch/arm/dts/phytium-pomelo.dts
new file mode 100644
index 0000000000..4961682058
--- /dev/null
+++ b/arch/arm/dts/phytium-pomelo.dts
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Phytium Pomelo board
+ * Copyright (C) 2021, Phytium Ltd.
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+/dts-v1/;
+
+/memreserve/	0x0000000080000000 0x0000000000100000;
+/ {
+	model = "Phytium Pomelo";
+	compatible = "phytium,pomelo";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <0x2>;
+		#size-cells = <0x0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu4: cpu@4 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x100>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu5: cpu@5 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x101>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu8: cpu@8 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x200>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu9: cpu@9 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x201>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu12: cpu@12 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x300>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu13: cpu@13 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x301>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+	};
+
+	pcie-controller@40000000 {
+		compatible = "pci-host-ecam-generic";
+		device_type = "pci";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		reg = <0x0 0x40000000 0x0 0x10000000>;
+		bus-range = <0x0 0xff>;
+		ranges = <0x01000000 0x00 0x00000000 0x0  0x50000000 0x0  0x00F00000>,
+			 <0x02000000 0x00 0x58000000 0x0  0x58000000 0x0  0x28000000>,
+			 <0x43000000 0x10 0x00000000 0x10 0x00000000 0x10  0x00000000>;
+	};
+
+	uart@28001000 {
+		compatible = "arm,pl011";
+		reg = <0x0 0x28001000 0x0 0x1000>;
+		clock = <48000000>;
+	};
+};
diff --git a/board/phytium/pomelo/Kconfig b/board/phytium/pomelo/Kconfig
new file mode 100644
index 0000000000..281aa8feff
--- /dev/null
+++ b/board/phytium/pomelo/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_POMELO
+
+config SYS_BOARD
+	default "pomelo"
+
+config SYS_VENDOR
+	default "phytium"
+
+config SYS_CONFIG_NAME
+	default "pomelo"
+
+endif
diff --git a/board/phytium/pomelo/MAINTAINERS b/board/phytium/pomelo/MAINTAINERS
new file mode 100644
index 0000000000..950449392b
--- /dev/null
+++ b/board/phytium/pomelo/MAINTAINERS
@@ -0,0 +1,8 @@
+POMELO BOARD
+M:	lixinde <lixinde@phytium.com.cn>
+M:	weichangzheng <weichangzheng@phytium.com.cn>
+S:	Maintained
+F:	board/phytium/pomelo/*
+F:	include/configs/pomelo.h
+F:	configs/pomelo_defconfig
+
diff --git a/board/phytium/pomelo/Makefile b/board/phytium/pomelo/Makefile
new file mode 100644
index 0000000000..b9cb3609bd
--- /dev/null
+++ b/board/phytium/pomelo/Makefile
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2021
+# lixinde         <lixinde@phytium.com.cn>
+# weichangzheng   <weichangzheng@phytium.com.cn>
+#
+
+obj-y += pomelo.o
+obj-y += pll.o
+obj-y += pcie.o
+obj-y += ddr.o
+obj-y += sec.o
+
+
diff --git a/board/phytium/pomelo/cpu.h b/board/phytium/pomelo/cpu.h
new file mode 100644
index 0000000000..e15917609b
--- /dev/null
+++ b/board/phytium/pomelo/cpu.h
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2021
+ * Phytium Technology Ltd <www.phytium.com>
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#ifndef _FT_POMELO_H
+#define _FT_POMELO_H
+
+/* SMCCC ID */
+#define CPU_SVC_VERSION			0xC2000F00
+#define CPU_GET_RST_SOURCE		0xC2000F01
+#define CPU_INIT_PLL			0xC2000F02
+#define CPU_INIT_PCIE			0xC2000F03
+#define CPU_INIT_MEM			0xC2000F04
+#define CPU_INIT_SEC_SVC		0xC2000F05
+
+/*CPU RESET*/
+#define CPU_RESET_POWER_ON		0x1
+#define CPU_RESET_PLL			0x4
+#define CPU_RESET_WATCH_DOG		0x8
+
+/* PLL */
+#define PARAMETER_PLL_MAGIC		0x54460010
+
+/* PCIE */
+#define PARAMETER_PCIE_MAGIC		0x54460011
+#define CONFIG_INDEPENDENT_TREE		0x0
+#define PCI_PEU0			0x1
+#define PCI_PEU1			0x1
+#define PEU1_OFFSET			16
+#define PEU_C_OFFSET_MODE		16
+#define PEU_C_OFFSET_SPEED		0
+#define RC_MODE				0x1
+#define X8X8				0x1
+#define GEN3				3
+
+/* DDR */
+#define PARAMETER_MCU_MAGIC		0x54460014
+#define PARAM_MCU_VERSION		0x1
+#define PARAM_MCU_SIZE			0x100
+#define PARAM_CH_ENABLE			0x3
+#define PARAM_ECC_ENABLE		0x3
+#define PARAM_FORCE_SPD_DISABLE		0x0
+#define PARAM_MCU_MISC_ENABLE		0x0
+
+#define UDIMM_TYPE			0x2
+#define DIMM_X8				0x1
+#define NO_MIRROR			0x0
+#define NO_ECC_TYPE			0
+#define DDR4_TYPE			0xC
+
+/* SEC */
+#define PARAMETER_COMMON_MAGIC		0x54460013
+
+/* FLUSH L3 CASHE */
+#define HNF_COUNT			0x8
+#define HNF_PSTATE_REQ			(HNF_BASE + 0x10)
+#define HNF_PSTATE_STAT			(HNF_BASE + 0x18)
+#define HNF_PSTATE_OFF			0x0
+#define HNF_PSTATE_SFONLY		0x1
+#define HNF_PSTATE_HALF			0x2
+#define HNF_PSTATE_FULL			0x3
+#define HNF_STRIDE			0x10000
+#define HNF_BASE			(unsigned long)(0x3A200000)
+void ddr_init(void);
+void sec_init(void);
+void check_reset(void);
+void pcie_init(void);
+
+#endif /* _FT_POMELO_H */
diff --git a/board/phytium/pomelo/ddr.c b/board/phytium/pomelo/ddr.c
new file mode 100644
index 0000000000..88756f5fc1
--- /dev/null
+++ b/board/phytium/pomelo/ddr.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct ddr_spd {
+	/******************* read from spd *****************/
+	unsigned char  dimm_type;	/* 1: RDIMM;2: UDIMM;3: SODIMM;4: LRDIMM */
+	unsigned char  data_width;	/* 0: x4; 1: x8; 2: x16 */
+	unsigned char  mirror_type;	/* 0: stardard; 1: mirror */
+	unsigned char  ecc_type;	/* 0: no-ecc; 1:ecc */
+	unsigned char  dram_type;	/* 0xB: DDR3; 0xC: DDR4 */
+	unsigned char  rank_num;
+	unsigned char  row_num;
+	unsigned char  col_num;
+
+	unsigned char  bg_num;	/*only DDR4*/
+	unsigned char  bank_num;
+	unsigned short int module_manufacturer_id;
+	unsigned short int taamin;
+	unsigned short int trcdmin;
+
+	unsigned short int trpmin;
+	unsigned short int trasmin;
+	unsigned short int trcmin;
+	unsigned short int tfawmin;
+
+	unsigned short int trrd_smin;	/*only DDR4*/
+	unsigned short int trrd_lmin;	/*only DDR4*/
+	unsigned short int tccd_lmin;	/*only DDR4*/
+	unsigned short int twrmin;
+
+	unsigned short int twtr_smin;	/*only DDR4*/
+	unsigned short int twtr_lmin;	/*only DDR4*/
+	unsigned short int twtrmin;	/*only DDR3*/
+	unsigned short int trrdmin;	/*only DDR3*/
+
+	/******************* RCD control words *****************/
+	unsigned char  f0rc03; /*bit[3:2]:CS		bit[1:0]:CA  */
+	unsigned char  f0rc04; /*bit[3:2]:ODT		bit[1:0]:CKE */
+	unsigned char  f0rc05; /*bit[3:2]:CLK-A side	bit[1:0]:CLK-B side */
+	unsigned char  bc00;
+	unsigned char  bc01;
+	unsigned char  bc02;
+	unsigned char  bc03;
+	unsigned char  bc04;
+
+	unsigned char  bc05;
+	unsigned char  f5bc5x;
+	unsigned char  f5bc6x;
+	/******************* LRDIMM special *****************/
+	unsigned char  vrefdq_pr0;
+	unsigned char  vrefdq_mdram;
+	unsigned char  rtt_mdram_1866;
+	unsigned char  rtt_mdram_2400;
+	unsigned char  rtt_mdram_3200;
+
+	unsigned char  drive_dram;
+	unsigned char  odt_dram_1866;
+	unsigned char  odt_dram_2400;
+	unsigned char  odt_dram_3200;
+	unsigned char  park_dram_1866;
+	unsigned char  park_dram_2400;
+	unsigned char  park_dram_3200;
+	unsigned char  rcd_num;
+} __attribute((aligned(4)));
+
+struct mcu_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+
+	unsigned char ch_enable;
+	unsigned char misc1_enable;
+	unsigned char misc2_enable;
+	unsigned char force_spd_enable;
+	unsigned char misc3_enable;
+	unsigned char train_debug;
+	unsigned char train_recover;
+	unsigned char rev2[9];
+
+	struct ddr_spd ddr_spd_info[2];
+} __attribute((aligned(4)));
+
+static void get_mcu_up_info_default(struct mcu_config *pm)
+{
+	pm->magic		= PARAMETER_MCU_MAGIC;
+	pm->version		= PARAM_MCU_VERSION;
+	pm->size		= PARAM_MCU_SIZE;
+	pm->ch_enable		= PARAM_CH_ENABLE;
+	pm->misc1_enable	= PARAM_ECC_ENABLE;
+	pm->force_spd_enable	= PARAM_FORCE_SPD_DISABLE;
+	pm->misc3_enable	= PARAM_MCU_MISC_ENABLE;
+	pm->train_recover	= 0x0;
+}
+
+static unsigned char init_dimm_param(unsigned char ch, struct mcu_config *pm)
+{
+	printf("manual config dimm info...\n");
+	pm->ddr_spd_info[ch].dimm_type = UDIMM_TYPE;
+	pm->ddr_spd_info[ch].data_width = DIMM_X8;
+	pm->ddr_spd_info[ch].mirror_type = NO_MIRROR;
+	pm->ddr_spd_info[ch].ecc_type = NO_ECC_TYPE;
+	pm->ddr_spd_info[ch].dram_type = DDR4_TYPE;
+	pm->ddr_spd_info[ch].rank_num = 1;
+	pm->ddr_spd_info[ch].row_num  = 16;
+	pm->ddr_spd_info[ch].col_num = 10;
+	pm->ddr_spd_info[ch].bg_num = 4;
+	pm->ddr_spd_info[ch].bank_num = 4;
+	pm->ddr_spd_info[ch].taamin = 13750;
+	pm->ddr_spd_info[ch].trcdmin = 13750;
+
+	pm->ddr_spd_info[ch].trpmin = 13750;
+	pm->ddr_spd_info[ch].trasmin = 32000;
+	pm->ddr_spd_info[ch].trcmin =  45750;
+	pm->ddr_spd_info[ch].tfawmin = 21000;
+
+	pm->ddr_spd_info[ch].trrd_smin = 3000;
+	pm->ddr_spd_info[ch].trrd_lmin = 4900;
+	pm->ddr_spd_info[ch].tccd_lmin = 5000;
+	pm->ddr_spd_info[ch].twrmin = 15000;
+
+	pm->ddr_spd_info[ch].twtr_smin = 2500;
+	pm->ddr_spd_info[ch].twtr_lmin = 7500;
+
+	return 0;
+}
+
+void get_default_mcu_info(unsigned char *data)
+{
+	get_mcu_up_info_default((struct mcu_config *)data);
+}
+
+void fix_mcu_info(unsigned char *data)
+{
+	unsigned char ch;
+	struct mcu_config *mcu_info = (struct mcu_config *)data;
+
+	for (ch = 0; ch < 2; ch++)
+		init_dimm_param(ch, mcu_info);
+}
+
+void ddr_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	get_default_mcu_info(buffer);
+	fix_mcu_info(buffer);
+
+	arm_smccc_smc(CPU_INIT_MEM, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+	if (res.a0 != 0) {
+		printf("error x0: 0x%lx, x1: 0x%lx\n", res.a0, res.a1);
+		while (true)
+			;
+	}
+}
diff --git a/board/phytium/pomelo/pcie.c b/board/phytium/pomelo/pcie.c
new file mode 100644
index 0000000000..3754d8eb9b
--- /dev/null
+++ b/board/phytium/pomelo/pcie.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct pcu_ctr {
+	unsigned int base_config[3];
+	unsigned int equalization[3];
+	unsigned char rev[80];
+} __attribute((aligned(4)));
+
+struct pcu_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+	unsigned int independent_tree;
+	unsigned int base_cfg;
+	unsigned char rev2[16];
+	struct pcu_ctr ctr_cfg[2];
+} __attribute((aligned(4)));
+
+struct pcu_config const peu_base_info = {
+	.magic = PARAMETER_PCIE_MAGIC,
+	.version = 0x2,
+	.size = 0x100,
+	.independent_tree = CONFIG_INDEPENDENT_TREE,
+	.base_cfg = ((PCI_PEU1 | (X8X8 << 1)) << PEU1_OFFSET | (PCI_PEU0 | (X8X8 << 1))),
+	.ctr_cfg[0].base_config[0] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[0].base_config[1] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[0].base_config[2] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[1].base_config[0] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[1].base_config[1] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[1].base_config[2] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[0].equalization[0] = 0x7,
+	.ctr_cfg[0].equalization[1] = 0x7,
+	.ctr_cfg[0].equalization[2] = 0x7,
+	.ctr_cfg[1].equalization[0] = 0x7,
+	.ctr_cfg[1].equalization[1] = 0x7,
+	.ctr_cfg[1].equalization[2] = 0x7,
+};
+
+void pcie_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	memcpy(buffer, &peu_base_info, sizeof(peu_base_info));
+	arm_smccc_smc(CPU_INIT_PCIE, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+	if (res.a0 != 0) {
+		while (true)
+			;
+	}
+}
diff --git a/board/phytium/pomelo/pll.c b/board/phytium/pomelo/pll.c
new file mode 100644
index 0000000000..1227b7dd80
--- /dev/null
+++ b/board/phytium/pomelo/pll.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <asm/io.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct pll_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+	unsigned int core_pll;
+	unsigned int res1;
+	unsigned int lmu_pll;
+	unsigned int res2;
+	unsigned int res3;
+	unsigned int res4;
+	unsigned int res5;
+} __attribute((aligned(4)));
+
+struct pll_config const pll_base_info = {
+	.magic = PARAMETER_PLL_MAGIC,
+	.version = 0x1,
+	.size = 0x30,
+	.core_pll = 2300,	/*MHz*/
+	.lmu_pll = 667,		/*MHz*/
+};
+
+unsigned int get_reset_source(void)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(CPU_GET_RST_SOURCE, 0, 0, 0, 0, 0, 0, 0, &res);
+	return res.a0;
+}
+
+void pll_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	memcpy(buffer, &pll_base_info, sizeof(pll_base_info));
+	arm_smccc_smc(CPU_INIT_PLL, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+	if (res.a0 != 0) {
+		while (true)
+			;
+	}
+}
+
+void check_reset(void)
+{
+	unsigned int rst;
+
+	rst = get_reset_source();
+
+	switch (rst) {
+	case CPU_RESET_POWER_ON:
+		pll_init();
+		break;
+	case CPU_RESET_PLL:
+		break;
+	case CPU_RESET_WATCH_DOG:
+		break;
+	default:
+		while (true)
+			;
+	}
+}
diff --git a/board/phytium/pomelo/pomelo.c b/board/phytium/pomelo/pomelo.c
new file mode 100644
index 0000000000..693e891d20
--- /dev/null
+++ b/board/phytium/pomelo/pomelo.c
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <command.h>
+#include <init.h>
+#include <asm/armv8/mmu.h>
+#include <asm/io.h>
+#include <linux/arm-smccc.h>
+#include <scsi.h>
+#include "cpu.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+	gd->mem_clk = 0;
+	gd->ram_size = PHYS_SDRAM_1_SIZE;
+
+	printf("Phytium ddr init\n");
+
+	ddr_init();
+	sec_init();
+	printf("PBF relocate done\n");
+
+	return 0;
+}
+
+int board_init(void)
+{
+	return 0;
+}
+
+void reset_cpu(void)
+{
+	struct arm_smccc_res res;
+
+	printf("run in reset cpu\n");
+	arm_smccc_smc(0x84000009, 0, 0, 0, 0, 0, 0, 0, &res);
+	printf("reset cpu error, %lx\n", res.a0);
+}
+
+int mach_cpu_init(void)
+{
+	check_reset();
+	return 0;
+}
+
+int board_early_init_f(void)
+{
+	pcie_init();
+	return 0;
+}
+
+int board_early_init_r(void)
+{
+	return 0;
+}
+
+static struct mm_region pomelo_mem_map[] = {
+	{
+		.virt = 0x0UL,
+		.phys = 0x0UL,
+		.size = 0x80000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+				 PTE_BLOCK_NON_SHARE |
+				 PTE_BLOCK_PXN |
+				 PTE_BLOCK_UXN
+	},
+	{
+		.virt = (u64)PHYS_SDRAM_1,
+		.phys = (u64)PHYS_SDRAM_1,
+		.size = (u64)PHYS_SDRAM_1_SIZE,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+				 PTE_BLOCK_NS |
+				 PTE_BLOCK_INNER_SHARE
+	},
+	{
+		0,
+	}
+};
+
+struct mm_region *mem_map = pomelo_mem_map;
+
+int __asm_flush_l3_dcache(void)
+{
+	int i, pstate;
+
+	for (i = 0; i < HNF_COUNT; i++)
+		writeq(HNF_PSTATE_SFONLY, HNF_PSTATE_REQ + i * HNF_STRIDE);
+	for (i = 0; i < HNF_COUNT; i++) {
+		do {
+			pstate = readq(HNF_PSTATE_STAT + i * HNF_STRIDE);
+		} while ((pstate & 0xf) != (HNF_PSTATE_SFONLY << 2));
+	}
+
+	for (i = 0; i < HNF_COUNT; i++)
+		writeq(HNF_PSTATE_FULL, HNF_PSTATE_REQ + i * HNF_STRIDE);
+
+	return 0;
+}
+
+int last_stage_init(void)
+{
+	int ret;
+
+	/* pci e */
+	pci_init();
+	/* scsi scan */
+	ret = scsi_scan(true);
+	if (ret) {
+		printf("scsi scan failed\n");
+		return CMD_RET_FAILURE;
+	}
+	return ret;
+}
diff --git a/board/phytium/pomelo/sec.c b/board/phytium/pomelo/sec.c
new file mode 100644
index 0000000000..8ec0fa797b
--- /dev/null
+++ b/board/phytium/pomelo/sec.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct common_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+	unsigned long long  core_bit_map;
+} __attribute((aligned(4)));
+
+struct common_config const common_base_info = {
+	.magic = PARAMETER_COMMON_MAGIC,
+	.version = 0x1,
+	.core_bit_map = 0x3333,
+};
+
+void sec_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	memcpy(buffer, &common_base_info, sizeof(common_base_info));
+	arm_smccc_smc(CPU_INIT_SEC_SVC, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+
+	if (res.a0 != 0) {
+		printf("error ret %lx\n", res.a0);
+		while (true)
+			;
+	}
+}
diff --git a/configs/pomelo_defconfig b/configs/pomelo_defconfig
new file mode 100644
index 0000000000..3e6c18196d
--- /dev/null
+++ b/configs/pomelo_defconfig
@@ -0,0 +1,36 @@
+CONFIG_ARM=y
+CONFIG_ARM_SMCCC=y
+CONFIG_TARGET_POMELO=y
+CONFIG_SYS_TEXT_BASE=0x180000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x1000
+# CONFIG_PSCI_RESET is not set
+CONFIG_DEFAULT_DEVICE_TREE="phytium-pomelo"
+CONFIG_AHCI=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyAMA0,115200 earlycon=pl011,0x28001000 root=/dev/sda2 rw"
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_LAST_STAGE_INIT=y
+CONFIG_SYS_PROMPT="pomelo#"
+# CONFIG_CMD_LZMADEC is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_PCI=y
+CONFIG_OF_CONTROL=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+# CONFIG_NET is not set
+CONFIG_DM=y
+CONFIG_SCSI_AHCI=y
+CONFIG_AHCI_PCI=y
+CONFIG_BLK=y
+# CONFIG_MMC is not set
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
+CONFIG_PCI_PHYTIUM=y
+CONFIG_PCIE_ECAM_GENERIC=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
+CONFIG_DM_SERIAL=y
+CONFIG_PL01X_SERIAL=y
diff --git a/include/configs/pomelo.h b/include/configs/pomelo.h
new file mode 100644
index 0000000000..69c4195d86
--- /dev/null
+++ b/include/configs/pomelo.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#ifndef __POMELO_CONFIG_H__
+#define __POMELO_CONFIG_H__
+
+/* SDRAM Bank #1 start address */
+#define PHYS_SDRAM_1			0x80000000
+#define PHYS_SDRAM_1_SIZE		0x7B000000
+#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
+
+#define CONFIG_SYS_LOAD_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x10000000)
+
+/* SIZE of malloc pool */
+#define CONFIG_SYS_MALLOC_LEN		(1 * 1024 * 1024  + CONFIG_ENV_SIZE)
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_BOARD_EARLY_INIT_R
+
+#define CONFIG_SYS_INIT_SP_ADDR		(0x29800000 + 0x1a000)
+
+/* PCI CONFIG */
+#define CONFIG_SYS_PCI_64BIT		1
+#define CONFIG_PCI_SCAN_SHOW
+
+/* SCSI */
+#define CONFIG_SYS_SCSI_MAX_SCSI_ID	4
+#define CONFIG_SYS_SCSI_MAX_LUN		1
+#define CONFIG_SYS_SCSI_MAX_DEVICE	128
+#define CONFIG_SCSI_AHCI_PLAT
+#define CONFIG_SYS_SATA_MAX_DEVICE	4
+
+/*BOOT*/
+#define CONFIG_SYS_BOOTM_LEN		(60 * 1024 * 1024)
+
+#define CONFIG_EXTRA_ENV_SETTINGS	\
+	"load_kernel=ext4load scsi 0:1 0x90100000 uImage_old\0"	\
+	"load_fdt=ext4load scsi 0:1 0x95000000 ft-d2000.dtb\0"\
+	"boot_fdt=bootm 0x90100000 -:- 0x17c000\0"	\
+	"distro_bootcmd=run load_kernel; run boot_fdt"
+
+#endif
-- 
2.17.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH]  arm: add initial support for the Phytium Pomelo Board
@ 2021-06-21  8:31 nicholas_zheng
  0 siblings, 0 replies; 12+ messages in thread
From: nicholas_zheng @ 2021-06-21  8:31 UTC (permalink / raw)
  To: trini, bharat.gooty, rayagonda.kokatanur
  Cc: jagan, kever.yang, andre.przywara, festevam, patrick.delaunay,
	tharvey, pbrobinson, hs, lokeshvutla, d-gerlach, u-boot,
	weichangzheng

From: weichangzheng <nicholas_zheng@outlook.com>

 This adds platform code and the device tree for the Phytium Pomelo Board.
 The initial support comprises the UART and the PCIE.

Signed-off-by: weichangzheng <nicholas_zheng@outlook.com>
---
 arch/arm/Kconfig                 |   8 ++
 arch/arm/dts/Makefile            |   1 +
 arch/arm/dts/phytium-pomelo.dts  | 103 +++++++++++++++++++
 board/phytium/pomelo/Kconfig     |  12 +++
 board/phytium/pomelo/MAINTAINERS |   8 ++
 board/phytium/pomelo/Makefile    |  14 +++
 board/phytium/pomelo/cpu.h       |  73 ++++++++++++++
 board/phytium/pomelo/ddr.c       | 164 +++++++++++++++++++++++++++++++
 board/phytium/pomelo/pcie.c      |  61 ++++++++++++
 board/phytium/pomelo/pll.c       |  75 ++++++++++++++
 board/phytium/pomelo/pomelo.c    | 120 ++++++++++++++++++++++
 board/phytium/pomelo/sec.c       |  40 ++++++++
 configs/pomelo_defconfig         |  36 +++++++
 include/configs/pomelo.h         |  45 +++++++++
 14 files changed, 760 insertions(+)
 create mode 100644 arch/arm/dts/phytium-pomelo.dts
 create mode 100644 board/phytium/pomelo/Kconfig
 create mode 100644 board/phytium/pomelo/MAINTAINERS
 create mode 100644 board/phytium/pomelo/Makefile
 create mode 100644 board/phytium/pomelo/cpu.h
 create mode 100644 board/phytium/pomelo/ddr.c
 create mode 100644 board/phytium/pomelo/pcie.c
 create mode 100644 board/phytium/pomelo/pll.c
 create mode 100644 board/phytium/pomelo/pomelo.c
 create mode 100644 board/phytium/pomelo/sec.c
 create mode 100644 configs/pomelo_defconfig
 create mode 100644 include/configs/pomelo.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 31d687ea01..6110fcddad 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1800,6 +1800,13 @@ config TARGET_DURIAN
 	  Support for durian platform.
 	  It has 2GB Sdram, uart and pcie.
 
+config TARGET_POMELO
+	bool "Support Phytium Pomelo Platform"
+	select ARM64
+	help
+		Support for pomelo platform.
+		It has 2GB Sdram, uart and pcie.
+
 config TARGET_PRESIDIO_ASIC
 	bool "Support Cortina Presidio ASIC Platform"
 	select ARM64
@@ -2019,6 +2026,7 @@ source "board/toradex/colibri_pxa270/Kconfig"
 source "board/variscite/dart_6ul/Kconfig"
 source "board/vscom/baltos/Kconfig"
 source "board/phytium/durian/Kconfig"
+source "board/phytium/pomelo/Kconfig"
 source "board/xen/xenguest_arm64/Kconfig"
 source "board/keymile/Kconfig"
 
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 096068261d..c26692c17e 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1098,6 +1098,7 @@ dtb-$(CONFIG_TARGET_MX53PPD) += imx53-ppd.dtb
 dtb-$(CONFIG_TARGET_TOTAL_COMPUTE) += total_compute.dtb
 
 dtb-$(CONFIG_TARGET_DURIAN) += phytium-durian.dtb
+dtb-$(CONFIG_TARGET_POMELO) += phytium-pomelo.dtb
 
 dtb-$(CONFIG_TARGET_PRESIDIO_ASIC) += ca-presidio-engboard.dtb
 
diff --git a/arch/arm/dts/phytium-pomelo.dts b/arch/arm/dts/phytium-pomelo.dts
new file mode 100644
index 0000000000..4961682058
--- /dev/null
+++ b/arch/arm/dts/phytium-pomelo.dts
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Phytium Pomelo board
+ * Copyright (C) 2021, Phytium Ltd.
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+/dts-v1/;
+
+/memreserve/	0x0000000080000000 0x0000000000100000;
+/ {
+	model = "Phytium Pomelo";
+	compatible = "phytium,pomelo";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <0x2>;
+		#size-cells = <0x0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu4: cpu@4 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x100>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu5: cpu@5 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x101>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu8: cpu@8 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x200>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu9: cpu@9 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x201>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu12: cpu@12 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x300>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu13: cpu@13 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x301>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+	};
+
+	pcie-controller@40000000 {
+		compatible = "pci-host-ecam-generic";
+		device_type = "pci";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		reg = <0x0 0x40000000 0x0 0x10000000>;
+		bus-range = <0x0 0xff>;
+		ranges = <0x01000000 0x00 0x00000000 0x0  0x50000000 0x0  0x00F00000>,
+			 <0x02000000 0x00 0x58000000 0x0  0x58000000 0x0  0x28000000>,
+			 <0x43000000 0x10 0x00000000 0x10 0x00000000 0x10  0x00000000>;
+	};
+
+	uart@28001000 {
+		compatible = "arm,pl011";
+		reg = <0x0 0x28001000 0x0 0x1000>;
+		clock = <48000000>;
+	};
+};
diff --git a/board/phytium/pomelo/Kconfig b/board/phytium/pomelo/Kconfig
new file mode 100644
index 0000000000..281aa8feff
--- /dev/null
+++ b/board/phytium/pomelo/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_POMELO
+
+config SYS_BOARD
+	default "pomelo"
+
+config SYS_VENDOR
+	default "phytium"
+
+config SYS_CONFIG_NAME
+	default "pomelo"
+
+endif
diff --git a/board/phytium/pomelo/MAINTAINERS b/board/phytium/pomelo/MAINTAINERS
new file mode 100644
index 0000000000..950449392b
--- /dev/null
+++ b/board/phytium/pomelo/MAINTAINERS
@@ -0,0 +1,8 @@
+POMELO BOARD
+M:	lixinde <lixinde@phytium.com.cn>
+M:	weichangzheng <weichangzheng@phytium.com.cn>
+S:	Maintained
+F:	board/phytium/pomelo/*
+F:	include/configs/pomelo.h
+F:	configs/pomelo_defconfig
+
diff --git a/board/phytium/pomelo/Makefile b/board/phytium/pomelo/Makefile
new file mode 100644
index 0000000000..b9cb3609bd
--- /dev/null
+++ b/board/phytium/pomelo/Makefile
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2021
+# lixinde         <lixinde@phytium.com.cn>
+# weichangzheng   <weichangzheng@phytium.com.cn>
+#
+
+obj-y += pomelo.o
+obj-y += pll.o
+obj-y += pcie.o
+obj-y += ddr.o
+obj-y += sec.o
+
+
diff --git a/board/phytium/pomelo/cpu.h b/board/phytium/pomelo/cpu.h
new file mode 100644
index 0000000000..e15917609b
--- /dev/null
+++ b/board/phytium/pomelo/cpu.h
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2021
+ * Phytium Technology Ltd <www.phytium.com>
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#ifndef _FT_POMELO_H
+#define _FT_POMELO_H
+
+/* SMCCC ID */
+#define CPU_SVC_VERSION			0xC2000F00
+#define CPU_GET_RST_SOURCE		0xC2000F01
+#define CPU_INIT_PLL			0xC2000F02
+#define CPU_INIT_PCIE			0xC2000F03
+#define CPU_INIT_MEM			0xC2000F04
+#define CPU_INIT_SEC_SVC		0xC2000F05
+
+/*CPU RESET*/
+#define CPU_RESET_POWER_ON		0x1
+#define CPU_RESET_PLL			0x4
+#define CPU_RESET_WATCH_DOG		0x8
+
+/* PLL */
+#define PARAMETER_PLL_MAGIC		0x54460010
+
+/* PCIE */
+#define PARAMETER_PCIE_MAGIC		0x54460011
+#define CONFIG_INDEPENDENT_TREE		0x0
+#define PCI_PEU0			0x1
+#define PCI_PEU1			0x1
+#define PEU1_OFFSET			16
+#define PEU_C_OFFSET_MODE		16
+#define PEU_C_OFFSET_SPEED		0
+#define RC_MODE				0x1
+#define X8X8				0x1
+#define GEN3				3
+
+/* DDR */
+#define PARAMETER_MCU_MAGIC		0x54460014
+#define PARAM_MCU_VERSION		0x1
+#define PARAM_MCU_SIZE			0x100
+#define PARAM_CH_ENABLE			0x3
+#define PARAM_ECC_ENABLE		0x3
+#define PARAM_FORCE_SPD_DISABLE		0x0
+#define PARAM_MCU_MISC_ENABLE		0x0
+
+#define UDIMM_TYPE			0x2
+#define DIMM_X8				0x1
+#define NO_MIRROR			0x0
+#define NO_ECC_TYPE			0
+#define DDR4_TYPE			0xC
+
+/* SEC */
+#define PARAMETER_COMMON_MAGIC		0x54460013
+
+/* FLUSH L3 CASHE */
+#define HNF_COUNT			0x8
+#define HNF_PSTATE_REQ			(HNF_BASE + 0x10)
+#define HNF_PSTATE_STAT			(HNF_BASE + 0x18)
+#define HNF_PSTATE_OFF			0x0
+#define HNF_PSTATE_SFONLY		0x1
+#define HNF_PSTATE_HALF			0x2
+#define HNF_PSTATE_FULL			0x3
+#define HNF_STRIDE			0x10000
+#define HNF_BASE			(unsigned long)(0x3A200000)
+void ddr_init(void);
+void sec_init(void);
+void check_reset(void);
+void pcie_init(void);
+
+#endif /* _FT_POMELO_H */
diff --git a/board/phytium/pomelo/ddr.c b/board/phytium/pomelo/ddr.c
new file mode 100644
index 0000000000..88756f5fc1
--- /dev/null
+++ b/board/phytium/pomelo/ddr.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct ddr_spd {
+	/******************* read from spd *****************/
+	unsigned char  dimm_type;	/* 1: RDIMM;2: UDIMM;3: SODIMM;4: LRDIMM */
+	unsigned char  data_width;	/* 0: x4; 1: x8; 2: x16 */
+	unsigned char  mirror_type;	/* 0: stardard; 1: mirror */
+	unsigned char  ecc_type;	/* 0: no-ecc; 1:ecc */
+	unsigned char  dram_type;	/* 0xB: DDR3; 0xC: DDR4 */
+	unsigned char  rank_num;
+	unsigned char  row_num;
+	unsigned char  col_num;
+
+	unsigned char  bg_num;	/*only DDR4*/
+	unsigned char  bank_num;
+	unsigned short int module_manufacturer_id;
+	unsigned short int taamin;
+	unsigned short int trcdmin;
+
+	unsigned short int trpmin;
+	unsigned short int trasmin;
+	unsigned short int trcmin;
+	unsigned short int tfawmin;
+
+	unsigned short int trrd_smin;	/*only DDR4*/
+	unsigned short int trrd_lmin;	/*only DDR4*/
+	unsigned short int tccd_lmin;	/*only DDR4*/
+	unsigned short int twrmin;
+
+	unsigned short int twtr_smin;	/*only DDR4*/
+	unsigned short int twtr_lmin;	/*only DDR4*/
+	unsigned short int twtrmin;	/*only DDR3*/
+	unsigned short int trrdmin;	/*only DDR3*/
+
+	/******************* RCD control words *****************/
+	unsigned char  f0rc03; /*bit[3:2]:CS		bit[1:0]:CA  */
+	unsigned char  f0rc04; /*bit[3:2]:ODT		bit[1:0]:CKE */
+	unsigned char  f0rc05; /*bit[3:2]:CLK-A side	bit[1:0]:CLK-B side */
+	unsigned char  bc00;
+	unsigned char  bc01;
+	unsigned char  bc02;
+	unsigned char  bc03;
+	unsigned char  bc04;
+
+	unsigned char  bc05;
+	unsigned char  f5bc5x;
+	unsigned char  f5bc6x;
+	/******************* LRDIMM special *****************/
+	unsigned char  vrefdq_pr0;
+	unsigned char  vrefdq_mdram;
+	unsigned char  rtt_mdram_1866;
+	unsigned char  rtt_mdram_2400;
+	unsigned char  rtt_mdram_3200;
+
+	unsigned char  drive_dram;
+	unsigned char  odt_dram_1866;
+	unsigned char  odt_dram_2400;
+	unsigned char  odt_dram_3200;
+	unsigned char  park_dram_1866;
+	unsigned char  park_dram_2400;
+	unsigned char  park_dram_3200;
+	unsigned char  rcd_num;
+} __attribute((aligned(4)));
+
+struct mcu_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+
+	unsigned char ch_enable;
+	unsigned char misc1_enable;
+	unsigned char misc2_enable;
+	unsigned char force_spd_enable;
+	unsigned char misc3_enable;
+	unsigned char train_debug;
+	unsigned char train_recover;
+	unsigned char rev2[9];
+
+	struct ddr_spd ddr_spd_info[2];
+} __attribute((aligned(4)));
+
+static void get_mcu_up_info_default(struct mcu_config *pm)
+{
+	pm->magic		= PARAMETER_MCU_MAGIC;
+	pm->version		= PARAM_MCU_VERSION;
+	pm->size		= PARAM_MCU_SIZE;
+	pm->ch_enable		= PARAM_CH_ENABLE;
+	pm->misc1_enable	= PARAM_ECC_ENABLE;
+	pm->force_spd_enable	= PARAM_FORCE_SPD_DISABLE;
+	pm->misc3_enable	= PARAM_MCU_MISC_ENABLE;
+	pm->train_recover	= 0x0;
+}
+
+static unsigned char init_dimm_param(unsigned char ch, struct mcu_config *pm)
+{
+	printf("manual config dimm info...\n");
+	pm->ddr_spd_info[ch].dimm_type = UDIMM_TYPE;
+	pm->ddr_spd_info[ch].data_width = DIMM_X8;
+	pm->ddr_spd_info[ch].mirror_type = NO_MIRROR;
+	pm->ddr_spd_info[ch].ecc_type = NO_ECC_TYPE;
+	pm->ddr_spd_info[ch].dram_type = DDR4_TYPE;
+	pm->ddr_spd_info[ch].rank_num = 1;
+	pm->ddr_spd_info[ch].row_num  = 16;
+	pm->ddr_spd_info[ch].col_num = 10;
+	pm->ddr_spd_info[ch].bg_num = 4;
+	pm->ddr_spd_info[ch].bank_num = 4;
+	pm->ddr_spd_info[ch].taamin = 13750;
+	pm->ddr_spd_info[ch].trcdmin = 13750;
+
+	pm->ddr_spd_info[ch].trpmin = 13750;
+	pm->ddr_spd_info[ch].trasmin = 32000;
+	pm->ddr_spd_info[ch].trcmin =  45750;
+	pm->ddr_spd_info[ch].tfawmin = 21000;
+
+	pm->ddr_spd_info[ch].trrd_smin = 3000;
+	pm->ddr_spd_info[ch].trrd_lmin = 4900;
+	pm->ddr_spd_info[ch].tccd_lmin = 5000;
+	pm->ddr_spd_info[ch].twrmin = 15000;
+
+	pm->ddr_spd_info[ch].twtr_smin = 2500;
+	pm->ddr_spd_info[ch].twtr_lmin = 7500;
+
+	return 0;
+}
+
+void get_default_mcu_info(unsigned char *data)
+{
+	get_mcu_up_info_default((struct mcu_config *)data);
+}
+
+void fix_mcu_info(unsigned char *data)
+{
+	unsigned char ch;
+	struct mcu_config *mcu_info = (struct mcu_config *)data;
+
+	for (ch = 0; ch < 2; ch++)
+		init_dimm_param(ch, mcu_info);
+}
+
+void ddr_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	get_default_mcu_info(buffer);
+	fix_mcu_info(buffer);
+
+	arm_smccc_smc(CPU_INIT_MEM, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+	if (res.a0 != 0) {
+		printf("error x0: 0x%lx, x1: 0x%lx\n", res.a0, res.a1);
+		while (true)
+			;
+	}
+}
diff --git a/board/phytium/pomelo/pcie.c b/board/phytium/pomelo/pcie.c
new file mode 100644
index 0000000000..3754d8eb9b
--- /dev/null
+++ b/board/phytium/pomelo/pcie.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct pcu_ctr {
+	unsigned int base_config[3];
+	unsigned int equalization[3];
+	unsigned char rev[80];
+} __attribute((aligned(4)));
+
+struct pcu_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+	unsigned int independent_tree;
+	unsigned int base_cfg;
+	unsigned char rev2[16];
+	struct pcu_ctr ctr_cfg[2];
+} __attribute((aligned(4)));
+
+struct pcu_config const peu_base_info = {
+	.magic = PARAMETER_PCIE_MAGIC,
+	.version = 0x2,
+	.size = 0x100,
+	.independent_tree = CONFIG_INDEPENDENT_TREE,
+	.base_cfg = ((PCI_PEU1 | (X8X8 << 1)) << PEU1_OFFSET | (PCI_PEU0 | (X8X8 << 1))),
+	.ctr_cfg[0].base_config[0] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[0].base_config[1] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[0].base_config[2] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[1].base_config[0] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[1].base_config[1] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[1].base_config[2] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[0].equalization[0] = 0x7,
+	.ctr_cfg[0].equalization[1] = 0x7,
+	.ctr_cfg[0].equalization[2] = 0x7,
+	.ctr_cfg[1].equalization[0] = 0x7,
+	.ctr_cfg[1].equalization[1] = 0x7,
+	.ctr_cfg[1].equalization[2] = 0x7,
+};
+
+void pcie_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	memcpy(buffer, &peu_base_info, sizeof(peu_base_info));
+	arm_smccc_smc(CPU_INIT_PCIE, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+	if (res.a0 != 0) {
+		while (true)
+			;
+	}
+}
diff --git a/board/phytium/pomelo/pll.c b/board/phytium/pomelo/pll.c
new file mode 100644
index 0000000000..1227b7dd80
--- /dev/null
+++ b/board/phytium/pomelo/pll.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <asm/io.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct pll_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+	unsigned int core_pll;
+	unsigned int res1;
+	unsigned int lmu_pll;
+	unsigned int res2;
+	unsigned int res3;
+	unsigned int res4;
+	unsigned int res5;
+} __attribute((aligned(4)));
+
+struct pll_config const pll_base_info = {
+	.magic = PARAMETER_PLL_MAGIC,
+	.version = 0x1,
+	.size = 0x30,
+	.core_pll = 2300,	/*MHz*/
+	.lmu_pll = 667,		/*MHz*/
+};
+
+unsigned int get_reset_source(void)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(CPU_GET_RST_SOURCE, 0, 0, 0, 0, 0, 0, 0, &res);
+	return res.a0;
+}
+
+void pll_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	memcpy(buffer, &pll_base_info, sizeof(pll_base_info));
+	arm_smccc_smc(CPU_INIT_PLL, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+	if (res.a0 != 0) {
+		while (true)
+			;
+	}
+}
+
+void check_reset(void)
+{
+	unsigned int rst;
+
+	rst = get_reset_source();
+
+	switch (rst) {
+	case CPU_RESET_POWER_ON:
+		pll_init();
+		break;
+	case CPU_RESET_PLL:
+		break;
+	case CPU_RESET_WATCH_DOG:
+		break;
+	default:
+		while (true)
+			;
+	}
+}
diff --git a/board/phytium/pomelo/pomelo.c b/board/phytium/pomelo/pomelo.c
new file mode 100644
index 0000000000..693e891d20
--- /dev/null
+++ b/board/phytium/pomelo/pomelo.c
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <command.h>
+#include <init.h>
+#include <asm/armv8/mmu.h>
+#include <asm/io.h>
+#include <linux/arm-smccc.h>
+#include <scsi.h>
+#include "cpu.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+	gd->mem_clk = 0;
+	gd->ram_size = PHYS_SDRAM_1_SIZE;
+
+	printf("Phytium ddr init\n");
+
+	ddr_init();
+	sec_init();
+	printf("PBF relocate done\n");
+
+	return 0;
+}
+
+int board_init(void)
+{
+	return 0;
+}
+
+void reset_cpu(void)
+{
+	struct arm_smccc_res res;
+
+	printf("run in reset cpu\n");
+	arm_smccc_smc(0x84000009, 0, 0, 0, 0, 0, 0, 0, &res);
+	printf("reset cpu error, %lx\n", res.a0);
+}
+
+int mach_cpu_init(void)
+{
+	check_reset();
+	return 0;
+}
+
+int board_early_init_f(void)
+{
+	pcie_init();
+	return 0;
+}
+
+int board_early_init_r(void)
+{
+	return 0;
+}
+
+static struct mm_region pomelo_mem_map[] = {
+	{
+		.virt = 0x0UL,
+		.phys = 0x0UL,
+		.size = 0x80000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+				 PTE_BLOCK_NON_SHARE |
+				 PTE_BLOCK_PXN |
+				 PTE_BLOCK_UXN
+	},
+	{
+		.virt = (u64)PHYS_SDRAM_1,
+		.phys = (u64)PHYS_SDRAM_1,
+		.size = (u64)PHYS_SDRAM_1_SIZE,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+				 PTE_BLOCK_NS |
+				 PTE_BLOCK_INNER_SHARE
+	},
+	{
+		0,
+	}
+};
+
+struct mm_region *mem_map = pomelo_mem_map;
+
+int __asm_flush_l3_dcache(void)
+{
+	int i, pstate;
+
+	for (i = 0; i < HNF_COUNT; i++)
+		writeq(HNF_PSTATE_SFONLY, HNF_PSTATE_REQ + i * HNF_STRIDE);
+	for (i = 0; i < HNF_COUNT; i++) {
+		do {
+			pstate = readq(HNF_PSTATE_STAT + i * HNF_STRIDE);
+		} while ((pstate & 0xf) != (HNF_PSTATE_SFONLY << 2));
+	}
+
+	for (i = 0; i < HNF_COUNT; i++)
+		writeq(HNF_PSTATE_FULL, HNF_PSTATE_REQ + i * HNF_STRIDE);
+
+	return 0;
+}
+
+int last_stage_init(void)
+{
+	int ret;
+
+	/* pci e */
+	pci_init();
+	/* scsi scan */
+	ret = scsi_scan(true);
+	if (ret) {
+		printf("scsi scan failed\n");
+		return CMD_RET_FAILURE;
+	}
+	return ret;
+}
diff --git a/board/phytium/pomelo/sec.c b/board/phytium/pomelo/sec.c
new file mode 100644
index 0000000000..8ec0fa797b
--- /dev/null
+++ b/board/phytium/pomelo/sec.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct common_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+	unsigned long long  core_bit_map;
+} __attribute((aligned(4)));
+
+struct common_config const common_base_info = {
+	.magic = PARAMETER_COMMON_MAGIC,
+	.version = 0x1,
+	.core_bit_map = 0x3333,
+};
+
+void sec_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	memcpy(buffer, &common_base_info, sizeof(common_base_info));
+	arm_smccc_smc(CPU_INIT_SEC_SVC, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+
+	if (res.a0 != 0) {
+		printf("error ret %lx\n", res.a0);
+		while (true)
+			;
+	}
+}
diff --git a/configs/pomelo_defconfig b/configs/pomelo_defconfig
new file mode 100644
index 0000000000..3e6c18196d
--- /dev/null
+++ b/configs/pomelo_defconfig
@@ -0,0 +1,36 @@
+CONFIG_ARM=y
+CONFIG_ARM_SMCCC=y
+CONFIG_TARGET_POMELO=y
+CONFIG_SYS_TEXT_BASE=0x180000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x1000
+# CONFIG_PSCI_RESET is not set
+CONFIG_DEFAULT_DEVICE_TREE="phytium-pomelo"
+CONFIG_AHCI=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyAMA0,115200 earlycon=pl011,0x28001000 root=/dev/sda2 rw"
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_LAST_STAGE_INIT=y
+CONFIG_SYS_PROMPT="pomelo#"
+# CONFIG_CMD_LZMADEC is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_PCI=y
+CONFIG_OF_CONTROL=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+# CONFIG_NET is not set
+CONFIG_DM=y
+CONFIG_SCSI_AHCI=y
+CONFIG_AHCI_PCI=y
+CONFIG_BLK=y
+# CONFIG_MMC is not set
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
+CONFIG_PCI_PHYTIUM=y
+CONFIG_PCIE_ECAM_GENERIC=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
+CONFIG_DM_SERIAL=y
+CONFIG_PL01X_SERIAL=y
diff --git a/include/configs/pomelo.h b/include/configs/pomelo.h
new file mode 100644
index 0000000000..69c4195d86
--- /dev/null
+++ b/include/configs/pomelo.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#ifndef __POMELO_CONFIG_H__
+#define __POMELO_CONFIG_H__
+
+/* SDRAM Bank #1 start address */
+#define PHYS_SDRAM_1			0x80000000
+#define PHYS_SDRAM_1_SIZE		0x7B000000
+#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
+
+#define CONFIG_SYS_LOAD_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x10000000)
+
+/* SIZE of malloc pool */
+#define CONFIG_SYS_MALLOC_LEN		(1 * 1024 * 1024  + CONFIG_ENV_SIZE)
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_BOARD_EARLY_INIT_R
+
+#define CONFIG_SYS_INIT_SP_ADDR		(0x29800000 + 0x1a000)
+
+/* PCI CONFIG */
+#define CONFIG_SYS_PCI_64BIT		1
+#define CONFIG_PCI_SCAN_SHOW
+
+/* SCSI */
+#define CONFIG_SYS_SCSI_MAX_SCSI_ID	4
+#define CONFIG_SYS_SCSI_MAX_LUN		1
+#define CONFIG_SYS_SCSI_MAX_DEVICE	128
+#define CONFIG_SCSI_AHCI_PLAT
+#define CONFIG_SYS_SATA_MAX_DEVICE	4
+
+/*BOOT*/
+#define CONFIG_SYS_BOOTM_LEN		(60 * 1024 * 1024)
+
+#define CONFIG_EXTRA_ENV_SETTINGS	\
+	"load_kernel=ext4load scsi 0:1 0x90100000 uImage_old\0"	\
+	"load_fdt=ext4load scsi 0:1 0x95000000 ft-d2000.dtb\0"\
+	"boot_fdt=bootm 0x90100000 -:- 0x17c000\0"	\
+	"distro_bootcmd=run load_kernel; run boot_fdt"
+
+#endif
-- 
2.17.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH]  arm: add initial support for the Phytium Pomelo Board
@ 2021-06-21  8:18 nicholas_zheng
  0 siblings, 0 replies; 12+ messages in thread
From: nicholas_zheng @ 2021-06-21  8:18 UTC (permalink / raw)
  To: trini, bharat.gooty, rayagonda.kokatanur
  Cc: jagan, kever.yang, andre.przywara, festevam, patrick.delaunay,
	tharvey, pbrobinson, hs, lokeshvutla, d-gerlach, u-boot,
	weichangzheng

From: weichangzheng <nicholas_zheng@outlook.com>

 This adds platform code and the device tree for the Phytium Pomelo Board.
 The initial support comprises the UART and the PCIE.

Signed-off-by: weichangzheng <nicholas_zheng@outlook.com>
---
 arch/arm/Kconfig                 |   8 ++
 arch/arm/dts/Makefile            |   1 +
 arch/arm/dts/phytium-pomelo.dts  | 103 +++++++++++++++++++
 board/phytium/pomelo/Kconfig     |  12 +++
 board/phytium/pomelo/MAINTAINERS |   8 ++
 board/phytium/pomelo/Makefile    |  14 +++
 board/phytium/pomelo/cpu.h       |  73 ++++++++++++++
 board/phytium/pomelo/ddr.c       | 164 +++++++++++++++++++++++++++++++
 board/phytium/pomelo/pcie.c      |  61 ++++++++++++
 board/phytium/pomelo/pll.c       |  75 ++++++++++++++
 board/phytium/pomelo/pomelo.c    | 120 ++++++++++++++++++++++
 board/phytium/pomelo/sec.c       |  40 ++++++++
 configs/pomelo_defconfig         |  36 +++++++
 include/configs/pomelo.h         |  45 +++++++++
 14 files changed, 760 insertions(+)
 create mode 100644 arch/arm/dts/phytium-pomelo.dts
 create mode 100644 board/phytium/pomelo/Kconfig
 create mode 100644 board/phytium/pomelo/MAINTAINERS
 create mode 100644 board/phytium/pomelo/Makefile
 create mode 100644 board/phytium/pomelo/cpu.h
 create mode 100644 board/phytium/pomelo/ddr.c
 create mode 100644 board/phytium/pomelo/pcie.c
 create mode 100644 board/phytium/pomelo/pll.c
 create mode 100644 board/phytium/pomelo/pomelo.c
 create mode 100644 board/phytium/pomelo/sec.c
 create mode 100644 configs/pomelo_defconfig
 create mode 100644 include/configs/pomelo.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 31d687ea01..6110fcddad 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1800,6 +1800,13 @@ config TARGET_DURIAN
 	  Support for durian platform.
 	  It has 2GB Sdram, uart and pcie.
 
+config TARGET_POMELO
+	bool "Support Phytium Pomelo Platform"
+	select ARM64
+	help
+		Support for pomelo platform.
+		It has 2GB Sdram, uart and pcie.
+
 config TARGET_PRESIDIO_ASIC
 	bool "Support Cortina Presidio ASIC Platform"
 	select ARM64
@@ -2019,6 +2026,7 @@ source "board/toradex/colibri_pxa270/Kconfig"
 source "board/variscite/dart_6ul/Kconfig"
 source "board/vscom/baltos/Kconfig"
 source "board/phytium/durian/Kconfig"
+source "board/phytium/pomelo/Kconfig"
 source "board/xen/xenguest_arm64/Kconfig"
 source "board/keymile/Kconfig"
 
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 096068261d..c26692c17e 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1098,6 +1098,7 @@ dtb-$(CONFIG_TARGET_MX53PPD) += imx53-ppd.dtb
 dtb-$(CONFIG_TARGET_TOTAL_COMPUTE) += total_compute.dtb
 
 dtb-$(CONFIG_TARGET_DURIAN) += phytium-durian.dtb
+dtb-$(CONFIG_TARGET_POMELO) += phytium-pomelo.dtb
 
 dtb-$(CONFIG_TARGET_PRESIDIO_ASIC) += ca-presidio-engboard.dtb
 
diff --git a/arch/arm/dts/phytium-pomelo.dts b/arch/arm/dts/phytium-pomelo.dts
new file mode 100644
index 0000000000..4961682058
--- /dev/null
+++ b/arch/arm/dts/phytium-pomelo.dts
@@ -0,0 +1,103 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * dts file for Phytium Pomelo board
+ * Copyright (C) 2021, Phytium Ltd.
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+/dts-v1/;
+
+/memreserve/	0x0000000080000000 0x0000000000100000;
+/ {
+	model = "Phytium Pomelo";
+	compatible = "phytium,pomelo";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	cpus {
+		#address-cells = <0x2>;
+		#size-cells = <0x0>;
+
+		cpu0: cpu@0 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x0>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu1: cpu@1 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x1>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu4: cpu@4 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x100>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu5: cpu@5 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x101>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu8: cpu@8 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x200>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu9: cpu@9 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x201>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu12: cpu@12 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x300>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+
+		cpu13: cpu@13 {
+			device_type = "cpu";
+			compatible = "arm,armv8";
+			reg = <0x0 0x301>;
+			enable-method = "psci";
+			numa-node-id = <0>;
+		};
+	};
+
+	pcie-controller@40000000 {
+		compatible = "pci-host-ecam-generic";
+		device_type = "pci";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		reg = <0x0 0x40000000 0x0 0x10000000>;
+		bus-range = <0x0 0xff>;
+		ranges = <0x01000000 0x00 0x00000000 0x0  0x50000000 0x0  0x00F00000>,
+			 <0x02000000 0x00 0x58000000 0x0  0x58000000 0x0  0x28000000>,
+			 <0x43000000 0x10 0x00000000 0x10 0x00000000 0x10  0x00000000>;
+	};
+
+	uart@28001000 {
+		compatible = "arm,pl011";
+		reg = <0x0 0x28001000 0x0 0x1000>;
+		clock = <48000000>;
+	};
+};
diff --git a/board/phytium/pomelo/Kconfig b/board/phytium/pomelo/Kconfig
new file mode 100644
index 0000000000..281aa8feff
--- /dev/null
+++ b/board/phytium/pomelo/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_POMELO
+
+config SYS_BOARD
+	default "pomelo"
+
+config SYS_VENDOR
+	default "phytium"
+
+config SYS_CONFIG_NAME
+	default "pomelo"
+
+endif
diff --git a/board/phytium/pomelo/MAINTAINERS b/board/phytium/pomelo/MAINTAINERS
new file mode 100644
index 0000000000..950449392b
--- /dev/null
+++ b/board/phytium/pomelo/MAINTAINERS
@@ -0,0 +1,8 @@
+POMELO BOARD
+M:	lixinde <lixinde@phytium.com.cn>
+M:	weichangzheng <weichangzheng@phytium.com.cn>
+S:	Maintained
+F:	board/phytium/pomelo/*
+F:	include/configs/pomelo.h
+F:	configs/pomelo_defconfig
+
diff --git a/board/phytium/pomelo/Makefile b/board/phytium/pomelo/Makefile
new file mode 100644
index 0000000000..b9cb3609bd
--- /dev/null
+++ b/board/phytium/pomelo/Makefile
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2021
+# lixinde         <lixinde@phytium.com.cn>
+# weichangzheng   <weichangzheng@phytium.com.cn>
+#
+
+obj-y += pomelo.o
+obj-y += pll.o
+obj-y += pcie.o
+obj-y += ddr.o
+obj-y += sec.o
+
+
diff --git a/board/phytium/pomelo/cpu.h b/board/phytium/pomelo/cpu.h
new file mode 100644
index 0000000000..e15917609b
--- /dev/null
+++ b/board/phytium/pomelo/cpu.h
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2021
+ * Phytium Technology Ltd <www.phytium.com>
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#ifndef _FT_POMELO_H
+#define _FT_POMELO_H
+
+/* SMCCC ID */
+#define CPU_SVC_VERSION			0xC2000F00
+#define CPU_GET_RST_SOURCE		0xC2000F01
+#define CPU_INIT_PLL			0xC2000F02
+#define CPU_INIT_PCIE			0xC2000F03
+#define CPU_INIT_MEM			0xC2000F04
+#define CPU_INIT_SEC_SVC		0xC2000F05
+
+/*CPU RESET*/
+#define CPU_RESET_POWER_ON		0x1
+#define CPU_RESET_PLL			0x4
+#define CPU_RESET_WATCH_DOG		0x8
+
+/* PLL */
+#define PARAMETER_PLL_MAGIC		0x54460010
+
+/* PCIE */
+#define PARAMETER_PCIE_MAGIC		0x54460011
+#define CONFIG_INDEPENDENT_TREE		0x0
+#define PCI_PEU0			0x1
+#define PCI_PEU1			0x1
+#define PEU1_OFFSET			16
+#define PEU_C_OFFSET_MODE		16
+#define PEU_C_OFFSET_SPEED		0
+#define RC_MODE				0x1
+#define X8X8				0x1
+#define GEN3				3
+
+/* DDR */
+#define PARAMETER_MCU_MAGIC		0x54460014
+#define PARAM_MCU_VERSION		0x1
+#define PARAM_MCU_SIZE			0x100
+#define PARAM_CH_ENABLE			0x3
+#define PARAM_ECC_ENABLE		0x3
+#define PARAM_FORCE_SPD_DISABLE		0x0
+#define PARAM_MCU_MISC_ENABLE		0x0
+
+#define UDIMM_TYPE			0x2
+#define DIMM_X8				0x1
+#define NO_MIRROR			0x0
+#define NO_ECC_TYPE			0
+#define DDR4_TYPE			0xC
+
+/* SEC */
+#define PARAMETER_COMMON_MAGIC		0x54460013
+
+/* FLUSH L3 CASHE */
+#define HNF_COUNT			0x8
+#define HNF_PSTATE_REQ			(HNF_BASE + 0x10)
+#define HNF_PSTATE_STAT			(HNF_BASE + 0x18)
+#define HNF_PSTATE_OFF			0x0
+#define HNF_PSTATE_SFONLY		0x1
+#define HNF_PSTATE_HALF			0x2
+#define HNF_PSTATE_FULL			0x3
+#define HNF_STRIDE			0x10000
+#define HNF_BASE			(unsigned long)(0x3A200000)
+void ddr_init(void);
+void sec_init(void);
+void check_reset(void);
+void pcie_init(void);
+
+#endif /* _FT_POMELO_H */
diff --git a/board/phytium/pomelo/ddr.c b/board/phytium/pomelo/ddr.c
new file mode 100644
index 0000000000..88756f5fc1
--- /dev/null
+++ b/board/phytium/pomelo/ddr.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct ddr_spd {
+	/******************* read from spd *****************/
+	unsigned char  dimm_type;	/* 1: RDIMM;2: UDIMM;3: SODIMM;4: LRDIMM */
+	unsigned char  data_width;	/* 0: x4; 1: x8; 2: x16 */
+	unsigned char  mirror_type;	/* 0: stardard; 1: mirror */
+	unsigned char  ecc_type;	/* 0: no-ecc; 1:ecc */
+	unsigned char  dram_type;	/* 0xB: DDR3; 0xC: DDR4 */
+	unsigned char  rank_num;
+	unsigned char  row_num;
+	unsigned char  col_num;
+
+	unsigned char  bg_num;	/*only DDR4*/
+	unsigned char  bank_num;
+	unsigned short int module_manufacturer_id;
+	unsigned short int taamin;
+	unsigned short int trcdmin;
+
+	unsigned short int trpmin;
+	unsigned short int trasmin;
+	unsigned short int trcmin;
+	unsigned short int tfawmin;
+
+	unsigned short int trrd_smin;	/*only DDR4*/
+	unsigned short int trrd_lmin;	/*only DDR4*/
+	unsigned short int tccd_lmin;	/*only DDR4*/
+	unsigned short int twrmin;
+
+	unsigned short int twtr_smin;	/*only DDR4*/
+	unsigned short int twtr_lmin;	/*only DDR4*/
+	unsigned short int twtrmin;	/*only DDR3*/
+	unsigned short int trrdmin;	/*only DDR3*/
+
+	/******************* RCD control words *****************/
+	unsigned char  f0rc03; /*bit[3:2]:CS		bit[1:0]:CA  */
+	unsigned char  f0rc04; /*bit[3:2]:ODT		bit[1:0]:CKE */
+	unsigned char  f0rc05; /*bit[3:2]:CLK-A side	bit[1:0]:CLK-B side */
+	unsigned char  bc00;
+	unsigned char  bc01;
+	unsigned char  bc02;
+	unsigned char  bc03;
+	unsigned char  bc04;
+
+	unsigned char  bc05;
+	unsigned char  f5bc5x;
+	unsigned char  f5bc6x;
+	/******************* LRDIMM special *****************/
+	unsigned char  vrefdq_pr0;
+	unsigned char  vrefdq_mdram;
+	unsigned char  rtt_mdram_1866;
+	unsigned char  rtt_mdram_2400;
+	unsigned char  rtt_mdram_3200;
+
+	unsigned char  drive_dram;
+	unsigned char  odt_dram_1866;
+	unsigned char  odt_dram_2400;
+	unsigned char  odt_dram_3200;
+	unsigned char  park_dram_1866;
+	unsigned char  park_dram_2400;
+	unsigned char  park_dram_3200;
+	unsigned char  rcd_num;
+} __attribute((aligned(4)));
+
+struct mcu_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+
+	unsigned char ch_enable;
+	unsigned char misc1_enable;
+	unsigned char misc2_enable;
+	unsigned char force_spd_enable;
+	unsigned char misc3_enable;
+	unsigned char train_debug;
+	unsigned char train_recover;
+	unsigned char rev2[9];
+
+	struct ddr_spd ddr_spd_info[2];
+} __attribute((aligned(4)));
+
+static void get_mcu_up_info_default(struct mcu_config *pm)
+{
+	pm->magic		= PARAMETER_MCU_MAGIC;
+	pm->version		= PARAM_MCU_VERSION;
+	pm->size		= PARAM_MCU_SIZE;
+	pm->ch_enable		= PARAM_CH_ENABLE;
+	pm->misc1_enable	= PARAM_ECC_ENABLE;
+	pm->force_spd_enable	= PARAM_FORCE_SPD_DISABLE;
+	pm->misc3_enable	= PARAM_MCU_MISC_ENABLE;
+	pm->train_recover	= 0x0;
+}
+
+static unsigned char init_dimm_param(unsigned char ch, struct mcu_config *pm)
+{
+	printf("manual config dimm info...\n");
+	pm->ddr_spd_info[ch].dimm_type = UDIMM_TYPE;
+	pm->ddr_spd_info[ch].data_width = DIMM_X8;
+	pm->ddr_spd_info[ch].mirror_type = NO_MIRROR;
+	pm->ddr_spd_info[ch].ecc_type = NO_ECC_TYPE;
+	pm->ddr_spd_info[ch].dram_type = DDR4_TYPE;
+	pm->ddr_spd_info[ch].rank_num = 1;
+	pm->ddr_spd_info[ch].row_num  = 16;
+	pm->ddr_spd_info[ch].col_num = 10;
+	pm->ddr_spd_info[ch].bg_num = 4;
+	pm->ddr_spd_info[ch].bank_num = 4;
+	pm->ddr_spd_info[ch].taamin = 13750;
+	pm->ddr_spd_info[ch].trcdmin = 13750;
+
+	pm->ddr_spd_info[ch].trpmin = 13750;
+	pm->ddr_spd_info[ch].trasmin = 32000;
+	pm->ddr_spd_info[ch].trcmin =  45750;
+	pm->ddr_spd_info[ch].tfawmin = 21000;
+
+	pm->ddr_spd_info[ch].trrd_smin = 3000;
+	pm->ddr_spd_info[ch].trrd_lmin = 4900;
+	pm->ddr_spd_info[ch].tccd_lmin = 5000;
+	pm->ddr_spd_info[ch].twrmin = 15000;
+
+	pm->ddr_spd_info[ch].twtr_smin = 2500;
+	pm->ddr_spd_info[ch].twtr_lmin = 7500;
+
+	return 0;
+}
+
+void get_default_mcu_info(unsigned char *data)
+{
+	get_mcu_up_info_default((struct mcu_config *)data);
+}
+
+void fix_mcu_info(unsigned char *data)
+{
+	unsigned char ch;
+	struct mcu_config *mcu_info = (struct mcu_config *)data;
+
+	for (ch = 0; ch < 2; ch++)
+		init_dimm_param(ch, mcu_info);
+}
+
+void ddr_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	get_default_mcu_info(buffer);
+	fix_mcu_info(buffer);
+
+	arm_smccc_smc(CPU_INIT_MEM, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+	if (res.a0 != 0) {
+		printf("error x0: 0x%lx, x1: 0x%lx\n", res.a0, res.a1);
+		while (true)
+			;
+	}
+}
diff --git a/board/phytium/pomelo/pcie.c b/board/phytium/pomelo/pcie.c
new file mode 100644
index 0000000000..3754d8eb9b
--- /dev/null
+++ b/board/phytium/pomelo/pcie.c
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct pcu_ctr {
+	unsigned int base_config[3];
+	unsigned int equalization[3];
+	unsigned char rev[80];
+} __attribute((aligned(4)));
+
+struct pcu_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+	unsigned int independent_tree;
+	unsigned int base_cfg;
+	unsigned char rev2[16];
+	struct pcu_ctr ctr_cfg[2];
+} __attribute((aligned(4)));
+
+struct pcu_config const peu_base_info = {
+	.magic = PARAMETER_PCIE_MAGIC,
+	.version = 0x2,
+	.size = 0x100,
+	.independent_tree = CONFIG_INDEPENDENT_TREE,
+	.base_cfg = ((PCI_PEU1 | (X8X8 << 1)) << PEU1_OFFSET | (PCI_PEU0 | (X8X8 << 1))),
+	.ctr_cfg[0].base_config[0] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[0].base_config[1] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[0].base_config[2] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[1].base_config[0] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[1].base_config[1] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[1].base_config[2] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[0].equalization[0] = 0x7,
+	.ctr_cfg[0].equalization[1] = 0x7,
+	.ctr_cfg[0].equalization[2] = 0x7,
+	.ctr_cfg[1].equalization[0] = 0x7,
+	.ctr_cfg[1].equalization[1] = 0x7,
+	.ctr_cfg[1].equalization[2] = 0x7,
+};
+
+void pcie_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	memcpy(buffer, &peu_base_info, sizeof(peu_base_info));
+	arm_smccc_smc(CPU_INIT_PCIE, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+	if (res.a0 != 0) {
+		while (true)
+			;
+	}
+}
diff --git a/board/phytium/pomelo/pll.c b/board/phytium/pomelo/pll.c
new file mode 100644
index 0000000000..1227b7dd80
--- /dev/null
+++ b/board/phytium/pomelo/pll.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <asm/io.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct pll_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+	unsigned int core_pll;
+	unsigned int res1;
+	unsigned int lmu_pll;
+	unsigned int res2;
+	unsigned int res3;
+	unsigned int res4;
+	unsigned int res5;
+} __attribute((aligned(4)));
+
+struct pll_config const pll_base_info = {
+	.magic = PARAMETER_PLL_MAGIC,
+	.version = 0x1,
+	.size = 0x30,
+	.core_pll = 2300,	/*MHz*/
+	.lmu_pll = 667,		/*MHz*/
+};
+
+unsigned int get_reset_source(void)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(CPU_GET_RST_SOURCE, 0, 0, 0, 0, 0, 0, 0, &res);
+	return res.a0;
+}
+
+void pll_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	memcpy(buffer, &pll_base_info, sizeof(pll_base_info));
+	arm_smccc_smc(CPU_INIT_PLL, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+	if (res.a0 != 0) {
+		while (true)
+			;
+	}
+}
+
+void check_reset(void)
+{
+	unsigned int rst;
+
+	rst = get_reset_source();
+
+	switch (rst) {
+	case CPU_RESET_POWER_ON:
+		pll_init();
+		break;
+	case CPU_RESET_PLL:
+		break;
+	case CPU_RESET_WATCH_DOG:
+		break;
+	default:
+		while (true)
+			;
+	}
+}
diff --git a/board/phytium/pomelo/pomelo.c b/board/phytium/pomelo/pomelo.c
new file mode 100644
index 0000000000..693e891d20
--- /dev/null
+++ b/board/phytium/pomelo/pomelo.c
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <command.h>
+#include <init.h>
+#include <asm/armv8/mmu.h>
+#include <asm/io.h>
+#include <linux/arm-smccc.h>
+#include <scsi.h>
+#include "cpu.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+	gd->mem_clk = 0;
+	gd->ram_size = PHYS_SDRAM_1_SIZE;
+
+	printf("Phytium ddr init\n");
+
+	ddr_init();
+	sec_init();
+	printf("PBF relocate done\n");
+
+	return 0;
+}
+
+int board_init(void)
+{
+	return 0;
+}
+
+void reset_cpu(void)
+{
+	struct arm_smccc_res res;
+
+	printf("run in reset cpu\n");
+	arm_smccc_smc(0x84000009, 0, 0, 0, 0, 0, 0, 0, &res);
+	printf("reset cpu error, %lx\n", res.a0);
+}
+
+int mach_cpu_init(void)
+{
+	check_reset();
+	return 0;
+}
+
+int board_early_init_f(void)
+{
+	pcie_init();
+	return 0;
+}
+
+int board_early_init_r(void)
+{
+	return 0;
+}
+
+static struct mm_region pomelo_mem_map[] = {
+	{
+		.virt = 0x0UL,
+		.phys = 0x0UL,
+		.size = 0x80000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+				 PTE_BLOCK_NON_SHARE |
+				 PTE_BLOCK_PXN |
+				 PTE_BLOCK_UXN
+	},
+	{
+		.virt = (u64)PHYS_SDRAM_1,
+		.phys = (u64)PHYS_SDRAM_1,
+		.size = (u64)PHYS_SDRAM_1_SIZE,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+				 PTE_BLOCK_NS |
+				 PTE_BLOCK_INNER_SHARE
+	},
+	{
+		0,
+	}
+};
+
+struct mm_region *mem_map = pomelo_mem_map;
+
+int __asm_flush_l3_dcache(void)
+{
+	int i, pstate;
+
+	for (i = 0; i < HNF_COUNT; i++)
+		writeq(HNF_PSTATE_SFONLY, HNF_PSTATE_REQ + i * HNF_STRIDE);
+	for (i = 0; i < HNF_COUNT; i++) {
+		do {
+			pstate = readq(HNF_PSTATE_STAT + i * HNF_STRIDE);
+		} while ((pstate & 0xf) != (HNF_PSTATE_SFONLY << 2));
+	}
+
+	for (i = 0; i < HNF_COUNT; i++)
+		writeq(HNF_PSTATE_FULL, HNF_PSTATE_REQ + i * HNF_STRIDE);
+
+	return 0;
+}
+
+int last_stage_init(void)
+{
+	int ret;
+
+	/* pci e */
+	pci_init();
+	/* scsi scan */
+	ret = scsi_scan(true);
+	if (ret) {
+		printf("scsi scan failed\n");
+		return CMD_RET_FAILURE;
+	}
+	return ret;
+}
diff --git a/board/phytium/pomelo/sec.c b/board/phytium/pomelo/sec.c
new file mode 100644
index 0000000000..8ec0fa797b
--- /dev/null
+++ b/board/phytium/pomelo/sec.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct common_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+	unsigned long long  core_bit_map;
+} __attribute((aligned(4)));
+
+struct common_config const common_base_info = {
+	.magic = PARAMETER_COMMON_MAGIC,
+	.version = 0x1,
+	.core_bit_map = 0x3333,
+};
+
+void sec_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	memcpy(buffer, &common_base_info, sizeof(common_base_info));
+	arm_smccc_smc(CPU_INIT_SEC_SVC, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+
+	if (res.a0 != 0) {
+		printf("error ret %lx\n", res.a0);
+		while (true)
+			;
+	}
+}
diff --git a/configs/pomelo_defconfig b/configs/pomelo_defconfig
new file mode 100644
index 0000000000..3e6c18196d
--- /dev/null
+++ b/configs/pomelo_defconfig
@@ -0,0 +1,36 @@
+CONFIG_ARM=y
+CONFIG_ARM_SMCCC=y
+CONFIG_TARGET_POMELO=y
+CONFIG_SYS_TEXT_BASE=0x180000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x1000
+# CONFIG_PSCI_RESET is not set
+CONFIG_DEFAULT_DEVICE_TREE="phytium-pomelo"
+CONFIG_AHCI=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyAMA0,115200 earlycon=pl011,0x28001000 root=/dev/sda2 rw"
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_LAST_STAGE_INIT=y
+CONFIG_SYS_PROMPT="pomelo#"
+# CONFIG_CMD_LZMADEC is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_PCI=y
+CONFIG_OF_CONTROL=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+# CONFIG_NET is not set
+CONFIG_DM=y
+CONFIG_SCSI_AHCI=y
+CONFIG_AHCI_PCI=y
+CONFIG_BLK=y
+# CONFIG_MMC is not set
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
+CONFIG_PCI_PHYTIUM=y
+CONFIG_PCIE_ECAM_GENERIC=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
+CONFIG_DM_SERIAL=y
+CONFIG_PL01X_SERIAL=y
diff --git a/include/configs/pomelo.h b/include/configs/pomelo.h
new file mode 100644
index 0000000000..69c4195d86
--- /dev/null
+++ b/include/configs/pomelo.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#ifndef __POMELO_CONFIG_H__
+#define __POMELO_CONFIG_H__
+
+/* SDRAM Bank #1 start address */
+#define PHYS_SDRAM_1			0x80000000
+#define PHYS_SDRAM_1_SIZE		0x7B000000
+#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
+
+#define CONFIG_SYS_LOAD_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x10000000)
+
+/* SIZE of malloc pool */
+#define CONFIG_SYS_MALLOC_LEN		(1 * 1024 * 1024  + CONFIG_ENV_SIZE)
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_BOARD_EARLY_INIT_R
+
+#define CONFIG_SYS_INIT_SP_ADDR		(0x29800000 + 0x1a000)
+
+/* PCI CONFIG */
+#define CONFIG_SYS_PCI_64BIT		1
+#define CONFIG_PCI_SCAN_SHOW
+
+/* SCSI */
+#define CONFIG_SYS_SCSI_MAX_SCSI_ID	4
+#define CONFIG_SYS_SCSI_MAX_LUN		1
+#define CONFIG_SYS_SCSI_MAX_DEVICE	128
+#define CONFIG_SCSI_AHCI_PLAT
+#define CONFIG_SYS_SATA_MAX_DEVICE	4
+
+/*BOOT*/
+#define CONFIG_SYS_BOOTM_LEN		(60 * 1024 * 1024)
+
+#define CONFIG_EXTRA_ENV_SETTINGS	\
+	"load_kernel=ext4load scsi 0:1 0x90100000 uImage_old\0"	\
+	"load_fdt=ext4load scsi 0:1 0x95000000 ft-d2000.dtb\0"\
+	"boot_fdt=bootm 0x90100000 -:- 0x17c000\0"	\
+	"distro_bootcmd=run load_kernel; run boot_fdt"
+
+#endif
-- 
2.17.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] arm: add initial support for the Phytium Pomelo Board
  2021-06-15  9:44 nicholas_zheng
  2021-06-15 12:45 ` Tom Rini
@ 2021-06-15 12:59 ` Peter Robinson
  1 sibling, 0 replies; 12+ messages in thread
From: Peter Robinson @ 2021-06-15 12:59 UTC (permalink / raw)
  To: nicholas_zheng
  Cc: trini, bharat.gooty, rayagonda.kokatanur, jagan, kever.yang,
	andre.przywara, festevam, patrick.delaunay, tharvey, hs,
	lokeshvutla, d-gerlach, u-boot

On Tue, Jun 15, 2021 at 10:45 AM <nicholas_zheng@outlook.com> wrote:
>
> From: weichangzheng <nicholas_zheng@outlook.com>
>
>  This adds platform code and the device tree for the Phytium Pomelo Board.
>  The initial support comprises the UART and the PCIE.
>
> Signed-off-by: weichangzheng <nicholas_zheng@outlook.com>
> ---
>  arch/arm/Kconfig                 |   8 ++
>  arch/arm/dts/Makefile            |   1 +
>  arch/arm/dts/phytium-pomelo.dts  |  34 +++++++
>  board/phytium/pomelo/Kconfig     |  12 +++
>  board/phytium/pomelo/MAINTAINERS |   8 ++
>  board/phytium/pomelo/Makefile    |  14 +++
>  board/phytium/pomelo/cpu.h       |  73 ++++++++++++++
>  board/phytium/pomelo/ddr.c       | 164 +++++++++++++++++++++++++++++++
>  board/phytium/pomelo/pcie.c      |  60 +++++++++++
>  board/phytium/pomelo/pll.c       |  74 ++++++++++++++
>  board/phytium/pomelo/pomelo.c    | 120 ++++++++++++++++++++++
>  board/phytium/pomelo/sec.c       |  39 ++++++++
>  configs/pomelo_defconfig         |  36 +++++++
>  include/configs/pomelo.h         |  45 +++++++++
>  14 files changed, 688 insertions(+)
>  create mode 100644 arch/arm/dts/phytium-pomelo.dts
>  create mode 100644 board/phytium/pomelo/Kconfig
>  create mode 100644 board/phytium/pomelo/MAINTAINERS
>  create mode 100644 board/phytium/pomelo/Makefile
>  create mode 100644 board/phytium/pomelo/cpu.h
>  create mode 100644 board/phytium/pomelo/ddr.c
>  create mode 100644 board/phytium/pomelo/pcie.c
>  create mode 100644 board/phytium/pomelo/pll.c
>  create mode 100644 board/phytium/pomelo/pomelo.c
>  create mode 100644 board/phytium/pomelo/sec.c
>  create mode 100644 configs/pomelo_defconfig
>  create mode 100644 include/configs/pomelo.h
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index 31d687ea01..6110fcddad 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -1800,6 +1800,13 @@ config TARGET_DURIAN
>           Support for durian platform.
>           It has 2GB Sdram, uart and pcie.
>
> +config TARGET_POMELO
> +       bool "Support Phytium Pomelo Platform"
> +       select ARM64
> +       help
> +               Support for pomelo platform.
> +               It has 2GB Sdram, uart and pcie.
> +
>  config TARGET_PRESIDIO_ASIC
>         bool "Support Cortina Presidio ASIC Platform"
>         select ARM64
> @@ -2019,6 +2026,7 @@ source "board/toradex/colibri_pxa270/Kconfig"
>  source "board/variscite/dart_6ul/Kconfig"
>  source "board/vscom/baltos/Kconfig"
>  source "board/phytium/durian/Kconfig"
> +source "board/phytium/pomelo/Kconfig"
>  source "board/xen/xenguest_arm64/Kconfig"
>  source "board/keymile/Kconfig"
>
> diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
> index 096068261d..c26692c17e 100644
> --- a/arch/arm/dts/Makefile
> +++ b/arch/arm/dts/Makefile
> @@ -1098,6 +1098,7 @@ dtb-$(CONFIG_TARGET_MX53PPD) += imx53-ppd.dtb
>  dtb-$(CONFIG_TARGET_TOTAL_COMPUTE) += total_compute.dtb
>
>  dtb-$(CONFIG_TARGET_DURIAN) += phytium-durian.dtb
> +dtb-$(CONFIG_TARGET_POMELO) += phytium-pomelo.dtb
>
>  dtb-$(CONFIG_TARGET_PRESIDIO_ASIC) += ca-presidio-engboard.dtb
>
> diff --git a/arch/arm/dts/phytium-pomelo.dts b/arch/arm/dts/phytium-pomelo.dts
> new file mode 100644
> index 0000000000..e9602cb3a8
> --- /dev/null
> +++ b/arch/arm/dts/phytium-pomelo.dts
> @@ -0,0 +1,34 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021, Phytium Ltd.
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */
> +
> +/dts-v1/;
> +
> +/memreserve/   0x0000000080000000 0x0000000000100000;
> +/ {
> +       model = "Phytium Pomelo";
> +       compatible = "phytium,pomelo";
> +       #address-cells = <2>;
> +       #size-cells = <2>;

This doesn't look like a particularly standard DT, and I would expect
it to be including a SoC level .dtsi file with all the CPU core and
related pieces. Is there a reason for the divergence?

> +       pcie-controller@40000000 {
> +               compatible = "pci-host-ecam-generic";
> +               device_type = "pci";
> +               #address-cells = <3>;
> +               #size-cells = <2>;
> +               reg = <0x0 0x40000000 0x0 0x10000000>;
> +               bus-range = <0x0 0xff>;
> +               ranges = <0x01000000 0x00 0x00000000 0x0  0x50000000 0x0  0x00F00000>,
> +                        <0x02000000 0x00 0x58000000 0x0  0x58000000 0x0  0x28000000>,
> +                        <0x43000000 0x10 0x00000000 0x10 0x00000000 0x10  0x00000000>;
> +       };
> +
> +       uart@28001000 {
> +               compatible = "arm,pl011";
> +               reg = <0x0 0x28001000 0x0 0x1000>;
> +               clock = <48000000>;
> +       };
> +};
> diff --git a/board/phytium/pomelo/Kconfig b/board/phytium/pomelo/Kconfig
> new file mode 100644
> index 0000000000..281aa8feff
> --- /dev/null
> +++ b/board/phytium/pomelo/Kconfig
> @@ -0,0 +1,12 @@
> +if TARGET_POMELO
> +
> +config SYS_BOARD
> +       default "pomelo"
> +
> +config SYS_VENDOR
> +       default "phytium"
> +
> +config SYS_CONFIG_NAME
> +       default "pomelo"
> +
> +endif
> diff --git a/board/phytium/pomelo/MAINTAINERS b/board/phytium/pomelo/MAINTAINERS
> new file mode 100644
> index 0000000000..950449392b
> --- /dev/null
> +++ b/board/phytium/pomelo/MAINTAINERS
> @@ -0,0 +1,8 @@
> +POMELO BOARD
> +M:     lixinde <lixinde@phytium.com.cn>
> +M:     weichangzheng <weichangzheng@phytium.com.cn>
> +S:     Maintained
> +F:     board/phytium/pomelo/*
> +F:     include/configs/pomelo.h
> +F:     configs/pomelo_defconfig
> +
> diff --git a/board/phytium/pomelo/Makefile b/board/phytium/pomelo/Makefile
> new file mode 100644
> index 0000000000..b9cb3609bd
> --- /dev/null
> +++ b/board/phytium/pomelo/Makefile
> @@ -0,0 +1,14 @@
> +# SPDX-License-Identifier: GPL-2.0+
> +#
> +# Copyright (C) 2021
> +# lixinde         <lixinde@phytium.com.cn>
> +# weichangzheng   <weichangzheng@phytium.com.cn>
> +#
> +
> +obj-y += pomelo.o
> +obj-y += pll.o
> +obj-y += pcie.o
> +obj-y += ddr.o
> +obj-y += sec.o
> +
> +
> diff --git a/board/phytium/pomelo/cpu.h b/board/phytium/pomelo/cpu.h
> new file mode 100644
> index 0000000000..e15917609b
> --- /dev/null
> +++ b/board/phytium/pomelo/cpu.h
> @@ -0,0 +1,73 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * (C) Copyright 2021
> + * Phytium Technology Ltd <www.phytium.com>
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */
> +
> +#ifndef _FT_POMELO_H
> +#define _FT_POMELO_H
> +
> +/* SMCCC ID */
> +#define CPU_SVC_VERSION                        0xC2000F00
> +#define CPU_GET_RST_SOURCE             0xC2000F01
> +#define CPU_INIT_PLL                   0xC2000F02
> +#define CPU_INIT_PCIE                  0xC2000F03
> +#define CPU_INIT_MEM                   0xC2000F04
> +#define CPU_INIT_SEC_SVC               0xC2000F05
> +
> +/*CPU RESET*/
> +#define CPU_RESET_POWER_ON             0x1
> +#define CPU_RESET_PLL                  0x4
> +#define CPU_RESET_WATCH_DOG            0x8
> +
> +/* PLL */
> +#define PARAMETER_PLL_MAGIC            0x54460010
> +
> +/* PCIE */
> +#define PARAMETER_PCIE_MAGIC           0x54460011
> +#define CONFIG_INDEPENDENT_TREE                0x0
> +#define PCI_PEU0                       0x1
> +#define PCI_PEU1                       0x1
> +#define PEU1_OFFSET                    16
> +#define PEU_C_OFFSET_MODE              16
> +#define PEU_C_OFFSET_SPEED             0
> +#define RC_MODE                                0x1
> +#define X8X8                           0x1
> +#define GEN3                           3
> +
> +/* DDR */
> +#define PARAMETER_MCU_MAGIC            0x54460014
> +#define PARAM_MCU_VERSION              0x1
> +#define PARAM_MCU_SIZE                 0x100
> +#define PARAM_CH_ENABLE                        0x3
> +#define PARAM_ECC_ENABLE               0x3
> +#define PARAM_FORCE_SPD_DISABLE                0x0
> +#define PARAM_MCU_MISC_ENABLE          0x0
> +
> +#define UDIMM_TYPE                     0x2
> +#define DIMM_X8                                0x1
> +#define NO_MIRROR                      0x0
> +#define NO_ECC_TYPE                    0
> +#define DDR4_TYPE                      0xC
> +
> +/* SEC */
> +#define PARAMETER_COMMON_MAGIC         0x54460013
> +
> +/* FLUSH L3 CASHE */
> +#define HNF_COUNT                      0x8
> +#define HNF_PSTATE_REQ                 (HNF_BASE + 0x10)
> +#define HNF_PSTATE_STAT                        (HNF_BASE + 0x18)
> +#define HNF_PSTATE_OFF                 0x0
> +#define HNF_PSTATE_SFONLY              0x1
> +#define HNF_PSTATE_HALF                        0x2
> +#define HNF_PSTATE_FULL                        0x3
> +#define HNF_STRIDE                     0x10000
> +#define HNF_BASE                       (unsigned long)(0x3A200000)
> +void ddr_init(void);
> +void sec_init(void);
> +void check_reset(void);
> +void pcie_init(void);
> +
> +#endif /* _FT_POMELO_H */
> diff --git a/board/phytium/pomelo/ddr.c b/board/phytium/pomelo/ddr.c
> new file mode 100644
> index 0000000000..b3471721f2
> --- /dev/null
> +++ b/board/phytium/pomelo/ddr.c
> @@ -0,0 +1,164 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */
> +
> +#include <common.h>
> +#include <linux/arm-smccc.h>
> +#include "cpu.h"
> +
> +struct ddr_spd {
> +       /******************* read from spd *****************/
> +       unsigned char  dimm_type;       /* 1: RDIMM;2: UDIMM;3: SODIMM;4: LRDIMM */
> +       unsigned char  data_width;      /* 0: x4; 1: x8; 2: x16 */
> +       unsigned char  mirror_type;     /* 0: stardard; 1: mirror */
> +       unsigned char  ecc_type;        /* 0: no-ecc; 1:ecc */
> +       unsigned char  dram_type;       /* 0xB: DDR3; 0xC: DDR4 */
> +       unsigned char  rank_num;
> +       unsigned char  row_num;
> +       unsigned char  col_num;
> +
> +       unsigned char  bg_num;  /*only DDR4*/
> +       unsigned char  bank_num;
> +       unsigned short int module_manufacturer_id;
> +       unsigned short int taamin;
> +       unsigned short int trcdmin;
> +
> +       unsigned short int trpmin;
> +       unsigned short int trasmin;
> +       unsigned short int trcmin;
> +       unsigned short int tfawmin;
> +
> +       unsigned short int trrd_smin;   /*only DDR4*/
> +       unsigned short int trrd_lmin;   /*only DDR4*/
> +       unsigned short int tccd_lmin;   /*only DDR4*/
> +       unsigned short int twrmin;
> +
> +       unsigned short int twtr_smin;   /*only DDR4*/
> +       unsigned short int twtr_lmin;   /*only DDR4*/
> +       unsigned short int twtrmin;     /*only DDR3*/
> +       unsigned short int trrdmin;     /*only DDR3*/
> +
> +       /******************* RCD control words *****************/
> +       unsigned char  f0rc03; /*bit[3:2]:CS            bit[1:0]:CA  */
> +       unsigned char  f0rc04; /*bit[3:2]:ODT           bit[1:0]:CKE */
> +       unsigned char  f0rc05; /*bit[3:2]:CLK-A side    bit[1:0]:CLK-B side */
> +       unsigned char  bc00;
> +       unsigned char  bc01;
> +       unsigned char  bc02;
> +       unsigned char  bc03;
> +       unsigned char  bc04;
> +
> +       unsigned char  bc05;
> +       unsigned char  f5bc5x;
> +       unsigned char  f5bc6x;
> +       /******************* LRDIMM special *****************/
> +       unsigned char  vrefdq_pr0;
> +       unsigned char  vrefdq_mdram;
> +       unsigned char  rtt_mdram_1866;
> +       unsigned char  rtt_mdram_2400;
> +       unsigned char  rtt_mdram_3200;
> +
> +       unsigned char  drive_dram;
> +       unsigned char  odt_dram_1866;
> +       unsigned char  odt_dram_2400;
> +       unsigned char  odt_dram_3200;
> +       unsigned char  park_dram_1866;
> +       unsigned char  park_dram_2400;
> +       unsigned char  park_dram_3200;
> +       unsigned char  rcd_num;
> +} __attribute((aligned(4)));
> +
> +struct mcu_config {
> +       unsigned int magic;
> +       unsigned int version;
> +       unsigned int size;
> +       unsigned char rev1[4];
> +
> +       unsigned char ch_enable;
> +       unsigned char misc1_enable;
> +       unsigned char misc2_enable;
> +       unsigned char force_spd_enable;
> +       unsigned char misc3_enable;
> +       unsigned char train_debug;
> +       unsigned char train_recover;
> +       unsigned char rev2[9];
> +
> +       struct ddr_spd ddr_spd_info[2];
> +} __attribute((aligned(4)));
> +
> +static void get_mcu_up_info_default(struct mcu_config *pm)
> +{
> +       pm->magic               = PARAMETER_MCU_MAGIC;
> +       pm->version             = PARAM_MCU_VERSION;
> +       pm->size                = PARAM_MCU_SIZE;
> +       pm->ch_enable           = PARAM_CH_ENABLE;
> +       pm->misc1_enable        = PARAM_ECC_ENABLE;
> +       pm->force_spd_enable    = PARAM_FORCE_SPD_DISABLE;
> +       pm->misc3_enable        = PARAM_MCU_MISC_ENABLE;
> +       pm->train_recover       = 0x0;
> +}
> +
> +static unsigned char init_dimm_param(unsigned char ch, struct mcu_config *pm)
> +{
> +       printf("manual config dimm info...\n");
> +       pm->ddr_spd_info[ch].dimm_type = UDIMM_TYPE;
> +       pm->ddr_spd_info[ch].data_width = DIMM_X8;
> +       pm->ddr_spd_info[ch].mirror_type = NO_MIRROR;
> +       pm->ddr_spd_info[ch].ecc_type = NO_ECC_TYPE;
> +       pm->ddr_spd_info[ch].dram_type = DDR4_TYPE;
> +       pm->ddr_spd_info[ch].rank_num = 1;
> +       pm->ddr_spd_info[ch].row_num  = 16;
> +       pm->ddr_spd_info[ch].col_num = 10;
> +       pm->ddr_spd_info[ch].bg_num = 4;
> +       pm->ddr_spd_info[ch].bank_num = 4;
> +       pm->ddr_spd_info[ch].taamin = 13750;
> +       pm->ddr_spd_info[ch].trcdmin = 13750;
> +
> +       pm->ddr_spd_info[ch].trpmin = 13750;
> +       pm->ddr_spd_info[ch].trasmin = 32000;
> +       pm->ddr_spd_info[ch].trcmin =  45750;
> +       pm->ddr_spd_info[ch].tfawmin = 21000;
> +
> +       pm->ddr_spd_info[ch].trrd_smin = 3000;
> +       pm->ddr_spd_info[ch].trrd_lmin = 4900;
> +       pm->ddr_spd_info[ch].tccd_lmin = 5000;
> +       pm->ddr_spd_info[ch].twrmin = 15000;
> +
> +       pm->ddr_spd_info[ch].twtr_smin = 2500;
> +       pm->ddr_spd_info[ch].twtr_lmin = 7500;
> +
> +       return 0;
> +}
> +
> +void get_default_mcu_info(unsigned char *data)
> +{
> +       get_mcu_up_info_default((struct mcu_config *)data);
> +}
> +
> +void fix_mcu_info(unsigned char *data)
> +{
> +       unsigned char ch;
> +       struct mcu_config *mcu_info = (struct mcu_config *)data;
> +
> +       for (ch = 0; ch < 2; ch++)
> +               init_dimm_param(ch, mcu_info);
> +}
> +
> +void ddr_init(void)
> +{
> +       unsigned char buffer[0x100];
> +       struct arm_smccc_res res;
> +
> +       get_default_mcu_info(buffer);
> +       fix_mcu_info(buffer);
> +
> +       arm_smccc_smc(CPU_INIT_MEM, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
> +       if (res.a0 != 0) {
> +               printf("error x0: 0x%lx, x1: 0x%lx\n", res.a0, res.a1);
> +               while (true)
> +                       ;
> +       }
> +}
> diff --git a/board/phytium/pomelo/pcie.c b/board/phytium/pomelo/pcie.c
> new file mode 100644
> index 0000000000..6d7792f0be
> --- /dev/null
> +++ b/board/phytium/pomelo/pcie.c
> @@ -0,0 +1,60 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */
> +
> +#include <common.h>
> +#include <linux/arm-smccc.h>
> +#include "cpu.h"
> +
> +struct pcu_ctr {
> +       unsigned int base_config[3];
> +       unsigned int equalization[3];
> +       unsigned char rev[80];
> +} __attribute((aligned(4)));
> +
> +struct pcu_config {
> +       unsigned int magic;
> +       unsigned int version;
> +       unsigned int size;
> +       unsigned char rev1[4];
> +       unsigned int independent_tree;
> +       unsigned int base_cfg;
> +       unsigned char rev2[16];
> +       struct pcu_ctr ctr_cfg[2];
> +} __attribute((aligned(4)));
> +
> +struct pcu_config const peu_base_info = {
> +       .magic = PARAMETER_PCIE_MAGIC,
> +       .version = 0x2,
> +       .size = 0x100,
> +       .independent_tree = CONFIG_INDEPENDENT_TREE,
> +       .base_cfg = ((PCI_PEU1 | (X8X8 << 1)) << PEU1_OFFSET | (PCI_PEU0 | (X8X8 << 1))),
> +       .ctr_cfg[0].base_config[0] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
> +       .ctr_cfg[0].base_config[1] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
> +       .ctr_cfg[0].base_config[2] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
> +       .ctr_cfg[1].base_config[0] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
> +       .ctr_cfg[1].base_config[1] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
> +       .ctr_cfg[1].base_config[2] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
> +       .ctr_cfg[0].equalization[0] = 0x7,
> +       .ctr_cfg[0].equalization[1] = 0x7,
> +       .ctr_cfg[0].equalization[2] = 0x7,
> +       .ctr_cfg[1].equalization[0] = 0x7,
> +       .ctr_cfg[1].equalization[1] = 0x7,
> +       .ctr_cfg[1].equalization[2] = 0x7,
> +};
> +
> +void pcie_init(void)
> +{
> +       unsigned char buffer[0x100];
> +       struct arm_smccc_res res;
> +
> +       memcpy(buffer, &peu_base_info, sizeof(peu_base_info));
> +       arm_smccc_smc(CPU_INIT_PCIE, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
> +       if (res.a0 != 0) {
> +               while (true)
> +                       ;
> +       }
> +}
> diff --git a/board/phytium/pomelo/pll.c b/board/phytium/pomelo/pll.c
> new file mode 100644
> index 0000000000..095131e815
> --- /dev/null
> +++ b/board/phytium/pomelo/pll.c
> @@ -0,0 +1,74 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <linux/arm-smccc.h>
> +#include "cpu.h"
> +
> +struct pll_config {
> +       unsigned int magic;
> +       unsigned int version;
> +       unsigned int size;
> +       unsigned char rev1[4];
> +       unsigned int core_pll;
> +       unsigned int res1;
> +       unsigned int lmu_pll;
> +       unsigned int res2;
> +       unsigned int res3;
> +       unsigned int res4;
> +       unsigned int res5;
> +} __attribute((aligned(4)));
> +
> +struct pll_config const pll_base_info = {
> +       .magic = PARAMETER_PLL_MAGIC,
> +       .version = 0x1,
> +       .size = 0x30,
> +       .core_pll = 2300,       /*MHz*/
> +       .lmu_pll = 667,         /*MHz*/
> +};
> +
> +unsigned int get_reset_source(void)
> +{
> +       struct arm_smccc_res res;
> +
> +       arm_smccc_smc(CPU_GET_RST_SOURCE, 0, 0, 0, 0, 0, 0, 0, &res);
> +       return res.a0;
> +}
> +
> +void pll_init(void)
> +{
> +       unsigned char buffer[0x100];
> +       struct arm_smccc_res res;
> +
> +       memcpy(buffer, &pll_base_info, sizeof(pll_base_info));
> +       arm_smccc_smc(CPU_INIT_PLL, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
> +       if (res.a0 != 0) {
> +               while (true)
> +                       ;
> +       }
> +}
> +
> +void check_reset(void)
> +{
> +       unsigned int rst;
> +
> +       rst = get_reset_source();
> +
> +       switch (rst) {
> +       case CPU_RESET_POWER_ON:
> +               pll_init();
> +               break;
> +       case CPU_RESET_PLL:
> +               break;
> +       case CPU_RESET_WATCH_DOG:
> +               break;
> +       default:
> +               while (true)
> +                       ;
> +       }
> +}
> diff --git a/board/phytium/pomelo/pomelo.c b/board/phytium/pomelo/pomelo.c
> new file mode 100644
> index 0000000000..6442bb80d3
> --- /dev/null
> +++ b/board/phytium/pomelo/pomelo.c
> @@ -0,0 +1,120 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */
> +
> +#include <common.h>
> +#include <command.h>
> +#include <init.h>
> +#include <asm/armv8/mmu.h>
> +#include <asm/io.h>
> +#include <linux/arm-smccc.h>
> +#include <scsi.h>
> +#include "cpu.h"
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +int dram_init(void)
> +{
> +       gd->mem_clk = 0;
> +       gd->ram_size = PHYS_SDRAM_1_SIZE;
> +
> +       printf("Phytium ddr init\n");
> +
> +       ddr_init();
> +       sec_init();
> +       printf("PBF relocate done\n");
> +
> +       return 0;
> +}
> +
> +int board_init(void)
> +{
> +       return 0;
> +}
> +
> +void reset_cpu(void)
> +{
> +       struct arm_smccc_res res;
> +
> +       printf("run in reset cpu\n");
> +       arm_smccc_smc(0x84000009, 0, 0, 0, 0, 0, 0, 0, &res);
> +       printf("reset cpu error, %lx\n", res.a0);
> +}
> +
> +int mach_cpu_init(void)
> +{
> +       check_reset();
> +       return 0;
> +}
> +
> +int board_early_init_f(void)
> +{
> +       pcie_init();
> +       return 0;
> +}
> +
> +int board_early_init_r(void)
> +{
> +       return 0;
> +}
> +
> +static struct mm_region pomelo_mem_map[] = {
> +       {
> +               .virt = 0x0UL,
> +               .phys = 0x0UL,
> +               .size = 0x80000000UL,
> +               .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
> +                                PTE_BLOCK_NON_SHARE |
> +                                PTE_BLOCK_PXN |
> +                                PTE_BLOCK_UXN
> +       },
> +       {
> +               .virt = (u64)PHYS_SDRAM_1,
> +               .phys = (u64)PHYS_SDRAM_1,
> +               .size = (u64)PHYS_SDRAM_1_SIZE,
> +               .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
> +                                PTE_BLOCK_NS |
> +                                PTE_BLOCK_INNER_SHARE
> +       },
> +       {
> +               0,
> +       }
> +};
> +
> +struct mm_region *mem_map = pomelo_mem_map;
> +
> +int __asm_flush_l3_dcache(void)
> +{
> +       int i, pstate;
> +
> +       for (i = 0; i < HNF_COUNT; i++)
> +               writeq(HNF_PSTATE_SFONLY, HNF_PSTATE_REQ + i * HNF_STRIDE);
> +       for (i = 0; i < HNF_COUNT; i++) {
> +               do {
> +                       pstate = readq(HNF_PSTATE_STAT + i * HNF_STRIDE);
> +               } while ((pstate & 0xf) != (HNF_PSTATE_SFONLY << 2));
> +       }
> +
> +       for (i = 0; i < HNF_COUNT; i++)
> +               writeq(HNF_PSTATE_FULL, HNF_PSTATE_REQ + i * HNF_STRIDE);
> +
> +       return 0;
> +}
> +
> +int last_stage_init(void)
> +{
> +       int ret;
> +
> +       /* pci e */
> +       pci_init();
> +       /* scsi scan */
> +       ret = scsi_scan(true);
> +       if (ret) {
> +               printf("scsi scan failed\n");
> +               return CMD_RET_FAILURE;
> +       }
> +       return ret;
> +}
> diff --git a/board/phytium/pomelo/sec.c b/board/phytium/pomelo/sec.c
> new file mode 100644
> index 0000000000..c000b3f369
> --- /dev/null
> +++ b/board/phytium/pomelo/sec.c
> @@ -0,0 +1,39 @@
> +// SPDX-License-Identifier: GPL-2.0+
> +/*
> + * Copyright (C) 2021
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */
> +
> +#include <common.h>
> +#include <linux/arm-smccc.h>
> +#include "cpu.h"
> +
> +struct common_config {
> +       unsigned int magic;
> +       unsigned int version;
> +       unsigned int size;
> +       unsigned char rev1[4];
> +       unsigned long long  core_bit_map;
> +} __attribute((aligned(4)));
> +
> +struct common_config const common_base_info = {
> +       .magic = PARAMETER_COMMON_MAGIC,
> +       .version = 0x1,
> +       .core_bit_map = 0x3333,
> +};
> +
> +void sec_init(void)
> +{
> +       unsigned char buffer[0x100];
> +       struct arm_smccc_res res;
> +
> +       memcpy(buffer, &common_base_info, sizeof(common_base_info));
> +       arm_smccc_smc(CPU_INIT_SEC_SVC, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
> +
> +       if (res.a0 != 0) {
> +               printf("error ret %lx\n", res.a0);
> +               while (true)
> +                       ;
> +       }
> +}
> diff --git a/configs/pomelo_defconfig b/configs/pomelo_defconfig
> new file mode 100644
> index 0000000000..3e6c18196d
> --- /dev/null
> +++ b/configs/pomelo_defconfig
> @@ -0,0 +1,36 @@
> +CONFIG_ARM=y
> +CONFIG_ARM_SMCCC=y
> +CONFIG_TARGET_POMELO=y
> +CONFIG_SYS_TEXT_BASE=0x180000
> +CONFIG_NR_DRAM_BANKS=1
> +CONFIG_ENV_SIZE=0x1000
> +# CONFIG_PSCI_RESET is not set
> +CONFIG_DEFAULT_DEVICE_TREE="phytium-pomelo"
> +CONFIG_AHCI=y
> +CONFIG_DISTRO_DEFAULTS=y
> +CONFIG_USE_BOOTARGS=y
> +CONFIG_BOOTARGS="console=ttyAMA0,115200 earlycon=pl011,0x28001000 root=/dev/sda2 rw"
> +# CONFIG_DISPLAY_CPUINFO is not set
> +# CONFIG_DISPLAY_BOARDINFO is not set
> +CONFIG_LAST_STAGE_INIT=y
> +CONFIG_SYS_PROMPT="pomelo#"
> +# CONFIG_CMD_LZMADEC is not set
> +# CONFIG_CMD_UNZIP is not set
> +CONFIG_CMD_PCI=y
> +CONFIG_OF_CONTROL=y
> +CONFIG_SYS_RELOC_GD_ENV_ADDR=y
> +# CONFIG_NET is not set
> +CONFIG_DM=y
> +CONFIG_SCSI_AHCI=y
> +CONFIG_AHCI_PCI=y
> +CONFIG_BLK=y
> +# CONFIG_MMC is not set
> +CONFIG_PCI=y
> +CONFIG_DM_PCI=y
> +CONFIG_DM_PCI_COMPAT=y
> +CONFIG_PCI_PHYTIUM=y
> +CONFIG_PCIE_ECAM_GENERIC=y
> +CONFIG_SCSI=y
> +CONFIG_DM_SCSI=y
> +CONFIG_DM_SERIAL=y
> +CONFIG_PL01X_SERIAL=y
> diff --git a/include/configs/pomelo.h b/include/configs/pomelo.h
> new file mode 100644
> index 0000000000..69c4195d86
> --- /dev/null
> +++ b/include/configs/pomelo.h
> @@ -0,0 +1,45 @@
> +/* SPDX-License-Identifier: GPL-2.0+ */
> +/*
> + * Copyright (C) 2021
> + * lixinde         <lixinde@phytium.com.cn>
> + * weichangzheng   <weichangzheng@phytium.com.cn>
> + */
> +
> +#ifndef __POMELO_CONFIG_H__
> +#define __POMELO_CONFIG_H__
> +
> +/* SDRAM Bank #1 start address */
> +#define PHYS_SDRAM_1                   0x80000000
> +#define PHYS_SDRAM_1_SIZE              0x7B000000
> +#define CONFIG_SYS_SDRAM_BASE          PHYS_SDRAM_1
> +
> +#define CONFIG_SYS_LOAD_ADDR           (CONFIG_SYS_SDRAM_BASE + 0x10000000)
> +
> +/* SIZE of malloc pool */
> +#define CONFIG_SYS_MALLOC_LEN          (1 * 1024 * 1024  + CONFIG_ENV_SIZE)
> +#define CONFIG_BOARD_EARLY_INIT_F
> +#define CONFIG_BOARD_EARLY_INIT_R
> +
> +#define CONFIG_SYS_INIT_SP_ADDR                (0x29800000 + 0x1a000)
> +
> +/* PCI CONFIG */
> +#define CONFIG_SYS_PCI_64BIT           1
> +#define CONFIG_PCI_SCAN_SHOW
> +
> +/* SCSI */
> +#define CONFIG_SYS_SCSI_MAX_SCSI_ID    4
> +#define CONFIG_SYS_SCSI_MAX_LUN                1
> +#define CONFIG_SYS_SCSI_MAX_DEVICE     128
> +#define CONFIG_SCSI_AHCI_PLAT
> +#define CONFIG_SYS_SATA_MAX_DEVICE     4
> +
> +/*BOOT*/
> +#define CONFIG_SYS_BOOTM_LEN           (60 * 1024 * 1024)
> +
> +#define CONFIG_EXTRA_ENV_SETTINGS      \
> +       "load_kernel=ext4load scsi 0:1 0x90100000 uImage_old\0" \
> +       "load_fdt=ext4load scsi 0:1 0x95000000 ft-d2000.dtb\0"\
> +       "boot_fdt=bootm 0x90100000 -:- 0x17c000\0"      \
> +       "distro_bootcmd=run load_kernel; run boot_fdt"
> +
> +#endif
> --
> 2.17.1
>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH]  arm: add initial support for the Phytium Pomelo Board
  2021-06-15  9:44 nicholas_zheng
@ 2021-06-15 12:45 ` Tom Rini
  2021-06-15 12:59 ` Peter Robinson
  1 sibling, 0 replies; 12+ messages in thread
From: Tom Rini @ 2021-06-15 12:45 UTC (permalink / raw)
  To: nicholas_zheng
  Cc: bharat.gooty, rayagonda.kokatanur, jagan, kever.yang,
	andre.przywara, festevam, patrick.delaunay, tharvey, pbrobinson,
	hs, lokeshvutla, d-gerlach, u-boot

[-- Attachment #1: Type: text/plain, Size: 528 bytes --]

On Tue, Jun 15, 2021 at 05:44:35PM +0800, nicholas_zheng@outlook.com wrote:

> From: weichangzheng <nicholas_zheng@outlook.com>
> 
>  This adds platform code and the device tree for the Phytium Pomelo Board.
>  The initial support comprises the UART and the PCIE.
> 
> Signed-off-by: weichangzheng <nicholas_zheng@outlook.com>

This looks better, thanks.  I see you're adding <common.h> in your code,
can you drop that and only include the headers it needs?  Most of
<common.h> has been removed, thanks.

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH]  arm: add initial support for the Phytium Pomelo Board
@ 2021-06-15  9:44 nicholas_zheng
  2021-06-15 12:45 ` Tom Rini
  2021-06-15 12:59 ` Peter Robinson
  0 siblings, 2 replies; 12+ messages in thread
From: nicholas_zheng @ 2021-06-15  9:44 UTC (permalink / raw)
  To: trini, bharat.gooty, rayagonda.kokatanur
  Cc: jagan, kever.yang, andre.przywara, festevam, patrick.delaunay,
	tharvey, pbrobinson, hs, lokeshvutla, d-gerlach, u-boot,
	weichangzheng

From: weichangzheng <nicholas_zheng@outlook.com>

 This adds platform code and the device tree for the Phytium Pomelo Board.
 The initial support comprises the UART and the PCIE.

Signed-off-by: weichangzheng <nicholas_zheng@outlook.com>
---
 arch/arm/Kconfig                 |   8 ++
 arch/arm/dts/Makefile            |   1 +
 arch/arm/dts/phytium-pomelo.dts  |  34 +++++++
 board/phytium/pomelo/Kconfig     |  12 +++
 board/phytium/pomelo/MAINTAINERS |   8 ++
 board/phytium/pomelo/Makefile    |  14 +++
 board/phytium/pomelo/cpu.h       |  73 ++++++++++++++
 board/phytium/pomelo/ddr.c       | 164 +++++++++++++++++++++++++++++++
 board/phytium/pomelo/pcie.c      |  60 +++++++++++
 board/phytium/pomelo/pll.c       |  74 ++++++++++++++
 board/phytium/pomelo/pomelo.c    | 120 ++++++++++++++++++++++
 board/phytium/pomelo/sec.c       |  39 ++++++++
 configs/pomelo_defconfig         |  36 +++++++
 include/configs/pomelo.h         |  45 +++++++++
 14 files changed, 688 insertions(+)
 create mode 100644 arch/arm/dts/phytium-pomelo.dts
 create mode 100644 board/phytium/pomelo/Kconfig
 create mode 100644 board/phytium/pomelo/MAINTAINERS
 create mode 100644 board/phytium/pomelo/Makefile
 create mode 100644 board/phytium/pomelo/cpu.h
 create mode 100644 board/phytium/pomelo/ddr.c
 create mode 100644 board/phytium/pomelo/pcie.c
 create mode 100644 board/phytium/pomelo/pll.c
 create mode 100644 board/phytium/pomelo/pomelo.c
 create mode 100644 board/phytium/pomelo/sec.c
 create mode 100644 configs/pomelo_defconfig
 create mode 100644 include/configs/pomelo.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 31d687ea01..6110fcddad 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1800,6 +1800,13 @@ config TARGET_DURIAN
 	  Support for durian platform.
 	  It has 2GB Sdram, uart and pcie.
 
+config TARGET_POMELO
+	bool "Support Phytium Pomelo Platform"
+	select ARM64
+	help
+		Support for pomelo platform.
+		It has 2GB Sdram, uart and pcie.
+
 config TARGET_PRESIDIO_ASIC
 	bool "Support Cortina Presidio ASIC Platform"
 	select ARM64
@@ -2019,6 +2026,7 @@ source "board/toradex/colibri_pxa270/Kconfig"
 source "board/variscite/dart_6ul/Kconfig"
 source "board/vscom/baltos/Kconfig"
 source "board/phytium/durian/Kconfig"
+source "board/phytium/pomelo/Kconfig"
 source "board/xen/xenguest_arm64/Kconfig"
 source "board/keymile/Kconfig"
 
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 096068261d..c26692c17e 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1098,6 +1098,7 @@ dtb-$(CONFIG_TARGET_MX53PPD) += imx53-ppd.dtb
 dtb-$(CONFIG_TARGET_TOTAL_COMPUTE) += total_compute.dtb
 
 dtb-$(CONFIG_TARGET_DURIAN) += phytium-durian.dtb
+dtb-$(CONFIG_TARGET_POMELO) += phytium-pomelo.dtb
 
 dtb-$(CONFIG_TARGET_PRESIDIO_ASIC) += ca-presidio-engboard.dtb
 
diff --git a/arch/arm/dts/phytium-pomelo.dts b/arch/arm/dts/phytium-pomelo.dts
new file mode 100644
index 0000000000..e9602cb3a8
--- /dev/null
+++ b/arch/arm/dts/phytium-pomelo.dts
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021, Phytium Ltd.
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+/dts-v1/;
+
+/memreserve/	0x0000000080000000 0x0000000000100000;
+/ {
+	model = "Phytium Pomelo";
+	compatible = "phytium,pomelo";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	pcie-controller@40000000 {
+		compatible = "pci-host-ecam-generic";
+		device_type = "pci";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		reg = <0x0 0x40000000 0x0 0x10000000>;
+		bus-range = <0x0 0xff>;
+		ranges = <0x01000000 0x00 0x00000000 0x0  0x50000000 0x0  0x00F00000>,
+			 <0x02000000 0x00 0x58000000 0x0  0x58000000 0x0  0x28000000>,
+			 <0x43000000 0x10 0x00000000 0x10 0x00000000 0x10  0x00000000>;
+	};
+
+	uart@28001000 {
+		compatible = "arm,pl011";
+		reg = <0x0 0x28001000 0x0 0x1000>;
+		clock = <48000000>;
+	};
+};
diff --git a/board/phytium/pomelo/Kconfig b/board/phytium/pomelo/Kconfig
new file mode 100644
index 0000000000..281aa8feff
--- /dev/null
+++ b/board/phytium/pomelo/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_POMELO
+
+config SYS_BOARD
+	default "pomelo"
+
+config SYS_VENDOR
+	default "phytium"
+
+config SYS_CONFIG_NAME
+	default "pomelo"
+
+endif
diff --git a/board/phytium/pomelo/MAINTAINERS b/board/phytium/pomelo/MAINTAINERS
new file mode 100644
index 0000000000..950449392b
--- /dev/null
+++ b/board/phytium/pomelo/MAINTAINERS
@@ -0,0 +1,8 @@
+POMELO BOARD
+M:	lixinde <lixinde@phytium.com.cn>
+M:	weichangzheng <weichangzheng@phytium.com.cn>
+S:	Maintained
+F:	board/phytium/pomelo/*
+F:	include/configs/pomelo.h
+F:	configs/pomelo_defconfig
+
diff --git a/board/phytium/pomelo/Makefile b/board/phytium/pomelo/Makefile
new file mode 100644
index 0000000000..b9cb3609bd
--- /dev/null
+++ b/board/phytium/pomelo/Makefile
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2021
+# lixinde         <lixinde@phytium.com.cn>
+# weichangzheng   <weichangzheng@phytium.com.cn>
+#
+
+obj-y += pomelo.o
+obj-y += pll.o
+obj-y += pcie.o
+obj-y += ddr.o
+obj-y += sec.o
+
+
diff --git a/board/phytium/pomelo/cpu.h b/board/phytium/pomelo/cpu.h
new file mode 100644
index 0000000000..e15917609b
--- /dev/null
+++ b/board/phytium/pomelo/cpu.h
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2021
+ * Phytium Technology Ltd <www.phytium.com>
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#ifndef _FT_POMELO_H
+#define _FT_POMELO_H
+
+/* SMCCC ID */
+#define CPU_SVC_VERSION			0xC2000F00
+#define CPU_GET_RST_SOURCE		0xC2000F01
+#define CPU_INIT_PLL			0xC2000F02
+#define CPU_INIT_PCIE			0xC2000F03
+#define CPU_INIT_MEM			0xC2000F04
+#define CPU_INIT_SEC_SVC		0xC2000F05
+
+/*CPU RESET*/
+#define CPU_RESET_POWER_ON		0x1
+#define CPU_RESET_PLL			0x4
+#define CPU_RESET_WATCH_DOG		0x8
+
+/* PLL */
+#define PARAMETER_PLL_MAGIC		0x54460010
+
+/* PCIE */
+#define PARAMETER_PCIE_MAGIC		0x54460011
+#define CONFIG_INDEPENDENT_TREE		0x0
+#define PCI_PEU0			0x1
+#define PCI_PEU1			0x1
+#define PEU1_OFFSET			16
+#define PEU_C_OFFSET_MODE		16
+#define PEU_C_OFFSET_SPEED		0
+#define RC_MODE				0x1
+#define X8X8				0x1
+#define GEN3				3
+
+/* DDR */
+#define PARAMETER_MCU_MAGIC		0x54460014
+#define PARAM_MCU_VERSION		0x1
+#define PARAM_MCU_SIZE			0x100
+#define PARAM_CH_ENABLE			0x3
+#define PARAM_ECC_ENABLE		0x3
+#define PARAM_FORCE_SPD_DISABLE		0x0
+#define PARAM_MCU_MISC_ENABLE		0x0
+
+#define UDIMM_TYPE			0x2
+#define DIMM_X8				0x1
+#define NO_MIRROR			0x0
+#define NO_ECC_TYPE			0
+#define DDR4_TYPE			0xC
+
+/* SEC */
+#define PARAMETER_COMMON_MAGIC		0x54460013
+
+/* FLUSH L3 CASHE */
+#define HNF_COUNT			0x8
+#define HNF_PSTATE_REQ			(HNF_BASE + 0x10)
+#define HNF_PSTATE_STAT			(HNF_BASE + 0x18)
+#define HNF_PSTATE_OFF			0x0
+#define HNF_PSTATE_SFONLY		0x1
+#define HNF_PSTATE_HALF			0x2
+#define HNF_PSTATE_FULL			0x3
+#define HNF_STRIDE			0x10000
+#define HNF_BASE			(unsigned long)(0x3A200000)
+void ddr_init(void);
+void sec_init(void);
+void check_reset(void);
+void pcie_init(void);
+
+#endif /* _FT_POMELO_H */
diff --git a/board/phytium/pomelo/ddr.c b/board/phytium/pomelo/ddr.c
new file mode 100644
index 0000000000..b3471721f2
--- /dev/null
+++ b/board/phytium/pomelo/ddr.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <common.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct ddr_spd {
+	/******************* read from spd *****************/
+	unsigned char  dimm_type;	/* 1: RDIMM;2: UDIMM;3: SODIMM;4: LRDIMM */
+	unsigned char  data_width;	/* 0: x4; 1: x8; 2: x16 */
+	unsigned char  mirror_type;	/* 0: stardard; 1: mirror */
+	unsigned char  ecc_type;	/* 0: no-ecc; 1:ecc */
+	unsigned char  dram_type;	/* 0xB: DDR3; 0xC: DDR4 */
+	unsigned char  rank_num;
+	unsigned char  row_num;
+	unsigned char  col_num;
+
+	unsigned char  bg_num;	/*only DDR4*/
+	unsigned char  bank_num;
+	unsigned short int module_manufacturer_id;
+	unsigned short int taamin;
+	unsigned short int trcdmin;
+
+	unsigned short int trpmin;
+	unsigned short int trasmin;
+	unsigned short int trcmin;
+	unsigned short int tfawmin;
+
+	unsigned short int trrd_smin;	/*only DDR4*/
+	unsigned short int trrd_lmin;	/*only DDR4*/
+	unsigned short int tccd_lmin;	/*only DDR4*/
+	unsigned short int twrmin;
+
+	unsigned short int twtr_smin;	/*only DDR4*/
+	unsigned short int twtr_lmin;	/*only DDR4*/
+	unsigned short int twtrmin;	/*only DDR3*/
+	unsigned short int trrdmin;	/*only DDR3*/
+
+	/******************* RCD control words *****************/
+	unsigned char  f0rc03; /*bit[3:2]:CS		bit[1:0]:CA  */
+	unsigned char  f0rc04; /*bit[3:2]:ODT		bit[1:0]:CKE */
+	unsigned char  f0rc05; /*bit[3:2]:CLK-A side	bit[1:0]:CLK-B side */
+	unsigned char  bc00;
+	unsigned char  bc01;
+	unsigned char  bc02;
+	unsigned char  bc03;
+	unsigned char  bc04;
+
+	unsigned char  bc05;
+	unsigned char  f5bc5x;
+	unsigned char  f5bc6x;
+	/******************* LRDIMM special *****************/
+	unsigned char  vrefdq_pr0;
+	unsigned char  vrefdq_mdram;
+	unsigned char  rtt_mdram_1866;
+	unsigned char  rtt_mdram_2400;
+	unsigned char  rtt_mdram_3200;
+
+	unsigned char  drive_dram;
+	unsigned char  odt_dram_1866;
+	unsigned char  odt_dram_2400;
+	unsigned char  odt_dram_3200;
+	unsigned char  park_dram_1866;
+	unsigned char  park_dram_2400;
+	unsigned char  park_dram_3200;
+	unsigned char  rcd_num;
+} __attribute((aligned(4)));
+
+struct mcu_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+
+	unsigned char ch_enable;
+	unsigned char misc1_enable;
+	unsigned char misc2_enable;
+	unsigned char force_spd_enable;
+	unsigned char misc3_enable;
+	unsigned char train_debug;
+	unsigned char train_recover;
+	unsigned char rev2[9];
+
+	struct ddr_spd ddr_spd_info[2];
+} __attribute((aligned(4)));
+
+static void get_mcu_up_info_default(struct mcu_config *pm)
+{
+	pm->magic		= PARAMETER_MCU_MAGIC;
+	pm->version		= PARAM_MCU_VERSION;
+	pm->size		= PARAM_MCU_SIZE;
+	pm->ch_enable		= PARAM_CH_ENABLE;
+	pm->misc1_enable	= PARAM_ECC_ENABLE;
+	pm->force_spd_enable	= PARAM_FORCE_SPD_DISABLE;
+	pm->misc3_enable	= PARAM_MCU_MISC_ENABLE;
+	pm->train_recover	= 0x0;
+}
+
+static unsigned char init_dimm_param(unsigned char ch, struct mcu_config *pm)
+{
+	printf("manual config dimm info...\n");
+	pm->ddr_spd_info[ch].dimm_type = UDIMM_TYPE;
+	pm->ddr_spd_info[ch].data_width = DIMM_X8;
+	pm->ddr_spd_info[ch].mirror_type = NO_MIRROR;
+	pm->ddr_spd_info[ch].ecc_type = NO_ECC_TYPE;
+	pm->ddr_spd_info[ch].dram_type = DDR4_TYPE;
+	pm->ddr_spd_info[ch].rank_num = 1;
+	pm->ddr_spd_info[ch].row_num  = 16;
+	pm->ddr_spd_info[ch].col_num = 10;
+	pm->ddr_spd_info[ch].bg_num = 4;
+	pm->ddr_spd_info[ch].bank_num = 4;
+	pm->ddr_spd_info[ch].taamin = 13750;
+	pm->ddr_spd_info[ch].trcdmin = 13750;
+
+	pm->ddr_spd_info[ch].trpmin = 13750;
+	pm->ddr_spd_info[ch].trasmin = 32000;
+	pm->ddr_spd_info[ch].trcmin =  45750;
+	pm->ddr_spd_info[ch].tfawmin = 21000;
+
+	pm->ddr_spd_info[ch].trrd_smin = 3000;
+	pm->ddr_spd_info[ch].trrd_lmin = 4900;
+	pm->ddr_spd_info[ch].tccd_lmin = 5000;
+	pm->ddr_spd_info[ch].twrmin = 15000;
+
+	pm->ddr_spd_info[ch].twtr_smin = 2500;
+	pm->ddr_spd_info[ch].twtr_lmin = 7500;
+
+	return 0;
+}
+
+void get_default_mcu_info(unsigned char *data)
+{
+	get_mcu_up_info_default((struct mcu_config *)data);
+}
+
+void fix_mcu_info(unsigned char *data)
+{
+	unsigned char ch;
+	struct mcu_config *mcu_info = (struct mcu_config *)data;
+
+	for (ch = 0; ch < 2; ch++)
+		init_dimm_param(ch, mcu_info);
+}
+
+void ddr_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	get_default_mcu_info(buffer);
+	fix_mcu_info(buffer);
+
+	arm_smccc_smc(CPU_INIT_MEM, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+	if (res.a0 != 0) {
+		printf("error x0: 0x%lx, x1: 0x%lx\n", res.a0, res.a1);
+		while (true)
+			;
+	}
+}
diff --git a/board/phytium/pomelo/pcie.c b/board/phytium/pomelo/pcie.c
new file mode 100644
index 0000000000..6d7792f0be
--- /dev/null
+++ b/board/phytium/pomelo/pcie.c
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <common.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct pcu_ctr {
+	unsigned int base_config[3];
+	unsigned int equalization[3];
+	unsigned char rev[80];
+} __attribute((aligned(4)));
+
+struct pcu_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+	unsigned int independent_tree;
+	unsigned int base_cfg;
+	unsigned char rev2[16];
+	struct pcu_ctr ctr_cfg[2];
+} __attribute((aligned(4)));
+
+struct pcu_config const peu_base_info = {
+	.magic = PARAMETER_PCIE_MAGIC,
+	.version = 0x2,
+	.size = 0x100,
+	.independent_tree = CONFIG_INDEPENDENT_TREE,
+	.base_cfg = ((PCI_PEU1 | (X8X8 << 1)) << PEU1_OFFSET | (PCI_PEU0 | (X8X8 << 1))),
+	.ctr_cfg[0].base_config[0] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[0].base_config[1] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[0].base_config[2] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[1].base_config[0] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[1].base_config[1] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[1].base_config[2] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[0].equalization[0] = 0x7,
+	.ctr_cfg[0].equalization[1] = 0x7,
+	.ctr_cfg[0].equalization[2] = 0x7,
+	.ctr_cfg[1].equalization[0] = 0x7,
+	.ctr_cfg[1].equalization[1] = 0x7,
+	.ctr_cfg[1].equalization[2] = 0x7,
+};
+
+void pcie_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	memcpy(buffer, &peu_base_info, sizeof(peu_base_info));
+	arm_smccc_smc(CPU_INIT_PCIE, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+	if (res.a0 != 0) {
+		while (true)
+			;
+	}
+}
diff --git a/board/phytium/pomelo/pll.c b/board/phytium/pomelo/pll.c
new file mode 100644
index 0000000000..095131e815
--- /dev/null
+++ b/board/phytium/pomelo/pll.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct pll_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+	unsigned int core_pll;
+	unsigned int res1;
+	unsigned int lmu_pll;
+	unsigned int res2;
+	unsigned int res3;
+	unsigned int res4;
+	unsigned int res5;
+} __attribute((aligned(4)));
+
+struct pll_config const pll_base_info = {
+	.magic = PARAMETER_PLL_MAGIC,
+	.version = 0x1,
+	.size = 0x30,
+	.core_pll = 2300,	/*MHz*/
+	.lmu_pll = 667,		/*MHz*/
+};
+
+unsigned int get_reset_source(void)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(CPU_GET_RST_SOURCE, 0, 0, 0, 0, 0, 0, 0, &res);
+	return res.a0;
+}
+
+void pll_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	memcpy(buffer, &pll_base_info, sizeof(pll_base_info));
+	arm_smccc_smc(CPU_INIT_PLL, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+	if (res.a0 != 0) {
+		while (true)
+			;
+	}
+}
+
+void check_reset(void)
+{
+	unsigned int rst;
+
+	rst = get_reset_source();
+
+	switch (rst) {
+	case CPU_RESET_POWER_ON:
+		pll_init();
+		break;
+	case CPU_RESET_PLL:
+		break;
+	case CPU_RESET_WATCH_DOG:
+		break;
+	default:
+		while (true)
+			;
+	}
+}
diff --git a/board/phytium/pomelo/pomelo.c b/board/phytium/pomelo/pomelo.c
new file mode 100644
index 0000000000..6442bb80d3
--- /dev/null
+++ b/board/phytium/pomelo/pomelo.c
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <common.h>
+#include <command.h>
+#include <init.h>
+#include <asm/armv8/mmu.h>
+#include <asm/io.h>
+#include <linux/arm-smccc.h>
+#include <scsi.h>
+#include "cpu.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+	gd->mem_clk = 0;
+	gd->ram_size = PHYS_SDRAM_1_SIZE;
+
+	printf("Phytium ddr init\n");
+
+	ddr_init();
+	sec_init();
+	printf("PBF relocate done\n");
+
+	return 0;
+}
+
+int board_init(void)
+{
+	return 0;
+}
+
+void reset_cpu(void)
+{
+	struct arm_smccc_res res;
+
+	printf("run in reset cpu\n");
+	arm_smccc_smc(0x84000009, 0, 0, 0, 0, 0, 0, 0, &res);
+	printf("reset cpu error, %lx\n", res.a0);
+}
+
+int mach_cpu_init(void)
+{
+	check_reset();
+	return 0;
+}
+
+int board_early_init_f(void)
+{
+	pcie_init();
+	return 0;
+}
+
+int board_early_init_r(void)
+{
+	return 0;
+}
+
+static struct mm_region pomelo_mem_map[] = {
+	{
+		.virt = 0x0UL,
+		.phys = 0x0UL,
+		.size = 0x80000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+				 PTE_BLOCK_NON_SHARE |
+				 PTE_BLOCK_PXN |
+				 PTE_BLOCK_UXN
+	},
+	{
+		.virt = (u64)PHYS_SDRAM_1,
+		.phys = (u64)PHYS_SDRAM_1,
+		.size = (u64)PHYS_SDRAM_1_SIZE,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+				 PTE_BLOCK_NS |
+				 PTE_BLOCK_INNER_SHARE
+	},
+	{
+		0,
+	}
+};
+
+struct mm_region *mem_map = pomelo_mem_map;
+
+int __asm_flush_l3_dcache(void)
+{
+	int i, pstate;
+
+	for (i = 0; i < HNF_COUNT; i++)
+		writeq(HNF_PSTATE_SFONLY, HNF_PSTATE_REQ + i * HNF_STRIDE);
+	for (i = 0; i < HNF_COUNT; i++) {
+		do {
+			pstate = readq(HNF_PSTATE_STAT + i * HNF_STRIDE);
+		} while ((pstate & 0xf) != (HNF_PSTATE_SFONLY << 2));
+	}
+
+	for (i = 0; i < HNF_COUNT; i++)
+		writeq(HNF_PSTATE_FULL, HNF_PSTATE_REQ + i * HNF_STRIDE);
+
+	return 0;
+}
+
+int last_stage_init(void)
+{
+	int ret;
+
+	/* pci e */
+	pci_init();
+	/* scsi scan */
+	ret = scsi_scan(true);
+	if (ret) {
+		printf("scsi scan failed\n");
+		return CMD_RET_FAILURE;
+	}
+	return ret;
+}
diff --git a/board/phytium/pomelo/sec.c b/board/phytium/pomelo/sec.c
new file mode 100644
index 0000000000..c000b3f369
--- /dev/null
+++ b/board/phytium/pomelo/sec.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <common.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct common_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+	unsigned long long  core_bit_map;
+} __attribute((aligned(4)));
+
+struct common_config const common_base_info = {
+	.magic = PARAMETER_COMMON_MAGIC,
+	.version = 0x1,
+	.core_bit_map = 0x3333,
+};
+
+void sec_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	memcpy(buffer, &common_base_info, sizeof(common_base_info));
+	arm_smccc_smc(CPU_INIT_SEC_SVC, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+
+	if (res.a0 != 0) {
+		printf("error ret %lx\n", res.a0);
+		while (true)
+			;
+	}
+}
diff --git a/configs/pomelo_defconfig b/configs/pomelo_defconfig
new file mode 100644
index 0000000000..3e6c18196d
--- /dev/null
+++ b/configs/pomelo_defconfig
@@ -0,0 +1,36 @@
+CONFIG_ARM=y
+CONFIG_ARM_SMCCC=y
+CONFIG_TARGET_POMELO=y
+CONFIG_SYS_TEXT_BASE=0x180000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x1000
+# CONFIG_PSCI_RESET is not set
+CONFIG_DEFAULT_DEVICE_TREE="phytium-pomelo"
+CONFIG_AHCI=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyAMA0,115200 earlycon=pl011,0x28001000 root=/dev/sda2 rw"
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_LAST_STAGE_INIT=y
+CONFIG_SYS_PROMPT="pomelo#"
+# CONFIG_CMD_LZMADEC is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_PCI=y
+CONFIG_OF_CONTROL=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+# CONFIG_NET is not set
+CONFIG_DM=y
+CONFIG_SCSI_AHCI=y
+CONFIG_AHCI_PCI=y
+CONFIG_BLK=y
+# CONFIG_MMC is not set
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
+CONFIG_PCI_PHYTIUM=y
+CONFIG_PCIE_ECAM_GENERIC=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
+CONFIG_DM_SERIAL=y
+CONFIG_PL01X_SERIAL=y
diff --git a/include/configs/pomelo.h b/include/configs/pomelo.h
new file mode 100644
index 0000000000..69c4195d86
--- /dev/null
+++ b/include/configs/pomelo.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#ifndef __POMELO_CONFIG_H__
+#define __POMELO_CONFIG_H__
+
+/* SDRAM Bank #1 start address */
+#define PHYS_SDRAM_1			0x80000000
+#define PHYS_SDRAM_1_SIZE		0x7B000000
+#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
+
+#define CONFIG_SYS_LOAD_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x10000000)
+
+/* SIZE of malloc pool */
+#define CONFIG_SYS_MALLOC_LEN		(1 * 1024 * 1024  + CONFIG_ENV_SIZE)
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_BOARD_EARLY_INIT_R
+
+#define CONFIG_SYS_INIT_SP_ADDR		(0x29800000 + 0x1a000)
+
+/* PCI CONFIG */
+#define CONFIG_SYS_PCI_64BIT		1
+#define CONFIG_PCI_SCAN_SHOW
+
+/* SCSI */
+#define CONFIG_SYS_SCSI_MAX_SCSI_ID	4
+#define CONFIG_SYS_SCSI_MAX_LUN		1
+#define CONFIG_SYS_SCSI_MAX_DEVICE	128
+#define CONFIG_SCSI_AHCI_PLAT
+#define CONFIG_SYS_SATA_MAX_DEVICE	4
+
+/*BOOT*/
+#define CONFIG_SYS_BOOTM_LEN		(60 * 1024 * 1024)
+
+#define CONFIG_EXTRA_ENV_SETTINGS	\
+	"load_kernel=ext4load scsi 0:1 0x90100000 uImage_old\0"	\
+	"load_fdt=ext4load scsi 0:1 0x95000000 ft-d2000.dtb\0"\
+	"boot_fdt=bootm 0x90100000 -:- 0x17c000\0"	\
+	"distro_bootcmd=run load_kernel; run boot_fdt"
+
+#endif
-- 
2.17.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] arm: add initial support for the Phytium Pomelo Board
  2021-06-09  9:34 nicholas_zheng
@ 2021-06-09 12:09 ` Tom Rini
  0 siblings, 0 replies; 12+ messages in thread
From: Tom Rini @ 2021-06-09 12:09 UTC (permalink / raw)
  To: nicholas_zheng
  Cc: bharat.gooty, rayagonda.kokatanur, jagan, kever.yang,
	andre.przywara, festevam, patrick.delaunay, tharvey, pbrobinson,
	hs, lokeshvutla, d-gerlach, u-boot

[-- Attachment #1: Type: text/plain, Size: 416 bytes --]

On Wed, Jun 09, 2021 at 05:34:36PM +0800, nicholas_zheng@outlook.com wrote:

> From: weichangzheng <nicholas_zheng@outlook.com>
> 
> This adds platform code and the device tree for the Phytium Pomelo Board.
> The initial support comprises the UART and the PCIE.
> 
> Signed-off-by: weichangzheng <nicholas_zheng@outlook.com>

Running checkpatch.pl shows CamelCase problems, please fix, thanks.

-- 
Tom

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH] arm: add initial support for the Phytium Pomelo Board
@ 2021-06-09  9:34 nicholas_zheng
  2021-06-09 12:09 ` Tom Rini
  0 siblings, 1 reply; 12+ messages in thread
From: nicholas_zheng @ 2021-06-09  9:34 UTC (permalink / raw)
  To: trini, bharat.gooty, rayagonda.kokatanur
  Cc: jagan, kever.yang, andre.przywara, festevam, patrick.delaunay,
	tharvey, pbrobinson, hs, lokeshvutla, d-gerlach, u-boot,
	weichangzheng

From: weichangzheng <nicholas_zheng@outlook.com>

This adds platform code and the device tree for the Phytium Pomelo Board.
The initial support comprises the UART and the PCIE.

Signed-off-by: weichangzheng <nicholas_zheng@outlook.com>
---
 arch/arm/Kconfig                 |   8 ++
 arch/arm/dts/Makefile            |   1 +
 arch/arm/dts/phytium-pomelo.dts  |  34 +++++++
 board/phytium/pomelo/Kconfig     |  12 +++
 board/phytium/pomelo/MAINTAINERS |   8 ++
 board/phytium/pomelo/Makefile    |  14 +++
 board/phytium/pomelo/cpu.h       |  73 ++++++++++++++
 board/phytium/pomelo/ddr.c       | 164 +++++++++++++++++++++++++++++++
 board/phytium/pomelo/pcie.c      |  60 +++++++++++
 board/phytium/pomelo/pll.c       |  74 ++++++++++++++
 board/phytium/pomelo/pomelo.c    | 120 ++++++++++++++++++++++
 board/phytium/pomelo/sec.c       |  39 ++++++++
 configs/pomelo_defconfig         |  36 +++++++
 include/configs/pomelo.h         |  45 +++++++++
 14 files changed, 688 insertions(+)
 create mode 100644 arch/arm/dts/phytium-pomelo.dts
 create mode 100644 board/phytium/pomelo/Kconfig
 create mode 100644 board/phytium/pomelo/MAINTAINERS
 create mode 100644 board/phytium/pomelo/Makefile
 create mode 100644 board/phytium/pomelo/cpu.h
 create mode 100644 board/phytium/pomelo/ddr.c
 create mode 100644 board/phytium/pomelo/pcie.c
 create mode 100644 board/phytium/pomelo/pll.c
 create mode 100644 board/phytium/pomelo/pomelo.c
 create mode 100644 board/phytium/pomelo/sec.c
 create mode 100644 configs/pomelo_defconfig
 create mode 100644 include/configs/pomelo.h

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 31d687ea01..6110fcddad 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1800,6 +1800,13 @@ config TARGET_DURIAN
 	  Support for durian platform.
 	  It has 2GB Sdram, uart and pcie.
 
+config TARGET_POMELO
+	bool "Support Phytium Pomelo Platform"
+	select ARM64
+	help
+		Support for pomelo platform.
+		It has 2GB Sdram, uart and pcie.
+
 config TARGET_PRESIDIO_ASIC
 	bool "Support Cortina Presidio ASIC Platform"
 	select ARM64
@@ -2019,6 +2026,7 @@ source "board/toradex/colibri_pxa270/Kconfig"
 source "board/variscite/dart_6ul/Kconfig"
 source "board/vscom/baltos/Kconfig"
 source "board/phytium/durian/Kconfig"
+source "board/phytium/pomelo/Kconfig"
 source "board/xen/xenguest_arm64/Kconfig"
 source "board/keymile/Kconfig"
 
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index 096068261d..c26692c17e 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -1098,6 +1098,7 @@ dtb-$(CONFIG_TARGET_MX53PPD) += imx53-ppd.dtb
 dtb-$(CONFIG_TARGET_TOTAL_COMPUTE) += total_compute.dtb
 
 dtb-$(CONFIG_TARGET_DURIAN) += phytium-durian.dtb
+dtb-$(CONFIG_TARGET_POMELO) += phytium-pomelo.dtb
 
 dtb-$(CONFIG_TARGET_PRESIDIO_ASIC) += ca-presidio-engboard.dtb
 
diff --git a/arch/arm/dts/phytium-pomelo.dts b/arch/arm/dts/phytium-pomelo.dts
new file mode 100644
index 0000000000..e9602cb3a8
--- /dev/null
+++ b/arch/arm/dts/phytium-pomelo.dts
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021, Phytium Ltd.
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+/dts-v1/;
+
+/memreserve/	0x0000000080000000 0x0000000000100000;
+/ {
+	model = "Phytium Pomelo";
+	compatible = "phytium,pomelo";
+	#address-cells = <2>;
+	#size-cells = <2>;
+
+	pcie-controller@40000000 {
+		compatible = "pci-host-ecam-generic";
+		device_type = "pci";
+		#address-cells = <3>;
+		#size-cells = <2>;
+		reg = <0x0 0x40000000 0x0 0x10000000>;
+		bus-range = <0x0 0xff>;
+		ranges = <0x01000000 0x00 0x00000000 0x0  0x50000000 0x0  0x00F00000>,
+			 <0x02000000 0x00 0x58000000 0x0  0x58000000 0x0  0x28000000>,
+			 <0x43000000 0x10 0x00000000 0x10 0x00000000 0x10  0x00000000>;
+	};
+
+	uart@28001000 {
+		compatible = "arm,pl011";
+		reg = <0x0 0x28001000 0x0 0x1000>;
+		clock = <48000000>;
+	};
+};
diff --git a/board/phytium/pomelo/Kconfig b/board/phytium/pomelo/Kconfig
new file mode 100644
index 0000000000..281aa8feff
--- /dev/null
+++ b/board/phytium/pomelo/Kconfig
@@ -0,0 +1,12 @@
+if TARGET_POMELO
+
+config SYS_BOARD
+	default "pomelo"
+
+config SYS_VENDOR
+	default "phytium"
+
+config SYS_CONFIG_NAME
+	default "pomelo"
+
+endif
diff --git a/board/phytium/pomelo/MAINTAINERS b/board/phytium/pomelo/MAINTAINERS
new file mode 100644
index 0000000000..07737f0f22
--- /dev/null
+++ b/board/phytium/pomelo/MAINTAINERS
@@ -0,0 +1,8 @@
+DURIAN BOARD
+M:	lixinde <lixinde@phytium.com.cn>
+M:	weichangzheng <weichangzheng@phytium.com.cn>
+S:	Maintained
+F:	board/phytium/pomelo/*
+F:	include/configs/pomelo.h
+F:	configs/pomelo_defconfig
+
diff --git a/board/phytium/pomelo/Makefile b/board/phytium/pomelo/Makefile
new file mode 100644
index 0000000000..b9cb3609bd
--- /dev/null
+++ b/board/phytium/pomelo/Makefile
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright (C) 2021
+# lixinde         <lixinde@phytium.com.cn>
+# weichangzheng   <weichangzheng@phytium.com.cn>
+#
+
+obj-y += pomelo.o
+obj-y += pll.o
+obj-y += pcie.o
+obj-y += ddr.o
+obj-y += sec.o
+
+
diff --git a/board/phytium/pomelo/cpu.h b/board/phytium/pomelo/cpu.h
new file mode 100644
index 0000000000..e15917609b
--- /dev/null
+++ b/board/phytium/pomelo/cpu.h
@@ -0,0 +1,73 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * (C) Copyright 2021
+ * Phytium Technology Ltd <www.phytium.com>
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#ifndef _FT_POMELO_H
+#define _FT_POMELO_H
+
+/* SMCCC ID */
+#define CPU_SVC_VERSION			0xC2000F00
+#define CPU_GET_RST_SOURCE		0xC2000F01
+#define CPU_INIT_PLL			0xC2000F02
+#define CPU_INIT_PCIE			0xC2000F03
+#define CPU_INIT_MEM			0xC2000F04
+#define CPU_INIT_SEC_SVC		0xC2000F05
+
+/*CPU RESET*/
+#define CPU_RESET_POWER_ON		0x1
+#define CPU_RESET_PLL			0x4
+#define CPU_RESET_WATCH_DOG		0x8
+
+/* PLL */
+#define PARAMETER_PLL_MAGIC		0x54460010
+
+/* PCIE */
+#define PARAMETER_PCIE_MAGIC		0x54460011
+#define CONFIG_INDEPENDENT_TREE		0x0
+#define PCI_PEU0			0x1
+#define PCI_PEU1			0x1
+#define PEU1_OFFSET			16
+#define PEU_C_OFFSET_MODE		16
+#define PEU_C_OFFSET_SPEED		0
+#define RC_MODE				0x1
+#define X8X8				0x1
+#define GEN3				3
+
+/* DDR */
+#define PARAMETER_MCU_MAGIC		0x54460014
+#define PARAM_MCU_VERSION		0x1
+#define PARAM_MCU_SIZE			0x100
+#define PARAM_CH_ENABLE			0x3
+#define PARAM_ECC_ENABLE		0x3
+#define PARAM_FORCE_SPD_DISABLE		0x0
+#define PARAM_MCU_MISC_ENABLE		0x0
+
+#define UDIMM_TYPE			0x2
+#define DIMM_X8				0x1
+#define NO_MIRROR			0x0
+#define NO_ECC_TYPE			0
+#define DDR4_TYPE			0xC
+
+/* SEC */
+#define PARAMETER_COMMON_MAGIC		0x54460013
+
+/* FLUSH L3 CASHE */
+#define HNF_COUNT			0x8
+#define HNF_PSTATE_REQ			(HNF_BASE + 0x10)
+#define HNF_PSTATE_STAT			(HNF_BASE + 0x18)
+#define HNF_PSTATE_OFF			0x0
+#define HNF_PSTATE_SFONLY		0x1
+#define HNF_PSTATE_HALF			0x2
+#define HNF_PSTATE_FULL			0x3
+#define HNF_STRIDE			0x10000
+#define HNF_BASE			(unsigned long)(0x3A200000)
+void ddr_init(void);
+void sec_init(void);
+void check_reset(void);
+void pcie_init(void);
+
+#endif /* _FT_POMELO_H */
diff --git a/board/phytium/pomelo/ddr.c b/board/phytium/pomelo/ddr.c
new file mode 100644
index 0000000000..b28a799926
--- /dev/null
+++ b/board/phytium/pomelo/ddr.c
@@ -0,0 +1,164 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <common.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct ddr_spd {
+	/******************* read from spd *****************/
+	unsigned char  dimm_type;	/* 1: RDIMM;2: UDIMM;3: SODIMM;4: LRDIMM */
+	unsigned char  data_width;	/* 0: x4; 1: x8; 2: x16 */
+	unsigned char  mirror_type;	/* 0: stardard; 1: mirror */
+	unsigned char  ecc_type;	/* 0: no-ecc; 1:ecc */
+	unsigned char  dram_type;	/* 0xB: DDR3; 0xC: DDR4 */
+	unsigned char  rank_num;
+	unsigned char  row_num;
+	unsigned char  col_num;
+
+	unsigned char  bg_num;	/*only DDR4*/
+	unsigned char  bank_num;
+	unsigned short int module_manufacturer_id;
+	unsigned short int tAAmin;
+	unsigned short int tRCDmin;
+
+	unsigned short int tRPmin;
+	unsigned short int tRASmin;
+	unsigned short int tRCmin;
+	unsigned short int tFAWmin;
+
+	unsigned short int tRRD_Smin;	/*only DDR4*/
+	unsigned short int tRRD_Lmin;	/*only DDR4*/
+	unsigned short int tCCD_Lmin;	/*only DDR4*/
+	unsigned short int tWRmin;
+
+	unsigned short int tWTR_Smin;	/*only DDR4*/
+	unsigned short int tWTR_Lmin;	/*only DDR4*/
+	unsigned short int tWTRmin;	/*only DDR3*/
+	unsigned short int tRRDmin;	/*only DDR3*/
+
+	/******************* RCD control words *****************/
+	unsigned char  F0RC03; /*bit[3:2]:CS		bit[1:0]:CA  */
+	unsigned char  F0RC04; /*bit[3:2]:ODT		bit[1:0]:CKE */
+	unsigned char  F0RC05; /*bit[3:2]:CLK-A side	bit[1:0]:CLK-B side */
+	unsigned char  BC00;
+	unsigned char  BC01;
+	unsigned char  BC02;
+	unsigned char  BC03;
+	unsigned char  BC04;
+
+	unsigned char  BC05;
+	unsigned char  F5BC5x;
+	unsigned char  F5BC6x;
+	/******************* LRDIMM special *****************/
+	unsigned char  vrefDQ_PR0;
+	unsigned char  vrefDQ_MDRAM;
+	unsigned char  RTT_MDRAM_1866;
+	unsigned char  RTT_MDRAM_2400;
+	unsigned char  RTT_MDRAM_3200;
+
+	unsigned char  Drive_DRAM;
+	unsigned char  ODT_DRAM_1866;
+	unsigned char  ODT_DRAM_2400;
+	unsigned char  ODT_DRAM_3200;
+	unsigned char  PARK_DRAM_1866;
+	unsigned char  PARK_DRAM_2400;
+	unsigned char  PARK_DRAM_3200;
+	unsigned char  rcd_num;
+} __attribute((aligned(4)));
+
+struct mcu_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+
+	unsigned char ch_enable;
+	unsigned char misc1_enable;
+	unsigned char misc2_enable;
+	unsigned char force_spd_enable;
+	unsigned char misc3_enable;
+	unsigned char train_debug;
+	unsigned char train_recover;
+	unsigned char rev2[9];
+
+	struct ddr_spd ddr_spd_info[2];
+} __attribute((aligned(4)));
+
+static void get_mcu_up_info_default(struct mcu_config *pm)
+{
+	pm->magic		= PARAMETER_MCU_MAGIC;
+	pm->version		= PARAM_MCU_VERSION;
+	pm->size		= PARAM_MCU_SIZE;
+	pm->ch_enable		= PARAM_CH_ENABLE;
+	pm->misc1_enable	= PARAM_ECC_ENABLE;
+	pm->force_spd_enable	= PARAM_FORCE_SPD_DISABLE;
+	pm->misc3_enable	= PARAM_MCU_MISC_ENABLE;
+	pm->train_recover	= 0x0;
+}
+
+static unsigned char init_dimm_param(unsigned char ch, struct mcu_config *pm)
+{
+	printf("manual config dimm info...\n");
+	pm->ddr_spd_info[ch].dimm_type = UDIMM_TYPE;
+	pm->ddr_spd_info[ch].data_width = DIMM_X8;
+	pm->ddr_spd_info[ch].mirror_type = NO_MIRROR;
+	pm->ddr_spd_info[ch].ecc_type = NO_ECC_TYPE;
+	pm->ddr_spd_info[ch].dram_type = DDR4_TYPE;
+	pm->ddr_spd_info[ch].rank_num = 1;
+	pm->ddr_spd_info[ch].row_num  = 16;
+	pm->ddr_spd_info[ch].col_num = 10;
+	pm->ddr_spd_info[ch].bg_num = 4;
+	pm->ddr_spd_info[ch].bank_num = 4;
+	pm->ddr_spd_info[ch].tAAmin = 13750;
+	pm->ddr_spd_info[ch].tRCDmin = 13750;
+
+	pm->ddr_spd_info[ch].tRPmin = 13750;
+	pm->ddr_spd_info[ch].tRASmin = 32000;
+	pm->ddr_spd_info[ch].tRCmin =  45750;
+	pm->ddr_spd_info[ch].tFAWmin = 21000;
+
+	pm->ddr_spd_info[ch].tRRD_Smin = 3000;
+	pm->ddr_spd_info[ch].tRRD_Lmin = 4900;
+	pm->ddr_spd_info[ch].tCCD_Lmin = 5000;
+	pm->ddr_spd_info[ch].tWRmin = 15000;
+
+	pm->ddr_spd_info[ch].tWTR_Smin = 2500;
+	pm->ddr_spd_info[ch].tWTR_Lmin = 7500;
+
+	return 0;
+}
+
+void get_default_mcu_info(unsigned char *data)
+{
+	get_mcu_up_info_default((struct mcu_config *)data);
+}
+
+void fix_mcu_info(unsigned char *data)
+{
+	unsigned char ch;
+	struct mcu_config *mcu_info = (struct mcu_config *)data;
+
+	for (ch = 0; ch < 2; ch++)
+		init_dimm_param(ch, mcu_info);
+}
+
+void ddr_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	get_default_mcu_info(buffer);
+	fix_mcu_info(buffer);
+
+	arm_smccc_smc(CPU_INIT_MEM, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+	if (res.a0 != 0) {
+		printf("error x0: 0x%lx, x1: 0x%lx\n", res.a0, res.a1);
+		while (true)
+			;
+	}
+}
diff --git a/board/phytium/pomelo/pcie.c b/board/phytium/pomelo/pcie.c
new file mode 100644
index 0000000000..6d7792f0be
--- /dev/null
+++ b/board/phytium/pomelo/pcie.c
@@ -0,0 +1,60 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <common.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct pcu_ctr {
+	unsigned int base_config[3];
+	unsigned int equalization[3];
+	unsigned char rev[80];
+} __attribute((aligned(4)));
+
+struct pcu_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+	unsigned int independent_tree;
+	unsigned int base_cfg;
+	unsigned char rev2[16];
+	struct pcu_ctr ctr_cfg[2];
+} __attribute((aligned(4)));
+
+struct pcu_config const peu_base_info = {
+	.magic = PARAMETER_PCIE_MAGIC,
+	.version = 0x2,
+	.size = 0x100,
+	.independent_tree = CONFIG_INDEPENDENT_TREE,
+	.base_cfg = ((PCI_PEU1 | (X8X8 << 1)) << PEU1_OFFSET | (PCI_PEU0 | (X8X8 << 1))),
+	.ctr_cfg[0].base_config[0] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[0].base_config[1] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[0].base_config[2] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[1].base_config[0] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[1].base_config[1] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[1].base_config[2] = (RC_MODE << PEU_C_OFFSET_MODE) | (GEN3 << PEU_C_OFFSET_SPEED),
+	.ctr_cfg[0].equalization[0] = 0x7,
+	.ctr_cfg[0].equalization[1] = 0x7,
+	.ctr_cfg[0].equalization[2] = 0x7,
+	.ctr_cfg[1].equalization[0] = 0x7,
+	.ctr_cfg[1].equalization[1] = 0x7,
+	.ctr_cfg[1].equalization[2] = 0x7,
+};
+
+void pcie_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	memcpy(buffer, &peu_base_info, sizeof(peu_base_info));
+	arm_smccc_smc(CPU_INIT_PCIE, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+	if (res.a0 != 0) {
+		while (true)
+			;
+	}
+}
diff --git a/board/phytium/pomelo/pll.c b/board/phytium/pomelo/pll.c
new file mode 100644
index 0000000000..095131e815
--- /dev/null
+++ b/board/phytium/pomelo/pll.c
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct pll_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+	unsigned int core_pll;
+	unsigned int res1;
+	unsigned int lmu_pll;
+	unsigned int res2;
+	unsigned int res3;
+	unsigned int res4;
+	unsigned int res5;
+} __attribute((aligned(4)));
+
+struct pll_config const pll_base_info = {
+	.magic = PARAMETER_PLL_MAGIC,
+	.version = 0x1,
+	.size = 0x30,
+	.core_pll = 2300,	/*MHz*/
+	.lmu_pll = 667,		/*MHz*/
+};
+
+unsigned int get_reset_source(void)
+{
+	struct arm_smccc_res res;
+
+	arm_smccc_smc(CPU_GET_RST_SOURCE, 0, 0, 0, 0, 0, 0, 0, &res);
+	return res.a0;
+}
+
+void pll_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	memcpy(buffer, &pll_base_info, sizeof(pll_base_info));
+	arm_smccc_smc(CPU_INIT_PLL, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+	if (res.a0 != 0) {
+		while (true)
+			;
+	}
+}
+
+void check_reset(void)
+{
+	unsigned int rst;
+
+	rst = get_reset_source();
+
+	switch (rst) {
+	case CPU_RESET_POWER_ON:
+		pll_init();
+		break;
+	case CPU_RESET_PLL:
+		break;
+	case CPU_RESET_WATCH_DOG:
+		break;
+	default:
+		while (true)
+			;
+	}
+}
diff --git a/board/phytium/pomelo/pomelo.c b/board/phytium/pomelo/pomelo.c
new file mode 100644
index 0000000000..6442bb80d3
--- /dev/null
+++ b/board/phytium/pomelo/pomelo.c
@@ -0,0 +1,120 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <common.h>
+#include <command.h>
+#include <init.h>
+#include <asm/armv8/mmu.h>
+#include <asm/io.h>
+#include <linux/arm-smccc.h>
+#include <scsi.h>
+#include "cpu.h"
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+	gd->mem_clk = 0;
+	gd->ram_size = PHYS_SDRAM_1_SIZE;
+
+	printf("Phytium ddr init\n");
+
+	ddr_init();
+	sec_init();
+	printf("PBF relocate done\n");
+
+	return 0;
+}
+
+int board_init(void)
+{
+	return 0;
+}
+
+void reset_cpu(void)
+{
+	struct arm_smccc_res res;
+
+	printf("run in reset cpu\n");
+	arm_smccc_smc(0x84000009, 0, 0, 0, 0, 0, 0, 0, &res);
+	printf("reset cpu error, %lx\n", res.a0);
+}
+
+int mach_cpu_init(void)
+{
+	check_reset();
+	return 0;
+}
+
+int board_early_init_f(void)
+{
+	pcie_init();
+	return 0;
+}
+
+int board_early_init_r(void)
+{
+	return 0;
+}
+
+static struct mm_region pomelo_mem_map[] = {
+	{
+		.virt = 0x0UL,
+		.phys = 0x0UL,
+		.size = 0x80000000UL,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+				 PTE_BLOCK_NON_SHARE |
+				 PTE_BLOCK_PXN |
+				 PTE_BLOCK_UXN
+	},
+	{
+		.virt = (u64)PHYS_SDRAM_1,
+		.phys = (u64)PHYS_SDRAM_1,
+		.size = (u64)PHYS_SDRAM_1_SIZE,
+		.attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
+				 PTE_BLOCK_NS |
+				 PTE_BLOCK_INNER_SHARE
+	},
+	{
+		0,
+	}
+};
+
+struct mm_region *mem_map = pomelo_mem_map;
+
+int __asm_flush_l3_dcache(void)
+{
+	int i, pstate;
+
+	for (i = 0; i < HNF_COUNT; i++)
+		writeq(HNF_PSTATE_SFONLY, HNF_PSTATE_REQ + i * HNF_STRIDE);
+	for (i = 0; i < HNF_COUNT; i++) {
+		do {
+			pstate = readq(HNF_PSTATE_STAT + i * HNF_STRIDE);
+		} while ((pstate & 0xf) != (HNF_PSTATE_SFONLY << 2));
+	}
+
+	for (i = 0; i < HNF_COUNT; i++)
+		writeq(HNF_PSTATE_FULL, HNF_PSTATE_REQ + i * HNF_STRIDE);
+
+	return 0;
+}
+
+int last_stage_init(void)
+{
+	int ret;
+
+	/* pci e */
+	pci_init();
+	/* scsi scan */
+	ret = scsi_scan(true);
+	if (ret) {
+		printf("scsi scan failed\n");
+		return CMD_RET_FAILURE;
+	}
+	return ret;
+}
diff --git a/board/phytium/pomelo/sec.c b/board/phytium/pomelo/sec.c
new file mode 100644
index 0000000000..c000b3f369
--- /dev/null
+++ b/board/phytium/pomelo/sec.c
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#include <common.h>
+#include <linux/arm-smccc.h>
+#include "cpu.h"
+
+struct common_config {
+	unsigned int magic;
+	unsigned int version;
+	unsigned int size;
+	unsigned char rev1[4];
+	unsigned long long  core_bit_map;
+} __attribute((aligned(4)));
+
+struct common_config const common_base_info = {
+	.magic = PARAMETER_COMMON_MAGIC,
+	.version = 0x1,
+	.core_bit_map = 0x3333,
+};
+
+void sec_init(void)
+{
+	unsigned char buffer[0x100];
+	struct arm_smccc_res res;
+
+	memcpy(buffer, &common_base_info, sizeof(common_base_info));
+	arm_smccc_smc(CPU_INIT_SEC_SVC, 0, (u64)buffer, 0, 0, 0, 0, 0, &res);
+
+	if (res.a0 != 0) {
+		printf("error ret %lx\n", res.a0);
+		while (true)
+			;
+	}
+}
diff --git a/configs/pomelo_defconfig b/configs/pomelo_defconfig
new file mode 100644
index 0000000000..3e6c18196d
--- /dev/null
+++ b/configs/pomelo_defconfig
@@ -0,0 +1,36 @@
+CONFIG_ARM=y
+CONFIG_ARM_SMCCC=y
+CONFIG_TARGET_POMELO=y
+CONFIG_SYS_TEXT_BASE=0x180000
+CONFIG_NR_DRAM_BANKS=1
+CONFIG_ENV_SIZE=0x1000
+# CONFIG_PSCI_RESET is not set
+CONFIG_DEFAULT_DEVICE_TREE="phytium-pomelo"
+CONFIG_AHCI=y
+CONFIG_DISTRO_DEFAULTS=y
+CONFIG_USE_BOOTARGS=y
+CONFIG_BOOTARGS="console=ttyAMA0,115200 earlycon=pl011,0x28001000 root=/dev/sda2 rw"
+# CONFIG_DISPLAY_CPUINFO is not set
+# CONFIG_DISPLAY_BOARDINFO is not set
+CONFIG_LAST_STAGE_INIT=y
+CONFIG_SYS_PROMPT="pomelo#"
+# CONFIG_CMD_LZMADEC is not set
+# CONFIG_CMD_UNZIP is not set
+CONFIG_CMD_PCI=y
+CONFIG_OF_CONTROL=y
+CONFIG_SYS_RELOC_GD_ENV_ADDR=y
+# CONFIG_NET is not set
+CONFIG_DM=y
+CONFIG_SCSI_AHCI=y
+CONFIG_AHCI_PCI=y
+CONFIG_BLK=y
+# CONFIG_MMC is not set
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_DM_PCI_COMPAT=y
+CONFIG_PCI_PHYTIUM=y
+CONFIG_PCIE_ECAM_GENERIC=y
+CONFIG_SCSI=y
+CONFIG_DM_SCSI=y
+CONFIG_DM_SERIAL=y
+CONFIG_PL01X_SERIAL=y
diff --git a/include/configs/pomelo.h b/include/configs/pomelo.h
new file mode 100644
index 0000000000..69c4195d86
--- /dev/null
+++ b/include/configs/pomelo.h
@@ -0,0 +1,45 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Copyright (C) 2021
+ * lixinde         <lixinde@phytium.com.cn>
+ * weichangzheng   <weichangzheng@phytium.com.cn>
+ */
+
+#ifndef __POMELO_CONFIG_H__
+#define __POMELO_CONFIG_H__
+
+/* SDRAM Bank #1 start address */
+#define PHYS_SDRAM_1			0x80000000
+#define PHYS_SDRAM_1_SIZE		0x7B000000
+#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
+
+#define CONFIG_SYS_LOAD_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x10000000)
+
+/* SIZE of malloc pool */
+#define CONFIG_SYS_MALLOC_LEN		(1 * 1024 * 1024  + CONFIG_ENV_SIZE)
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_BOARD_EARLY_INIT_R
+
+#define CONFIG_SYS_INIT_SP_ADDR		(0x29800000 + 0x1a000)
+
+/* PCI CONFIG */
+#define CONFIG_SYS_PCI_64BIT		1
+#define CONFIG_PCI_SCAN_SHOW
+
+/* SCSI */
+#define CONFIG_SYS_SCSI_MAX_SCSI_ID	4
+#define CONFIG_SYS_SCSI_MAX_LUN		1
+#define CONFIG_SYS_SCSI_MAX_DEVICE	128
+#define CONFIG_SCSI_AHCI_PLAT
+#define CONFIG_SYS_SATA_MAX_DEVICE	4
+
+/*BOOT*/
+#define CONFIG_SYS_BOOTM_LEN		(60 * 1024 * 1024)
+
+#define CONFIG_EXTRA_ENV_SETTINGS	\
+	"load_kernel=ext4load scsi 0:1 0x90100000 uImage_old\0"	\
+	"load_fdt=ext4load scsi 0:1 0x95000000 ft-d2000.dtb\0"\
+	"boot_fdt=bootm 0x90100000 -:- 0x17c000\0"	\
+	"distro_bootcmd=run load_kernel; run boot_fdt"
+
+#endif
-- 
2.17.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2021-06-29 11:39 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-06-16  6:16 [PATCH] arm: add initial support for the Phytium Pomelo Board nicholas_zheng
  -- strict thread matches above, loose matches on Subject: below --
2021-06-24  1:02 nicholas_zheng
2021-06-25 12:27 ` Andre Przywara
2021-06-29  7:41   ` 回复: " Nicholas zheng
2021-06-21  8:36 nicholas_zheng
2021-06-21  8:31 nicholas_zheng
2021-06-21  8:18 nicholas_zheng
2021-06-15  9:44 nicholas_zheng
2021-06-15 12:45 ` Tom Rini
2021-06-15 12:59 ` Peter Robinson
2021-06-09  9:34 nicholas_zheng
2021-06-09 12:09 ` Tom Rini

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.