From 6c6123d857e45d0ed6b06cb92b8d914f0eb56730 Mon Sep 17 00:00:00 2001 From: Thomas Cort Date: Sat, 3 Aug 2013 08:40:59 -0400 Subject: [PATCH] kernel: implement reboot for am335x/dm37xx Change-Id: Ied288326b9af8f31223b2dd76a064e32c9a03c45 --- kernel/arch/earm/Makefile.inc | 3 +- kernel/arch/earm/arch_reset.c | 15 +++++++-- kernel/arch/earm/arch_system.c | 3 ++ kernel/arch/earm/omap_reset.c | 60 ++++++++++++++++++++++++++++++++++ kernel/arch/earm/omap_reset.h | 7 ++++ 5 files changed, 85 insertions(+), 3 deletions(-) create mode 100644 kernel/arch/earm/omap_reset.c create mode 100644 kernel/arch/earm/omap_reset.h diff --git a/kernel/arch/earm/Makefile.inc b/kernel/arch/earm/Makefile.inc index 7d048fd85..2ca8212cb 100644 --- a/kernel/arch/earm/Makefile.inc +++ b/kernel/arch/earm/Makefile.inc @@ -53,6 +53,7 @@ CPPFLAGS.findfp.c+= -I ${NETBSDSRCDIR}/lib/libc/include # .for unpaged_obj in head.o pre_init.o direct_tty_utils.o \ pg_utils.o klib.o omap_serial.o omap_rtc.o utility.o arch_reset.o \ + omap_reset.o \ ${MINLIB_OBJS_UNPAGED} ${MINC_OBJS_UNPAGED} ${SYS_OBJS_UNPAGED} unpaged_${unpaged_obj}: ${unpaged_obj} ${OBJCOPY} --prefix-symbols=__k_unpaged_ ${.OBJDIR}/${unpaged_obj} $@ @@ -64,7 +65,7 @@ CLEANFILES+= ${ORIG_UNPAGED_OBJS} SRCS+= mpx.S arch_clock.c arch_do_vmctl.c arch_system.c \ omap_serial.c omap_timer.c omap_padconf.c omap_intr.c omap_rtc.c \ - exception.c klib.S memory.c \ + omap_reset.c exception.c klib.S memory.c \ protect.c direct_tty_utils.c arch_reset.c \ pg_utils.c phys_copy.S phys_memset.S exc.S OBJS.kernel+= ${UNPAGED_OBJS} diff --git a/kernel/arch/earm/arch_reset.c b/kernel/arch/earm/arch_reset.c index fc0d3a623..44d5dbe8f 100644 --- a/kernel/arch/earm/arch_reset.c +++ b/kernel/arch/earm/arch_reset.c @@ -34,7 +34,9 @@ halt_cpu(void) void reset(void) { - while (1); + omap3_reset(); + direct_print("Reset not supported."); + while (1); } void @@ -70,6 +72,10 @@ __dead void arch_shutdown(int how) { switch (how) { + case RBT_HALT: + /* Hang */ + for (; ; ) halt_cpu(); + NOT_REACHABLE; case RBT_POWEROFF: /* Power off if possible, hang otherwise */ @@ -77,7 +83,12 @@ arch_shutdown(int how) NOT_REACHABLE; default: - break; + case RBT_DEFAULT: + case RBT_REBOOT: + case RBT_RESET: + /* Reset the system */ + reset(); + NOT_REACHABLE; } while (1); } diff --git a/kernel/arch/earm/arch_system.c b/kernel/arch/earm/arch_system.c index 0f0fc3a0b..5231b9d7b 100644 --- a/kernel/arch/earm/arch_system.c +++ b/kernel/arch/earm/arch_system.c @@ -131,6 +131,9 @@ void arch_init(void) /* map memory for rtc */ omap3_rtc_init(); + + /* map memory for reset control */ + omap3_reset_init(); } /*===========================================================================* diff --git a/kernel/arch/earm/omap_reset.c b/kernel/arch/earm/omap_reset.c new file mode 100644 index 000000000..9407b81e1 --- /dev/null +++ b/kernel/arch/earm/omap_reset.c @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include + +#include "kernel/kernel.h" +#include "kernel/proc.h" +#include "kernel/vm.h" +#include "kernel/proto.h" +#include "arch_proto.h" +#include "omap_reset.h" + +#ifdef AM335X +#define CM_BASE 0x44E00000 +#define CM_SIZE 0x1000 +#define PRM_DEVICE_OFFSET 0xf00 +#define PRM_RSTCTRL_REG 0x00 +#define RST_GLOBAL_WARM_SW_BIT 0 +#elif DM37XX +#define CM_BASE 0x48307000 +#define CM_SIZE 0x1000 +#define PRM_RSTCTRL_REG 0x250 +#define RST_DPLL3_BIT 2 +#else +#define CM_BASE 0x00000000 +#define CM_SIZE 0x1000 +#endif + +struct omap_reset +{ + vir_bytes base; + vir_bytes size; +}; + +static struct omap_reset omap_reset = { + .base = CM_BASE, + .size = CM_SIZE +}; + +static kern_phys_map reset_phys_map; + +void +omap3_reset_init(void) +{ +#if defined(AM335X) || defined(DM37XX) + kern_phys_map_ptr(omap_reset.base, omap_reset.size, &reset_phys_map, + &omap_reset.base); +#endif /* AM335X || DM37XX */ +} + +void +omap3_reset(void) +{ +#ifdef AM335X + mmio_set((omap_reset.base + PRM_DEVICE_OFFSET + PRM_RSTCTRL_REG), (1 << RST_GLOBAL_WARM_SW_BIT)); +#elif DM37XX + mmio_set((omap_reset.base + PRM_RSTCTRL_REG), (1 << RST_DPLL3_BIT)); +#endif +} diff --git a/kernel/arch/earm/omap_reset.h b/kernel/arch/earm/omap_reset.h new file mode 100644 index 000000000..0f532fc0c --- /dev/null +++ b/kernel/arch/earm/omap_reset.h @@ -0,0 +1,7 @@ +#ifndef __OMAP_RESET_H +#define __OMAP_RESET_H + +void omap3_reset_init(void); +void omap3_reset(void); + +#endif /* __OMAP_RESET_H */