km_arm.c 10.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11
/*
 * (C) Copyright 2009
 * Marvell Semiconductor <www.marvell.com>
 * Prafulla Wadaskar <prafulla@marvell.com>
 *
 * (C) Copyright 2009
 * Stefan Roese, DENX Software Engineering, sr@denx.de.
 *
 * (C) Copyright 2010
 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
 *
12
 * SPDX-License-Identifier:	GPL-2.0+
13 14 15 16 17 18 19
 */

#include <common.h>
#include <i2c.h>
#include <nand.h>
#include <netdev.h>
#include <miiphy.h>
20
#include <spi.h>
21
#include <asm/io.h>
22
#include <asm/arch/cpu.h>
23
#include <asm/arch/soc.h>
24 25 26 27 28 29
#include <asm/arch/mpp.h>

#include "../common/common.h"

DECLARE_GLOBAL_DATA_PTR;

30 31 32 33 34 35 36 37 38 39
/*
 * BOCO FPGA definitions
 */
#define BOCO		0x10
#define REG_CTRL_H		0x02
#define MASK_WRL_UNITRUN	0x01
#define MASK_RBX_PGY_PRESENT	0x40
#define REG_IRQ_CIRQ2		0x2d
#define MASK_RBI_DEFECT_16	0x01

40
/* Multi-Purpose Pins Functionality configuration */
41
static const u32 kwmpp_config[] = {
42 43 44 45 46 47 48
	MPP0_NF_IO2,
	MPP1_NF_IO3,
	MPP2_NF_IO4,
	MPP3_NF_IO5,
	MPP4_NF_IO6,
	MPP5_NF_IO7,
	MPP6_SYSRST_OUTn,
49 50 51
#if defined(KM_PCIE_RESET_MPP7)
	MPP7_GPO,
#else
52
	MPP7_PEX_RST_OUTn,
53
#endif
54
#if defined(CONFIG_SYS_I2C_SOFT)
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
	MPP8_GPIO,		/* SDA */
	MPP9_GPIO,		/* SCL */
#endif
#if defined(CONFIG_HARD_I2C)
	MPP8_TW_SDA,
	MPP9_TW_SCK,
#endif
	MPP10_UART0_TXD,
	MPP11_UART0_RXD,
	MPP12_GPO,		/* Reserved */
	MPP13_UART1_TXD,
	MPP14_UART1_RXD,
	MPP15_GPIO,		/* Not used */
	MPP16_GPIO,		/* Not used */
	MPP17_GPIO,		/* Reserved */
	MPP18_NF_IO0,
	MPP19_NF_IO1,
	MPP20_GPIO,
	MPP21_GPIO,
	MPP22_GPIO,
	MPP23_GPIO,
	MPP24_GPIO,
	MPP25_GPIO,
	MPP26_GPIO,
	MPP27_GPIO,
	MPP28_GPIO,
	MPP29_GPIO,
	MPP30_GPIO,
	MPP31_GPIO,
	MPP32_GPIO,
	MPP33_GPIO,
	MPP34_GPIO,		/* CDL1 (input) */
	MPP35_GPIO,		/* CDL2 (input) */
	MPP36_GPIO,		/* MAIN_IRQ (input) */
	MPP37_GPIO,		/* BOARD_LED */
	MPP38_GPIO,		/* Piggy3 LED[1] */
	MPP39_GPIO,		/* Piggy3 LED[2] */
	MPP40_GPIO,		/* Piggy3 LED[3] */
	MPP41_GPIO,		/* Piggy3 LED[4] */
	MPP42_GPIO,		/* Piggy3 LED[5] */
	MPP43_GPIO,		/* Piggy3 LED[6] */
96
	MPP44_GPIO,		/* Piggy3 LED[7], BIST_EN_L */
97 98 99 100 101 102 103 104
	MPP45_GPIO,		/* Piggy3 LED[8] */
	MPP46_GPIO,		/* Reserved */
	MPP47_GPIO,		/* Reserved */
	MPP48_GPIO,		/* Reserved */
	MPP49_GPIO,		/* SW_INTOUTn */
	0
};

105
#if defined(CONFIG_KM_MGCOGE3UN)
106 107 108
/*
 * Wait for startup OK from mgcoge3ne
 */
109
static int startup_allowed(void)
110 111 112 113 114 115 116 117 118 119 120 121 122
{
	unsigned char buf;

	/*
	 * Read CIRQ16 bit (bit 0)
	 */
	if (i2c_read(BOCO, REG_IRQ_CIRQ2, 1, &buf, 1) != 0)
		printf("%s: Error reading Boco\n", __func__);
	else
		if ((buf & MASK_RBI_DEFECT_16) == MASK_RBI_DEFECT_16)
			return 1;
	return 0;
}
123
#endif
124

125
#if (defined(CONFIG_KM_PIGGY4_88E6061)|defined(CONFIG_KM_PIGGY4_88E6352))
126
/*
H
Holger Brunck 已提交
127 128
 * All boards with PIGGY4 connected via a simple switch have ethernet always
 * present.
129 130 131 132 133 134
 */
int ethernet_present(void)
{
	return 1;
}
#else
135 136 137 138 139
int ethernet_present(void)
{
	uchar	buf;
	int	ret = 0;

140
	if (i2c_read(BOCO, REG_CTRL_H, 1, &buf, 1) != 0) {
141
		printf("%s: Error reading Boco\n", __func__);
142 143
		return -1;
	}
144
	if ((buf & MASK_RBX_PGY_PRESENT) == MASK_RBX_PGY_PRESENT)
145
		ret = 1;
146

147 148
	return ret;
}
149
#endif
150

151
static int initialize_unit_leds(void)
152 153
{
	/*
154
	 * Init the unit LEDs per default they all are
155 156 157 158
	 * ok apart from bootstat
	 */
	uchar buf;

159
	if (i2c_read(BOCO, REG_CTRL_H, 1, &buf, 1) != 0) {
160 161 162
		printf("%s: Error reading Boco\n", __func__);
		return -1;
	}
163 164
	buf |= MASK_WRL_UNITRUN;
	if (i2c_write(BOCO, REG_CTRL_H, 1, &buf, 1) != 0) {
165 166 167 168 169 170
		printf("%s: Error writing Boco\n", __func__);
		return -1;
	}
	return 0;
}

171
static void set_bootcount_addr(void)
172 173 174 175 176 177 178 179
{
	uchar buf[32];
	unsigned int bootcountaddr;
	bootcountaddr = gd->ram_size - BOOTCOUNT_ADDR;
	sprintf((char *)buf, "0x%x", bootcountaddr);
	setenv("bootcountaddr", (char *)buf);
}

180 181
int misc_init_r(void)
{
182
#if defined(CONFIG_KM_MGCOGE3UN)
183 184 185 186 187
	char *wait_for_ne;
	wait_for_ne = getenv("waitforne");
	if (wait_for_ne != NULL) {
		if (strcmp(wait_for_ne, "true") == 0) {
			int cnt = 0;
188
			int abort = 0;
189 190
			puts("NE go: ");
			while (startup_allowed() == 0) {
191 192 193 194 195
				if (tstc()) {
					(void) getc(); /* consume input */
					abort = 1;
					break;
				}
196 197 198 199 200 201 202 203 204
				udelay(200000);
				cnt++;
				if (cnt == 5)
					puts("wait\b\b\b\b");
				if (cnt == 10) {
					cnt = 0;
					puts("    \b\b\b\b");
				}
			}
205 206 207 208
			if (abort == 1)
				printf("\nAbort waiting for ne\n");
			else
				puts("OK\n");
209 210 211
		}
	}
#endif
212 213

	initialize_unit_leds();
214 215
	set_km_env();
	set_bootcount_addr();
216 217 218
	return 0;
}

