[Zrouter-src-freebsd] ZRouter.org: push to FreeBSD HEAD tree

zrouter-src-freebsd at zrouter.org zrouter-src-freebsd at zrouter.org
Wed Apr 4 14:02:30 UTC 2012


details:   http://zrouter.org/hg/FreeBSD/head//rev/701b26f9bc86
changeset: 448:701b26f9bc86
user:      Aleksandr Rybalko <ray at ddteam.net>
date:      Wed Apr 04 16:52:15 2012 +0300
description:
* Autodetect boot source (NOR/NAND/SPI).
	Reboot now made in two different ways:
	1. SYSRST reg for SPI/NAND
	2. call to 0xbf000000 for CFI (NOR)
* Autodetect and share CPU and system bus clock

diffstat:

 head/sys/mips/rt305x/rt305x_machdep.c  |  269 ++++++++++++++++++++++++++++----
 head/sys/mips/rt305x/rt305xreg.h       |   12 +
 head/sys/mips/rt305x/uart_bus_rt305x.c |    2 +-
 head/sys/mips/rt305x/uart_cpu_rt305x.c |    2 +-
 head/sys/mips/rt305x/uart_dev_rt305x.c |    2 +-
 5 files changed, 251 insertions(+), 36 deletions(-)

diffs (391 lines):

diff -r c16742439ae8 -r 701b26f9bc86 head/sys/mips/rt305x/rt305x_machdep.c
--- a/head/sys/mips/rt305x/rt305x_machdep.c	Thu Mar 22 16:38:22 2012 +0200
+++ b/head/sys/mips/rt305x/rt305x_machdep.c	Wed Apr 04 16:52:15 2012 +0300
@@ -1,5 +1,5 @@
 /*-
- * Copyright (C) 2010-2011 by Aleksandr Rybalko. All rights reserved.
+ * Copyright (C) 2010-2012 by Aleksandr Rybalko. All rights reserved.
  * Copyright (C) 2007 by Oleksandr Tymoshenko. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -77,6 +77,43 @@
 extern int	*end;
 static char 	boot1_env[0x1000];
 
+/* Globals */
+int rt305x_chip_id = 0;
+int rt305x_boot_source;
+int rt305x_cpu_clock;
+int rt305x_system_clock;
+
+
+#define	RT305X_READ4(_reg)	(*((uint32_t *)MIPS_PHYS_TO_KSEG1(_reg)))
+
+static void
+parse_argv(char *str)
+{
+	char *n, *v;
+
+	while ((v = strsep(&str, " ")) != NULL) {
+		if (*v == '\0')
+			continue;
+		if (*v == '-') {
+			while (*v != '\0') {
+				v++;
+				switch (*v) {
+				case 'a': boothowto |= RB_ASKNAME; break;
+				case 'd': boothowto |= RB_KDB; break;
+				case 'g': boothowto |= RB_GDB; break;
+				case 's': boothowto |= RB_SINGLE; break;
+				case 'v': boothowto |= RB_VERBOSE; break;
+				}
+			}
+		} else {
+			n = strsep(&v, "=");
+			if (v == NULL)
+				setenv(n, "1");
+			else
+				setenv(n, v);
+		}
+	}
+}
 
 void
 platform_cpu_init()
@@ -121,28 +158,192 @@
 void
 platform_reset(void)
 {
-#ifdef	RSTCTRL_RESET
 	uint32_t *reset_ctl;
 
-	/* XXX: CFI must be reseted by call loader from flash */
-	reset_ctl = (uint32_t *)MIPS_KSEG0_TO_PHYS(SYSCTL_BASE +
-	    SYSCTL_RSTCTRL);
-	*reset_ctl = SYSCTL_RSTCTRL_SYS;
-#else
-	__asm __volatile("li	$25, 0xbf000000");
-	__asm __volatile("j	$25");
-#endif
+	if (rt305x_boot_source == BOOT_SOURCE_NOR) {
+		/* Call flash start */
+		__asm __volatile("li	$25, 0xbf000000");
+		__asm __volatile("j	$25");
+	} else {
+		/* Reset system */
+		reset_ctl = (uint32_t *)MIPS_PHYS_TO_KSEG1(SYSCTL_BASE +
+		    SYSCTL_RSTCTRL);
+		*reset_ctl = SYSCTL_RSTCTRL_SYS;
+	}
+
 }
 
-/* XXX: make it global */
-int rt305x_chip_id = 0;
+#define MHz	(1000 * 1000)
+#define	RETURN_CLOCK(_src, _x0, _x1, _x2, _x3)				\
+	switch (_src) {							\
+	case 0:								\
+		return (_x0);						\
+	case 1:								\
+		return (_x1);						\
+	case 2:								\
+		return (_x2);						\
+	case 3:								\
+		return (_x3);						\
+	}
+
+/*
+ * Get CPU timer clock
+ */
+static unsigned int
+rt305x_get_cpu_clock(void)
+{
+	uint32_t syscfg;
+
+        syscfg = RT305X_READ4(SYSCTL_BASE + SYSCTL_SYSCFG);
+
+	switch (rt305x_chip_id) {
+	case 0x2880:
+		RETURN_CLOCK(((syscfg>>20) & 0x03),
+		    233333333, 250*MHz, 266666666, 280*MHz);
+	case 0x2883:
+		RETURN_CLOCK(((syscfg>>18) & 0x03),
+		    380*MHz, 390*MHz, 400*MHz, 420*MHz);
+	case 0x3350:
+	case 0x3050:
+	case 0x3051:
+		return (320*MHz);
+	case 0x3052:
+		RETURN_CLOCK(((syscfg>>18) & 0x01),
+		    320*MHz, 384*MHz, 0, 0);
+	case 0x3352:
+		RETURN_CLOCK(((syscfg>>8) & 0x01),
+		    384*MHz, 400*MHz, 0, 0);
+	case 0x3883:
+		RETURN_CLOCK(((syscfg>>8) & 0x03),
+		    250*MHz, 384*MHz, 480*MHz, 500*MHz);
+	case 0x5350:
+		RETURN_CLOCK((((syscfg >> 9) & 0x02) | ((syscfg>>8) & 0x01)),
+		    360*MHz, 0, 320*MHz, 300*MHz);
+	case 0x6855:
+		return (400*MHz);
+	default:
+		return (0);
+	}
+}
+
+/*
+ * Get system clock, on which running most of devices
+ */
+static unsigned int
+rt305x_get_sysclk(unsigned int cpu_clk)
+{
+	uint32_t syscfg;
+#define	DDRBIT	(((syscfg >> 17) & 0x01) << 2)
+
+        syscfg = RT305X_READ4(SYSCTL_BASE + SYSCTL_SYSCFG);
+
+	switch (rt305x_chip_id) {
+	case 0x3883:
+		switch (DDRBIT | ((syscfg>>8) & 0x03)) {
+		/* SDR */
+		case 0:
+			return (cpu_clk/3);
+		case 1:
+			return (cpu_clk/4);
+		case 2:
+			return (cpu_clk/4);
+		case 3:
+			return (cpu_clk/4);
+		/* DDR2 */
+		case 4:
+			return (cpu_clk/2);
+		case 5:
+			return (cpu_clk/3);
+		case 6:
+			return (cpu_clk/3);
+		case 7:
+			return (cpu_clk/3);
+		}
+		break;
+	case 0x5350:
+		switch (((syscfg >> 9) & 0x02) | ((syscfg>>8) & 0x01)) {
+		case 0:
+			return (120*MHz);
+		case 2:
+			return (80*MHz);
+		case 3:
+			return (100*MHz);
+		default:
+			return (0);
+		}
+	case 0x6855:
+		return (cpu_clk/4);
+	case 0x2880:
+		return (cpu_clk/2);
+	}
+
+	return (cpu_clk/3);
+#undef	DDRBIT
+}
+
+static int
+rt305x_get_boot_source(void)
+{
+	uint32_t syscfg, boot_from;
+
+	syscfg = RT305X_READ4(SYSCTL_BASE + SYSCTL_SYSCFG);
+
+	switch (rt305x_chip_id) {
+	case 0x3050:
+	case 0x3051:
+	case 0x3052:
+	case 0x3350:
+		boot_from = (syscfg >> SYSCTL_SYSCFG_BOOT_FROM_SHIFT) & 0x3; 
+
+		switch(syscfg & SYSCTL_SYSCFG_BOOT_FROM_MASK) {
+		case SYSCTL_SYSCFG_BOOT_FROM_FLASH16:
+		case SYSCTL_SYSCFG_BOOT_FROM_FLASH8:
+			return (BOOT_SOURCE_NOR);
+		case SYSCTL_SYSCFG_BOOT_FROM_NANDFLASH:
+			return (BOOT_SOURCE_NAND);
+		case SYSCTL_SYSCFG_BOOT_FROM_ROM:
+			/* Internal ROM, start system from SPI */
+			return (BOOT_SOURCE_SPI);
+		}
+	case 0x3883:
+		switch((syscfg >> 4) & 0x03) {
+		case 0:
+		case 1:
+			return (BOOT_SOURCE_NOR);
+		case 2:
+		case 3:
+			switch (syscfg & 0x0f) {
+			case 0:
+			case 7:
+				return (BOOT_SOURCE_SPI);
+			case 8:
+				return (BOOT_SOURCE_NAND);
+			default:
+				printf("unknow chip_mode %d, assume NOR\n",
+				    syscfg & 0x0f);
+				return (BOOT_SOURCE_NOR);
+			}
+			break;
+		}
+	case 0x3352:
+	case 0x5350:
+	case 0x6855:
+		return (BOOT_SOURCE_SPI);
+	case 0x2880:
+		return (BOOT_SOURCE_NOR);
+	default:
+		printf("Boot source for RT%04x not defined\n"
+		    "\tDefaulting to NOR\n", rt305x_chip_id);
+		return (BOOT_SOURCE_NOR);
+    }
+}
 
 static void
 rt305x_get_chip_id(void)
 {
 	uint32_t id1, id2;
-	id1 = *((uint32_t *)MIPS_PHYS_TO_KSEG0(SYSCTL_BASE));
-	id2 = *((uint32_t *)MIPS_PHYS_TO_KSEG0(SYSCTL_BASE + 4));
+	id1 = RT305X_READ4(SYSCTL_BASE);
+	id2 = RT305X_READ4(SYSCTL_BASE + 4);
 
 	if ((id1 & 0xffff) != ('R' | ('T' << 8))) {
 		rt305x_chip_id = 0; /* XXX: found some safe value */
@@ -186,23 +387,21 @@
 	boothowto |= (RB_VERBOSE);
 
 	rt305x_get_chip_id();
-	switch (rt305x_chip_id) {
-	case 0x3050:
-		platform_counter_freq = (320 * 1000 * 1000);
-		break;
-	case 0x3052:
-		platform_counter_freq = (384 * 1000 * 1000);
-		break;
-	case 0x5350:
-		platform_counter_freq = (360 * 1000 * 1000);
-		break;
-	default:
-		platform_counter_freq = (320 * 1000 * 1000);
-		break;
-	}
+	rt305x_cpu_clock = rt305x_get_cpu_clock();
+	rt305x_system_clock = rt305x_get_sysclk(rt305x_cpu_clock);
+	rt305x_boot_source = rt305x_get_boot_source();
+
+	platform_counter_freq = rt305x_cpu_clock;
+
 	cninit();
 	printf("RT%x runing with %dMHz clock\n", rt305x_chip_id,
-	    (int)(platform_counter_freq/1000/1000));
+	    (int)(rt305x_cpu_clock/1000/1000));
+	printf("System bus clock - %dMHz\n", 
+	    (int)(rt305x_system_clock/1000/1000));
+	printf("System start from %s flash storage\n", 
+	    (rt305x_boot_source == BOOT_SOURCE_NOR) ? "NOR" :
+	    (rt305x_boot_source == BOOT_SOURCE_NAND) ? "NAND" :
+	    (rt305x_boot_source == BOOT_SOURCE_SPI) ? "SPI" : "UNKNOWN");
 
 	init_static_kenv(boot1_env, sizeof(boot1_env));
 
@@ -212,7 +411,8 @@
 		printf("\tNone\n");
 
 	for (i = 1; i < argc; i++) {
-		char *n = "argv  ", *arg;
+//		char *n = "argv  ";
+		char *arg;
 
 		if (i > 99)
 			break;
@@ -221,8 +421,9 @@
 		{
 			arg = (char *)(intptr_t)MIPS_PHYS_TO_KSEG0(argv[i]);
 			printf("\targv[%d] = %s\n", i, arg);
-			sprintf(n, "argv%d", i);
-			setenv(n, arg);
+			//sprintf(n, "argv%d", i);
+			//setenv(n, arg);
+			parse_argv(arg);
 		}
 	}
 
@@ -231,6 +432,8 @@
 	for (i = 0; envp[i] ; i++) {
 		char *n, *arg;
 
+		if (!MIPS_IS_VALID_PTR(envp[i]))
+			break;
 		arg = (char *)(intptr_t)MIPS_PHYS_TO_KSEG0(envp[i]);
 		printf("\t%s\n", arg);
 		n = strsep(&arg, "=");
@@ -249,5 +452,5 @@
 		*((uint32_t *)0xb0000304) = 0xe0120300;
 	}
 	mips_init();
-	mips_timer_init_params(platform_counter_freq, 3);
+	mips_timer_init_params(platform_counter_freq, 1);
 }
