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 ------------------------------------------------- */ 24void chipcHw_reset_run_from_aram(void); 25 26typedef 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/****************************************************************************/ 37void 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 */ 74void 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