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