xref: /rk3399_rockchip-uboot/board/keymile/km_arm/km_arm.c (revision 00caae6d47645e68d6e5277aceb69592b49381a6)
167fa8c25SHeiko Schocher /*
267fa8c25SHeiko Schocher  * (C) Copyright 2009
367fa8c25SHeiko Schocher  * Marvell Semiconductor <www.marvell.com>
467fa8c25SHeiko Schocher  * Prafulla Wadaskar <prafulla@marvell.com>
567fa8c25SHeiko Schocher  *
667fa8c25SHeiko Schocher  * (C) Copyright 2009
767fa8c25SHeiko Schocher  * Stefan Roese, DENX Software Engineering, sr@denx.de.
867fa8c25SHeiko Schocher  *
967fa8c25SHeiko Schocher  * (C) Copyright 2010
1067fa8c25SHeiko Schocher  * Heiko Schocher, DENX Software Engineering, hs@denx.de.
1167fa8c25SHeiko Schocher  *
121a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
1367fa8c25SHeiko Schocher  */
1467fa8c25SHeiko Schocher 
1567fa8c25SHeiko Schocher #include <common.h>
1667fa8c25SHeiko Schocher #include <i2c.h>
1767fa8c25SHeiko Schocher #include <nand.h>
1867fa8c25SHeiko Schocher #include <netdev.h>
1967fa8c25SHeiko Schocher #include <miiphy.h>
200c25defcSValentin Longchamp #include <spi.h>
2167fa8c25SHeiko Schocher #include <asm/io.h>
22a7efd719SLei Wen #include <asm/arch/cpu.h>
233dc23f78SStefan Roese #include <asm/arch/soc.h>
2467fa8c25SHeiko Schocher #include <asm/arch/mpp.h>
2567fa8c25SHeiko Schocher 
2667fa8c25SHeiko Schocher #include "../common/common.h"
2767fa8c25SHeiko Schocher 
2867fa8c25SHeiko Schocher DECLARE_GLOBAL_DATA_PTR;
2967fa8c25SHeiko Schocher 
308612b701SHolger Brunck /*
318612b701SHolger Brunck  * BOCO FPGA definitions
328612b701SHolger Brunck  */
338612b701SHolger Brunck #define BOCO		0x10
348612b701SHolger Brunck #define REG_CTRL_H		0x02
358612b701SHolger Brunck #define MASK_WRL_UNITRUN	0x01
368612b701SHolger Brunck #define MASK_RBX_PGY_PRESENT	0x40
378612b701SHolger Brunck #define REG_IRQ_CIRQ2		0x2d
388612b701SHolger Brunck #define MASK_RBI_DEFECT_16	0x01
398612b701SHolger Brunck 
409ff739e4STobias Müller /*
419ff739e4STobias Müller  * PHY registers definitions
429ff739e4STobias Müller  */
439ff739e4STobias Müller #define PHY_MARVELL_OUI					0x5043
449ff739e4STobias Müller #define PHY_MARVELL_88E1118_MODEL			0x0022
459ff739e4STobias Müller #define PHY_MARVELL_88E1118R_MODEL			0x0024
469ff739e4STobias Müller 
479ff739e4STobias Müller #define PHY_MARVELL_PAGE_REG				0x0016
489ff739e4STobias Müller #define PHY_MARVELL_DEFAULT_PAGE			0x0000
499ff739e4STobias Müller 
509ff739e4STobias Müller #define PHY_MARVELL_88E1118R_LED_CTRL_PAGE		0x0003
519ff739e4STobias Müller #define PHY_MARVELL_88E1118R_LED_CTRL_REG		0x0010
529ff739e4STobias Müller 
539ff739e4STobias Müller #define PHY_MARVELL_88E1118R_LED_CTRL_RESERVED		0x1000
549ff739e4STobias Müller #define PHY_MARVELL_88E1118R_LED_CTRL_LED0_1000MB	(0x7<<0)
559ff739e4STobias Müller #define PHY_MARVELL_88E1118R_LED_CTRL_LED1_ACT		(0x3<<4)
569ff739e4STobias Müller #define PHY_MARVELL_88E1118R_LED_CTRL_LED2_LINK		(0x0<<8)
579ff739e4STobias Müller 
58e23fde7dSHolger Brunck /* I/O pin to erase flash RGPP09 = MPP43 */
59e23fde7dSHolger Brunck #define KM_FLASH_ERASE_ENABLE	43
60e23fde7dSHolger Brunck 
6167fa8c25SHeiko Schocher /* Multi-Purpose Pins Functionality configuration */
629d86f0c3SAlbert ARIBAUD static const u32 kwmpp_config[] = {
6367fa8c25SHeiko Schocher 	MPP0_NF_IO2,
6467fa8c25SHeiko Schocher 	MPP1_NF_IO3,
6567fa8c25SHeiko Schocher 	MPP2_NF_IO4,
6667fa8c25SHeiko Schocher 	MPP3_NF_IO5,
6767fa8c25SHeiko Schocher 	MPP4_NF_IO6,
6867fa8c25SHeiko Schocher 	MPP5_NF_IO7,
6967fa8c25SHeiko Schocher 	MPP6_SYSRST_OUTn,
709c134e18SGerlando Falauto #if defined(KM_PCIE_RESET_MPP7)
719c134e18SGerlando Falauto 	MPP7_GPO,
729c134e18SGerlando Falauto #else
7367fa8c25SHeiko Schocher 	MPP7_PEX_RST_OUTn,
749c134e18SGerlando Falauto #endif
75ea818dbbSHeiko Schocher #if defined(CONFIG_SYS_I2C_SOFT)
7667fa8c25SHeiko Schocher 	MPP8_GPIO,		/* SDA */
7767fa8c25SHeiko Schocher 	MPP9_GPIO,		/* SCL */
7867fa8c25SHeiko Schocher #endif
7967fa8c25SHeiko Schocher 	MPP10_UART0_TXD,
8067fa8c25SHeiko Schocher 	MPP11_UART0_RXD,
8167fa8c25SHeiko Schocher 	MPP12_GPO,		/* Reserved */
8267fa8c25SHeiko Schocher 	MPP13_UART1_TXD,
8367fa8c25SHeiko Schocher 	MPP14_UART1_RXD,
8467fa8c25SHeiko Schocher 	MPP15_GPIO,		/* Not used */
8567fa8c25SHeiko Schocher 	MPP16_GPIO,		/* Not used */
8667fa8c25SHeiko Schocher 	MPP17_GPIO,		/* Reserved */
8767fa8c25SHeiko Schocher 	MPP18_NF_IO0,
8867fa8c25SHeiko Schocher 	MPP19_NF_IO1,
8967fa8c25SHeiko Schocher 	MPP20_GPIO,
9067fa8c25SHeiko Schocher 	MPP21_GPIO,
9167fa8c25SHeiko Schocher 	MPP22_GPIO,
9267fa8c25SHeiko Schocher 	MPP23_GPIO,
9367fa8c25SHeiko Schocher 	MPP24_GPIO,
9467fa8c25SHeiko Schocher 	MPP25_GPIO,
9567fa8c25SHeiko Schocher 	MPP26_GPIO,
9667fa8c25SHeiko Schocher 	MPP27_GPIO,
9767fa8c25SHeiko Schocher 	MPP28_GPIO,
9867fa8c25SHeiko Schocher 	MPP29_GPIO,
9967fa8c25SHeiko Schocher 	MPP30_GPIO,
10067fa8c25SHeiko Schocher 	MPP31_GPIO,
10167fa8c25SHeiko Schocher 	MPP32_GPIO,
10267fa8c25SHeiko Schocher 	MPP33_GPIO,
10367fa8c25SHeiko Schocher 	MPP34_GPIO,		/* CDL1 (input) */
10467fa8c25SHeiko Schocher 	MPP35_GPIO,		/* CDL2 (input) */
10567fa8c25SHeiko Schocher 	MPP36_GPIO,		/* MAIN_IRQ (input) */
10667fa8c25SHeiko Schocher 	MPP37_GPIO,		/* BOARD_LED */
10767fa8c25SHeiko Schocher 	MPP38_GPIO,		/* Piggy3 LED[1] */
10867fa8c25SHeiko Schocher 	MPP39_GPIO,		/* Piggy3 LED[2] */
10967fa8c25SHeiko Schocher 	MPP40_GPIO,		/* Piggy3 LED[3] */
11067fa8c25SHeiko Schocher 	MPP41_GPIO,		/* Piggy3 LED[4] */
11167fa8c25SHeiko Schocher 	MPP42_GPIO,		/* Piggy3 LED[5] */
11267fa8c25SHeiko Schocher 	MPP43_GPIO,		/* Piggy3 LED[6] */
11344097e26SHeiko Schocher 	MPP44_GPIO,		/* Piggy3 LED[7], BIST_EN_L */
11467fa8c25SHeiko Schocher 	MPP45_GPIO,		/* Piggy3 LED[8] */
11567fa8c25SHeiko Schocher 	MPP46_GPIO,		/* Reserved */
11667fa8c25SHeiko Schocher 	MPP47_GPIO,		/* Reserved */
11767fa8c25SHeiko Schocher 	MPP48_GPIO,		/* Reserved */
11867fa8c25SHeiko Schocher 	MPP49_GPIO,		/* SW_INTOUTn */
11967fa8c25SHeiko Schocher 	0
12067fa8c25SHeiko Schocher };
12167fa8c25SHeiko Schocher 
1220bb95a68SValentin Longchamp static uchar ivm_content[CONFIG_SYS_IVM_EEPROM_MAX_LEN];
1230bb95a68SValentin Longchamp 
124f945439aSHolger Brunck #if defined(CONFIG_KM_MGCOGE3UN)
1258612b701SHolger Brunck /*
1268612b701SHolger Brunck  * Wait for startup OK from mgcoge3ne
1278612b701SHolger Brunck  */
startup_allowed(void)128aef0bdc0SHolger Brunck static int startup_allowed(void)
1298612b701SHolger Brunck {
1308612b701SHolger Brunck 	unsigned char buf;
1318612b701SHolger Brunck 
1328612b701SHolger Brunck 	/*
1338612b701SHolger Brunck 	 * Read CIRQ16 bit (bit 0)
1348612b701SHolger Brunck 	 */
1358612b701SHolger Brunck 	if (i2c_read(BOCO, REG_IRQ_CIRQ2, 1, &buf, 1) != 0)
1368612b701SHolger Brunck 		printf("%s: Error reading Boco\n", __func__);
1378612b701SHolger Brunck 	else
1388612b701SHolger Brunck 		if ((buf & MASK_RBI_DEFECT_16) == MASK_RBI_DEFECT_16)
1398612b701SHolger Brunck 			return 1;
1408612b701SHolger Brunck 	return 0;
1418612b701SHolger Brunck }
14201fa4e8cSValentin Longchamp #endif
1438612b701SHolger Brunck 
144f945439aSHolger Brunck #if (defined(CONFIG_KM_PIGGY4_88E6061)|defined(CONFIG_KM_PIGGY4_88E6352))
1458612b701SHolger Brunck /*
1468170aefcSHolger Brunck  * All boards with PIGGY4 connected via a simple switch have ethernet always
1478170aefcSHolger Brunck  * present.
1488612b701SHolger Brunck  */
ethernet_present(void)1498612b701SHolger Brunck int ethernet_present(void)
1508612b701SHolger Brunck {
1518612b701SHolger Brunck 	return 1;
1528612b701SHolger Brunck }
1538612b701SHolger Brunck #else
ethernet_present(void)15467fa8c25SHeiko Schocher int ethernet_present(void)
15567fa8c25SHeiko Schocher {
15667fa8c25SHeiko Schocher 	uchar	buf;
15767fa8c25SHeiko Schocher 	int	ret = 0;
15867fa8c25SHeiko Schocher 
1598612b701SHolger Brunck 	if (i2c_read(BOCO, REG_CTRL_H, 1, &buf, 1) != 0) {
160b11f53f3SHeiko Schocher 		printf("%s: Error reading Boco\n", __func__);
16167fa8c25SHeiko Schocher 		return -1;
16267fa8c25SHeiko Schocher 	}
1638612b701SHolger Brunck 	if ((buf & MASK_RBX_PGY_PRESENT) == MASK_RBX_PGY_PRESENT)
16467fa8c25SHeiko Schocher 		ret = 1;
165b11f53f3SHeiko Schocher 
16667fa8c25SHeiko Schocher 	return ret;
16767fa8c25SHeiko Schocher }
1688612b701SHolger Brunck #endif
16967fa8c25SHeiko Schocher 
initialize_unit_leds(void)17074ae612fSHolger Brunck static int initialize_unit_leds(void)
171731b9680SHeiko Schocher {
172731b9680SHeiko Schocher 	/*
1738612b701SHolger Brunck 	 * Init the unit LEDs per default they all are
174731b9680SHeiko Schocher 	 * ok apart from bootstat
175731b9680SHeiko Schocher 	 */
176731b9680SHeiko Schocher 	uchar buf;
177731b9680SHeiko Schocher 
1788612b701SHolger Brunck 	if (i2c_read(BOCO, REG_CTRL_H, 1, &buf, 1) != 0) {
179731b9680SHeiko Schocher 		printf("%s: Error reading Boco\n", __func__);
180731b9680SHeiko Schocher 		return -1;
181731b9680SHeiko Schocher 	}
1828612b701SHolger Brunck 	buf |= MASK_WRL_UNITRUN;
1838612b701SHolger Brunck 	if (i2c_write(BOCO, REG_CTRL_H, 1, &buf, 1) != 0) {
184731b9680SHeiko Schocher 		printf("%s: Error writing Boco\n", __func__);
185731b9680SHeiko Schocher 		return -1;
186731b9680SHeiko Schocher 	}
187731b9680SHeiko Schocher 	return 0;
188731b9680SHeiko Schocher }
189731b9680SHeiko Schocher 
set_bootcount_addr(void)19074ae612fSHolger Brunck static void set_bootcount_addr(void)
19122c67d08SValentin Longchamp {
19222c67d08SValentin Longchamp 	uchar buf[32];
19322c67d08SValentin Longchamp 	unsigned int bootcountaddr;
19422c67d08SValentin Longchamp 	bootcountaddr = gd->ram_size - BOOTCOUNT_ADDR;
19522c67d08SValentin Longchamp 	sprintf((char *)buf, "0x%x", bootcountaddr);
196382bee57SSimon Glass 	env_set("bootcountaddr", (char *)buf);
19722c67d08SValentin Longchamp }
19822c67d08SValentin Longchamp 
misc_init_r(void)19967fa8c25SHeiko Schocher int misc_init_r(void)
20067fa8c25SHeiko Schocher {
201f945439aSHolger Brunck #if defined(CONFIG_KM_MGCOGE3UN)
2028612b701SHolger Brunck 	char *wait_for_ne;
203e23fde7dSHolger Brunck 	u8 dip_switch = kw_gpio_get_value(KM_FLASH_ERASE_ENABLE);
204*00caae6dSSimon Glass 	wait_for_ne = env_get("waitforne");
205e23fde7dSHolger Brunck 
206e23fde7dSHolger Brunck 	if ((wait_for_ne != NULL) && (dip_switch == 0)) {
2078612b701SHolger Brunck 		if (strcmp(wait_for_ne, "true") == 0) {
2088612b701SHolger Brunck 			int cnt = 0;
2096264800eSHolger Brunck 			int abort = 0;
2108612b701SHolger Brunck 			puts("NE go: ");
2118612b701SHolger Brunck 			while (startup_allowed() == 0) {
2126264800eSHolger Brunck 				if (tstc()) {
2136264800eSHolger Brunck 					(void) getc(); /* consume input */
2146264800eSHolger Brunck 					abort = 1;
2156264800eSHolger Brunck 					break;
2166264800eSHolger Brunck 				}
2178612b701SHolger Brunck 				udelay(200000);
2188612b701SHolger Brunck 				cnt++;
2198612b701SHolger Brunck 				if (cnt == 5)
2208612b701SHolger Brunck 					puts("wait\b\b\b\b");
2218612b701SHolger Brunck 				if (cnt == 10) {
2228612b701SHolger Brunck 					cnt = 0;
2238612b701SHolger Brunck 					puts("    \b\b\b\b");
2248612b701SHolger Brunck 				}
2258612b701SHolger Brunck 			}
2266264800eSHolger Brunck 			if (abort == 1)
2276264800eSHolger Brunck 				printf("\nAbort waiting for ne\n");
2286264800eSHolger Brunck 			else
2298612b701SHolger Brunck 				puts("OK\n");
2308612b701SHolger Brunck 		}
2318612b701SHolger Brunck 	}
2328612b701SHolger Brunck #endif
233731b9680SHeiko Schocher 
23460c4ae00SValentin Longchamp 	ivm_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN);
2350bb95a68SValentin Longchamp 
236731b9680SHeiko Schocher 	initialize_unit_leds();
23722c67d08SValentin Longchamp 	set_km_env();
23822c67d08SValentin Longchamp 	set_bootcount_addr();
23967fa8c25SHeiko Schocher 	return 0;
24067fa8c25SHeiko Schocher }
24167fa8c25SHeiko Schocher 
board_early_init_f(void)2426b0ccc3bSHeiko Schocher int board_early_init_f(void)
24367fa8c25SHeiko Schocher {
244ea818dbbSHeiko Schocher #if defined(CONFIG_SYS_I2C_SOFT)
24567fa8c25SHeiko Schocher 	u32 tmp;
24667fa8c25SHeiko Schocher 
247c471d848SHolger Brunck 	/* set the 2 bitbang i2c pins as output gpios */
248d5c5132fSStefan Roese 	tmp = readl(MVEBU_GPIO0_BASE + 4);
249d5c5132fSStefan Roese 	writel(tmp & (~KM_KIRKWOOD_SOFT_I2C_GPIOS) , MVEBU_GPIO0_BASE + 4);
250c471d848SHolger Brunck #endif
2513a5b9fe6SHolger Brunck 	/* adjust SDRAM size for bank 0 */
25296c5f081SStefan Roese 	mvebu_sdram_size_adjust(0);
253c471d848SHolger Brunck 	kirkwood_mpp_conf(kwmpp_config, NULL);
2546b0ccc3bSHeiko Schocher 	return 0;
2556b0ccc3bSHeiko Schocher }
2566b0ccc3bSHeiko Schocher 
board_init(void)2576b0ccc3bSHeiko Schocher int board_init(void)
2586b0ccc3bSHeiko Schocher {
2596b0ccc3bSHeiko Schocher 	/* address of boot parameters */
26096c5f081SStefan Roese 	gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
2616b0ccc3bSHeiko Schocher 
262c471d848SHolger Brunck 	/*
263c471d848SHolger Brunck 	 * The KM_FLASH_GPIO_PIN switches between using a
264c471d848SHolger Brunck 	 * NAND or a SPI FLASH. Set this pin on start
265c471d848SHolger Brunck 	 * to NAND mode.
266c471d848SHolger Brunck 	 */
267c471d848SHolger Brunck 	kw_gpio_set_valid(KM_FLASH_GPIO_PIN, 1);
268c471d848SHolger Brunck 	kw_gpio_direction_output(KM_FLASH_GPIO_PIN, 1);
269c471d848SHolger Brunck 
270ea818dbbSHeiko Schocher #if defined(CONFIG_SYS_I2C_SOFT)
271c471d848SHolger Brunck 	/*
272c471d848SHolger Brunck 	 * Reinit the GPIO for I2C Bitbang driver so that the now
273c471d848SHolger Brunck 	 * available gpio framework is consistent. The calls to
274c471d848SHolger Brunck 	 * direction output in are not necessary, they are already done in
275c471d848SHolger Brunck 	 * board_early_init_f
276c471d848SHolger Brunck 	 */
277c471d848SHolger Brunck 	kw_gpio_set_valid(KM_KIRKWOOD_SDA_PIN, 1);
278c471d848SHolger Brunck 	kw_gpio_set_valid(KM_KIRKWOOD_SCL_PIN, 1);
279c471d848SHolger Brunck #endif
280c471d848SHolger Brunck 
281c471d848SHolger Brunck #if defined(CONFIG_SYS_EEPROM_WREN)
282c471d848SHolger Brunck 	kw_gpio_set_valid(KM_KIRKWOOD_ENV_WP, 38);
283c471d848SHolger Brunck 	kw_gpio_direction_output(KM_KIRKWOOD_ENV_WP, 1);
284c471d848SHolger Brunck #endif
285c471d848SHolger Brunck 
286b37f7724SValentin Longchamp #if defined(CONFIG_KM_FPGA_CONFIG)
287b37f7724SValentin Longchamp 	trigger_fpga_config();
288b37f7724SValentin Longchamp #endif
289b37f7724SValentin Longchamp 
290b37f7724SValentin Longchamp 	return 0;
291b37f7724SValentin Longchamp }
292b37f7724SValentin Longchamp 
board_late_init(void)293b37f7724SValentin Longchamp int board_late_init(void)
294b37f7724SValentin Longchamp {
29530f9ad77SValentin Longchamp #if (defined(CONFIG_KM_COGE5UN) | defined(CONFIG_KM_MGCOGE3UN))
296b8cf7cc8SThomas Herzmann 	u8 dip_switch = kw_gpio_get_value(KM_FLASH_ERASE_ENABLE);
297b8cf7cc8SThomas Herzmann 
298b8cf7cc8SThomas Herzmann 	/* if pin 1 do full erase */
299b8cf7cc8SThomas Herzmann 	if (dip_switch != 0) {
300b8cf7cc8SThomas Herzmann 		/* start bootloader */
301b8cf7cc8SThomas Herzmann 		puts("DIP:   Enabled\n");
302382bee57SSimon Glass 		env_set("actual_bank", "0");
303b8cf7cc8SThomas Herzmann 	}
304b8cf7cc8SThomas Herzmann #endif
305b8cf7cc8SThomas Herzmann 
306b37f7724SValentin Longchamp #if defined(CONFIG_KM_FPGA_CONFIG)
307b37f7724SValentin Longchamp 	wait_for_fpga_config();
308b37f7724SValentin Longchamp 	fpga_reset();
309b37f7724SValentin Longchamp 	toggle_eeprom_spi_bus();
310b37f7724SValentin Longchamp #endif
31167fa8c25SHeiko Schocher 	return 0;
31267fa8c25SHeiko Schocher }
31367fa8c25SHeiko Schocher 
board_spi_claim_bus(struct spi_slave * slave)3140c25defcSValentin Longchamp int board_spi_claim_bus(struct spi_slave *slave)
31567fa8c25SHeiko Schocher {
3160c25defcSValentin Longchamp 	kw_gpio_set_value(KM_FLASH_GPIO_PIN, 0);
31767fa8c25SHeiko Schocher 
31867fa8c25SHeiko Schocher 	return 0;
31967fa8c25SHeiko Schocher }
32067fa8c25SHeiko Schocher 
board_spi_release_bus(struct spi_slave * slave)3210c25defcSValentin Longchamp void board_spi_release_bus(struct spi_slave *slave)
3220c25defcSValentin Longchamp {
3230c25defcSValentin Longchamp 	kw_gpio_set_value(KM_FLASH_GPIO_PIN, 1);
3240c25defcSValentin Longchamp }
32567fa8c25SHeiko Schocher 
3266ef64861SHolger Brunck #if (defined(CONFIG_KM_PIGGY4_88E6061))
3278f2827fcSValentin Longchamp 
328c1b8514aSValentin Longchamp #define	PHY_LED_SEL_REG		0x18
3298f2827fcSValentin Longchamp #define PHY_LED0_LINK		(0x5)
3308f2827fcSValentin Longchamp #define PHY_LED1_ACT		(0x8<<4)
3318f2827fcSValentin Longchamp #define PHY_LED2_INT		(0xe<<8)
332c1b8514aSValentin Longchamp #define	PHY_SPEC_CTRL_REG	0x1c
3338f2827fcSValentin Longchamp #define PHY_RGMII_CLK_STABLE	(0x1<<10)
3348f2827fcSValentin Longchamp #define PHY_CLSA		(0x1<<1)
3358f2827fcSValentin Longchamp 
3368f2827fcSValentin Longchamp /* Configure and enable MV88E3018 PHY */
reset_phy(void)3378f2827fcSValentin Longchamp void reset_phy(void)
3388f2827fcSValentin Longchamp {
3398f2827fcSValentin Longchamp 	char *name = "egiga0";
3408f2827fcSValentin Longchamp 	unsigned short reg;
3418f2827fcSValentin Longchamp 
3428f2827fcSValentin Longchamp 	if (miiphy_set_current_dev(name))
3438f2827fcSValentin Longchamp 		return;
3448f2827fcSValentin Longchamp 
3458f2827fcSValentin Longchamp 	/* RGMII clk transition on data stable */
346fa6e0ecbSHolger Brunck 	if (miiphy_read(name, CONFIG_PHY_BASE_ADR, PHY_SPEC_CTRL_REG, &reg))
3478f2827fcSValentin Longchamp 		printf("Error reading PHY spec ctrl reg\n");
348fa6e0ecbSHolger Brunck 	if (miiphy_write(name, CONFIG_PHY_BASE_ADR, PHY_SPEC_CTRL_REG,
349c1b8514aSValentin Longchamp 			 reg | PHY_RGMII_CLK_STABLE | PHY_CLSA))
3508f2827fcSValentin Longchamp 		printf("Error writing PHY spec ctrl reg\n");
3518f2827fcSValentin Longchamp 
3528f2827fcSValentin Longchamp 	/* leds setup */
353fa6e0ecbSHolger Brunck 	if (miiphy_write(name, CONFIG_PHY_BASE_ADR, PHY_LED_SEL_REG,
354c1b8514aSValentin Longchamp 			 PHY_LED0_LINK | PHY_LED1_ACT | PHY_LED2_INT))
3558f2827fcSValentin Longchamp 		printf("Error writing PHY LED reg\n");
3568f2827fcSValentin Longchamp 
3578f2827fcSValentin Longchamp 	/* reset the phy */
3588f2827fcSValentin Longchamp 	miiphy_reset(name, CONFIG_PHY_BASE_ADR);
3598f2827fcSValentin Longchamp }
36052638c41SValentin Longchamp #elif defined(CONFIG_KM_PIGGY4_88E6352)
36152638c41SValentin Longchamp 
36252638c41SValentin Longchamp #include <mv88e6352.h>
36352638c41SValentin Longchamp 
36452638c41SValentin Longchamp #if defined(CONFIG_KM_NUSA)
36552638c41SValentin Longchamp struct mv88e_sw_reg extsw_conf[] = {
36652638c41SValentin Longchamp 	/*
36752638c41SValentin Longchamp 	 * port 0, PIGGY4, autoneg
36852638c41SValentin Longchamp 	 * first the fix for the 1000Mbits Autoneg, this is from
36952638c41SValentin Longchamp 	 * a Marvell errata, the regs are undocumented
37052638c41SValentin Longchamp 	 */
37152638c41SValentin Longchamp 	{ PHY(0), PHY_PAGE, AN1000FIX_PAGE },
37252638c41SValentin Longchamp 	{ PHY(0), PHY_STATUS, AN1000FIX },
37352638c41SValentin Longchamp 	{ PHY(0), PHY_PAGE, 0 },
37452638c41SValentin Longchamp 	/* now the real port and phy configuration */
37552638c41SValentin Longchamp 	{ PORT(0), PORT_PHY, NO_SPEED_FOR },
37652638c41SValentin Longchamp 	{ PORT(0), PORT_CTRL, FORWARDING | EGRS_FLD_ALL },
37752638c41SValentin Longchamp 	{ PHY(0), PHY_1000_CTRL, NO_ADV },
37852638c41SValentin Longchamp 	{ PHY(0), PHY_SPEC_CTRL, AUTO_MDIX_EN },
37952638c41SValentin Longchamp 	{ PHY(0), PHY_CTRL, PHY_100_MBPS | AUTONEG_EN | AUTONEG_RST |
38052638c41SValentin Longchamp 		FULL_DUPLEX },
38152638c41SValentin Longchamp 	/* port 1, unused */
38252638c41SValentin Longchamp 	{ PORT(1), PORT_CTRL, PORT_DIS },
38352638c41SValentin Longchamp 	{ PHY(1), PHY_CTRL, PHY_PWR_DOWN },
38452638c41SValentin Longchamp 	{ PHY(1), PHY_SPEC_CTRL, SPEC_PWR_DOWN },
38552638c41SValentin Longchamp 	/* port 2, unused */
38652638c41SValentin Longchamp 	{ PORT(2), PORT_CTRL, PORT_DIS },
38752638c41SValentin Longchamp 	{ PHY(2), PHY_CTRL, PHY_PWR_DOWN },
38852638c41SValentin Longchamp 	{ PHY(2), PHY_SPEC_CTRL, SPEC_PWR_DOWN },
38952638c41SValentin Longchamp 	/* port 3, unused */
39052638c41SValentin Longchamp 	{ PORT(3), PORT_CTRL, PORT_DIS },
39152638c41SValentin Longchamp 	{ PHY(3), PHY_CTRL, PHY_PWR_DOWN },
39252638c41SValentin Longchamp 	{ PHY(3), PHY_SPEC_CTRL, SPEC_PWR_DOWN },
39352638c41SValentin Longchamp 	/* port 4, ICNEV, SerDes, SGMII */
39452638c41SValentin Longchamp 	{ PORT(4), PORT_STATUS, NO_PHY_DETECT },
39552638c41SValentin Longchamp 	{ PORT(4), PORT_PHY, SPEED_1000_FOR },
39652638c41SValentin Longchamp 	{ PORT(4), PORT_CTRL, FORWARDING | EGRS_FLD_ALL },
39752638c41SValentin Longchamp 	{ PHY(4), PHY_CTRL, PHY_PWR_DOWN },
39852638c41SValentin Longchamp 	{ PHY(4), PHY_SPEC_CTRL, SPEC_PWR_DOWN },
39952638c41SValentin Longchamp 	/* port 5, CPU_RGMII */
40052638c41SValentin Longchamp 	{ PORT(5), PORT_PHY, RX_RGMII_TIM | TX_RGMII_TIM | FLOW_CTRL_EN |
40152638c41SValentin Longchamp 		FLOW_CTRL_FOR | LINK_VAL | LINK_FOR | FULL_DPX |
40252638c41SValentin Longchamp 		FULL_DPX_FOR | SPEED_1000_FOR },
40352638c41SValentin Longchamp 	{ PORT(5), PORT_CTRL, FORWARDING | EGRS_FLD_ALL },
40452638c41SValentin Longchamp 	/* port 6, unused, this port has no phy */
40552638c41SValentin Longchamp 	{ PORT(6), PORT_CTRL, PORT_DIS },
40652638c41SValentin Longchamp };
40752638c41SValentin Longchamp #else
40852638c41SValentin Longchamp struct mv88e_sw_reg extsw_conf[] = {};
40952638c41SValentin Longchamp #endif
41052638c41SValentin Longchamp 
reset_phy(void)41152638c41SValentin Longchamp void reset_phy(void)
41252638c41SValentin Longchamp {
41352638c41SValentin Longchamp #if defined(CONFIG_KM_MVEXTSW_ADDR)
41452638c41SValentin Longchamp 	char *name = "egiga0";
41552638c41SValentin Longchamp 
41652638c41SValentin Longchamp 	if (miiphy_set_current_dev(name))
41752638c41SValentin Longchamp 		return;
41852638c41SValentin Longchamp 
41952638c41SValentin Longchamp 	mv88e_sw_program(name, CONFIG_KM_MVEXTSW_ADDR, extsw_conf,
42052638c41SValentin Longchamp 		ARRAY_SIZE(extsw_conf));
42152638c41SValentin Longchamp 	mv88e_sw_reset(name, CONFIG_KM_MVEXTSW_ADDR);
42252638c41SValentin Longchamp #endif
42352638c41SValentin Longchamp }
42452638c41SValentin Longchamp 
4258f2827fcSValentin Longchamp #else
4268f2827fcSValentin Longchamp /* Configure and enable MV88E1118 PHY on the piggy*/
reset_phy(void)42767fa8c25SHeiko Schocher void reset_phy(void)
42867fa8c25SHeiko Schocher {
4299ff739e4STobias Müller 	unsigned int oui;
4309ff739e4STobias Müller 	unsigned char model, rev;
4319ff739e4STobias Müller 
43267fa8c25SHeiko Schocher 	char *name = "egiga0";
43367fa8c25SHeiko Schocher 
43467fa8c25SHeiko Schocher 	if (miiphy_set_current_dev(name))
43567fa8c25SHeiko Schocher 		return;
43667fa8c25SHeiko Schocher 
43767fa8c25SHeiko Schocher 	/* reset the phy */
43867fa8c25SHeiko Schocher 	miiphy_reset(name, CONFIG_PHY_BASE_ADR);
4399ff739e4STobias Müller 
4409ff739e4STobias Müller 	/* get PHY model */
4419ff739e4STobias Müller 	if (miiphy_info(name, CONFIG_PHY_BASE_ADR, &oui, &model, &rev))
4429ff739e4STobias Müller 		return;
4439ff739e4STobias Müller 
4449ff739e4STobias Müller 	/* check for Marvell 88E1118R Gigabit PHY (PIGGY3) */
4459ff739e4STobias Müller 	if ((oui == PHY_MARVELL_OUI) &&
4469ff739e4STobias Müller 	    (model == PHY_MARVELL_88E1118R_MODEL)) {
4479ff739e4STobias Müller 		/* set page register to 3 */
4489ff739e4STobias Müller 		if (miiphy_write(name, CONFIG_PHY_BASE_ADR,
4499ff739e4STobias Müller 				 PHY_MARVELL_PAGE_REG,
4509ff739e4STobias Müller 				 PHY_MARVELL_88E1118R_LED_CTRL_PAGE))
4519ff739e4STobias Müller 			printf("Error writing PHY page reg\n");
4529ff739e4STobias Müller 
4539ff739e4STobias Müller 		/*
4549ff739e4STobias Müller 		 * leds setup as printed on PCB:
4559ff739e4STobias Müller 		 * LED2 (Link): 0x0 (On Link, Off No Link)
4569ff739e4STobias Müller 		 * LED1 (Activity): 0x3 (On Activity, Off No Activity)
4579ff739e4STobias Müller 		 * LED0 (Speed): 0x7 (On 1000 MBits, Off Else)
4589ff739e4STobias Müller 		 */
4599ff739e4STobias Müller 		if (miiphy_write(name, CONFIG_PHY_BASE_ADR,
4609ff739e4STobias Müller 				 PHY_MARVELL_88E1118R_LED_CTRL_REG,
4619ff739e4STobias Müller 				 PHY_MARVELL_88E1118R_LED_CTRL_RESERVED |
4629ff739e4STobias Müller 				 PHY_MARVELL_88E1118R_LED_CTRL_LED0_1000MB |
4639ff739e4STobias Müller 				 PHY_MARVELL_88E1118R_LED_CTRL_LED1_ACT |
4649ff739e4STobias Müller 				 PHY_MARVELL_88E1118R_LED_CTRL_LED2_LINK))
4659ff739e4STobias Müller 			printf("Error writing PHY LED reg\n");
4669ff739e4STobias Müller 
4679ff739e4STobias Müller 		/* set page register back to 0 */
4689ff739e4STobias Müller 		if (miiphy_write(name, CONFIG_PHY_BASE_ADR,
4699ff739e4STobias Müller 				 PHY_MARVELL_PAGE_REG,
4709ff739e4STobias Müller 				 PHY_MARVELL_DEFAULT_PAGE))
4719ff739e4STobias Müller 			printf("Error writing PHY page reg\n");
4729ff739e4STobias Müller 	}
47367fa8c25SHeiko Schocher }
4748f2827fcSValentin Longchamp #endif
4758f2827fcSValentin Longchamp 
47667fa8c25SHeiko Schocher 
47767fa8c25SHeiko Schocher #if defined(CONFIG_HUSH_INIT_VAR)
hush_init_var(void)47867fa8c25SHeiko Schocher int hush_init_var(void)
47967fa8c25SHeiko Schocher {
4800bb95a68SValentin Longchamp 	ivm_analyze_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN);
48167fa8c25SHeiko Schocher 	return 0;
48267fa8c25SHeiko Schocher }
48367fa8c25SHeiko Schocher #endif
48467fa8c25SHeiko Schocher 
485ea818dbbSHeiko Schocher #if defined(CONFIG_SYS_I2C_SOFT)
set_sda(int state)48667fa8c25SHeiko Schocher void set_sda(int state)
48767fa8c25SHeiko Schocher {
48867fa8c25SHeiko Schocher 	I2C_ACTIVE;
48967fa8c25SHeiko Schocher 	I2C_SDA(state);
49067fa8c25SHeiko Schocher }
49167fa8c25SHeiko Schocher 
set_scl(int state)49267fa8c25SHeiko Schocher void set_scl(int state)
49367fa8c25SHeiko Schocher {
49467fa8c25SHeiko Schocher 	I2C_SCL(state);
49567fa8c25SHeiko Schocher }
49667fa8c25SHeiko Schocher 
get_sda(void)49767fa8c25SHeiko Schocher int get_sda(void)
49867fa8c25SHeiko Schocher {
49967fa8c25SHeiko Schocher 	I2C_TRISTATE;
50067fa8c25SHeiko Schocher 	return I2C_READ;
50167fa8c25SHeiko Schocher }
50267fa8c25SHeiko Schocher 
get_scl(void)50367fa8c25SHeiko Schocher int get_scl(void)
50467fa8c25SHeiko Schocher {
50544097e26SHeiko Schocher 	return kw_gpio_get_value(KM_KIRKWOOD_SCL_PIN) ? 1 : 0;
50667fa8c25SHeiko Schocher }
50767fa8c25SHeiko Schocher #endif
50867fa8c25SHeiko Schocher 
5099400f8faSValentin Longchamp #if defined(CONFIG_POST)
5109400f8faSValentin Longchamp 
5119400f8faSValentin Longchamp #define KM_POST_EN_L	44
5129400f8faSValentin Longchamp #define POST_WORD_OFF	8
5139400f8faSValentin Longchamp 
post_hotkeys_pressed(void)5149400f8faSValentin Longchamp int post_hotkeys_pressed(void)
5159400f8faSValentin Longchamp {
516d9354530SHolger Brunck #if defined(CONFIG_KM_COGE5UN)
517d9354530SHolger Brunck 	return kw_gpio_get_value(KM_POST_EN_L);
518d9354530SHolger Brunck #else
5199400f8faSValentin Longchamp 	return !kw_gpio_get_value(KM_POST_EN_L);
520d9354530SHolger Brunck #endif
5219400f8faSValentin Longchamp }
5229400f8faSValentin Longchamp 
post_word_load(void)5239400f8faSValentin Longchamp ulong post_word_load(void)
5249400f8faSValentin Longchamp {
5256a23f311SHolger Brunck 	void* addr = (void *) (gd->ram_size - BOOTCOUNT_ADDR + POST_WORD_OFF);
5269400f8faSValentin Longchamp 	return in_le32(addr);
5279400f8faSValentin Longchamp 
5289400f8faSValentin Longchamp }
post_word_store(ulong value)5299400f8faSValentin Longchamp void post_word_store(ulong value)
5309400f8faSValentin Longchamp {
5316a23f311SHolger Brunck 	void* addr = (void *) (gd->ram_size - BOOTCOUNT_ADDR + POST_WORD_OFF);
5329400f8faSValentin Longchamp 	out_le32(addr, value);
5339400f8faSValentin Longchamp }
5349400f8faSValentin Longchamp 
arch_memory_test_prepare(u32 * vstart,u32 * size,phys_addr_t * phys_offset)5359400f8faSValentin Longchamp int arch_memory_test_prepare(u32 *vstart, u32 *size, phys_addr_t *phys_offset)
5369400f8faSValentin Longchamp {
5379400f8faSValentin Longchamp 	*vstart = CONFIG_SYS_SDRAM_BASE;
5389400f8faSValentin Longchamp 
5399400f8faSValentin Longchamp 	/* we go up to relocation plus a 1 MB margin */
5409400f8faSValentin Longchamp 	*size = CONFIG_SYS_TEXT_BASE - (1<<20);
5419400f8faSValentin Longchamp 
5429400f8faSValentin Longchamp 	return 0;
5439400f8faSValentin Longchamp }
5449400f8faSValentin Longchamp #endif
5459400f8faSValentin Longchamp 
54667fa8c25SHeiko Schocher #if defined(CONFIG_SYS_EEPROM_WREN)
eeprom_write_enable(unsigned dev_addr,int state)54767fa8c25SHeiko Schocher int eeprom_write_enable(unsigned dev_addr, int state)
54867fa8c25SHeiko Schocher {
54944097e26SHeiko Schocher 	kw_gpio_set_value(KM_KIRKWOOD_ENV_WP, !state);
55067fa8c25SHeiko Schocher 
55144097e26SHeiko Schocher 	return !kw_gpio_get_value(KM_KIRKWOOD_ENV_WP);
55267fa8c25SHeiko Schocher }
55367fa8c25SHeiko Schocher #endif
554