Patchwork [U-Boot,V2] AT91: EMK/TOP9000 board actualization

login
register
mail settings
Submitter Reinhard Meyer
Date July 26, 2011, 8:12 a.m.
Message ID <1311667964-13186-1-git-send-email-u-boot@emk-elektronik.de>
Download mbox | patch
Permalink /patch/106795/
State Accepted
Delegated to: Reinhard Meyer
Headers show

Comments

Reinhard Meyer - July 26, 2011, 8:12 a.m.
This is a general update of all projects involving the TOP9000 CPU module.
Changes:
 Enable the /RESET input
 Add more ARCH numbers
 Add EAN13 checksum routine
 Add reading of VPD EEPROM
 Remove obsolete reset_phy()
 Add boot progress LEDs

Signed-off-by: Reinhard Meyer <u-boot@emk-elektronik.de>
---
 board/emk/top9000/top9000.c |  131 ++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 116 insertions(+), 15 deletions(-)
Reinhard Meyer - July 26, 2011, 11:54 a.m.
Dear Reinhard Meyer,
> This is a general update of all projects involving the TOP9000 CPU module.
> Changes:
>  Enable the /RESET input
>  Add more ARCH numbers
>  Add EAN13 checksum routine
>  Add reading of VPD EEPROM
>  Remove obsolete reset_phy()
>  Add boot progress LEDs
> 
> Signed-off-by: Reinhard Meyer <u-boot@emk-elektronik.de>
> ---
>  board/emk/top9000/top9000.c |  131 ++++++++++++++++++++++++++++++++++++++-----
>  1 files changed, 116 insertions(+), 15 deletions(-)
Removed trailing empty line.
Applied to u-boot-atmel/next.
Thanks, Reinhard

Patch

