Title: [5373] trunk: use the Blackfin on-chip ROM to do software reset when possible
Revision
5373
Author
vapier
Date
2008-10-03 02:28:03 -0500 (Fri, 03 Oct 2008)

Log Message

use the Blackfin on-chip ROM to do software reset when possible

Modified Paths


Added Paths

Diff

Modified: trunk/arch/blackfin/kernel/reboot.c (5372 => 5373)


--- trunk/arch/blackfin/kernel/reboot.c	2008-10-03 02:39:57 UTC (rev 5372)
+++ trunk/arch/blackfin/kernel/reboot.c	2008-10-03 07:28:03 UTC (rev 5373)
@@ -10,6 +10,7 @@
 #include <asm/bfin-global.h>
 #include <asm/reboot.h>
 #include <asm/system.h>
+#include <asm/bfrom.h>
 
 /* A system soft reset makes external memory unusable so force
  * this function into L1.  We use the compiler ssync here rather
@@ -74,7 +75,10 @@
 {
 	native_machine_restart(cmd);
 	local_irq_disable();
-	bfin_reset();
+	if (ANOMALY_05000353 || ANOMALY_05000386)
+		bfin_reset();
+	else
+		bfrom_SoftReset((void *)(L1_SCRATCH_START + L1_SCRATCH_LENGTH - 20));
 }
 
 __attribute__((weak))

Added: trunk/include/asm-blackfin/bfrom.h (0 => 5373)


--- trunk/include/asm-blackfin/bfrom.h	                        (rev 0)
+++ trunk/include/asm-blackfin/bfrom.h	2008-10-03 07:28:03 UTC (rev 5373)
@@ -0,0 +1,57 @@
+/* Blackfin on-chip ROM API
+ *
+ * Copyright 2008 Analog Devices Inc.
+ *
+ * Licensed under the GPL-2 or later.
+ */
+
+#ifndef __BFROM_H__
+#define __BFROM_H__
+
+#include <linux/types.h>
+
+/* Possible syscontrol action flags */
+#define SYSCTRL_READ        0x00000000    /* read registers */
+#define SYSCTRL_WRITE       0x00000001    /* write registers */
+#define SYSCTRL_SYSRESET    0x00000002    /* perform system reset */
+#define SYSCTRL_CORERESET   0x00000004    /* perform core reset */
+#define SYSCTRL_SOFTRESET   0x00000006    /* perform core and system reset */
+#define SYSCTRL_VRCTL       0x00000010    /* read/write VR_CTL register */
+#define SYSCTRL_EXTVOLTAGE  0x00000020    /* VDDINT supplied externally */
+#define SYSCTRL_INTVOLTAGE  0x00000000    /* VDDINT generated by on-chip regulator */
+#define SYSCTRL_OTPVOLTAGE  0x00000040    /* For Factory Purposes Only */
+#define SYSCTRL_PLLCTL      0x00000100    /* read/write PLL_CTL register */
+#define SYSCTRL_PLLDIV      0x00000200    /* read/write PLL_DIV register */
+#define SYSCTRL_LOCKCNT     0x00000400    /* read/write PLL_LOCKCNT register */
+#define SYSCTRL_PLLSTAT     0x00000800    /* read/write PLL_STAT register */
+
+typedef struct ADI_SYSCTRL_VALUES {
+	uint16_t uwVrCtl;
+	uint16_t uwPllCtl;
+	uint16_t uwPllDiv;
+	uint16_t uwPllLockCnt;
+	uint16_t uwPllStat;
+} ADI_SYSCTRL_VALUES;
+
+static uint32_t (* const bfrom_SysControl)(uint32_t action_flags, ADI_SYSCTRL_VALUES *power_settings, void *reserved) = (void *)0xEF000038;
+
+/* We need a dedicated function since we need to screw with the stack pointer
+ * when resetting.  The on-chip ROM will save/restore registers on the stack
+ * when doing a system reset, so the stack cannot be outside of the chip.
+ */
+__attribute__((__noreturn__))
+static inline void bfrom_SoftReset(void *new_stack)
+{
+	while (1)
+		__asm__ __volatile__(
+			"sp = %[stack];"
+			"jump (%[bfrom_syscontrol]);"
+			: : [bfrom_syscontrol] "p"(bfrom_SysControl),
+				"q0"(SYSCTRL_SOFTRESET),
+				"q1"(0),
+				"q2"(NULL),
+				[stack] "p"(new_stack)
+		);
+}
+
+#endif
_______________________________________________
Linux-kernel-commits mailing list
[email protected]
http://blackfin.uclinux.org/mailman/listinfo/linux-kernel-commits

Reply via email to