[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