summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2007-05-28 18:19:16 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2007-05-30 13:15:23 +0100
commiteca8c2424171b6b6b2dcb0faa92dfddd1e3297d9 (patch)
tree680afa1b68832a4a81f07d706e4249a0f4290afa
parent486cab2ba25b469f7a8822e84fd43960a472e3d9 (diff)
[ARM] 4412/1: S3C2412: reset errata fix
The S3C2412 has an reset-errata where the clock may cause a glitch switching back to EXTCLK. We force a switch to EXTCLK before writing the reset register to force use of the CLKCON sync logic to properly switch. Fix problem reported by Matthieu Castet. Signed-off-by: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--arch/arm/mach-s3c2412/s3c2412.c24
-rw-r--r--include/asm-arm/arch-s3c2410/regs-s3c2412.h21
2 files changed, 45 insertions, 0 deletions
diff --git a/arch/arm/mach-s3c2412/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c
index c602aa39f9c4..782b5814ced2 100644
--- a/arch/arm/mach-s3c2412/s3c2412.c
+++ b/arch/arm/mach-s3c2412/s3c2412.c
@@ -16,6 +16,7 @@
#include <linux/list.h>
#include <linux/timer.h>
#include <linux/init.h>
+#include <linux/delay.h>
#include <linux/sysdev.h>
#include <linux/serial_core.h>
#include <linux/platform_device.h>
@@ -29,6 +30,7 @@
#include <asm/io.h>
#include <asm/irq.h>
+#include <asm/arch/reset.h>
#include <asm/arch/idle.h>
#include <asm/arch/regs-clock.h>
@@ -38,6 +40,7 @@
#include <asm/arch/regs-gpioj.h>
#include <asm/arch/regs-dsc.h>
#include <asm/arch/regs-spi.h>
+#include <asm/arch/regs-s3c2412.h>
#include <asm/plat-s3c24xx/s3c2412.h>
#include <asm/plat-s3c24xx/cpu.h>
@@ -106,6 +109,23 @@ static void s3c2412_idle(void)
cpu_do_idle();
}
+static void s3c2412_hard_reset(void)
+{
+ /* errata "Watch-dog/Software Reset Problem" specifies that
+ * this reset must be done with the SYSCLK sourced from
+ * EXTCLK instead of FOUT to avoid a glitch in the reset
+ * mechanism.
+ *
+ * See the watchdog section of the S3C2412 manual for more
+ * information on this fix.
+ */
+
+ __raw_writel(0x00, S3C2412_CLKSRC);
+ __raw_writel(S3C2412_SWRST_RESET, S3C2412_SWRST);
+
+ mdelay(1);
+}
+
/* s3c2412_map_io
*
* register the standard cpu IO areas, and any passed in from the
@@ -122,6 +142,10 @@ void __init s3c2412_map_io(struct map_desc *mach_desc, int mach_size)
s3c24xx_idle = s3c2412_idle;
+ /* set custom reset hook */
+
+ s3c24xx_reset_hook = s3c2412_hard_reset;
+
/* register our io-tables */
iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc));
diff --git a/include/asm-arm/arch-s3c2410/regs-s3c2412.h b/include/asm-arm/arch-s3c2410/regs-s3c2412.h
new file mode 100644
index 000000000000..8ca6a3bc8555
--- /dev/null
+++ b/include/asm-arm/arch-s3c2410/regs-s3c2412.h
@@ -0,0 +1,21 @@
+/* linux/include/asm-arm/arch-s3c2410/regs-s3c2412.h
+ *
+ * Copyright 2007 Simtec Electronics
+ * http://armlinux.simtec.co.uk/
+ * Ben Dooks <ben@simtec.co.uk>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * S3C2412 specific register definitions
+*/
+
+#ifndef __ASM_ARCH_REGS_S3C2412_H
+#define __ASM_ARCH_REGS_S3C2412_H "s3c2412"
+
+#define S3C2412_SWRST (S3C24XX_VA_CLKPWR + 0x30)
+#define S3C2412_SWRST_RESET (0x533C2412)
+
+#endif /* __ASM_ARCH_REGS_S3C2412_H */
+