219
int board_early_init_f(void)
220
{
221
#if defined(CONFIG_SYS_I2C_SOFT)
222 223
	u32 tmp;

224
	/* set the 2 bitbang i2c pins as output gpios */
225 226
	tmp = readl(MVEBU_GPIO0_BASE + 4);
	writel(tmp & (~KM_KIRKWOOD_SOFT_I2C_GPIOS) , MVEBU_GPIO0_BASE + 4);
227
#endif
228
	/* adjust SDRAM size for bank 0 */
229
	mvebu_sdram_size_adjust(0);
230
	kirkwood_mpp_conf(kwmpp_config, NULL);
231 232
	return 0;
}
233

234 235 236
int board_init(void)
{
	/* address of boot parameters */
237
	gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
238 239 240

	/*
	 * The KM_FLASH_GPIO_PIN switches between using a
241 242 243
	 * NAND or a SPI FLASH. Set this pin on start
	 * to NAND mode.
	 */
244 245
	kw_gpio_set_valid(KM_FLASH_GPIO_PIN, 1);
	kw_gpio_direction_output(KM_FLASH_GPIO_PIN, 1);
246

247
#if defined(CONFIG_SYS_I2C_SOFT)
248 249 250 251 252 253
	/*
	 * Reinit the GPIO for I2C Bitbang driver so that the now
	 * available gpio framework is consistent. The calls to
	 * direction output in are not necessary, they are already done in
	 * board_early_init_f
	 */
254 255
	kw_gpio_set_valid(KM_KIRKWOOD_SDA_PIN, 1);
	kw_gpio_set_valid(KM_KIRKWOOD_SCL_PIN, 1);
256
#endif
257

258
#if defined(CONFIG_SYS_EEPROM_WREN)
259 260
	kw_gpio_set_valid(KM_KIRKWOOD_ENV_WP, 38);
	kw_gpio_direction_output(KM_KIRKWOOD_ENV_WP, 1);
261
#endif
262

263 264 265 266 267 268 269 270 271
#if defined(CONFIG_KM_FPGA_CONFIG)
	trigger_fpga_config();
#endif

	return 0;
}

int board_late_init(void)
{
272 273 274 275 276 277 278 279 280 281 282 283 284
#if defined(CONFIG_KMCOGE5UN)
/* I/O pin to erase flash RGPP09 = MPP43 */
#define KM_FLASH_ERASE_ENABLE	43
	u8 dip_switch = kw_gpio_get_value(KM_FLASH_ERASE_ENABLE);

	/* if pin 1 do full erase */
	if (dip_switch != 0) {
		/* start bootloader */
		puts("DIP:   Enabled\n");
		setenv("actual_bank", "0");
	}
#endif

285 286 287 288 289
#if defined(CONFIG_KM_FPGA_CONFIG)
	wait_for_fpga_config();
	fpga_reset();
	toggle_eeprom_spi_bus();
#endif
290 291 292
	return 0;
}

293
int board_spi_claim_bus(struct spi_slave *slave)
294
{
295
	kw_gpio_set_value(KM_FLASH_GPIO_PIN, 0);
296 297 298 299

	return 0;
}

300 301 302 303
void board_spi_release_bus(struct spi_slave *slave)
{
	kw_gpio_set_value(KM_FLASH_GPIO_PIN, 1);
}
304

305
#if (defined(CONFIG_KM_PIGGY4_88E6061))
306

307 308 309 310 311
#define	PHY_LED_SEL_REG		0x18
#define PHY_LED0_LINK		(0x5)
#define PHY_LED1_ACT		(0x8<<4)
#define PHY_LED2_INT		(0xe<<8)
#define	PHY_SPEC_CTRL_REG	0x1c
312
#define PHY_RGMII_CLK_STABLE	(0x1<<10)
313
#define PHY_CLSA		(0x1<<1)
314 315 316 317 318 319 320 321 322 323 324

