km_arm.c 12.3 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 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
/*
 * PHY registers definitions
 */
#define PHY_MARVELL_OUI					0x5043
#define PHY_MARVELL_88E1118_MODEL			0x0022
#define PHY_MARVELL_88E1118R_MODEL			0x0024

#define PHY_MARVELL_PAGE_REG				0x0016
#define PHY_MARVELL_DEFAULT_PAGE			0x0000

#define PHY_MARVELL_88E1118R_LED_CTRL_PAGE		0x0003
#define PHY_MARVELL_88E1118R_LED_CTRL_REG		0x0010

#define PHY_MARVELL_88E1118R_LED_CTRL_RESERVED		0x1000
#define PHY_MARVELL_88E1118R_LED_CTRL_LED0_1000MB	(0x7<<0)
#define PHY_MARVELL_88E1118R_LED_CTRL_LED1_ACT		(0x3<<4)
#define PHY_MARVELL_88E1118R_LED_CTRL_LED2_LINK		(0x0<<8)

58
/* Multi-Purpose Pins Functionality configuration */
59
static const u32 kwmpp_config[] = {
60 61 62 63 64 65 66
	MPP0_NF_IO2,
	MPP1_NF_IO3,
	MPP2_NF_IO4,
	MPP3_NF_IO5,
	MPP4_NF_IO6,
	MPP5_NF_IO7,
	MPP6_SYSRST_OUTn,
67 68 69
#if defined(KM_PCIE_RESET_MPP7)
	MPP7_GPO,
#else
70
	MPP7_PEX_RST_OUTn,
71
#endif
72
#if defined(CONFIG_SYS_I2C_SOFT)
73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
	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] */
114
	MPP44_GPIO,		/* Piggy3 LED[7], BIST_EN_L */
115 116 117 118 119 120 121 122
	MPP45_GPIO,		/* Piggy3 LED[8] */
	MPP46_GPIO,		/* Reserved */
	MPP47_GPIO,		/* Reserved */
	MPP48_GPIO,		/* Reserved */
	MPP49_GPIO,		/* SW_INTOUTn */
	0
};

123 124
static uchar ivm_content[CONFIG_SYS_IVM_EEPROM_MAX_LEN];

125
#if defined(CONFIG_KM_MGCOGE3UN)
126 127 128
/*
 * Wait for startup OK from mgcoge3ne
 */
129
static int startup_allowed(void)
130 131 132 133 134 135 136 137 138 139 140 141 142
{
	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;
}
143
#endif
144

145
#if (defined(CONFIG_KM_PIGGY4_88E6061)|defined(CONFIG_KM_PIGGY4_88E6352))
146
/*
H
Holger Brunck 已提交
147 148
 * All boards with PIGGY4 connected via a simple switch have ethernet always
 * present.
149 150 151 152 153 154
 */
int ethernet_present(void)
{
	return 1;
}
#else
155 156 157 158 159
int ethernet_present(void)
{
	uchar	buf;
	int	ret = 0;

160
	if (i2c_read(BOCO, REG_CTRL_H, 1, &buf, 1) != 0) {
161
		printf("%s: Error reading Boco\n", __func__);
162 163
		return -1;
	}
164
	if ((buf & MASK_RBX_PGY_PRESENT) == MASK_RBX_PGY_PRESENT)
165
		ret = 1;
166

167 168
	return ret;
}
169
#endif
170

171
static int initialize_unit_leds(void)
172 173
{
	/*
174
	 * Init the unit LEDs per default they all are
175 176 177 178
	 * ok apart from bootstat
	 */
	uchar buf;

179
	if (i2c_read(BOCO, REG_CTRL_H, 1, &buf, 1) != 0) {
180 181 182
		printf("%s: Error reading Boco\n", __func__);
		return -1;
	}
183 184
	buf |= MASK_WRL_UNITRUN;
	if (i2c_write(BOCO, REG_CTRL_H, 1, &buf, 1) != 0) {
185 186 187 188 189 190
		printf("%s: Error writing Boco\n", __func__);
		return -1;
	}
	return 0;
}

191
static void set_bootcount_addr(void)
192 193 194 195 196 197 198 199
{
	uchar buf[32];
	unsigned int bootcountaddr;
	bootcountaddr = gd->ram_size - BOOTCOUNT_ADDR;
	sprintf((char *)buf, "0x%x", bootcountaddr);
	setenv("bootcountaddr", (char *)buf);
}

