nand_init.S 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. ##=============================================================================
  2. ##
  3. ## nand_init.S
  4. ##
  5. ## The bootrom copies data from the NAND flash to the internal RAM but
  6. ## due to a bug/feature we can only trust the 256 first bytes. So this
  7. ## code copies more data from NAND flash to internal RAM. Obvioulsy this
  8. ## code must fit in the first 256 bytes so alter with care.
  9. ##
  10. ## Some notes about the bug/feature for future reference:
  11. ## The bootrom copies the first 127 KB from NAND flash to internal
  12. ## memory. The problem is that it does a bytewise copy. NAND flashes
  13. ## does autoincrement on the address so for a 16-bite device each
  14. ## read/write increases the address by two. So the copy loop in the
  15. ## bootrom will discard every second byte. This is solved by inserting
  16. ## zeroes in every second byte in the first erase block.
  17. ##
  18. ## The bootrom also incorrectly assumes that it can read the flash
  19. ## linear with only one read command but the flash will actually
  20. ## switch between normal area and spare area if you do that so we
  21. ## can't trust more than the first 256 bytes.
  22. ##
  23. ##=============================================================================
  24. #include <asm/arch/hwregs/asm/reg_map_asm.h>
  25. #include <asm/arch/hwregs/asm/gio_defs_asm.h>
  26. #include <asm/arch/hwregs/asm/pinmux_defs_asm.h>
  27. #include <asm/arch/hwregs/asm/bif_core_defs_asm.h>
  28. #include <asm/arch/hwregs/asm/config_defs_asm.h>
  29. ;; There are 8-bit NAND flashes and 16-bit NAND flashes.
  30. ;; We need to treat them slightly different.
  31. #if CONFIG_ETRAX_FLASH_BUSWIDTH==2
  32. #define PAGE_SIZE 256
  33. #else
  34. #error 2
  35. #define PAGE_SIZE 512
  36. #endif
  37. #define ERASE_BLOCK 16384
  38. ;; GPIO pins connected to NAND flash
  39. #define CE 4
  40. #define CLE 5
  41. #define ALE 6
  42. #define BY 7
  43. ;; Address space for NAND flash
  44. #define NAND_RD_ADDR 0x90000000
  45. #define NAND_WR_ADDR 0x94000000
  46. #define READ_CMD 0x00
  47. ;; Readability macros
  48. #define CSP_MASK \
  49. REG_MASK(bif_core, rw_grp3_cfg, gated_csp0) | \
  50. REG_MASK(bif_core, rw_grp3_cfg, gated_csp1)
  51. #define CSP_VAL \
  52. REG_STATE(bif_core, rw_grp3_cfg, gated_csp0, rd) | \
  53. REG_STATE(bif_core, rw_grp3_cfg, gated_csp1, wr)
  54. ;;----------------------------------------------------------------------------
  55. ;; Macros to set/clear GPIO bits
  56. .macro SET x
  57. or.b (1<<\x),$r9
  58. move.d $r9, [$r2]
  59. .endm
  60. .macro CLR x
  61. and.b ~(1<<\x),$r9
  62. move.d $r9, [$r2]
  63. .endm
  64. ;;----------------------------------------------------------------------------
  65. nand_boot:
  66. ;; Check if nand boot was selected
  67. move.d REG_ADDR(config, regi_config, r_bootsel), $r0
  68. move.d [$r0], $r0
  69. and.d REG_MASK(config, r_bootsel, boot_mode), $r0
  70. cmp.d REG_STATE(config, r_bootsel, boot_mode, nand), $r0
  71. bne normal_boot ; No NAND boot
  72. nop
  73. copy_nand_to_ram:
  74. ;; copy_nand_to_ram
  75. ;; Arguments
  76. ;; r10 - destination
  77. ;; r11 - source offset
  78. ;; r12 - size
  79. ;; r13 - Address to jump to after completion
  80. ;; Note : r10-r12 are clobbered on return
  81. ;; Registers used:
  82. ;; r0 - NAND_RD_ADDR
  83. ;; r1 - NAND_WR_ADDR
  84. ;; r2 - reg_gio_rw_pa_dout
  85. ;; r3 - reg_gio_r_pa_din
  86. ;; r4 - tmp
  87. ;; r5 - byte counter within a page
  88. ;; r6 - reg_pinmux_rw_pa
  89. ;; r7 - reg_gio_rw_pa_oe
  90. ;; r8 - reg_bif_core_rw_grp3_cfg
  91. ;; r9 - reg_gio_rw_pa_dout shadow
  92. move.d 0x90000000, $r0
  93. move.d 0x94000000, $r1
  94. move.d REG_ADDR(gio, regi_gio, rw_pa_dout), $r2
  95. move.d REG_ADDR(gio, regi_gio, r_pa_din), $r3
  96. move.d REG_ADDR(pinmux, regi_pinmux, rw_pa), $r6
  97. move.d REG_ADDR(gio, regi_gio, rw_pa_oe), $r7
  98. move.d REG_ADDR(bif_core, regi_bif_core, rw_grp3_cfg), $r8
  99. #if CONFIG_ETRAX_FLASH_BUSWIDTH==2
  100. lsrq 1, $r11
  101. #endif
  102. ;; Set up GPIO
  103. move.d [$r2], $r9
  104. move.d [$r7], $r4
  105. or.b (1<<ALE) | (1 << CLE) | (1<<CE), $r4
  106. move.d $r4, [$r7]
  107. ;; Set up bif
  108. move.d [$r8], $r4
  109. and.d CSP_MASK, $r4
  110. or.d CSP_VAL, $r4
  111. move.d $r4, [$r8]
  112. 1: ;; Copy one page
  113. CLR CE
  114. SET CLE
  115. moveq READ_CMD, $r4
  116. move.b $r4, [$r1]
  117. moveq 20, $r4
  118. 2: bne 2b
  119. subq 1, $r4
  120. CLR CLE
  121. SET ALE
  122. clear.w [$r1] ; Column address = 0
  123. move.d $r11, $r4
  124. lsrq 8, $r4
  125. move.b $r4, [$r1] ; Row address
  126. lsrq 8, $r4
  127. move.b $r4, [$r1] ; Row adddress
  128. moveq 20, $r4
  129. 2: bne 2b
  130. subq 1, $r4
  131. CLR ALE
  132. 2: move.d [$r3], $r4
  133. and.d 1 << BY, $r4
  134. beq 2b
  135. movu.w PAGE_SIZE, $r5
  136. 2: ; Copy one byte/word
  137. #if CONFIG_ETRAX_FLASH_BUSWIDTH==2
  138. move.w [$r0], $r4
  139. #else
  140. move.b [$r0], $r4
  141. #endif
  142. subq 1, $r5
  143. bne 2b
  144. #if CONFIG_ETRAX_FLASH_BUSWIDTH==2
  145. move.w $r4, [$r10+]
  146. subu.w PAGE_SIZE*2, $r12
  147. #else
  148. move.b $r4, [$r10+]
  149. subu.w PAGE_SIZE, $r12
  150. #endif
  151. bpl 1b
  152. addu.w PAGE_SIZE, $r11
  153. ;; End of copy
  154. jump $r13
  155. nop
  156. ;; This will warn if the code above is too large. If you consider
  157. ;; to remove this you don't understand the bug/feature.
  158. .org 256
  159. .org ERASE_BLOCK
  160. normal_boot: