nand_init.S 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  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. #include <linux/config.h>
  30. ;; There are 8-bit NAND flashes and 16-bit NAND flashes.
  31. ;; We need to treat them slightly different.
  32. #if CONFIG_ETRAX_FLASH_BUSWIDTH==2
  33. #define PAGE_SIZE 256
  34. #else
  35. #error 2
  36. #define PAGE_SIZE 512
  37. #endif
  38. #define ERASE_BLOCK 16384
  39. ;; GPIO pins connected to NAND flash
  40. #define CE 4
  41. #define CLE 5
  42. #define ALE 6
  43. #define BY 7
  44. ;; Address space for NAND flash
  45. #define NAND_RD_ADDR 0x90000000
  46. #define NAND_WR_ADDR 0x94000000
  47. #define READ_CMD 0x00
  48. ;; Readability macros
  49. #define CSP_MASK \
  50. REG_MASK(bif_core, rw_grp3_cfg, gated_csp0) | \
  51. REG_MASK(bif_core, rw_grp3_cfg, gated_csp1)
  52. #define CSP_VAL \
  53. REG_STATE(bif_core, rw_grp3_cfg, gated_csp0, rd) | \
  54. REG_STATE(bif_core, rw_grp3_cfg, gated_csp1, wr)
  55. ;;----------------------------------------------------------------------------
  56. ;; Macros to set/clear GPIO bits
  57. .macro SET x
  58. or.b (1<<\x),$r9
  59. move.d $r9, [$r2]
  60. .endm
  61. .macro CLR x
  62. and.b ~(1<<\x),$r9
  63. move.d $r9, [$r2]
  64. .endm
  65. ;;----------------------------------------------------------------------------
  66. nand_boot:
  67. ;; Check if nand boot was selected
  68. move.d REG_ADDR(config, regi_config, r_bootsel), $r0
  69. move.d [$r0], $r0
  70. and.d REG_MASK(config, r_bootsel, boot_mode), $r0
  71. cmp.d REG_STATE(config, r_bootsel, boot_mode, nand), $r0
  72. bne normal_boot ; No NAND boot
  73. nop
  74. copy_nand_to_ram:
  75. ;; copy_nand_to_ram
  76. ;; Arguments
  77. ;; r10 - destination
  78. ;; r11 - source offset
  79. ;; r12 - size
  80. ;; r13 - Address to jump to after completion
  81. ;; Note : r10-r12 are clobbered on return
  82. ;; Registers used:
  83. ;; r0 - NAND_RD_ADDR
  84. ;; r1 - NAND_WR_ADDR
  85. ;; r2 - reg_gio_rw_pa_dout
  86. ;; r3 - reg_gio_r_pa_din
  87. ;; r4 - tmp
  88. ;; r5 - byte counter within a page
  89. ;; r6 - reg_pinmux_rw_pa
  90. ;; r7 - reg_gio_rw_pa_oe
  91. ;; r8 - reg_bif_core_rw_grp3_cfg
  92. ;; r9 - reg_gio_rw_pa_dout shadow
  93. move.d 0x90000000, $r0
  94. move.d 0x94000000, $r1
  95. move.d REG_ADDR(gio, regi_gio, rw_pa_dout), $r2
  96. move.d REG_ADDR(gio, regi_gio, r_pa_din), $r3
  97. move.d REG_ADDR(pinmux, regi_pinmux, rw_pa), $r6
  98. move.d REG_ADDR(gio, regi_gio, rw_pa_oe), $r7
  99. move.d REG_ADDR(bif_core, regi_bif_core, rw_grp3_cfg), $r8
  100. #if CONFIG_ETRAX_FLASH_BUSWIDTH==2
  101. lsrq 1, $r11
  102. #endif
  103. ;; Set up GPIO
  104. move.d [$r2], $r9
  105. move.d [$r7], $r4
  106. or.b (1<<ALE) | (1 << CLE) | (1<<CE), $r4
  107. move.d $r4, [$r7]
  108. ;; Set up bif
  109. move.d [$r8], $r4
  110. and.d CSP_MASK, $r4
  111. or.d CSP_VAL, $r4
  112. move.d $r4, [$r8]
  113. 1: ;; Copy one page
  114. CLR CE
  115. SET CLE
  116. moveq READ_CMD, $r4
  117. move.b $r4, [$r1]
  118. moveq 20, $r4
  119. 2: bne 2b
  120. subq 1, $r4
  121. CLR CLE
  122. SET ALE
  123. clear.w [$r1] ; Column address = 0
  124. move.d $r11, $r4
  125. lsrq 8, $r4
  126. move.b $r4, [$r1] ; Row address
  127. lsrq 8, $r4
  128. move.b $r4, [$r1] ; Row adddress
  129. moveq 20, $r4
  130. 2: bne 2b
  131. subq 1, $r4
  132. CLR ALE
  133. 2: move.d [$r3], $r4
  134. and.d 1 << BY, $r4
  135. beq 2b
  136. movu.w PAGE_SIZE, $r5
  137. 2: ; Copy one byte/word
  138. #if CONFIG_ETRAX_FLASH_BUSWIDTH==2
  139. move.w [$r0], $r4
  140. #else
  141. move.b [$r0], $r4
  142. #endif
  143. subq 1, $r5
  144. bne 2b
  145. #if CONFIG_ETRAX_FLASH_BUSWIDTH==2
  146. move.w $r4, [$r10+]
  147. subu.w PAGE_SIZE*2, $r12
  148. #else
  149. move.b $r4, [$r10+]
  150. subu.w PAGE_SIZE, $r12
  151. #endif
  152. bpl 1b
  153. addu.w PAGE_SIZE, $r11
  154. ;; End of copy
  155. jump $r13
  156. nop
  157. ;; This will warn if the code above is too large. If you consider
  158. ;; to remove this you don't understand the bug/feature.
  159. .org 256
  160. .org ERASE_BLOCK
  161. normal_boot: