1 /*****************************************************************************
2 * Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
3 *
4 * Unless you and Broadcom execute a separate written software license
5 * agreement governing use of this software, this software is licensed to you
6 * under the terms of the GNU General Public License version 2, available at
7 * http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8 *
9 * Notwithstanding the above, under no circumstances may you combine this
10 * software in any way with any other Broadcom software provided under a
11 * license other than the GPL, without Broadcom's express prior written
12 * consent.
13 *****************************************************************************/
14 
15 /* ---- Include Files ---------------------------------------------------- */
16 #include <csp/stdint.h>
17 #include <mach/csp/chipcHw_def.h>
18 #include <mach/csp/chipcHw_inline.h>
19 #include <csp/intcHw.h>
20 #include <csp/cache.h>
21 
22 /* ---- Private Constants and Types --------------------------------------- */
23 /* ---- Private Variables ------------------------------------------------- */
24 void chipcHw_reset_run_from_aram(void);
25 
26 typedef void (*RUNFUNC) (void);
27 
28 /****************************************************************************/
29 /**
30 *  @brief   warmReset
31 *
32 *  @note warmReset configures the clocks which are not reset back to the state
33 *   required to execute on reset.  To do so we need to copy the code into internal
34 *   memory to change the ARM clock while we are not executing from DDR.
35 */
36 /****************************************************************************/
chipcHw_reset(uint32_t mask)37 void chipcHw_reset(uint32_t mask)
38 {
39 	int i = 0;
40 	RUNFUNC runFunc = (RUNFUNC) (unsigned long)MM_ADDR_IO_ARAM;
41 
42 	/* Disable all interrupts */
43 	intcHw_irq_disable(INTCHW_INTC0, 0xffffffff);
44 	intcHw_irq_disable(INTCHW_INTC1, 0xffffffff);
45 	intcHw_irq_disable(INTCHW_SINTC, 0xffffffff);
46 
47 	{
48 		REG_LOCAL_IRQ_SAVE;
49 		if (mask & chipcHw_REG_SOFT_RESET_CHIP_SOFT) {
50 			chipcHw_softReset(chipcHw_REG_SOFT_RESET_CHIP_SOFT);
51 		}
52 		/* Bypass the PLL clocks before reboot */
53 		pChipcHw->UARTClock |= chipcHw_REG_PLL_CLOCK_BYPASS_SELECT;
54 		pChipcHw->SPIClock |= chipcHw_REG_PLL_CLOCK_BYPASS_SELECT;
55 
56 		/* Copy the chipcHw_warmReset_run_from_aram function into ARAM */
57 		do {
58 			((uint32_t *) MM_IO_BASE_ARAM)[i] =
59 			    ((uint32_t *) &chipcHw_reset_run_from_aram)[i];
60 			i++;
61 		} while (((uint32_t *) MM_IO_BASE_ARAM)[i - 1] != 0xe1a0f00f);	/* 0xe1a0f00f == asm ("mov r15, r15"); */
62 
63 		CSP_CACHE_FLUSH_ALL;
64 
65 		/* run the function from ARAM */
66 		runFunc();
67 
68 		/* Code will never get here, but include it to balance REG_LOCAL_IRQ_SAVE above */
69 		REG_LOCAL_IRQ_RESTORE;
70 	}
71 }
72 
73 /* This function must run from internal memory */
chipcHw_reset_run_from_aram(void)74 void chipcHw_reset_run_from_aram(void)
75 {
76 /* Make sure, pipeline is filled with instructions coming from ARAM */
77 __asm (" nop                                                            \n\t"
78 		" nop                                                            \n\t"
79 #if defined(__KERNEL__) && !defined(STANDALONE)
80 		" MRC      p15,#0x0,r0,c1,c0,#0                                  \n\t"
81 		" BIC      r0,r0,#0xd                                            \n\t"
82 		" MCR      p15,#0x0,r0,c1,c0,#0                                  \n\t"
83 		" nop                                                            \n\t"
84 		" nop                                                            \n\t"
85 		" nop                                                            \n\t"
86 		" nop                                                            \n\t"
87 		" nop                                                            \n\t"
88 		" nop                                                            \n\t"
89 #endif
90 		" nop                                                            \n\t"
91 		" nop                                                            \n\t"
92 /* Bypass the ARM clock and switch to XTAL clock */
93 		" MOV      r2,#0x80000000                                        \n\t"
94 		" LDR      r3,[r2,#8]                                            \n\t"
95 		" ORR      r3,r3,#0x20000                                        \n\t"
96 		" STR      r3,[r2,#8]                                            \n\t"
97 
98 		" nop                                                            \n\t"
99 		" nop                                                            \n\t"
100 		" nop                                                            \n\t"
101 		" nop                                                            \n\t"
102 		" nop                                                            \n\t"
103 		" nop                                                            \n\t"
104 		" nop                                                            \n\t"
105 		" nop                                                            \n\t"
106 		" nop                                                            \n\t"
107 		" nop                                                            \n\t"
108 		" nop                                                            \n\t"
109 		" nop                                                            \n\t"
110 		" nop                                                            \n\t"
111 		" nop                                                            \n\t"
112 		" nop                                                            \n\t"
113 		" nop                                                            \n\t"
114 		" nop                                                            \n\t"
115 		" nop                                                            \n\t"
116 		" nop                                                            \n\t"
117 		" nop                                                            \n\t"
118 /* Issue reset */
119 		" MOV      r3,#0x2                                               \n\t"
120 		" STR      r3,[r2,#0x80]                                         \n\t"
121 /* End here */
122 		" MOV      pc,pc                                                 \n\t");
123 /* 0xe1a0f00f ==  asm ("mov r15, r15"); */
124 }
125