diff --git a/board/emk/top9000/top9000.c b/board/emk/top9000/top9000.c
index 61dee62..92e8a9d 100644
--- a/board/emk/top9000/top9000.c
+++ b/board/emk/top9000/top9000.c
@@ -126,6 +126,7 @@  int board_mmc_getcd(u8 *cd, struct mmc *mmc)
 int board_early_init_f(void)
 {
 	struct at91_shdwn *shdwn = (struct at91_shdwn *)ATMEL_BASE_SHDWN;
+	struct at91_rstc *rstc = (struct at91_rstc *)ATMEL_BASE_RSTC;
 	struct at91_pmc *pmc = (struct at91_pmc *)ATMEL_BASE_PMC;
 
 	/*
@@ -135,6 +136,13 @@  int board_early_init_f(void)
 	writel(AT91_SHDW_MR_WKMODE0H2L | AT91_SHDW_MR_WKMODE0L2H,
 		&shdwn->mr);
 
+	/*
+	 * make sure the board can be reset by
+	 * low level on nRST
+	 */
+	writel(AT91_RSTC_KEY | AT91_RSTC_MR_URSTEN,
+		&rstc->mr);
+
 	/* Enable clocks for all PIOs */
 	writel((1 << ATMEL_ID_PIOA) | (1 << ATMEL_ID_PIOB) |
 		(1 << ATMEL_ID_PIOC),
@@ -160,8 +168,14 @@  int board_early_init_f(void)
 
 int board_init(void)
 {
-	/* arch number of TOP9000 Board */
-	gd->bd->bi_arch_number = MACH_TYPE_TOP9000;
+	/* arch numbers of TOP9000 and baseboards */
+#if defined(CONFIG_EVAL9000)
+	gd->bd->bi_arch_number = MACH_TYPE_TOP9000_EVAL;
+#elif defined(CONFIG_SU9000)
+	gd->bd->bi_arch_number = MACH_TYPE_TOP9000_SU;
+#else
+	gd->bd->bi_arch_number = MACH_TYPE_TOP9000;
+#endif
 	/* adress of boot parameters */
 	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
 
@@ -183,10 +197,97 @@  int board_init(void)
 }
 
 #ifdef CONFIG_MISC_INIT_R
+static int checksum(char *p)
+{
+	int sum = 0;
+	int i = 13;
+
+	while (i > 0) {
+		if (*p < '0' || *p > '9')
+			return -1;
+		sum += *p;
+		if (!(i & 1))
+			sum += 2 * *p;
+		--i;
+		++p;
+	}
+	return sum % 10;
+}
+
 int misc_init_r(void)
 {
 	/* read 'factory' part of EEPROM */
-	read_factory_r();
+	char buf[32];
+	char tag[4];
+	uint addr = CONFIG_SYS_FACT_OFFSET;
+	uint len = CONFIG_SYS_FACT_SIZE;
+	int have_top = 0;
+
+	/* read entries */
+	while (len >= 16) {
+		/* read one entry */
+		if (eeprom_read(CONFIG_SYS_I2C_FACT_ADDR,
+						addr, (uchar *)buf, 16))
+			goto bailout;
+		addr += 16;
+		len -= 16;
+		/* get tag field */
+		tag[0] = buf[0];
+		tag[1] = buf[1];
+		tag[2] = buf[2];
+		tag[3] = 0;
+		/* skip entries with bad checksum */
+		if (checksum(buf + 3))
+			continue;
+		/* test for specific entries */
+		if (!strcmp(tag, "TOP")) {
+			unsigned serialno;
+			/* retrieve serialnumber */
+			buf[15] = 0;
+			serialno = simple_strtoul(buf + 10, NULL, 10);
+			buf[10] = 0;
+			setenv("board_id", buf);
+			sprintf(buf, "%05d", serialno);
+			setenv("serial#", buf);
+			sprintf(buf, "00:80:d9:0d:%02x:%02x",
+				serialno / 256,
+				serialno % 256);
+			setenv("ethaddr", buf);
+			have_top = 1;
+		} else if (!strcmp(tag, "MA2")) {
+			unsigned serialno;
+			/* retrieve serialnumber */
+			buf[15] = 0;
+			serialno = simple_strtoul(buf + 10, NULL, 10);
+			sprintf(buf, "00:80:d9:0e:%02x:%02x",
+				serialno / 256,
+				serialno % 256);
+			setenv("eth2addr", buf);
+		} else if (!strcmp(tag, "MA3")) {
+			unsigned serialno;
+			/* retrieve serialnumber */
+			buf[15] = 0;
+			serialno = simple_strtoul(buf + 10, NULL, 10);
+			sprintf(buf, "00:80:d9:0e:%02x:%02x",
+				serialno / 256,
+				serialno % 256);
+			setenv("eth3addr", buf);
+		} else if (!strcmp(tag, "MA4")) {
+			unsigned serialno;
+			/* retrieve serialnumber */
+			buf[15] = 0;
+			serialno = simple_strtoul(buf + 10, NULL, 10);
+			sprintf(buf, "00:80:d9:0e:%02x:%02x",
+				serialno / 256,
+				serialno % 256);
+			setenv("eth4addr", buf);
+		}
+	}
+bailout:
+	if (!have_top) {
+		printf("cannot read factory configuration\n");
+		printf("be sure to set ethaddr	yourself!\n");
+	}
 	return 0;
 }
 #endif
@@ -199,18 +300,6 @@  int dram_init(void)
 	return 0;
 }
 
-#ifdef CONFIG_RESET_PHY_R
-void reset_phy(void)
-{
-	/*
-	 * Initialize ethernet HW addresses prior to starting Linux,
-	 * needed for nfsroot.
-	 * TODO: We need to investigate if that is really necessary.
-	 */
-	eth_init(gd->bd);
-}
-#endif
-
 int board_eth_init(bd_t *bis)
 {
 	int rc = 0;
@@ -292,5 +381,17 @@  void iic_scl(int bit)
 		break;
 	}
 }
+#endif
 
+void show_boot_progress(int status)
+{
+#if defined(CONFIG_SU9000)
+	at91_set_pio_output(LED_PORT, LED1_PIN, status & 1);
+	at91_set_pio_output(LED_PORT, LED2_PIN, status & 2);
+	at91_set_pio_output(LED_PORT, LED3_PIN, status & 4);
+	at91_set_pio_output(LED_PORT, LED4_PIN, status & 8);
+	at91_set_pio_output(LED_PORT, LED5_PIN, status & 16);
+	at91_set_pio_output(LED_PORT, LED6_PIN, status & 32);
 #endif
+}
+