xref: /openbmc/u-boot/board/sunxi/board.c (revision 552452f80caf1e1069e547b6605987427e93111b)
183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2cba69eeeSIan Campbell /*
3cba69eeeSIan Campbell  * (C) Copyright 2012-2013 Henrik Nordstrom <henrik@henriknordstrom.net>
4cba69eeeSIan Campbell  * (C) Copyright 2013 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
5cba69eeeSIan Campbell  *
6cba69eeeSIan Campbell  * (C) Copyright 2007-2011
7cba69eeeSIan Campbell  * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
8cba69eeeSIan Campbell  * Tom Cubie <tangliang@allwinnertech.com>
9cba69eeeSIan Campbell  *
10cba69eeeSIan Campbell  * Some board init for the Allwinner A10-evb board.
11cba69eeeSIan Campbell  */
12cba69eeeSIan Campbell 
13cba69eeeSIan Campbell #include <common.h>
14237050fcSJagan Teki #include <dm.h>
15e79c7c88SHans de Goede #include <mmc.h>
166944aff1SHans de Goede #include <axp_pmic.h>
17237050fcSJagan Teki #include <generic-phy.h>
18237050fcSJagan Teki #include <phy-sun4i-usb.h>
19cba69eeeSIan Campbell #include <asm/arch/clock.h>
20b41d7d05SJonathan Liu #include <asm/arch/cpu.h>
212d7a084bSLuc Verhaegen #include <asm/arch/display.h>
22cba69eeeSIan Campbell #include <asm/arch/dram.h>
23e24ea55cSIan Campbell #include <asm/arch/gpio.h>
24e24ea55cSIan Campbell #include <asm/arch/mmc.h>
254a8c7c1fSHans de Goede #include <asm/arch/spl.h>
26d96ebc46SSiarhei Siamashka #ifndef CONFIG_ARM64
27d96ebc46SSiarhei Siamashka #include <asm/armv7.h>
28d96ebc46SSiarhei Siamashka #endif
294f7e01c9SHans de Goede #include <asm/gpio.h>
30b41d7d05SJonathan Liu #include <asm/io.h>
31a740ee91SPhilipp Tomsich #include <u-boot/crc.h>
324a8c7c1fSHans de Goede #include <environment.h>
33b08c8c48SMasahiro Yamada #include <linux/libfdt.h>
34f62bfa56SHans de Goede #include <nand.h>
35b41d7d05SJonathan Liu #include <net.h>
36f4c3523cSMaxime Ripard #include <spl.h>
370d8382aeSJelle van der Waa #include <sy8106a.h>
385d982856SSimon Glass #include <asm/setup.h>
39cba69eeeSIan Campbell 
4055410089SHans de Goede #if defined CONFIG_VIDEO_LCD_PANEL_I2C && !(defined CONFIG_SPL_BUILD)
4155410089SHans de Goede /* So that we can use pin names in Kconfig and sunxi_name_to_gpio() */
4255410089SHans de Goede int soft_i2c_gpio_sda;
4355410089SHans de Goede int soft_i2c_gpio_scl;
444f7e01c9SHans de Goede 
soft_i2c_board_init(void)454f7e01c9SHans de Goede static int soft_i2c_board_init(void)
464f7e01c9SHans de Goede {
474f7e01c9SHans de Goede 	int ret;
484f7e01c9SHans de Goede 
494f7e01c9SHans de Goede 	soft_i2c_gpio_sda = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_PANEL_I2C_SDA);
504f7e01c9SHans de Goede 	if (soft_i2c_gpio_sda < 0) {
514f7e01c9SHans de Goede 		printf("Error invalid soft i2c sda pin: '%s', err %d\n",
524f7e01c9SHans de Goede 		       CONFIG_VIDEO_LCD_PANEL_I2C_SDA, soft_i2c_gpio_sda);
534f7e01c9SHans de Goede 		return soft_i2c_gpio_sda;
544f7e01c9SHans de Goede 	}
554f7e01c9SHans de Goede 	ret = gpio_request(soft_i2c_gpio_sda, "soft-i2c-sda");
564f7e01c9SHans de Goede 	if (ret) {
574f7e01c9SHans de Goede 		printf("Error requesting soft i2c sda pin: '%s', err %d\n",
584f7e01c9SHans de Goede 		       CONFIG_VIDEO_LCD_PANEL_I2C_SDA, ret);
594f7e01c9SHans de Goede 		return ret;
604f7e01c9SHans de Goede 	}
614f7e01c9SHans de Goede 
624f7e01c9SHans de Goede 	soft_i2c_gpio_scl = sunxi_name_to_gpio(CONFIG_VIDEO_LCD_PANEL_I2C_SCL);
634f7e01c9SHans de Goede 	if (soft_i2c_gpio_scl < 0) {
644f7e01c9SHans de Goede 		printf("Error invalid soft i2c scl pin: '%s', err %d\n",
654f7e01c9SHans de Goede 		       CONFIG_VIDEO_LCD_PANEL_I2C_SCL, soft_i2c_gpio_scl);
664f7e01c9SHans de Goede 		return soft_i2c_gpio_scl;
674f7e01c9SHans de Goede 	}
684f7e01c9SHans de Goede 	ret = gpio_request(soft_i2c_gpio_scl, "soft-i2c-scl");
694f7e01c9SHans de Goede 	if (ret) {
704f7e01c9SHans de Goede 		printf("Error requesting soft i2c scl pin: '%s', err %d\n",
714f7e01c9SHans de Goede 		       CONFIG_VIDEO_LCD_PANEL_I2C_SCL, ret);
724f7e01c9SHans de Goede 		return ret;
734f7e01c9SHans de Goede 	}
744f7e01c9SHans de Goede 
754f7e01c9SHans de Goede 	return 0;
764f7e01c9SHans de Goede }
774f7e01c9SHans de Goede #else
soft_i2c_board_init(void)784f7e01c9SHans de Goede static int soft_i2c_board_init(void) { return 0; }
7955410089SHans de Goede #endif
8055410089SHans de Goede 
81cba69eeeSIan Campbell DECLARE_GLOBAL_DATA_PTR;
82cba69eeeSIan Campbell 
i2c_init_board(void)83acbc7e0aSJernej Skrabec void i2c_init_board(void)
84acbc7e0aSJernej Skrabec {
85acbc7e0aSJernej Skrabec #ifdef CONFIG_I2C0_ENABLE
86acbc7e0aSJernej Skrabec #if defined(CONFIG_MACH_SUN4I) || \
87acbc7e0aSJernej Skrabec     defined(CONFIG_MACH_SUN5I) || \
88acbc7e0aSJernej Skrabec     defined(CONFIG_MACH_SUN7I) || \
89acbc7e0aSJernej Skrabec     defined(CONFIG_MACH_SUN8I_R40)
90acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPB(0), SUN4I_GPB_TWI0);
91acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPB(1), SUN4I_GPB_TWI0);
92acbc7e0aSJernej Skrabec 	clock_twi_onoff(0, 1);
93acbc7e0aSJernej Skrabec #elif defined(CONFIG_MACH_SUN6I)
94acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPH(14), SUN6I_GPH_TWI0);
95acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPH(15), SUN6I_GPH_TWI0);
96acbc7e0aSJernej Skrabec 	clock_twi_onoff(0, 1);
97acbc7e0aSJernej Skrabec #elif defined(CONFIG_MACH_SUN8I)
98acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPH(2), SUN8I_GPH_TWI0);
99acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN8I_GPH_TWI0);
100acbc7e0aSJernej Skrabec 	clock_twi_onoff(0, 1);
101da1ae590SStefan Mavrodiev #elif defined(CONFIG_MACH_SUN50I)
102da1ae590SStefan Mavrodiev 	sunxi_gpio_set_cfgpin(SUNXI_GPH(0), SUN50I_GPH_TWI0);
103da1ae590SStefan Mavrodiev 	sunxi_gpio_set_cfgpin(SUNXI_GPH(1), SUN50I_GPH_TWI0);
104da1ae590SStefan Mavrodiev 	clock_twi_onoff(0, 1);
105acbc7e0aSJernej Skrabec #endif
106acbc7e0aSJernej Skrabec #endif
107acbc7e0aSJernej Skrabec 
108acbc7e0aSJernej Skrabec #ifdef CONFIG_I2C1_ENABLE
109acbc7e0aSJernej Skrabec #if defined(CONFIG_MACH_SUN4I) || \
110acbc7e0aSJernej Skrabec     defined(CONFIG_MACH_SUN7I) || \
111acbc7e0aSJernej Skrabec     defined(CONFIG_MACH_SUN8I_R40)
112acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPB(18), SUN4I_GPB_TWI1);
113acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN4I_GPB_TWI1);
114acbc7e0aSJernej Skrabec 	clock_twi_onoff(1, 1);
115acbc7e0aSJernej Skrabec #elif defined(CONFIG_MACH_SUN5I)
116acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPB(15), SUN5I_GPB_TWI1);
117acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPB(16), SUN5I_GPB_TWI1);
118acbc7e0aSJernej Skrabec 	clock_twi_onoff(1, 1);
119acbc7e0aSJernej Skrabec #elif defined(CONFIG_MACH_SUN6I)
120acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPH(16), SUN6I_GPH_TWI1);
121acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPH(17), SUN6I_GPH_TWI1);
122acbc7e0aSJernej Skrabec 	clock_twi_onoff(1, 1);
123acbc7e0aSJernej Skrabec #elif defined(CONFIG_MACH_SUN8I)
124acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPH(4), SUN8I_GPH_TWI1);
125acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPH(5), SUN8I_GPH_TWI1);
126acbc7e0aSJernej Skrabec 	clock_twi_onoff(1, 1);
127da1ae590SStefan Mavrodiev #elif defined(CONFIG_MACH_SUN50I)
128da1ae590SStefan Mavrodiev 	sunxi_gpio_set_cfgpin(SUNXI_GPH(2), SUN50I_GPH_TWI1);
129da1ae590SStefan Mavrodiev 	sunxi_gpio_set_cfgpin(SUNXI_GPH(3), SUN50I_GPH_TWI1);
130da1ae590SStefan Mavrodiev 	clock_twi_onoff(1, 1);
131acbc7e0aSJernej Skrabec #endif
132acbc7e0aSJernej Skrabec #endif
133acbc7e0aSJernej Skrabec 
134acbc7e0aSJernej Skrabec #ifdef CONFIG_I2C2_ENABLE
135acbc7e0aSJernej Skrabec #if defined(CONFIG_MACH_SUN4I) || \
136acbc7e0aSJernej Skrabec     defined(CONFIG_MACH_SUN7I) || \
137acbc7e0aSJernej Skrabec     defined(CONFIG_MACH_SUN8I_R40)
138acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN4I_GPB_TWI2);
139acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPB(21), SUN4I_GPB_TWI2);
140acbc7e0aSJernej Skrabec 	clock_twi_onoff(2, 1);
141acbc7e0aSJernej Skrabec #elif defined(CONFIG_MACH_SUN5I)
142acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPB(17), SUN5I_GPB_TWI2);
143acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPB(18), SUN5I_GPB_TWI2);
144acbc7e0aSJernej Skrabec 	clock_twi_onoff(2, 1);
145acbc7e0aSJernej Skrabec #elif defined(CONFIG_MACH_SUN6I)
146acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPH(18), SUN6I_GPH_TWI2);
147acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPH(19), SUN6I_GPH_TWI2);
148acbc7e0aSJernej Skrabec 	clock_twi_onoff(2, 1);
149acbc7e0aSJernej Skrabec #elif defined(CONFIG_MACH_SUN8I)
150acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPE(12), SUN8I_GPE_TWI2);
151acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPE(13), SUN8I_GPE_TWI2);
152acbc7e0aSJernej Skrabec 	clock_twi_onoff(2, 1);
153da1ae590SStefan Mavrodiev #elif defined(CONFIG_MACH_SUN50I)
154da1ae590SStefan Mavrodiev 	sunxi_gpio_set_cfgpin(SUNXI_GPE(14), SUN50I_GPE_TWI2);
155da1ae590SStefan Mavrodiev 	sunxi_gpio_set_cfgpin(SUNXI_GPE(15), SUN50I_GPE_TWI2);
156da1ae590SStefan Mavrodiev 	clock_twi_onoff(2, 1);
157acbc7e0aSJernej Skrabec #endif
158acbc7e0aSJernej Skrabec #endif
159acbc7e0aSJernej Skrabec 
160acbc7e0aSJernej Skrabec #ifdef CONFIG_I2C3_ENABLE
161acbc7e0aSJernej Skrabec #if defined(CONFIG_MACH_SUN6I)
162acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPG(10), SUN6I_GPG_TWI3);
163acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPG(11), SUN6I_GPG_TWI3);
164acbc7e0aSJernej Skrabec 	clock_twi_onoff(3, 1);
165acbc7e0aSJernej Skrabec #elif defined(CONFIG_MACH_SUN7I) || \
166acbc7e0aSJernej Skrabec       defined(CONFIG_MACH_SUN8I_R40)
167acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPI(0), SUN7I_GPI_TWI3);
168acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPI(1), SUN7I_GPI_TWI3);
169acbc7e0aSJernej Skrabec 	clock_twi_onoff(3, 1);
170acbc7e0aSJernej Skrabec #endif
171acbc7e0aSJernej Skrabec #endif
172acbc7e0aSJernej Skrabec 
173acbc7e0aSJernej Skrabec #ifdef CONFIG_I2C4_ENABLE
174acbc7e0aSJernej Skrabec #if defined(CONFIG_MACH_SUN7I) || \
175acbc7e0aSJernej Skrabec     defined(CONFIG_MACH_SUN8I_R40)
176acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPI(2), SUN7I_GPI_TWI4);
177acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPI(3), SUN7I_GPI_TWI4);
178acbc7e0aSJernej Skrabec 	clock_twi_onoff(4, 1);
179acbc7e0aSJernej Skrabec #endif
180acbc7e0aSJernej Skrabec #endif
181acbc7e0aSJernej Skrabec 
182acbc7e0aSJernej Skrabec #ifdef CONFIG_R_I2C_ENABLE
18331a4ac4dSVasily Khoruzhick #ifdef CONFIG_MACH_SUN50I
18431a4ac4dSVasily Khoruzhick 	clock_twi_onoff(5, 1);
18531a4ac4dSVasily Khoruzhick 	sunxi_gpio_set_cfgpin(SUNXI_GPL(8), SUN50I_GPL_R_TWI);
18631a4ac4dSVasily Khoruzhick 	sunxi_gpio_set_cfgpin(SUNXI_GPL(9), SUN50I_GPL_R_TWI);
18731a4ac4dSVasily Khoruzhick #else
188acbc7e0aSJernej Skrabec 	clock_twi_onoff(5, 1);
189acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_H3_GPL_R_TWI);
190acbc7e0aSJernej Skrabec 	sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_H3_GPL_R_TWI);
191acbc7e0aSJernej Skrabec #endif
19231a4ac4dSVasily Khoruzhick #endif
193acbc7e0aSJernej Skrabec }
194acbc7e0aSJernej Skrabec 
195b39117caSMaxime Ripard #if defined(CONFIG_ENV_IS_IN_MMC) && defined(CONFIG_ENV_IS_IN_FAT)
env_get_location(enum env_operation op,int prio)196b39117caSMaxime Ripard enum env_location env_get_location(enum env_operation op, int prio)
197b39117caSMaxime Ripard {
198b39117caSMaxime Ripard 	switch (prio) {
199b39117caSMaxime Ripard 	case 0:
200b39117caSMaxime Ripard 		return ENVL_FAT;
201b39117caSMaxime Ripard 
202b39117caSMaxime Ripard 	case 1:
203b39117caSMaxime Ripard 		return ENVL_MMC;
204b39117caSMaxime Ripard 
205b39117caSMaxime Ripard 	default:
206b39117caSMaxime Ripard 		return ENVL_UNKNOWN;
207b39117caSMaxime Ripard 	}
208b39117caSMaxime Ripard }
209b39117caSMaxime Ripard #endif
210b39117caSMaxime Ripard 
211*a7ae1599SAndre Przywara #ifdef CONFIG_DM_MMC
212*a7ae1599SAndre Przywara static void mmc_pinmux_setup(int sdc);
213*a7ae1599SAndre Przywara #endif
214*a7ae1599SAndre Przywara 
215cba69eeeSIan Campbell /* add board specific code here */
board_init(void)216cba69eeeSIan Campbell int board_init(void)
217cba69eeeSIan Campbell {
218f5fd7886SMylène Josserand 	__maybe_unused int id_pfr1, ret, satapwr_pin, macpwr_pin;
219cba69eeeSIan Campbell 
220cba69eeeSIan Campbell 	gd->bd->bi_boot_params = (PHYS_SDRAM_0 + 0x100);
221cba69eeeSIan Campbell 
222d96ebc46SSiarhei Siamashka #ifndef CONFIG_ARM64
223cba69eeeSIan Campbell 	asm volatile("mrc p15, 0, %0, c0, c1, 1" : "=r"(id_pfr1));
224cba69eeeSIan Campbell 	debug("id_pfr1: 0x%08x\n", id_pfr1);
225cba69eeeSIan Campbell 	/* Generic Timer Extension available? */
226d96ebc46SSiarhei Siamashka 	if ((id_pfr1 >> CPUID_ARM_GENTIMER_SHIFT) & 0xf) {
227d96ebc46SSiarhei Siamashka 		uint32_t freq;
228d96ebc46SSiarhei Siamashka 
229cba69eeeSIan Campbell 		debug("Setting CNTFRQ\n");
230d96ebc46SSiarhei Siamashka 
231d96ebc46SSiarhei Siamashka 		/*
232d96ebc46SSiarhei Siamashka 		 * CNTFRQ is a secure register, so we will crash if we try to
233d96ebc46SSiarhei Siamashka 		 * write this from the non-secure world (read is OK, though).
234d96ebc46SSiarhei Siamashka 		 * In case some bootcode has already set the correct value,
235d96ebc46SSiarhei Siamashka 		 * we avoid the risk of writing to it.
236d96ebc46SSiarhei Siamashka 		 */
237d96ebc46SSiarhei Siamashka 		asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r"(freq));
238e4916e85SAndre Przywara 		if (freq != COUNTER_FREQUENCY) {
239d96ebc46SSiarhei Siamashka 			debug("arch timer frequency is %d Hz, should be %d, fixing ...\n",
240e4916e85SAndre Przywara 			      freq, COUNTER_FREQUENCY);
241d96ebc46SSiarhei Siamashka #ifdef CONFIG_NON_SECURE
242d96ebc46SSiarhei Siamashka 			printf("arch timer frequency is wrong, but cannot adjust it\n");
243d96ebc46SSiarhei Siamashka #else
244d96ebc46SSiarhei Siamashka 			asm volatile("mcr p15, 0, %0, c14, c0, 0"
245e4916e85SAndre Przywara 				     : : "r"(COUNTER_FREQUENCY));
246d96ebc46SSiarhei Siamashka #endif
247cba69eeeSIan Campbell 		}
248d96ebc46SSiarhei Siamashka 	}
249d96ebc46SSiarhei Siamashka #endif /* !CONFIG_ARM64 */
250cba69eeeSIan Campbell 
2512fcf033dSHans de Goede 	ret = axp_gpio_init();
2522fcf033dSHans de Goede 	if (ret)
2532fcf033dSHans de Goede 		return ret;
2542fcf033dSHans de Goede 
2559fbb0c3aSHans de Goede #ifdef CONFIG_SATAPWR
256d7b560e6SMylène Josserand 	satapwr_pin = sunxi_name_to_gpio(CONFIG_SATAPWR);
257d7b560e6SMylène Josserand 	gpio_request(satapwr_pin, "satapwr");
258d7b560e6SMylène Josserand 	gpio_direction_output(satapwr_pin, 1);
2598e2c2d41SWerner Böllmann 	/* Give attached sata device time to power-up to avoid link timeouts */
2608e2c2d41SWerner Böllmann 	mdelay(500);
2619fbb0c3aSHans de Goede #endif
262fc8991c6SHans de Goede #ifdef CONFIG_MACPWR
263f5fd7886SMylène Josserand 	macpwr_pin = sunxi_name_to_gpio(CONFIG_MACPWR);
264f5fd7886SMylène Josserand 	gpio_request(macpwr_pin, "macpwr");
265f5fd7886SMylène Josserand 	gpio_direction_output(macpwr_pin, 1);
266fc8991c6SHans de Goede #endif
267fc8991c6SHans de Goede 
268a8f01ccfSJernej Skrabec #ifdef CONFIG_DM_I2C
269a8f01ccfSJernej Skrabec 	/*
270a8f01ccfSJernej Skrabec 	 * Temporary workaround for enabling I2C clocks until proper sunxi DM
271a8f01ccfSJernej Skrabec 	 * clk, reset and pinctrl drivers land.
272a8f01ccfSJernej Skrabec 	 */
273a8f01ccfSJernej Skrabec 	i2c_init_board();
274a8f01ccfSJernej Skrabec #endif
275a8f01ccfSJernej Skrabec 
276*a7ae1599SAndre Przywara #ifdef CONFIG_DM_MMC
277*a7ae1599SAndre Przywara 	/*
278*a7ae1599SAndre Przywara 	 * Temporary workaround for enabling MMC clocks until a sunxi DM
279*a7ae1599SAndre Przywara 	 * pinctrl driver lands.
280*a7ae1599SAndre Przywara 	 */
281*a7ae1599SAndre Przywara 	mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT);
282*a7ae1599SAndre Przywara #if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
283*a7ae1599SAndre Przywara 	mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA);
284*a7ae1599SAndre Przywara #endif
285*a7ae1599SAndre Przywara #endif	/* CONFIG_DM_MMC */
286*a7ae1599SAndre Przywara 
2874f7e01c9SHans de Goede 	/* Uses dm gpio code so do this here and not in i2c_init_board() */
2884f7e01c9SHans de Goede 	return soft_i2c_board_init();
289cba69eeeSIan Campbell }
290cba69eeeSIan Campbell 
291cff5c138SAndre Przywara /*
292cff5c138SAndre Przywara  * On older SoCs the SPL is actually at address zero, so using NULL as
293cff5c138SAndre Przywara  * an error value does not work.
294cff5c138SAndre Przywara  */
295cff5c138SAndre Przywara #define INVALID_SPL_HEADER ((void *)~0UL)
296cff5c138SAndre Przywara 
get_spl_header(uint8_t req_version)297cff5c138SAndre Przywara static struct boot_file_head * get_spl_header(uint8_t req_version)
298cff5c138SAndre Przywara {
299cff5c138SAndre Przywara 	struct boot_file_head *spl = (void *)(ulong)SPL_ADDR;
300cff5c138SAndre Przywara 	uint8_t spl_header_version = spl->spl_signature[3];
301cff5c138SAndre Przywara 
302cff5c138SAndre Przywara 	/* Is there really the SPL header (still) there? */
303cff5c138SAndre Przywara 	if (memcmp(spl->spl_signature, SPL_SIGNATURE, 3) != 0)
304cff5c138SAndre Przywara 		return INVALID_SPL_HEADER;
305cff5c138SAndre Przywara 
306cff5c138SAndre Przywara 	if (spl_header_version < req_version) {
307cff5c138SAndre Przywara 		printf("sunxi SPL version mismatch: expected %u, got %u\n",
308cff5c138SAndre Przywara 		       req_version, spl_header_version);
309cff5c138SAndre Przywara 		return INVALID_SPL_HEADER;
310cff5c138SAndre Przywara 	}
311cff5c138SAndre Przywara 
312cff5c138SAndre Przywara 	return spl;
313cff5c138SAndre Przywara }
314cff5c138SAndre Przywara 
dram_init(void)315cba69eeeSIan Campbell int dram_init(void)
316cba69eeeSIan Campbell {
3175776610eSAndre Przywara 	struct boot_file_head *spl = get_spl_header(SPL_DRAM_HEADER_VERSION);
3185776610eSAndre Przywara 
3195776610eSAndre Przywara 	if (spl == INVALID_SPL_HEADER)
3205776610eSAndre Przywara 		gd->ram_size = get_ram_size((long *)PHYS_SDRAM_0,
3215776610eSAndre Przywara 					    PHYS_SDRAM_0_SIZE);
3225776610eSAndre Przywara 	else
3235776610eSAndre Przywara 		gd->ram_size = (phys_addr_t)spl->dram_size << 20;
3245776610eSAndre Przywara 
3255776610eSAndre Przywara 	if (gd->ram_size > CONFIG_SUNXI_DRAM_MAX_SIZE)
3265776610eSAndre Przywara 		gd->ram_size = CONFIG_SUNXI_DRAM_MAX_SIZE;
327cba69eeeSIan Campbell 
328cba69eeeSIan Campbell 	return 0;
329cba69eeeSIan Campbell }
330cba69eeeSIan Campbell 
3314ccae81cSBoris Brezillon #if defined(CONFIG_NAND_SUNXI)
nand_pinmux_setup(void)332ad008299SKarol Gugala static void nand_pinmux_setup(void)
333ad008299SKarol Gugala {
334ad008299SKarol Gugala 	unsigned int pin;
335022a99d8SHans de Goede 
336022a99d8SHans de Goede 	for (pin = SUNXI_GPC(0); pin <= SUNXI_GPC(19); pin++)
337ad008299SKarol Gugala 		sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND);
338ad008299SKarol Gugala 
339022a99d8SHans de Goede #if defined CONFIG_MACH_SUN4I || defined CONFIG_MACH_SUN7I
340022a99d8SHans de Goede 	for (pin = SUNXI_GPC(20); pin <= SUNXI_GPC(22); pin++)
341ad008299SKarol Gugala 		sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_NAND);
342022a99d8SHans de Goede #endif
343022a99d8SHans de Goede 	/* sun4i / sun7i do have a PC23, but it is not used for nand,
344022a99d8SHans de Goede 	 * only sun7i has a PC24 */
345022a99d8SHans de Goede #ifdef CONFIG_MACH_SUN7I
346ad008299SKarol Gugala 	sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_NAND);
347022a99d8SHans de Goede #endif
348ad008299SKarol Gugala }
349ad008299SKarol Gugala 
nand_clock_setup(void)350ad008299SKarol Gugala static void nand_clock_setup(void)
351ad008299SKarol Gugala {
352ad008299SKarol Gugala 	struct sunxi_ccm_reg *const ccm =
353ad008299SKarol Gugala 		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
35431c21471SHans de Goede 
355ad008299SKarol Gugala 	setbits_le32(&ccm->ahb_gate0, (CLK_GATE_OPEN << AHB_GATE_OFFSET_NAND0));
356ba1c98baSMiquel Raynal #if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I || \
357ba1c98baSMiquel Raynal     defined CONFIG_MACH_SUN9I || defined CONFIG_MACH_SUN50I
358ba1c98baSMiquel Raynal 	setbits_le32(&ccm->ahb_reset0_cfg, (1 << AHB_GATE_OFFSET_NAND0));
359ba1c98baSMiquel Raynal #endif
360ad008299SKarol Gugala 	setbits_le32(&ccm->nand0_clk_cfg, CCM_NAND_CTRL_ENABLE | AHB_DIV_1);
361ad008299SKarol Gugala }
362f62bfa56SHans de Goede 
board_nand_init(void)363f62bfa56SHans de Goede void board_nand_init(void)
364f62bfa56SHans de Goede {
365f62bfa56SHans de Goede 	nand_pinmux_setup();
366f62bfa56SHans de Goede 	nand_clock_setup();
3674ccae81cSBoris Brezillon #ifndef CONFIG_SPL_BUILD
3684ccae81cSBoris Brezillon 	sunxi_nand_init();
3694ccae81cSBoris Brezillon #endif
370f62bfa56SHans de Goede }
371ad008299SKarol Gugala #endif
372ad008299SKarol Gugala 
3734aa2ba3aSMasahiro Yamada #ifdef CONFIG_MMC
mmc_pinmux_setup(int sdc)374e24ea55cSIan Campbell static void mmc_pinmux_setup(int sdc)
375e24ea55cSIan Campbell {
376e24ea55cSIan Campbell 	unsigned int pin;
3778deacca9SPaul Kocialkowski 	__maybe_unused int pins;
378e24ea55cSIan Campbell 
379e24ea55cSIan Campbell 	switch (sdc) {
380e24ea55cSIan Campbell 	case 0:
3818deacca9SPaul Kocialkowski 		/* SDC0: PF0-PF5 */
382e24ea55cSIan Campbell 		for (pin = SUNXI_GPF(0); pin <= SUNXI_GPF(5); pin++) {
383487b3277SPaul Kocialkowski 			sunxi_gpio_set_cfgpin(pin, SUNXI_GPF_SDC0);
384e24ea55cSIan Campbell 			sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
385e24ea55cSIan Campbell 			sunxi_gpio_set_drv(pin, 2);
386e24ea55cSIan Campbell 		}
387e24ea55cSIan Campbell 		break;
388e24ea55cSIan Campbell 
389e24ea55cSIan Campbell 	case 1:
3908deacca9SPaul Kocialkowski 		pins = sunxi_name_to_gpio_bank(CONFIG_MMC1_PINS);
3918deacca9SPaul Kocialkowski 
3928094a4a2SChen-Yu Tsai #if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) || \
3938094a4a2SChen-Yu Tsai     defined(CONFIG_MACH_SUN8I_R40)
3948deacca9SPaul Kocialkowski 		if (pins == SUNXI_GPIO_H) {
3958deacca9SPaul Kocialkowski 			/* SDC1: PH22-PH-27 */
3968deacca9SPaul Kocialkowski 			for (pin = SUNXI_GPH(22); pin <= SUNXI_GPH(27); pin++) {
3978deacca9SPaul Kocialkowski 				sunxi_gpio_set_cfgpin(pin, SUN4I_GPH_SDC1);
3988deacca9SPaul Kocialkowski 				sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
3998deacca9SPaul Kocialkowski 				sunxi_gpio_set_drv(pin, 2);
4008deacca9SPaul Kocialkowski 			}
4018deacca9SPaul Kocialkowski 		} else {
4028deacca9SPaul Kocialkowski 			/* SDC1: PG0-PG5 */
4038deacca9SPaul Kocialkowski 			for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) {
4048deacca9SPaul Kocialkowski 				sunxi_gpio_set_cfgpin(pin, SUN4I_GPG_SDC1);
4058deacca9SPaul Kocialkowski 				sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
4068deacca9SPaul Kocialkowski 				sunxi_gpio_set_drv(pin, 2);
4078deacca9SPaul Kocialkowski 			}
4088deacca9SPaul Kocialkowski 		}
4098deacca9SPaul Kocialkowski #elif defined(CONFIG_MACH_SUN5I)
4108deacca9SPaul Kocialkowski 		/* SDC1: PG3-PG8 */
411bbff84b3SHans de Goede 		for (pin = SUNXI_GPG(3); pin <= SUNXI_GPG(8); pin++) {
412487b3277SPaul Kocialkowski 			sunxi_gpio_set_cfgpin(pin, SUN5I_GPG_SDC1);
413e24ea55cSIan Campbell 			sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
414e24ea55cSIan Campbell 			sunxi_gpio_set_drv(pin, 2);
415e24ea55cSIan Campbell 		}
4168deacca9SPaul Kocialkowski #elif defined(CONFIG_MACH_SUN6I)
4178deacca9SPaul Kocialkowski 		/* SDC1: PG0-PG5 */
4188deacca9SPaul Kocialkowski 		for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) {
4198deacca9SPaul Kocialkowski 			sunxi_gpio_set_cfgpin(pin, SUN6I_GPG_SDC1);
4208deacca9SPaul Kocialkowski 			sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
4218deacca9SPaul Kocialkowski 			sunxi_gpio_set_drv(pin, 2);
4228deacca9SPaul Kocialkowski 		}
4238deacca9SPaul Kocialkowski #elif defined(CONFIG_MACH_SUN8I)
4248deacca9SPaul Kocialkowski 		if (pins == SUNXI_GPIO_D) {
4258deacca9SPaul Kocialkowski 			/* SDC1: PD2-PD7 */
4268deacca9SPaul Kocialkowski 			for (pin = SUNXI_GPD(2); pin <= SUNXI_GPD(7); pin++) {
4278deacca9SPaul Kocialkowski 				sunxi_gpio_set_cfgpin(pin, SUN8I_GPD_SDC1);
4288deacca9SPaul Kocialkowski 				sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
4298deacca9SPaul Kocialkowski 				sunxi_gpio_set_drv(pin, 2);
4308deacca9SPaul Kocialkowski 			}
4318deacca9SPaul Kocialkowski 		} else {
4328deacca9SPaul Kocialkowski 			/* SDC1: PG0-PG5 */
4338deacca9SPaul Kocialkowski 			for (pin = SUNXI_GPG(0); pin <= SUNXI_GPG(5); pin++) {
4348deacca9SPaul Kocialkowski 				sunxi_gpio_set_cfgpin(pin, SUN8I_GPG_SDC1);
4358deacca9SPaul Kocialkowski 				sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
4368deacca9SPaul Kocialkowski 				sunxi_gpio_set_drv(pin, 2);
4378deacca9SPaul Kocialkowski 			}
4388deacca9SPaul Kocialkowski 		}
4398deacca9SPaul Kocialkowski #endif
440e24ea55cSIan Campbell 		break;
441e24ea55cSIan Campbell 
442e24ea55cSIan Campbell 	case 2:
4438deacca9SPaul Kocialkowski 		pins = sunxi_name_to_gpio_bank(CONFIG_MMC2_PINS);
4448deacca9SPaul Kocialkowski 
4458deacca9SPaul Kocialkowski #if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I)
4468deacca9SPaul Kocialkowski 		/* SDC2: PC6-PC11 */
447e24ea55cSIan Campbell 		for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(11); pin++) {
448487b3277SPaul Kocialkowski 			sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
449e24ea55cSIan Campbell 			sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
450e24ea55cSIan Campbell 			sunxi_gpio_set_drv(pin, 2);
451e24ea55cSIan Campbell 		}
4528deacca9SPaul Kocialkowski #elif defined(CONFIG_MACH_SUN5I)
4538deacca9SPaul Kocialkowski 		if (pins == SUNXI_GPIO_E) {
4548deacca9SPaul Kocialkowski 			/* SDC2: PE4-PE9 */
4558deacca9SPaul Kocialkowski 			for (pin = SUNXI_GPE(4); pin <= SUNXI_GPD(9); pin++) {
4568deacca9SPaul Kocialkowski 				sunxi_gpio_set_cfgpin(pin, SUN5I_GPE_SDC2);
457e24ea55cSIan Campbell 				sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
458e24ea55cSIan Campbell 				sunxi_gpio_set_drv(pin, 2);
459e24ea55cSIan Campbell 			}
4608deacca9SPaul Kocialkowski 		} else {
4618deacca9SPaul Kocialkowski 			/* SDC2: PC6-PC15 */
4628deacca9SPaul Kocialkowski 			for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) {
4638deacca9SPaul Kocialkowski 				sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
4648deacca9SPaul Kocialkowski 				sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
4658deacca9SPaul Kocialkowski 				sunxi_gpio_set_drv(pin, 2);
4668deacca9SPaul Kocialkowski 			}
4678deacca9SPaul Kocialkowski 		}
4688deacca9SPaul Kocialkowski #elif defined(CONFIG_MACH_SUN6I)
4698deacca9SPaul Kocialkowski 		if (pins == SUNXI_GPIO_A) {
4708deacca9SPaul Kocialkowski 			/* SDC2: PA9-PA14 */
4718deacca9SPaul Kocialkowski 			for (pin = SUNXI_GPA(9); pin <= SUNXI_GPA(14); pin++) {
4728deacca9SPaul Kocialkowski 				sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_SDC2);
4738deacca9SPaul Kocialkowski 				sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
4748deacca9SPaul Kocialkowski 				sunxi_gpio_set_drv(pin, 2);
4758deacca9SPaul Kocialkowski 			}
4768deacca9SPaul Kocialkowski 		} else {
4778deacca9SPaul Kocialkowski 			/* SDC2: PC6-PC15, PC24 */
4788deacca9SPaul Kocialkowski 			for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) {
4798deacca9SPaul Kocialkowski 				sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
4808deacca9SPaul Kocialkowski 				sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
4818deacca9SPaul Kocialkowski 				sunxi_gpio_set_drv(pin, 2);
4828deacca9SPaul Kocialkowski 			}
4838deacca9SPaul Kocialkowski 
4848deacca9SPaul Kocialkowski 			sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_SDC2);
4858deacca9SPaul Kocialkowski 			sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP);
4868deacca9SPaul Kocialkowski 			sunxi_gpio_set_drv(SUNXI_GPC(24), 2);
4878deacca9SPaul Kocialkowski 		}
4888094a4a2SChen-Yu Tsai #elif defined(CONFIG_MACH_SUN8I_R40)
4898094a4a2SChen-Yu Tsai 		/* SDC2: PC6-PC15, PC24 */
4908094a4a2SChen-Yu Tsai 		for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) {
4918094a4a2SChen-Yu Tsai 			sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
4928094a4a2SChen-Yu Tsai 			sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
4938094a4a2SChen-Yu Tsai 			sunxi_gpio_set_drv(pin, 2);
4948094a4a2SChen-Yu Tsai 		}
4958094a4a2SChen-Yu Tsai 
4968094a4a2SChen-Yu Tsai 		sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUNXI_GPC_SDC2);
4978094a4a2SChen-Yu Tsai 		sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP);
4988094a4a2SChen-Yu Tsai 		sunxi_gpio_set_drv(SUNXI_GPC(24), 2);
499d96ebc46SSiarhei Siamashka #elif defined(CONFIG_MACH_SUN8I) || defined(CONFIG_MACH_SUN50I)
5008deacca9SPaul Kocialkowski 		/* SDC2: PC5-PC6, PC8-PC16 */
5018deacca9SPaul Kocialkowski 		for (pin = SUNXI_GPC(5); pin <= SUNXI_GPC(6); pin++) {
5028deacca9SPaul Kocialkowski 			sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
5038deacca9SPaul Kocialkowski 			sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
5048deacca9SPaul Kocialkowski 			sunxi_gpio_set_drv(pin, 2);
5058deacca9SPaul Kocialkowski 		}
5068deacca9SPaul Kocialkowski 
5078deacca9SPaul Kocialkowski 		for (pin = SUNXI_GPC(8); pin <= SUNXI_GPC(16); pin++) {
5088deacca9SPaul Kocialkowski 			sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
5098deacca9SPaul Kocialkowski 			sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
5108deacca9SPaul Kocialkowski 			sunxi_gpio_set_drv(pin, 2);
5118deacca9SPaul Kocialkowski 		}
51242956f1bSIcenowy Zheng #elif defined(CONFIG_MACH_SUN50I_H6)
51342956f1bSIcenowy Zheng 		/* SDC2: PC4-PC14 */
51442956f1bSIcenowy Zheng 		for (pin = SUNXI_GPC(4); pin <= SUNXI_GPC(14); pin++) {
51542956f1bSIcenowy Zheng 			sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
51642956f1bSIcenowy Zheng 			sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
51742956f1bSIcenowy Zheng 			sunxi_gpio_set_drv(pin, 2);
51842956f1bSIcenowy Zheng 		}
5193ebb4567SPhilipp Tomsich #elif defined(CONFIG_MACH_SUN9I)
5203ebb4567SPhilipp Tomsich 		/* SDC2: PC6-PC16 */
5213ebb4567SPhilipp Tomsich 		for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(16); pin++) {
5223ebb4567SPhilipp Tomsich 			sunxi_gpio_set_cfgpin(pin, SUNXI_GPC_SDC2);
5233ebb4567SPhilipp Tomsich 			sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
5243ebb4567SPhilipp Tomsich 			sunxi_gpio_set_drv(pin, 2);
5253ebb4567SPhilipp Tomsich 		}
5268deacca9SPaul Kocialkowski #endif
5278deacca9SPaul Kocialkowski 		break;
5288deacca9SPaul Kocialkowski 
5298deacca9SPaul Kocialkowski 	case 3:
5308deacca9SPaul Kocialkowski 		pins = sunxi_name_to_gpio_bank(CONFIG_MMC3_PINS);
5318deacca9SPaul Kocialkowski 
5328094a4a2SChen-Yu Tsai #if defined(CONFIG_MACH_SUN4I) || defined(CONFIG_MACH_SUN7I) || \
5338094a4a2SChen-Yu Tsai     defined(CONFIG_MACH_SUN8I_R40)
5348deacca9SPaul Kocialkowski 		/* SDC3: PI4-PI9 */
5358deacca9SPaul Kocialkowski 		for (pin = SUNXI_GPI(4); pin <= SUNXI_GPI(9); pin++) {
5368deacca9SPaul Kocialkowski 			sunxi_gpio_set_cfgpin(pin, SUNXI_GPI_SDC3);
5378deacca9SPaul Kocialkowski 			sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
5388deacca9SPaul Kocialkowski 			sunxi_gpio_set_drv(pin, 2);
5398deacca9SPaul Kocialkowski 		}
5408deacca9SPaul Kocialkowski #elif defined(CONFIG_MACH_SUN6I)
5418deacca9SPaul Kocialkowski 		if (pins == SUNXI_GPIO_A) {
5428deacca9SPaul Kocialkowski 			/* SDC3: PA9-PA14 */
5438deacca9SPaul Kocialkowski 			for (pin = SUNXI_GPA(9); pin <= SUNXI_GPA(14); pin++) {
5448deacca9SPaul Kocialkowski 				sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_SDC3);
5458deacca9SPaul Kocialkowski 				sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
5468deacca9SPaul Kocialkowski 				sunxi_gpio_set_drv(pin, 2);
5478deacca9SPaul Kocialkowski 			}
5488deacca9SPaul Kocialkowski 		} else {
5498deacca9SPaul Kocialkowski 			/* SDC3: PC6-PC15, PC24 */
5508deacca9SPaul Kocialkowski 			for (pin = SUNXI_GPC(6); pin <= SUNXI_GPC(15); pin++) {
5518deacca9SPaul Kocialkowski 				sunxi_gpio_set_cfgpin(pin, SUN6I_GPC_SDC3);
5528deacca9SPaul Kocialkowski 				sunxi_gpio_set_pull(pin, SUNXI_GPIO_PULL_UP);
5538deacca9SPaul Kocialkowski 				sunxi_gpio_set_drv(pin, 2);
5548deacca9SPaul Kocialkowski 			}
5558deacca9SPaul Kocialkowski 
5568deacca9SPaul Kocialkowski 			sunxi_gpio_set_cfgpin(SUNXI_GPC(24), SUN6I_GPC_SDC3);
5578deacca9SPaul Kocialkowski 			sunxi_gpio_set_pull(SUNXI_GPC(24), SUNXI_GPIO_PULL_UP);
5588deacca9SPaul Kocialkowski 			sunxi_gpio_set_drv(SUNXI_GPC(24), 2);
5598deacca9SPaul Kocialkowski 		}
5608deacca9SPaul Kocialkowski #endif
561e24ea55cSIan Campbell 		break;
562e24ea55cSIan Campbell 
563e24ea55cSIan Campbell 	default:
564e24ea55cSIan Campbell 		printf("sunxi: invalid MMC slot %d for pinmux setup\n", sdc);
565e24ea55cSIan Campbell 		break;
566e24ea55cSIan Campbell 	}
567e24ea55cSIan Campbell }
568e24ea55cSIan Campbell 
board_mmc_init(bd_t * bis)569e24ea55cSIan Campbell int board_mmc_init(bd_t *bis)
570e24ea55cSIan Campbell {
571e79c7c88SHans de Goede 	__maybe_unused struct mmc *mmc0, *mmc1;
572e79c7c88SHans de Goede 
573e24ea55cSIan Campbell 	mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT);
574e79c7c88SHans de Goede 	mmc0 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT);
575e79c7c88SHans de Goede 	if (!mmc0)
576e79c7c88SHans de Goede 		return -1;
577e79c7c88SHans de Goede 
5782ccfac01SHans de Goede #if CONFIG_MMC_SUNXI_SLOT_EXTRA != -1
579e24ea55cSIan Campbell 	mmc_pinmux_setup(CONFIG_MMC_SUNXI_SLOT_EXTRA);
580e79c7c88SHans de Goede 	mmc1 = sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT_EXTRA);
581e79c7c88SHans de Goede 	if (!mmc1)
582e79c7c88SHans de Goede 		return -1;
583e79c7c88SHans de Goede #endif
584e79c7c88SHans de Goede 
585e24ea55cSIan Campbell 	return 0;
586e24ea55cSIan Campbell }
587e24ea55cSIan Campbell #endif
588e24ea55cSIan Campbell 
589cba69eeeSIan Campbell #ifdef CONFIG_SPL_BUILD
5905776610eSAndre Przywara 
sunxi_spl_store_dram_size(phys_addr_t dram_size)5915776610eSAndre Przywara static void sunxi_spl_store_dram_size(phys_addr_t dram_size)
5925776610eSAndre Przywara {
5935776610eSAndre Przywara 	struct boot_file_head *spl = get_spl_header(SPL_DT_HEADER_VERSION);
5945776610eSAndre Przywara 
5955776610eSAndre Przywara 	if (spl == INVALID_SPL_HEADER)
5965776610eSAndre Przywara 		return;
5975776610eSAndre Przywara 
5985776610eSAndre Przywara 	/* Promote the header version for U-Boot proper, if needed. */
5995776610eSAndre Przywara 	if (spl->spl_signature[3] < SPL_DRAM_HEADER_VERSION)
6005776610eSAndre Przywara 		spl->spl_signature[3] = SPL_DRAM_HEADER_VERSION;
6015776610eSAndre Przywara 
6025776610eSAndre Przywara 	spl->dram_size = dram_size >> 20;
6035776610eSAndre Przywara }
6045776610eSAndre Przywara 
sunxi_board_init(void)605cba69eeeSIan Campbell void sunxi_board_init(void)
606cba69eeeSIan Campbell {
60714bc66bdSHenrik Nordstrom 	int power_failed = 0;
608cba69eeeSIan Campbell 
6090d8382aeSJelle van der Waa #ifdef CONFIG_SY8106A_POWER
6100d8382aeSJelle van der Waa 	power_failed = sy8106a_set_vout1(CONFIG_SY8106A_VOUT1_VOLT);
6110d8382aeSJelle van der Waa #endif
6120d8382aeSJelle van der Waa 
61395ab8feeSvishnupatekar #if defined CONFIG_AXP152_POWER || defined CONFIG_AXP209_POWER || \
614795857dfSChen-Yu Tsai 	defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \
615795857dfSChen-Yu Tsai 	defined CONFIG_AXP818_POWER
6166944aff1SHans de Goede 	power_failed = axp_init();
6176944aff1SHans de Goede 
618795857dfSChen-Yu Tsai #if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \
619795857dfSChen-Yu Tsai 	defined CONFIG_AXP818_POWER
6206944aff1SHans de Goede 	power_failed |= axp_set_dcdc1(CONFIG_AXP_DCDC1_VOLT);
62124289208SHans de Goede #endif
6226944aff1SHans de Goede 	power_failed |= axp_set_dcdc2(CONFIG_AXP_DCDC2_VOLT);
6236944aff1SHans de Goede 	power_failed |= axp_set_dcdc3(CONFIG_AXP_DCDC3_VOLT);
62495ab8feeSvishnupatekar #if !defined(CONFIG_AXP209_POWER) && !defined(CONFIG_AXP818_POWER)
6256944aff1SHans de Goede 	power_failed |= axp_set_dcdc4(CONFIG_AXP_DCDC4_VOLT);
62614bc66bdSHenrik Nordstrom #endif
627795857dfSChen-Yu Tsai #if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \
628795857dfSChen-Yu Tsai 	defined CONFIG_AXP818_POWER
6296944aff1SHans de Goede 	power_failed |= axp_set_dcdc5(CONFIG_AXP_DCDC5_VOLT);
6305c7f10fdSOliver Schinagl #endif
63114bc66bdSHenrik Nordstrom 
632795857dfSChen-Yu Tsai #if defined CONFIG_AXP221_POWER || defined CONFIG_AXP809_POWER || \
633795857dfSChen-Yu Tsai 	defined CONFIG_AXP818_POWER
6346944aff1SHans de Goede 	power_failed |= axp_set_aldo1(CONFIG_AXP_ALDO1_VOLT);
6356944aff1SHans de Goede #endif
6366944aff1SHans de Goede 	power_failed |= axp_set_aldo2(CONFIG_AXP_ALDO2_VOLT);
637f3c5045aSChen-Yu Tsai #if !defined(CONFIG_AXP152_POWER)
6386944aff1SHans de Goede 	power_failed |= axp_set_aldo3(CONFIG_AXP_ALDO3_VOLT);
6396944aff1SHans de Goede #endif
6406944aff1SHans de Goede #ifdef CONFIG_AXP209_POWER
6416944aff1SHans de Goede 	power_failed |= axp_set_aldo4(CONFIG_AXP_ALDO4_VOLT);
6426944aff1SHans de Goede #endif
6436944aff1SHans de Goede 
644795857dfSChen-Yu Tsai #if defined(CONFIG_AXP221_POWER) || defined(CONFIG_AXP809_POWER) || \
645795857dfSChen-Yu Tsai 	defined(CONFIG_AXP818_POWER)
6463517a27dSChen-Yu Tsai 	power_failed |= axp_set_dldo(1, CONFIG_AXP_DLDO1_VOLT);
6473517a27dSChen-Yu Tsai 	power_failed |= axp_set_dldo(2, CONFIG_AXP_DLDO2_VOLT);
648795857dfSChen-Yu Tsai #if !defined CONFIG_AXP809_POWER
6493517a27dSChen-Yu Tsai 	power_failed |= axp_set_dldo(3, CONFIG_AXP_DLDO3_VOLT);
6503517a27dSChen-Yu Tsai 	power_failed |= axp_set_dldo(4, CONFIG_AXP_DLDO4_VOLT);
651795857dfSChen-Yu Tsai #endif
6526944aff1SHans de Goede 	power_failed |= axp_set_eldo(1, CONFIG_AXP_ELDO1_VOLT);
6536944aff1SHans de Goede 	power_failed |= axp_set_eldo(2, CONFIG_AXP_ELDO2_VOLT);
6546944aff1SHans de Goede 	power_failed |= axp_set_eldo(3, CONFIG_AXP_ELDO3_VOLT);
6556944aff1SHans de Goede #endif
65638491d9cSChen-Yu Tsai 
65738491d9cSChen-Yu Tsai #ifdef CONFIG_AXP818_POWER
65838491d9cSChen-Yu Tsai 	power_failed |= axp_set_fldo(1, CONFIG_AXP_FLDO1_VOLT);
65938491d9cSChen-Yu Tsai 	power_failed |= axp_set_fldo(2, CONFIG_AXP_FLDO2_VOLT);
66038491d9cSChen-Yu Tsai 	power_failed |= axp_set_fldo(3, CONFIG_AXP_FLDO3_VOLT);
661795857dfSChen-Yu Tsai #endif
662795857dfSChen-Yu Tsai 
663795857dfSChen-Yu Tsai #if defined CONFIG_AXP809_POWER || defined CONFIG_AXP818_POWER
66415278ccbSChen-Yu Tsai 	power_failed |= axp_set_sw(IS_ENABLED(CONFIG_AXP_SW_ON));
66538491d9cSChen-Yu Tsai #endif
6666944aff1SHans de Goede #endif
66744c214dcSFrom: Karl Palsson 	printf("DRAM:");
66844c214dcSFrom: Karl Palsson 	gd->ram_size = sunxi_dram_init();
66944c214dcSFrom: Karl Palsson 	printf(" %d MiB\n", (int)(gd->ram_size >> 20));
67044c214dcSFrom: Karl Palsson 	if (!gd->ram_size)
67144c214dcSFrom: Karl Palsson 		hang();
67244c214dcSFrom: Karl Palsson 
67344c214dcSFrom: Karl Palsson 	sunxi_spl_store_dram_size(gd->ram_size);
6745776610eSAndre Przywara 
67514bc66bdSHenrik Nordstrom 	/*
67614bc66bdSHenrik Nordstrom 	 * Only clock up the CPU to full speed if we are reasonably
67714bc66bdSHenrik Nordstrom 	 * assured it's being powered with suitable core voltage
67814bc66bdSHenrik Nordstrom 	 */
67914bc66bdSHenrik Nordstrom 	if (!power_failed)
680e71b422bSIain Paton 		clock_set_pll1(CONFIG_SYS_CLK_FREQ);
68114bc66bdSHenrik Nordstrom 	else
68244c214dcSFrom: Karl Palsson 		printf("Failed to set core voltage! Can't set CPU frequency\n");
683cba69eeeSIan Campbell }
684cba69eeeSIan Campbell #endif
685b41d7d05SJonathan Liu 
686f1df758dSPaul Kocialkowski #ifdef CONFIG_USB_GADGET
g_dnl_board_usb_cable_connected(void)687f1df758dSPaul Kocialkowski int g_dnl_board_usb_cable_connected(void)
688f1df758dSPaul Kocialkowski {
689237050fcSJagan Teki 	struct udevice *dev;
690237050fcSJagan Teki 	struct phy phy;
691237050fcSJagan Teki 	int ret;
692237050fcSJagan Teki 
69301311624SJean-Jacques Hiblot 	ret = uclass_get_device(UCLASS_USB_GADGET_GENERIC, 0, &dev);
694237050fcSJagan Teki 	if (ret) {
695237050fcSJagan Teki 		pr_err("%s: Cannot find USB device\n", __func__);
696237050fcSJagan Teki 		return ret;
697237050fcSJagan Teki 	}
698237050fcSJagan Teki 
699237050fcSJagan Teki 	ret = generic_phy_get_by_name(dev, "usb", &phy);
700237050fcSJagan Teki 	if (ret) {
701237050fcSJagan Teki 		pr_err("failed to get %s USB PHY\n", dev->name);
702237050fcSJagan Teki 		return ret;
703237050fcSJagan Teki 	}
704237050fcSJagan Teki 
705237050fcSJagan Teki 	ret = generic_phy_init(&phy);
706237050fcSJagan Teki 	if (ret) {
707237050fcSJagan Teki 		pr_err("failed to init %s USB PHY\n", dev->name);
708237050fcSJagan Teki 		return ret;
709237050fcSJagan Teki 	}
710237050fcSJagan Teki 
711237050fcSJagan Teki 	ret = sun4i_usb_phy_vbus_detect(&phy);
712237050fcSJagan Teki 	if (ret == 1) {
713237050fcSJagan Teki 		pr_err("A charger is plugged into the OTG\n");
714237050fcSJagan Teki 		return -ENODEV;
715237050fcSJagan Teki 	}
716237050fcSJagan Teki 
717237050fcSJagan Teki 	return ret;
718f1df758dSPaul Kocialkowski }
719f1df758dSPaul Kocialkowski #endif
720f1df758dSPaul Kocialkowski 
7219f852211SPaul Kocialkowski #ifdef CONFIG_SERIAL_TAG
get_board_serial(struct tag_serialnr * serialnr)7229f852211SPaul Kocialkowski void get_board_serial(struct tag_serialnr *serialnr)
7239f852211SPaul Kocialkowski {
7249f852211SPaul Kocialkowski 	char *serial_string;
7259f852211SPaul Kocialkowski 	unsigned long long serial;
7269f852211SPaul Kocialkowski 
72700caae6dSSimon Glass 	serial_string = env_get("serial#");
7289f852211SPaul Kocialkowski 
7299f852211SPaul Kocialkowski 	if (serial_string) {
7309f852211SPaul Kocialkowski 		serial = simple_strtoull(serial_string, NULL, 16);
7319f852211SPaul Kocialkowski 
7329f852211SPaul Kocialkowski 		serialnr->high = (unsigned int) (serial >> 32);
7339f852211SPaul Kocialkowski 		serialnr->low = (unsigned int) (serial & 0xffffffff);
7349f852211SPaul Kocialkowski 	} else {
7359f852211SPaul Kocialkowski 		serialnr->high = 0;
7369f852211SPaul Kocialkowski 		serialnr->low = 0;
7379f852211SPaul Kocialkowski 	}
7389f852211SPaul Kocialkowski }
7399f852211SPaul Kocialkowski #endif
7409f852211SPaul Kocialkowski 
741af654d14SBernhard Nortmann /*
742af654d14SBernhard Nortmann  * Check the SPL header for the "sunxi" variant. If found: parse values
743af654d14SBernhard Nortmann  * that might have been passed by the loader ("fel" utility), and update
744af654d14SBernhard Nortmann  * the environment accordingly.
745af654d14SBernhard Nortmann  */
parse_spl_header(const uint32_t spl_addr)746af654d14SBernhard Nortmann static void parse_spl_header(const uint32_t spl_addr)
747af654d14SBernhard Nortmann {
748cff5c138SAndre Przywara 	struct boot_file_head *spl = get_spl_header(SPL_ENV_HEADER_VERSION);
749320e0570SBernhard Nortmann 
750cff5c138SAndre Przywara 	if (spl == INVALID_SPL_HEADER)
751320e0570SBernhard Nortmann 		return;
752cff5c138SAndre Przywara 
753320e0570SBernhard Nortmann 	if (!spl->fel_script_address)
754320e0570SBernhard Nortmann 		return;
755320e0570SBernhard Nortmann 
756320e0570SBernhard Nortmann 	if (spl->fel_uEnv_length != 0) {
757320e0570SBernhard Nortmann 		/*
758320e0570SBernhard Nortmann 		 * data is expected in uEnv.txt compatible format, so "env
759320e0570SBernhard Nortmann 		 * import -t" the string(s) at fel_script_address right away.
760320e0570SBernhard Nortmann 		 */
7615a74a391SAndre Przywara 		himport_r(&env_htab, (char *)(uintptr_t)spl->fel_script_address,
762320e0570SBernhard Nortmann 			  spl->fel_uEnv_length, '\n', H_NOCLEAR, 0, 0, NULL);
763320e0570SBernhard Nortmann 		return;
764320e0570SBernhard Nortmann 	}
765320e0570SBernhard Nortmann 	/* otherwise assume .scr format (mkimage-type script) */
766018f5303SSimon Glass 	env_set_hex("fel_scriptaddr", spl->fel_script_address);
767af654d14SBernhard Nortmann }
768af654d14SBernhard Nortmann 
769f221961eSHans de Goede /*
770f221961eSHans de Goede  * Note this function gets called multiple times.
771f221961eSHans de Goede  * It must not make any changes to env variables which already exist.
772f221961eSHans de Goede  */
setup_environment(const void * fdt)773f221961eSHans de Goede static void setup_environment(const void *fdt)
774b41d7d05SJonathan Liu {
7758c816573SPaul Kocialkowski 	char serial_string[17] = { 0 };
776cac5b1ccSHans de Goede 	unsigned int sid[4];
777b41d7d05SJonathan Liu 	uint8_t mac_addr[6];
778f221961eSHans de Goede 	char ethaddr[16];
779f221961eSHans de Goede 	int i, ret;
780f221961eSHans de Goede 
781f221961eSHans de Goede 	ret = sunxi_get_sid(sid);
7823f8ea3b0SHans de Goede 	if (ret == 0 && sid[0] != 0) {
7833f8ea3b0SHans de Goede 		/*
7843f8ea3b0SHans de Goede 		 * The single words 1 - 3 of the SID have quite a few bits
7853f8ea3b0SHans de Goede 		 * which are the same on many models, so we take a crc32
7863f8ea3b0SHans de Goede 		 * of all 3 words, to get a more unique value.
7873f8ea3b0SHans de Goede 		 *
7883f8ea3b0SHans de Goede 		 * Note we only do this on newer SoCs as we cannot change
7893f8ea3b0SHans de Goede 		 * the algorithm on older SoCs since those have been using
7903f8ea3b0SHans de Goede 		 * fixed mac-addresses based on only using word 3 for a
7913f8ea3b0SHans de Goede 		 * long time and changing a fixed mac-address with an
7923f8ea3b0SHans de Goede 		 * u-boot update is not good.
7933f8ea3b0SHans de Goede 		 */
7943f8ea3b0SHans de Goede #if !defined(CONFIG_MACH_SUN4I) && !defined(CONFIG_MACH_SUN5I) && \
7953f8ea3b0SHans de Goede     !defined(CONFIG_MACH_SUN6I) && !defined(CONFIG_MACH_SUN7I) && \
7963f8ea3b0SHans de Goede     !defined(CONFIG_MACH_SUN8I_A23) && !defined(CONFIG_MACH_SUN8I_A33)
7973f8ea3b0SHans de Goede 		sid[3] = crc32(0, (unsigned char *)&sid[1], 12);
7983f8ea3b0SHans de Goede #endif
7993f8ea3b0SHans de Goede 
80097322c3eSHans de Goede 		/* Ensure the NIC specific bytes of the mac are not all 0 */
80197322c3eSHans de Goede 		if ((sid[3] & 0xffffff) == 0)
80297322c3eSHans de Goede 			sid[3] |= 0x800000;
80397322c3eSHans de Goede 
804f221961eSHans de Goede 		for (i = 0; i < 4; i++) {
805f221961eSHans de Goede 			sprintf(ethaddr, "ethernet%d", i);
806f221961eSHans de Goede 			if (!fdt_get_alias(fdt, ethaddr))
807f221961eSHans de Goede 				continue;
808f221961eSHans de Goede 
809f221961eSHans de Goede 			if (i == 0)
810f221961eSHans de Goede 				strcpy(ethaddr, "ethaddr");
811f221961eSHans de Goede 			else
812f221961eSHans de Goede 				sprintf(ethaddr, "eth%daddr", i);
813f221961eSHans de Goede 
81400caae6dSSimon Glass 			if (env_get(ethaddr))
815f221961eSHans de Goede 				continue;
816f221961eSHans de Goede 
817f221961eSHans de Goede 			/* Non OUI / registered MAC address */
818f221961eSHans de Goede 			mac_addr[0] = (i << 4) | 0x02;
819f221961eSHans de Goede 			mac_addr[1] = (sid[0] >>  0) & 0xff;
820f221961eSHans de Goede 			mac_addr[2] = (sid[3] >> 24) & 0xff;
821f221961eSHans de Goede 			mac_addr[3] = (sid[3] >> 16) & 0xff;
822f221961eSHans de Goede 			mac_addr[4] = (sid[3] >>  8) & 0xff;
823f221961eSHans de Goede 			mac_addr[5] = (sid[3] >>  0) & 0xff;
824f221961eSHans de Goede 
825fd1e959eSSimon Glass 			eth_env_set_enetaddr(ethaddr, mac_addr);
826f221961eSHans de Goede 		}
827f221961eSHans de Goede 
82800caae6dSSimon Glass 		if (!env_get("serial#")) {
829f221961eSHans de Goede 			snprintf(serial_string, sizeof(serial_string),
830f221961eSHans de Goede 				"%08x%08x", sid[0], sid[3]);
831f221961eSHans de Goede 
832382bee57SSimon Glass 			env_set("serial#", serial_string);
833f221961eSHans de Goede 		}
834f221961eSHans de Goede 	}
835f221961eSHans de Goede }
836f221961eSHans de Goede 
misc_init_r(void)837f221961eSHans de Goede int misc_init_r(void)
838f221961eSHans de Goede {
839f4c3523cSMaxime Ripard 	uint boot;
840b41d7d05SJonathan Liu 
841382bee57SSimon Glass 	env_set("fel_booted", NULL);
842382bee57SSimon Glass 	env_set("fel_scriptaddr", NULL);
843de86fc38SMaxime Ripard 	env_set("mmc_bootdev", NULL);
844f4c3523cSMaxime Ripard 
845f4c3523cSMaxime Ripard 	boot = sunxi_get_boot_device();
846af654d14SBernhard Nortmann 	/* determine if we are running in FEL mode */
847f4c3523cSMaxime Ripard 	if (boot == BOOT_DEVICE_BOARD) {
848382bee57SSimon Glass 		env_set("fel_booted", "1");
849af654d14SBernhard Nortmann 		parse_spl_header(SPL_ADDR);
850de86fc38SMaxime Ripard 	/* or if we booted from MMC, and which one */
851de86fc38SMaxime Ripard 	} else if (boot == BOOT_DEVICE_MMC1) {
852de86fc38SMaxime Ripard 		env_set("mmc_bootdev", "0");
853de86fc38SMaxime Ripard 	} else if (boot == BOOT_DEVICE_MMC2) {
854de86fc38SMaxime Ripard 		env_set("mmc_bootdev", "1");
855af654d14SBernhard Nortmann 	}
856af654d14SBernhard Nortmann 
857f221961eSHans de Goede 	setup_environment(gd->fdt_blob);
8588c816573SPaul Kocialkowski 
859e6ee85a6SIcenowy Zheng #ifdef CONFIG_USB_ETHER
86090dd2f19SMaxime Ripard 	usb_ether_init();
861e6ee85a6SIcenowy Zheng #endif
86290dd2f19SMaxime Ripard 
863b41d7d05SJonathan Liu 	return 0;
864b41d7d05SJonathan Liu }
8652d7a084bSLuc Verhaegen 
ft_board_setup(void * blob,bd_t * bd)8662d7a084bSLuc Verhaegen int ft_board_setup(void *blob, bd_t *bd)
8672d7a084bSLuc Verhaegen {
868d75111a7SHans de Goede 	int __maybe_unused r;
869d75111a7SHans de Goede 
870f221961eSHans de Goede 	/*
871f221961eSHans de Goede 	 * Call setup_environment again in case the boot fdt has
872f221961eSHans de Goede 	 * ethernet aliases the u-boot copy does not have.
873f221961eSHans de Goede 	 */
874f221961eSHans de Goede 	setup_environment(blob);
875f221961eSHans de Goede 
8762d7a084bSLuc Verhaegen #ifdef CONFIG_VIDEO_DT_SIMPLEFB
877d75111a7SHans de Goede 	r = sunxi_simplefb_setup(blob);
878d75111a7SHans de Goede 	if (r)
879d75111a7SHans de Goede 		return r;
8802d7a084bSLuc Verhaegen #endif
881d75111a7SHans de Goede 	return 0;
8822d7a084bSLuc Verhaegen }
8839ea3c35aSAndre Przywara 
8849ea3c35aSAndre Przywara #ifdef CONFIG_SPL_LOAD_FIT
board_fit_config_name_match(const char * name)8859ea3c35aSAndre Przywara int board_fit_config_name_match(const char *name)
8869ea3c35aSAndre Przywara {
887cff5c138SAndre Przywara 	struct boot_file_head *spl = get_spl_header(SPL_DT_HEADER_VERSION);
888cff5c138SAndre Przywara 	const char *cmp_str = (const char *)spl;
8899ea3c35aSAndre Przywara 
89054254ba7SAndre Przywara 	/* Check if there is a DT name stored in the SPL header and use that. */
891cff5c138SAndre Przywara 	if (spl != INVALID_SPL_HEADER && spl->dt_name_offset) {
89254254ba7SAndre Przywara 		cmp_str += spl->dt_name_offset;
89354254ba7SAndre Przywara 	} else {
8949ea3c35aSAndre Przywara #ifdef CONFIG_DEFAULT_DEVICE_TREE
8959ea3c35aSAndre Przywara 		cmp_str = CONFIG_DEFAULT_DEVICE_TREE;
8969ea3c35aSAndre Przywara #else
8979ea3c35aSAndre Przywara 		return 0;
8989ea3c35aSAndre Przywara #endif
89954254ba7SAndre Przywara 	};
9009ea3c35aSAndre Przywara 
901c6c2c85eSIcenowy Zheng #ifdef CONFIG_PINE64_DT_SELECTION
9029ea3c35aSAndre Przywara /* Differentiate the two Pine64 board DTs by their DRAM size. */
9039ea3c35aSAndre Przywara 	if (strstr(name, "-pine64") && strstr(cmp_str, "-pine64")) {
9049ea3c35aSAndre Przywara 		if ((gd->ram_size > 512 * 1024 * 1024))
9059ea3c35aSAndre Przywara 			return !strstr(name, "plus");
9069ea3c35aSAndre Przywara 		else
9079ea3c35aSAndre Przywara 			return !!strstr(name, "plus");
9089ea3c35aSAndre Przywara 	} else {
9099ea3c35aSAndre Przywara 		return strcmp(name, cmp_str);
9109ea3c35aSAndre Przywara 	}
911c6c2c85eSIcenowy Zheng #endif
912c6c2c85eSIcenowy Zheng 	return strcmp(name, cmp_str);
9139ea3c35aSAndre Przywara }
9149ea3c35aSAndre Przywara #endif
915