200 201
int misc_init_r(void)
{
202
#if defined(CONFIG_KM_MGCOGE3UN)
203 204 205 206 207
	char *wait_for_ne;
	wait_for_ne = getenv("waitforne");
	if (wait_for_ne != NULL) {
		if (strcmp(wait_for_ne, "true") == 0) {
			int cnt = 0;
208
			int abort = 0;
209 210
			puts("NE go: ");
			while (startup_allowed() == 0) {
211 212 213 214 215
				if (tstc()) {
					(void) getc(); /* consume input */
					abort = 1;
					break;
				}
216 217 218 219 220 221 222 223 224
				udelay(200000);
				cnt++;
				if (cnt == 5)
					puts("wait\b\b\b\b");
				if (cnt == 10) {
					cnt = 0;
					puts("    \b\b\b\b");
				}
			}
225 226 227 228
			if (abort == 1)
				printf("\nAbort waiting for ne\n");
			else
				puts("OK\n");
229 230 231
		}
	}
#endif
232

233
	ivm_read_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN);
234

235
	initialize_unit_leds();
236 237
	set_km_env();
	set_bootcount_addr();
238 239 240
	return 0;
}

241
int board_early_init_f(void)
242
{
243
#if defined(CONFIG_SYS_I2C_SOFT)
244 245
	u32 tmp;

246
	/* set the 2 bitbang i2c pins as output gpios */
247 248
	tmp = readl(MVEBU_GPIO0_BASE + 4);
	writel(tmp & (~KM_KIRKWOOD_SOFT_I2C_GPIOS) , MVEBU_GPIO0_BASE + 4);
249
#endif
250
	/* adjust SDRAM size for bank 0 */
251
	mvebu_sdram_size_adjust(0);
252
	kirkwood_mpp_conf(kwmpp_config, NULL);
253 254
	return 0;
}
255

256 257 258
int board_init(void)
{
	/* address of boot parameters */
259
	gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100;
260 261 262

	/*
	 * The KM_FLASH_GPIO_PIN switches between using a
263 264 265
	 * NAND or a SPI FLASH. Set this pin on start
	 * to NAND mode.
	 */
266 267
	kw_gpio_set_valid(KM_FLASH_GPIO_PIN, 1);
	kw_gpio_direction_output(KM_FLASH_GPIO_PIN, 1);
268

269
#if defined(CONFIG_SYS_I2C_SOFT)
270 271 272 273 274 275
	/*
	 * 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
	 */
276 277
	kw_gpio_set_valid(KM_KIRKWOOD_SDA_PIN, 1);
	kw_gpio_set_valid(KM_KIRKWOOD_SCL_PIN, 1);
278
#endif
279

280
#if defined(CONFIG_SYS_EEPROM_WREN)
281 282
	kw_gpio_set_valid(KM_KIRKWOOD_ENV_WP, 38);
	kw_gpio_direction_output(KM_KIRKWOOD_ENV_WP, 1);
283
#endif
284

285 286 287 288 289 290 291 292 293
#if defined(CONFIG_KM_FPGA_CONFIG)
	trigger_fpga_config();
#endif

	return 0;
}

int board_late_init(void)
{
294 295 296 297 298 299 300 301 302 303 304 305 306
#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

307 308 309 310 311
#if defined(CONFIG_KM_FPGA_CONFIG)
	wait_for_fpga_config();
	fpga_reset();
	toggle_eeprom_spi_bus();
#endif
312 313 314
	return 0;
}

315
int board_spi_claim_bus(struct spi_slave *slave)
316
{
317
	kw_gpio_set_value(KM_FLASH_GPIO_PIN, 0);
318 319 320 321

	return 0;
}

322 323 324 325
void board_spi_release_bus(struct spi_slave *slave)
{
	kw_gpio_set_value(KM_FLASH_GPIO_PIN, 1);
}
326

327
#if (defined(CONFIG_KM_PIGGY4_88E6061))
328

329 330 331 332 333
#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
334
#define PHY_RGMII_CLK_STABLE	(0x1<<10)
335
#define PHY_CLSA		(0x1<<1)
336 337 338 339 340 341 342 343 344 345 346

/* 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 已提交
347
	if (miiphy_read(name, CONFIG_PHY_BASE_ADR, PHY_SPEC_CTRL_REG, &reg))
348
		printf("Error reading PHY spec ctrl reg\n");
H
Holger Brunck 已提交
349 350
	if (miiphy_write(name, CONFIG_PHY_BASE_ADR, PHY_SPEC_CTRL_REG,
			 reg | PHY_RGMII_CLK_STABLE | PHY_CLSA))
351 352 353
		printf("Error writing PHY spec ctrl reg\n");

	/* leds setup */
H
Holger Brunck 已提交
354 355
	if (miiphy_write(name, CONFIG_PHY_BASE_ADR, PHY_LED_SEL_REG,
			 PHY_LED0_LINK | PHY_LED1_ACT | PHY_LED2_INT))
356 357 358 359 360
		printf("Error writing PHY LED reg\n");

	/* reset the phy */
	miiphy_reset(name, CONFIG_PHY_BASE_ADR);
}
361 362 363 364 365 366 367
#elif defined(CONFIG_KM_PIGGY4_88E6352)

