chipcHw_reset.c 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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. /* ---- Include Files ---------------------------------------------------- */
  15. #include <linux/types.h>
  16. #include <mach/csp/chipcHw_def.h>
  17. #include <mach/csp/chipcHw_inline.h>
  18. #include <mach/csp/intcHw_reg.h>
  19. #include <asm/cacheflush.h>
  20. /* ---- Private Constants and Types --------------------------------------- */
  21. /* ---- Private Variables ------------------------------------------------- */
  22. void chipcHw_reset_run_from_aram(void);
  23. typedef void (*RUNFUNC) (void);
  24. /****************************************************************************/
  25. /**
  26. * @brief warmReset
  27. *
  28. * @note warmReset configures the clocks which are not reset back to the state
  29. * required to execute on reset. To do so we need to copy the code into internal
  30. * memory to change the ARM clock while we are not executing from DDR.
  31. */
  32. /****************************************************************************/
  33. void chipcHw_reset(uint32_t mask)
  34. {
  35. int i = 0;
  36. RUNFUNC runFunc = (RUNFUNC) (unsigned long)MM_ADDR_IO_ARAM;
  37. /* Disable all interrupts */
  38. intcHw_irq_disable(INTCHW_INTC0, 0xffffffff);
  39. intcHw_irq_disable(INTCHW_INTC1, 0xffffffff);
  40. intcHw_irq_disable(INTCHW_SINTC, 0xffffffff);
  41. {
  42. REG_LOCAL_IRQ_SAVE;
  43. if (mask & chipcHw_REG_SOFT_RESET_CHIP_SOFT) {
  44. chipcHw_softReset(chipcHw_REG_SOFT_RESET_CHIP_SOFT);
  45. }
  46. /* Bypass the PLL clocks before reboot */
  47. writel(readl(&pChipcHw->UARTClock) | chipcHw_REG_PLL_CLOCK_BYPASS_SELECT,
  48. &pChipcHw->UARTClock);
  49. writel(readl(&pChipcHw->SPIClock) | chipcHw_REG_PLL_CLOCK_BYPASS_SELECT,
  50. &pChipcHw->SPIClock);
  51. /* Copy the chipcHw_warmReset_run_from_aram function into ARAM */
  52. do {
  53. writel(((uint32_t *) &chipcHw_reset_run_from_aram)[i], ((uint32_t __iomem *) MM_IO_BASE_ARAM) + i);
  54. i++;
  55. } while (readl(((uint32_t __iomem*) MM_IO_BASE_ARAM) + i - 1) != 0xe1a0f00f); /* 0xe1a0f00f == asm ("mov r15, r15"); */
  56. flush_cache_all();
  57. /* run the function from ARAM */
  58. runFunc();
  59. /* Code will never get here, but include it to balance REG_LOCAL_IRQ_SAVE above */
  60. REG_LOCAL_IRQ_RESTORE;
  61. }
  62. }
  63. /* This function must run from internal memory */
  64. void chipcHw_reset_run_from_aram(void)
  65. {
  66. /* Make sure, pipeline is filled with instructions coming from ARAM */
  67. __asm (" nop \n\t"
  68. " nop \n\t"
  69. #if defined(__KERNEL__) && !defined(STANDALONE)
  70. " MRC p15,#0x0,r0,c1,c0,#0 \n\t"
  71. " BIC r0,r0,#0xd \n\t"
  72. " MCR p15,#0x0,r0,c1,c0,#0 \n\t"
  73. " nop \n\t"
  74. " nop \n\t"
  75. " nop \n\t"
  76. " nop \n\t"
  77. " nop \n\t"
  78. " nop \n\t"
  79. #endif
  80. " nop \n\t"
  81. " nop \n\t"
  82. /* Bypass the ARM clock and switch to XTAL clock */
  83. " MOV r2,#0x80000000 \n\t"
  84. " LDR r3,[r2,#8] \n\t"
  85. " ORR r3,r3,#0x20000 \n\t"
  86. " STR r3,[r2,#8] \n\t"
  87. " nop \n\t"
  88. " nop \n\t"
  89. " nop \n\t"
  90. " nop \n\t"
  91. " nop \n\t"
  92. " nop \n\t"
  93. " nop \n\t"
  94. " nop \n\t"
  95. " nop \n\t"
  96. " nop \n\t"
  97. " 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. /* Issue reset */
  108. " MOV r3,#0x2 \n\t"
  109. " STR r3,[r2,#0x80] \n\t"
  110. /* End here */
  111. " MOV pc,pc \n\t");
  112. /* 0xe1a0f00f == asm ("mov r15, r15"); */
  113. }