diff -r c16742439ae8 -r 701b26f9bc86 head/sys/mips/rt305x/rt305xreg.h
--- a/head/sys/mips/rt305x/rt305xreg.h	Thu Mar 22 16:38:22 2012 +0200
+++ b/head/sys/mips/rt305x/rt305xreg.h	Wed Apr 04 16:52:15 2012 +0300
@@ -399,4 +399,16 @@
 #define	RT305X_SPI_WRITE	1
 #define	RT305X_SPI_READ		0
 
+enum RT305X_BOOT_SOURCE {
+	BOOT_SOURCE_UNKNOWN = 0,
+	BOOT_SOURCE_NOR,
+	BOOT_SOURCE_NAND,
+	BOOT_SOURCE_SPI
+};
+
+extern int rt305x_chip_id;
+extern int rt305x_boot_source;
+extern int rt305x_cpu_clock;
+extern int rt305x_system_clock;
+
 #endif /* _RT305XREG_H_ */
diff -r c16742439ae8 -r 701b26f9bc86 head/sys/mips/rt305x/uart_bus_rt305x.c
--- a/head/sys/mips/rt305x/uart_bus_rt305x.c	Thu Mar 22 16:38:22 2012 +0200
+++ b/head/sys/mips/rt305x/uart_bus_rt305x.c	Wed Apr 04 16:52:15 2012 +0300
@@ -95,7 +95,7 @@
 	sc->sc_bas.bsh = 
 	    MIPS_PHYS_TO_KSEG1(device_get_unit(dev)?UARTLITE_BASE:UART_BASE);
 
