brcmstb.S 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*
  2. * Copyright (C) 2016 Broadcom
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as
  6. * published by the Free Software Foundation version 2.
  7. *
  8. * This program is distributed "as is" WITHOUT ANY WARRANTY of any
  9. * kind, whether express or implied; without even the implied warranty
  10. * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include <linux/serial_reg.h>
  14. /* Physical register offset and virtual register offset */
  15. #define REG_PHYS_BASE 0xf0000000
  16. #define REG_VIRT_BASE 0xfc000000
  17. #define REG_PHYS_ADDR(x) ((x) + REG_PHYS_BASE)
  18. /* Product id can be read from here */
  19. #define SUN_TOP_CTRL_BASE REG_PHYS_ADDR(0x404000)
  20. #define UARTA_3390 REG_PHYS_ADDR(0x40a900)
  21. #define UARTA_7250 REG_PHYS_ADDR(0x40b400)
  22. #define UARTA_7268 REG_PHYS_ADDR(0x40c000)
  23. #define UARTA_7271 UARTA_7268
  24. #define UARTA_7364 REG_PHYS_ADDR(0x40b000)
  25. #define UARTA_7366 UARTA_7364
  26. #define UARTA_74371 REG_PHYS_ADDR(0x406b00)
  27. #define UARTA_7439 REG_PHYS_ADDR(0x40a900)
  28. #define UARTA_7445 REG_PHYS_ADDR(0x40ab00)
  29. #define UART_SHIFT 2
  30. #define checkuart(rp, rv, family_id, family) \
  31. /* Load family id */ \
  32. ldr rp, =family_id ; \
  33. /* Compare SUN_TOP_CTRL value against it */ \
  34. cmp rp, rv ; \
  35. /* Passed test, load address */ \
  36. ldreq rp, =UARTA_##family ; \
  37. /* Jump to save UART address */ \
  38. beq 91f
  39. .macro addruart, rp, rv, tmp
  40. adr \rp, 99f @ actual addr of 99f
  41. ldr \rv, [\rp] @ linked addr is stored there
  42. sub \rv, \rv, \rp @ offset between the two
  43. ldr \rp, [\rp, #4] @ linked brcmstb_uart_config
  44. sub \tmp, \rp, \rv @ actual brcmstb_uart_config
  45. ldr \rp, [\tmp] @ Load brcmstb_uart_config
  46. cmp \rp, #1 @ needs initialization?
  47. bne 100f @ no; go load the addresses
  48. mov \rv, #0 @ yes; record init is done
  49. str \rv, [\tmp]
  50. /* Check SUN_TOP_CTRL base */
  51. ldr \rp, =SUN_TOP_CTRL_BASE @ load SUN_TOP_CTRL PA
  52. ldr \rv, [\rp, #0] @ get register contents
  53. and \rv, \rv, #0xffffff00 @ strip revision bits [7:0]
  54. /* Chip specific detection starts here */
  55. 20: checkuart(\rp, \rv, 0x33900000, 3390)
  56. 21: checkuart(\rp, \rv, 0x72500000, 7250)
  57. 22: checkuart(\rp, \rv, 0x72680000, 7268)
  58. 23: checkuart(\rp, \rv, 0x72710000, 7271)
  59. 24: checkuart(\rp, \rv, 0x73640000, 7364)
  60. 25: checkuart(\rp, \rv, 0x73660000, 7366)
  61. 26: checkuart(\rp, \rv, 0x07437100, 74371)
  62. 27: checkuart(\rp, \rv, 0x74390000, 7439)
  63. 28: checkuart(\rp, \rv, 0x74450000, 7445)
  64. /* No valid UART found */
  65. 90: mov \rp, #0
  66. /* fall through */
  67. /* Record whichever UART we chose */
  68. 91: str \rp, [\tmp, #4] @ Store in brcmstb_uart_phys
  69. cmp \rp, #0 @ Valid UART address?
  70. bne 92f @ Yes, go process it
  71. str \rp, [\tmp, #8] @ Store 0 in brcmstb_uart_virt
  72. b 100f @ Done
  73. 92: and \rv, \rp, #0xffffff @ offset within 16MB section
  74. add \rv, \rv, #REG_VIRT_BASE
  75. str \rv, [\tmp, #8] @ Store in brcmstb_uart_virt
  76. b 100f
  77. .align
  78. 99: .word .
  79. .word brcmstb_uart_config
  80. .ltorg
  81. /* Load previously selected UART address */
  82. 100: ldr \rp, [\tmp, #4] @ Load brcmstb_uart_phys
  83. ldr \rv, [\tmp, #8] @ Load brcmstb_uart_virt
  84. .endm
  85. .macro store, rd, rx:vararg
  86. str \rd, \rx
  87. .endm
  88. .macro load, rd, rx:vararg
  89. ldr \rd, \rx
  90. .endm
  91. .macro senduart,rd,rx
  92. store \rd, [\rx, #UART_TX << UART_SHIFT]
  93. .endm
  94. .macro busyuart,rd,rx
  95. 1002: load \rd, [\rx, #UART_LSR << UART_SHIFT]
  96. and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE
  97. teq \rd, #UART_LSR_TEMT | UART_LSR_THRE
  98. bne 1002b
  99. .endm
  100. .macro waituart,rd,rx
  101. .endm
  102. /*
  103. * Storage for the state maintained by the macros above.
  104. *
  105. * In the kernel proper, this data is located in arch/arm/mach-bcm/brcmstb.c.
  106. * That's because this header is included from multiple files, and we only
  107. * want a single copy of the data. In particular, the UART probing code above
  108. * assumes it's running using physical addresses. This is true when this file
  109. * is included from head.o, but not when included from debug.o. So we need
  110. * to share the probe results between the two copies, rather than having
  111. * to re-run the probing again later.
  112. *
  113. * In the decompressor, we put the symbol/storage right here, since common.c
  114. * isn't included in the decompressor build. This symbol gets put in .text
  115. * even though it's really data, since .data is discarded from the
  116. * decompressor. Luckily, .text is writeable in the decompressor, unless
  117. * CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug.
  118. */
  119. #if defined(ZIMAGE)
  120. brcmstb_uart_config:
  121. /* Debug UART initialization required */
  122. .word 1
  123. /* Debug UART physical address */
  124. .word 0
  125. /* Debug UART virtual address */
  126. .word 0
  127. #endif