Commit eca8c242 authored by Ben Dooks's avatar Ben Dooks Committed by Russell King

[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: default avatarBen Dooks <ben-linux@fluff.org>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 486cab2b
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/delay.h>
#include <linux/sysdev.h> #include <linux/sysdev.h>
#include <linux/serial_core.h> #include <linux/serial_core.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
...@@ -29,6 +30,7 @@ ...@@ -29,6 +30,7 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/arch/reset.h>
#include <asm/arch/idle.h> #include <asm/arch/idle.h>
#include <asm/arch/regs-clock.h> #include <asm/arch/regs-clock.h>
...@@ -38,6 +40,7 @@ ...@@ -38,6 +40,7 @@
#include <asm/arch/regs-gpioj.h> #include <asm/arch/regs-gpioj.h>
#include <asm/arch/regs-dsc.h> #include <asm/arch/regs-dsc.h>
#include <asm/arch/regs-spi.h> #include <asm/arch/regs-spi.h>
#include <asm/arch/regs-s3c2412.h>
#include <asm/plat-s3c24xx/s3c2412.h> #include <asm/plat-s3c24xx/s3c2412.h>
#include <asm/plat-s3c24xx/cpu.h> #include <asm/plat-s3c24xx/cpu.h>
...@@ -106,6 +109,23 @@ static void s3c2412_idle(void) ...@@ -106,6 +109,23 @@ static void s3c2412_idle(void)
cpu_do_idle(); 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 /* s3c2412_map_io
* *
* register the standard cpu IO areas, and any passed in from the * 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) ...@@ -122,6 +142,10 @@ void __init s3c2412_map_io(struct map_desc *mach_desc, int mach_size)
s3c24xx_idle = s3c2412_idle; s3c24xx_idle = s3c2412_idle;
/* set custom reset hook */
s3c24xx_reset_hook = s3c2412_hard_reset;
/* register our io-tables */ /* register our io-tables */
iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc)); iotable_init(s3c2412_iodesc, ARRAY_SIZE(s3c2412_iodesc));
......
/* 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 */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment