cmode.S 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /* cmode.S: clock mode management
  2. *
  3. * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
  4. * Written by David Woodhouse (dwmw2@infradead.org)
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the License, or (at your option) any later version.
  10. *
  11. */
  12. #include <linux/sys.h>
  13. #include <linux/linkage.h>
  14. #include <asm/setup.h>
  15. #include <asm/segment.h>
  16. #include <asm/ptrace.h>
  17. #include <asm/errno.h>
  18. #include <asm/cache.h>
  19. #include <asm/spr-regs.h>
  20. #define __addr_MASK 0xfeff9820 /* interrupt controller mask */
  21. #define __addr_SDRAMC 0xfe000400 /* SDRAM controller regs */
  22. #define SDRAMC_DSTS 0x28 /* SDRAM status */
  23. #define SDRAMC_DSTS_SSI 0x00000001 /* indicates that the SDRAM is in self-refresh mode */
  24. #define SDRAMC_DRCN 0x30 /* SDRAM refresh control */
  25. #define SDRAMC_DRCN_SR 0x00000001 /* transition SDRAM into self-refresh mode */
  26. #define __addr_CLKC 0xfeff9a00
  27. #define CLKC_SWCMODE 0x00000008
  28. #define __addr_LEDS 0xe1200004
  29. .macro li v r
  30. sethi.p %hi(\v),\r
  31. setlo %lo(\v),\r
  32. .endm
  33. .text
  34. .balign 4
  35. ###############################################################################
  36. #
  37. # Change CMODE
  38. # - void frv_change_cmode(int cmode)
  39. #
  40. ###############################################################################
  41. .globl frv_change_cmode
  42. .type frv_change_cmode,@function
  43. .macro LEDS v
  44. #ifdef DEBUG_CMODE
  45. setlos #~\v,gr10
  46. sti gr10,@(gr11,#0)
  47. membar
  48. #endif
  49. .endm
  50. frv_change_cmode:
  51. movsg lr,gr9
  52. #ifdef DEBUG_CMODE
  53. li __addr_LEDS,gr11
  54. #endif
  55. dcef @(gr0,gr0),#1
  56. # Shift argument left by 24 bits to fit in SWCMODE register later.
  57. slli gr8,#24,gr8
  58. # (1) Set '0' in the PSR.ET bit, and prohibit interrupts.
  59. movsg psr,gr14
  60. andi gr14,#~PSR_ET,gr3
  61. movgs gr3,psr
  62. #if 0 // Fujitsu recommend to skip this and will update docs.
  63. # (2) Set '0' to all bits of the MASK register of the interrupt
  64. # controller, and mask interrupts.
  65. li __addr_MASK,gr12
  66. ldi @(gr12,#0),gr13
  67. li 0xffff0000,gr4
  68. sti gr4,@(gr12,#0)
  69. #endif
  70. # (3) Stop the transfer function of DMAC. Stop all the bus masters
  71. # to access SDRAM and the internal resources.
  72. # (already done by caller)
  73. # (4) Preload a series of following instructions to the instruction
  74. # cache.
  75. li #__cmode_icache_lock_start,gr3
  76. li #__cmode_icache_lock_end,gr4
  77. 1: icpl gr3,gr0,#1
  78. addi gr3,#L1_CACHE_BYTES,gr3
  79. cmp gr4,gr3,icc0
  80. bhi icc0,#0,1b
  81. # Set up addresses in regs for later steps.
  82. setlos SDRAMC_DRCN_SR,gr3
  83. li __addr_SDRAMC,gr4
  84. li __addr_CLKC,gr5
  85. ldi @(gr5,#0),gr6
  86. li #0x80000000,gr7
  87. or gr6,gr7,gr6
  88. bra __cmode_icache_lock_start
  89. .balign L1_CACHE_BYTES
  90. __cmode_icache_lock_start:
  91. # (5) Flush the content of all caches by the DCEF instruction.
  92. dcef @(gr0,gr0),#1
  93. # (6) Execute loading the dummy for SDRAM.
  94. ldi @(gr9,#0),gr0
  95. # (7) Set '1' to the DRCN.SR bit, and change SDRAM to the
  96. # self-refresh mode. Execute the dummy load to all memory
  97. # devices set to cacheable on the external bus side in parallel
  98. # with this.
  99. sti gr3,@(gr4,#SDRAMC_DRCN)
  100. # (8) Execute memory barrier instruction (MEMBAR).
  101. membar
  102. # (9) Read the DSTS register repeatedly until '1' stands in the
  103. # DSTS.SSI field.
  104. 1: ldi @(gr4,#SDRAMC_DSTS),gr3
  105. andicc gr3,#SDRAMC_DSTS_SSI,gr3,icc0
  106. beq icc0,#0,1b
  107. # (10) Execute memory barrier instruction (MEMBAR).
  108. membar
  109. #if 1
  110. # (11) Set the value of CMODE that you want to change to
  111. # SWCMODE.SWCM[3:0].
  112. sti gr8,@(gr5,#CLKC_SWCMODE)
  113. # (12) Set '1' to the CLKC.SWEN bit. In that case, do not change
  114. # fields other than SWEN of the CLKC register.
  115. sti gr6,@(gr5,#0)
  116. #endif
  117. # (13) Execute the instruction just after the memory barrier
  118. # instruction that executes the self-loop 256 times. (Meanwhile,
  119. # the CMODE switch is done.)
  120. membar
  121. setlos #256,gr7
  122. 2: subicc gr7,#1,gr7,icc0
  123. bne icc0,#2,2b
  124. LEDS 0x36
  125. # (14) Release the self-refresh of SDRAM.
  126. sti gr0,@(gr4,#SDRAMC_DRCN)
  127. # Wait for it...
  128. 3: ldi @(gr4,#SDRAMC_DSTS),gr3
  129. andicc gr3,#SDRAMC_DSTS_SSI,gr3,icc0
  130. bne icc0,#2,3b
  131. #if 0
  132. li 0x0100000,gr10
  133. 4: subicc gr10,#1,gr10,icc0
  134. bne icc0,#0,4b
  135. #endif
  136. __cmode_icache_lock_end:
  137. li #__cmode_icache_lock_start,gr3
  138. li #__cmode_icache_lock_end,gr4
  139. 4: icul gr3
  140. addi gr3,#L1_CACHE_BYTES,gr3
  141. cmp gr4,gr3,icc0
  142. bhi icc0,#0,4b
  143. #if 0 // Fujitsu recommend to skip this and will update docs.
  144. # (15) Release the interrupt mask setting of the MASK register of
  145. # the interrupt controller if necessary.
  146. sti gr13,@(gr12,#0)
  147. #endif
  148. # (16) Set 1' in the PSR.ET bit, and permit interrupt.
  149. movgs gr14,psr
  150. bralr
  151. .size frv_change_cmode, .-frv_change_cmode