1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2022 StarFive Technology Co., Ltd.
4  * Author: Yanhong Wang<yanhong.wang@starfivetech.com>
5  */
6 
7 #include <asm/arch/eeprom.h>
8 #include <asm/arch/gpio.h>
9 #include <asm/arch/regs.h>
10 #include <asm/arch/spl.h>
11 #include <asm/io.h>
12 #include <dt-bindings/clock/starfive,jh7110-crg.h>
13 #include <fdt_support.h>
14 #include <linux/libfdt.h>
15 #include <log.h>
16 #include <spl.h>
17 
18 DECLARE_GLOBAL_DATA_PTR;
19 #define JH7110_CLK_CPU_ROOT_OFFSET		0x0U
20 #define JH7110_CLK_CPU_ROOT_SHIFT		24
21 #define JH7110_CLK_CPU_ROOT_MASK		GENMASK(29, 24)
22 
spl_perform_fixups(struct spl_image_info * spl_image)23 void spl_perform_fixups(struct spl_image_info *spl_image)
24 {
25 	/* Update the memory size which read from eeprom or DT */
26 	fdt_fixup_memory(spl_image->fdt_addr, 0x40000000, gd->ram_size);
27 }
28 
jh7110_jtag_init(void)29 static void jh7110_jtag_init(void)
30 {
31 	/* nTRST: GPIO36 */
32 	SYS_IOMUX_DOEN(36, HIGH);
33 	SYS_IOMUX_DIN(36, 4);
34 	/* TDI: GPIO61 */
35 	SYS_IOMUX_DOEN(61, HIGH);
36 	SYS_IOMUX_DIN(61, 19);
37 	/* TMS: GPIO63 */
38 	SYS_IOMUX_DOEN(63, HIGH);
39 	SYS_IOMUX_DIN(63, 20);
40 	/* TCK: GPIO60 */
41 	SYS_IOMUX_DOEN(60, HIGH);
42 	SYS_IOMUX_DIN(60, 29);
43 	/* TDO: GPIO44 */
44 	SYS_IOMUX_DOEN(44, 8);
45 	SYS_IOMUX_DOUT(44, 22);
46 }
47 
spl_board_init_f(void)48 int spl_board_init_f(void)
49 {
50 	int ret;
51 
52 	jh7110_jtag_init();
53 
54 	ret = spl_dram_init();
55 	if (ret) {
56 		debug("JH7110 DRAM init failed: %d\n", ret);
57 		return ret;
58 	}
59 
60 	return 0;
61 }
62 
spl_boot_device(void)63 u32 spl_boot_device(void)
64 {
65 	u32 mode;
66 
67 	mode = in_le32(JH7110_BOOT_MODE_SELECT_REG)
68 				& JH7110_BOOT_MODE_SELECT_MASK;
69 	switch (mode) {
70 	case 0:
71 		return BOOT_DEVICE_SPI;
72 
73 	case 1:
74 		return BOOT_DEVICE_MMC2;
75 
76 	case 2:
77 		return BOOT_DEVICE_MMC1;
78 
79 	case 3:
80 		return BOOT_DEVICE_UART;
81 
82 	default:
83 		debug("Unsupported boot device 0x%x.\n", mode);
84 		return BOOT_DEVICE_NONE;
85 	}
86 }
87 
board_init_f(ulong dummy)88 void board_init_f(ulong dummy)
89 {
90 	int ret;
91 
92 	ret = spl_early_init();
93 	if (ret)
94 		panic("spl_early_init() failed: %d\n", ret);
95 
96 	riscv_cpu_setup();
97 	preloader_console_init();
98 
99 	/* Set the parent clock of cpu_root clock to pll0,
100 	 * it must be initialized here
101 	 */
102 	clrsetbits_le32(JH7110_SYS_CRG + JH7110_CLK_CPU_ROOT_OFFSET,
103 			JH7110_CLK_CPU_ROOT_MASK,
104 			BIT(JH7110_CLK_CPU_ROOT_SHIFT));
105 
106 	/* Set USB overcurrent overflow pin disable */
107 	SYS_IOMUX_DIN_DISABLED(2);
108 
109 	ret = spl_board_init_f();
110 	if (ret) {
111 		debug("spl_board_init_f init failed: %d\n", ret);
112 		return;
113 	}
114 }
115 
116 #if CONFIG_IS_ENABLED(LOAD_FIT)
board_fit_config_name_match(const char * name)117 int board_fit_config_name_match(const char *name)
118 {
119 	if (!strcmp(name, "starfive/jh7110-deepcomputing-fml13v01") &&
120 		    !strncmp(get_product_id_from_eeprom(), "FML13V01", 8)) {
121 		return 0;
122 	} else if (!strcmp(name, "starfive/jh7110-milkv-mars") &&
123 		    !strncmp(get_product_id_from_eeprom(), "MARS", 4)) {
124 		return 0;
125 	} else if (!strcmp(name, "starfive/jh7110-pine64-star64") &&
126 		    !strncmp(get_product_id_from_eeprom(), "STAR64", 6)) {
127 		return 0;
128 	} else if (!strcmp(name, "starfive/jh7110-starfive-visionfive-2-v1.2a") &&
129 		    !strncmp(get_product_id_from_eeprom(), "VF7110", 6)) {
130 		switch (get_pcb_revision_from_eeprom()) {
131 		case 'a':
132 		case 'A':
133 			return 0;
134 		}
135 	} else if (!strcmp(name, "starfive/jh7110-starfive-visionfive-2-v1.3b") &&
136 		    !strncmp(get_product_id_from_eeprom(), "VF7110", 6)) {
137 		switch (get_pcb_revision_from_eeprom()) {
138 		case 'b':
139 		case 'B':
140 			return 0;
141 		}
142 	}
143 
144 	return -EINVAL;
145 }
146 #endif
147