#include <mv88e6352.h>

#if defined(CONFIG_KM_NUSA)
struct mv88e_sw_reg extsw_conf[] = {
	/*
368
	 * port 0, PIGGY4, autoneg
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 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425
	 * 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
}

426 427
#else
/* Configure and enable MV88E1118 PHY on the piggy*/
428 429
void reset_phy(void)
{
430 431 432
	unsigned int oui;
	unsigned char model, rev;

433 434 435 436 437 438 439
	char *name = "egiga0";

	if (miiphy_set_current_dev(name))
		return;

	/* reset the phy */
	miiphy_reset(name, CONFIG_PHY_BASE_ADR);
440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473

	/* get PHY model */
	if (miiphy_info(name, CONFIG_PHY_BASE_ADR, &oui, &model, &rev))
		return;

	/* check for Marvell 88E1118R Gigabit PHY (PIGGY3) */
	if ((oui == PHY_MARVELL_OUI) &&
	    (model == PHY_MARVELL_88E1118R_MODEL)) {
		/* set page register to 3 */
		if (miiphy_write(name, CONFIG_PHY_BASE_ADR,
				 PHY_MARVELL_PAGE_REG,
				 PHY_MARVELL_88E1118R_LED_CTRL_PAGE))
			printf("Error writing PHY page reg\n");

		/*
		 * leds setup as printed on PCB:
		 * LED2 (Link): 0x0 (On Link, Off No Link)
		 * LED1 (Activity): 0x3 (On Activity, Off No Activity)
		 * LED0 (Speed): 0x7 (On 1000 MBits, Off Else)
		 */
		if (miiphy_write(name, CONFIG_PHY_BASE_ADR,
				 PHY_MARVELL_88E1118R_LED_CTRL_REG,
				 PHY_MARVELL_88E1118R_LED_CTRL_RESERVED |
				 PHY_MARVELL_88E1118R_LED_CTRL_LED0_1000MB |
				 PHY_MARVELL_88E1118R_LED_CTRL_LED1_ACT |
				 PHY_MARVELL_88E1118R_LED_CTRL_LED2_LINK))
			printf("Error writing PHY LED reg\n");

		/* set page register back to 0 */
		if (miiphy_write(name, CONFIG_PHY_BASE_ADR,
				 PHY_MARVELL_PAGE_REG,
				 PHY_MARVELL_DEFAULT_PAGE))
			printf("Error writing PHY page reg\n");
	}
474
}
475 476
#endif

477 478

#if defined(CONFIG_HUSH_INIT_VAR)
479
int hush_init_var(void)
480
{
481
	ivm_analyze_eeprom(ivm_content, CONFIG_SYS_IVM_EEPROM_MAX_LEN);
482 483 484 485
	return 0;
}
#endif

486
#if defined(CONFIG_SYS_I2C_SOFT)
487
void set_sda(int state)
488 489 490 491 492
{
	I2C_ACTIVE;
	I2C_SDA(state);
}

493
void set_scl(int state)
494 495 496 497
{
	I2C_SCL(state);
}

498
int get_sda(void)
499 500 501 502 503
{
	I2C_TRISTATE;
	return I2C_READ;
}

504
int get_scl(void)
505
{
506
	return kw_gpio_get_value(KM_KIRKWOOD_SCL_PIN) ? 1 : 0;
507 508 509
}
#endif

510 511 512 513 514 515 516
#if defined(CONFIG_POST)

#define KM_POST_EN_L	44
#define POST_WORD_OFF	8

int post_hotkeys_pressed(void)
{
517 518 519
#if defined(CONFIG_KM_COGE5UN)
	return kw_gpio_get_value(KM_POST_EN_L);
#else
520
	return !kw_gpio_get_value(KM_POST_EN_L);
521
#endif
522 523 524 525
}

ulong post_word_load(void)
{
H
Holger Brunck 已提交
526
	void* addr = (void *) (gd->ram_size - BOOTCOUNT_ADDR + POST_WORD_OFF);
527 528 529 530 531
	return in_le32(addr);

}
void post_word_store(ulong value)
{
H
Holger Brunck 已提交
532
	void* addr = (void *) (gd->ram_size - BOOTCOUNT_ADDR + POST_WORD_OFF);
533 534 535 536 537 538 539 540 541 542 543 544 545 546
	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

547
#if defined(CONFIG_SYS_EEPROM_WREN)
548
int eeprom_write_enable(unsigned dev_addr, int state)
549
{
550
	kw_gpio_set_value(KM_KIRKWOOD_ENV_WP, !state);
551

552
	return !kw_gpio_get_value(KM_KIRKWOOD_ENV_WP);
553 554
}
#endif