/* Configure and enable MV88E3018 PHY */
void reset_phy(void)
{
	char *name = "egiga0";
	unsigned short reg;

	if (miiphy_set_current_dev(name))
		return;

	/* RGMII clk transition on data stable */
H
Holger Brunck 已提交
325
	if (miiphy_read(name, CONFIG_PHY_BASE_ADR, PHY_SPEC_CTRL_REG, &reg))
326
		printf("Error reading PHY spec ctrl reg\n");
H
Holger Brunck 已提交
327 328
	if (miiphy_write(name, CONFIG_PHY_BASE_ADR, PHY_SPEC_CTRL_REG,
			 reg | PHY_RGMII_CLK_STABLE | PHY_CLSA))
329 330 331
		printf("Error writing PHY spec ctrl reg\n");

	/* leds setup */
H
Holger Brunck 已提交
332 333
	if (miiphy_write(name, CONFIG_PHY_BASE_ADR, PHY_LED_SEL_REG,
			 PHY_LED0_LINK | PHY_LED1_ACT | PHY_LED2_INT))
334 335 336 337 338
		printf("Error writing PHY LED reg\n");

	/* reset the phy */
	miiphy_reset(name, CONFIG_PHY_BASE_ADR);
}
339 340 341 342 343 344 345
#elif defined(CONFIG_KM_PIGGY4_88E6352)

#include <mv88e6352.h>

#if defined(CONFIG_KM_NUSA)
struct mv88e_sw_reg extsw_conf[] = {
	/*
346
	 * port 0, PIGGY4, autoneg
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403
	 * first the fix for the 1000Mbits Autoneg, this is from
	 * a Marvell errata, the regs are undocumented
	 */
	{ PHY(0), PHY_PAGE, AN1000FIX_PAGE },
	{ PHY(0), PHY_STATUS, AN1000FIX },
	{ PHY(0), PHY_PAGE, 0 },
	/* now the real port and phy configuration */
	{ PORT(0), PORT_PHY, NO_SPEED_FOR },
	{ PORT(0), PORT_CTRL, FORWARDING | EGRS_FLD_ALL },
	{ PHY(0), PHY_1000_CTRL, NO_ADV },
	{ PHY(0), PHY_SPEC_CTRL, AUTO_MDIX_EN },
	{ PHY(0), PHY_CTRL, PHY_100_MBPS | AUTONEG_EN | AUTONEG_RST |
		FULL_DUPLEX },
	/* port 1, unused */
	{ PORT(1), PORT_CTRL, PORT_DIS },
	{ PHY(1), PHY_CTRL, PHY_PWR_DOWN },
	{ PHY(1), PHY_SPEC_CTRL, SPEC_PWR_DOWN },
	/* port 2, unused */
	{ PORT(2), PORT_CTRL, PORT_DIS },
	{ PHY(2), PHY_CTRL, PHY_PWR_DOWN },
	{ PHY(2), PHY_SPEC_CTRL, SPEC_PWR_DOWN },
	/* port 3, unused */
	{ PORT(3), PORT_CTRL, PORT_DIS },
	{ PHY(3), PHY_CTRL, PHY_PWR_DOWN },
	{ PHY(3), PHY_SPEC_CTRL, SPEC_PWR_DOWN },
	/* port 4, ICNEV, SerDes, SGMII */
	{ PORT(4), PORT_STATUS, NO_PHY_DETECT },
	{ PORT(4), PORT_PHY, SPEED_1000_FOR },
	{ PORT(4), PORT_CTRL, FORWARDING | EGRS_FLD_ALL },
	{ PHY(4), PHY_CTRL, PHY_PWR_DOWN },
	{ PHY(4), PHY_SPEC_CTRL, SPEC_PWR_DOWN },
	/* port 5, CPU_RGMII */
	{ PORT(5), PORT_PHY, RX_RGMII_TIM | TX_RGMII_TIM | FLOW_CTRL_EN |
		FLOW_CTRL_FOR | LINK_VAL | LINK_FOR | FULL_DPX |
		FULL_DPX_FOR | SPEED_1000_FOR },
	{ PORT(5), PORT_CTRL, FORWARDING | EGRS_FLD_ALL },
	/* port 6, unused, this port has no phy */
	{ PORT(6), PORT_CTRL, PORT_DIS },
};
#else
struct mv88e_sw_reg extsw_conf[] = {};
#endif

