Path: blob/master/arch/arm/mach-bcmring/csp/chipc/chipcHw_reset.c
10820 views
/*****************************************************************************1* Copyright 2003 - 2008 Broadcom Corporation. All rights reserved.2*3* Unless you and Broadcom execute a separate written software license4* agreement governing use of this software, this software is licensed to you5* under the terms of the GNU General Public License version 2, available at6* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").7*8* Notwithstanding the above, under no circumstances may you combine this9* software in any way with any other Broadcom software provided under a10* license other than the GPL, without Broadcom's express prior written11* consent.12*****************************************************************************/1314/* ---- Include Files ---------------------------------------------------- */15#include <csp/stdint.h>16#include <mach/csp/chipcHw_def.h>17#include <mach/csp/chipcHw_inline.h>18#include <csp/intcHw.h>19#include <csp/cache.h>2021/* ---- Private Constants and Types --------------------------------------- */22/* ---- Private Variables ------------------------------------------------- */23void chipcHw_reset_run_from_aram(void);2425typedef void (*RUNFUNC) (void);2627/****************************************************************************/28/**29* @brief warmReset30*31* @note warmReset configures the clocks which are not reset back to the state32* required to execute on reset. To do so we need to copy the code into internal33* memory to change the ARM clock while we are not executing from DDR.34*/35/****************************************************************************/36void chipcHw_reset(uint32_t mask)37{38int i = 0;39RUNFUNC runFunc = (RUNFUNC) (unsigned long)MM_ADDR_IO_ARAM;4041/* Disable all interrupts */42intcHw_irq_disable(INTCHW_INTC0, 0xffffffff);43intcHw_irq_disable(INTCHW_INTC1, 0xffffffff);44intcHw_irq_disable(INTCHW_SINTC, 0xffffffff);4546{47REG_LOCAL_IRQ_SAVE;48if (mask & chipcHw_REG_SOFT_RESET_CHIP_SOFT) {49chipcHw_softReset(chipcHw_REG_SOFT_RESET_CHIP_SOFT);50}51/* Bypass the PLL clocks before reboot */52pChipcHw->UARTClock |= chipcHw_REG_PLL_CLOCK_BYPASS_SELECT;53pChipcHw->SPIClock |= chipcHw_REG_PLL_CLOCK_BYPASS_SELECT;5455/* Copy the chipcHw_warmReset_run_from_aram function into ARAM */56do {57((uint32_t *) MM_IO_BASE_ARAM)[i] =58((uint32_t *) &chipcHw_reset_run_from_aram)[i];59i++;60} while (((uint32_t *) MM_IO_BASE_ARAM)[i - 1] != 0xe1a0f00f); /* 0xe1a0f00f == asm ("mov r15, r15"); */6162CSP_CACHE_FLUSH_ALL;6364/* run the function from ARAM */65runFunc();6667/* Code will never get here, but include it to balance REG_LOCAL_IRQ_SAVE above */68REG_LOCAL_IRQ_RESTORE;69}70}7172/* This function must run from internal memory */73void chipcHw_reset_run_from_aram(void)74{75/* Make sure, pipeline is filled with instructions coming from ARAM */76__asm (" nop \n\t"77" nop \n\t"78#if defined(__KERNEL__) && !defined(STANDALONE)79" MRC p15,#0x0,r0,c1,c0,#0 \n\t"80" BIC r0,r0,#0xd \n\t"81" MCR p15,#0x0,r0,c1,c0,#0 \n\t"82" nop \n\t"83" nop \n\t"84" nop \n\t"85" nop \n\t"86" nop \n\t"87" nop \n\t"88#endif89" nop \n\t"90" nop \n\t"91/* Bypass the ARM clock and switch to XTAL clock */92" MOV r2,#0x80000000 \n\t"93" LDR r3,[r2,#8] \n\t"94" ORR r3,r3,#0x20000 \n\t"95" STR r3,[r2,#8] \n\t"9697" nop \n\t"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/* Issue reset */118" MOV r3,#0x2 \n\t"119" STR r3,[r2,#0x80] \n\t"120/* End here */121" MOV pc,pc \n\t");122/* 0xe1a0f00f == asm ("mov r15, r15"); */123}124125126