-	return (uart_bus_probe(dev, 2, SYSTEM_CLOCK, 0, 0));
+	return (uart_bus_probe(dev, 2, rt305x_system_clock, 0, 0));
 }
 
 DRIVER_MODULE(uart, obio, uart_rt305x_driver, uart_devclass, 0, 0);
diff -r c16742439ae8 -r 701b26f9bc86 head/sys/mips/rt305x/uart_cpu_rt305x.c
--- a/head/sys/mips/rt305x/uart_cpu_rt305x.c	Thu Mar 22 16:38:22 2012 +0200
+++ b/head/sys/mips/rt305x/uart_cpu_rt305x.c	Wed Apr 04 16:52:15 2012 +0300
@@ -68,7 +68,7 @@
 	di->bas.chan = 0;
 	di->bas.bst = mips_bus_space_generic;
 	di->bas.regshft = 2;
-	di->bas.rclk = SYSTEM_CLOCK;
+	di->bas.rclk = rt305x_system_clock;
 	di->baudrate = 115200;
 	di->databits = 8;
 	di->stopbits = 1;
diff -r c16742439ae8 -r 701b26f9bc86 head/sys/mips/rt305x/uart_dev_rt305x.c
--- a/head/sys/mips/rt305x/uart_dev_rt305x.c	Thu Mar 22 16:38:22 2012 +0200
+++ b/head/sys/mips/rt305x/uart_dev_rt305x.c	Wed Apr 04 16:52:15 2012 +0300
@@ -118,7 +118,7 @@
 	/* Unsupported */
 	default:		return;
 	}
-        uart_setreg(bas, UART_CDDL_REG, 8000000/baudrate);
+        uart_setreg(bas, UART_CDDL_REG, rt305x_system_clock/16/baudrate);
 	uart_barrier(bas);
         uart_setreg(bas, UART_LCR_REG, databits | (stopbits==1?0:4) | parity);
 	uart_barrier(bas);


More information about the Zrouter-src-freebsd mailing list