void reset_phy(void)
{
#if defined(CONFIG_KM_MVEXTSW_ADDR)
	char *name = "egiga0";

	if (miiphy_set_current_dev(name))
		return;

	mv88e_sw_program(name, CONFIG_KM_MVEXTSW_ADDR, extsw_conf,
		ARRAY_SIZE(extsw_conf));
	mv88e_sw_reset(name, CONFIG_KM_MVEXTSW_ADDR);
#endif
}

404 405
#else
/* Configure and enable MV88E1118 PHY on the piggy*/
406 407 408 409 410 411 412 413 414 415
void reset_phy(void)
{
	char *name = "egiga0";

	if (miiphy_set_current_dev(name))
		return;

	/* reset the phy */
	miiphy_reset(name, CONFIG_PHY_BASE_ADR);
}
416 417
#endif

418 419

#if defined(CONFIG_HUSH_INIT_VAR)
420
int hush_init_var(void)
421
{
422
	ivm_read_eeprom();
423 424 425 426
	return 0;
}
#endif

427
#if defined(CONFIG_SYS_I2C_SOFT)
428
void set_sda(int state)
429 430 431 432 433
{
	I2C_ACTIVE;
	I2C_SDA(state);
}

434
void set_scl(int state)
435 436 437 438
{
	I2C_SCL(state);
}

439
int get_sda(void)
440 441 442 443 444
{
	I2C_TRISTATE;
	return I2C_READ;
}

445
int get_scl(void)
446
{
447
	return kw_gpio_get_value(KM_KIRKWOOD_SCL_PIN) ? 1 : 0;
448 449 450
}
#endif

451 452 453 454 455 456 457
#if defined(CONFIG_POST)

#define KM_POST_EN_L	44
#define POST_WORD_OFF	8

int post_hotkeys_pressed(void)
{
458 459 460
#if defined(CONFIG_KM_COGE5UN)
	return kw_gpio_get_value(KM_POST_EN_L);
#else
461
	return !kw_gpio_get_value(KM_POST_EN_L);
462
#endif
463 464 465 466
}

ulong post_word_load(void)
{
H
Holger Brunck 已提交
467
	void* addr = (void *) (gd->ram_size - BOOTCOUNT_ADDR + POST_WORD_OFF);
468 469 470 471 472
	return in_le32(addr);

}
void post_word_store(ulong value)
{
H
Holger Brunck 已提交
473
	void* addr = (void *) (gd->ram_size - BOOTCOUNT_ADDR + POST_WORD_OFF);
474 475 476 477 478 479 480 481 482 483 484 485 486 487
	out_le32(addr, value);
}

int arch_memory_test_prepare(u32 *vstart, u32 *size, phys_addr_t *phys_offset)
{
	*vstart = CONFIG_SYS_SDRAM_BASE;

	/* we go up to relocation plus a 1 MB margin */
	*size = CONFIG_SYS_TEXT_BASE - (1<<20);

	return 0;
}
#endif

488
#if defined(CONFIG_SYS_EEPROM_WREN)
489
int eeprom_write_enable(unsigned dev_addr, int state)
490
{
491
	kw_gpio_set_value(KM_KIRKWOOD_ENV_WP, !state);
492

493
	return !kw_gpio_get_value(KM_KIRKWOOD_ENV_WP);
494 495
}
#endif