123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 |
- /*
- * Copyright (C) 2016 Broadcom
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
- #include <linux/serial_reg.h>
- #include <asm/cputype.h>
- /* Physical register offset and virtual register offset */
- #define REG_PHYS_BASE 0xf0000000
- #define REG_PHYS_BASE_V7 0x08000000
- #define REG_VIRT_BASE 0xfc000000
- #define REG_PHYS_ADDR(x) ((x) + REG_PHYS_BASE)
- #define REG_PHYS_ADDR_V7(x) ((x) + REG_PHYS_BASE_V7)
- /* Product id can be read from here */
- #define SUN_TOP_CTRL_BASE REG_PHYS_ADDR(0x404000)
- #define SUN_TOP_CTRL_BASE_V7 REG_PHYS_ADDR_V7(0x404000)
- #define UARTA_3390 REG_PHYS_ADDR(0x40a900)
- #define UARTA_7250 REG_PHYS_ADDR(0x40b400)
- #define UARTA_7260 REG_PHYS_ADDR(0x40c000)
- #define UARTA_7268 UARTA_7260
- #define UARTA_7271 UARTA_7268
- #define UARTA_7278 REG_PHYS_ADDR_V7(0x40c000)
- #define UARTA_7364 REG_PHYS_ADDR(0x40b000)
- #define UARTA_7366 UARTA_7364
- #define UARTA_74371 REG_PHYS_ADDR(0x406b00)
- #define UARTA_7439 REG_PHYS_ADDR(0x40a900)
- #define UARTA_7445 REG_PHYS_ADDR(0x40ab00)
- #define UART_SHIFT 2
- #define checkuart(rp, rv, family_id, family) \
- /* Load family id */ \
- ldr rp, =family_id ; \
- /* Compare SUN_TOP_CTRL value against it */ \
- cmp rp, rv ; \
- /* Passed test, load address */ \
- ldreq rp, =UARTA_##family ; \
- /* Jump to save UART address */ \
- beq 91f
- .macro addruart, rp, rv, tmp
- adr \rp, 99f @ actual addr of 99f
- ldr \rv, [\rp] @ linked addr is stored there
- sub \rv, \rv, \rp @ offset between the two
- ldr \rp, [\rp, #4] @ linked brcmstb_uart_config
- sub \tmp, \rp, \rv @ actual brcmstb_uart_config
- ldr \rp, [\tmp] @ Load brcmstb_uart_config
- cmp \rp, #1 @ needs initialization?
- bne 100f @ no; go load the addresses
- mov \rv, #0 @ yes; record init is done
- str \rv, [\tmp]
- /* Check for V7 memory map if B53 */
- mrc p15, 0, \rv, c0, c0, 0 @ get Main ID register
- ldr \rp, =ARM_CPU_PART_MASK
- and \rv, \rv, \rp
- ldr \rp, =ARM_CPU_PART_BRAHMA_B53 @ check for B53 CPU
- cmp \rv, \rp
- bne 10f
- /* if PERIPHBASE doesn't overlap REG_PHYS_BASE use V7 map */
- mrc p15, 1, \rv, c15, c3, 0 @ get PERIPHBASE from CBAR
- ands \rv, \rv, #REG_PHYS_BASE
- ldreq \rp, =SUN_TOP_CTRL_BASE_V7
- /* Check SUN_TOP_CTRL base */
- 10: ldrne \rp, =SUN_TOP_CTRL_BASE @ load SUN_TOP_CTRL PA
- ldr \rv, [\rp, #0] @ get register contents
- ARM_BE8( rev \rv, \rv )
- and \rv, \rv, #0xffffff00 @ strip revision bits [7:0]
- /* Chip specific detection starts here */
- 20: checkuart(\rp, \rv, 0x33900000, 3390)
- 21: checkuart(\rp, \rv, 0x72500000, 7250)
- 22: checkuart(\rp, \rv, 0x72600000, 7260)
- 23: checkuart(\rp, \rv, 0x72680000, 7268)
- 24: checkuart(\rp, \rv, 0x72710000, 7271)
- 25: checkuart(\rp, \rv, 0x73640000, 7364)
- 26: checkuart(\rp, \rv, 0x73660000, 7366)
- 27: checkuart(\rp, \rv, 0x07437100, 74371)
- 28: checkuart(\rp, \rv, 0x74390000, 7439)
- 29: checkuart(\rp, \rv, 0x74450000, 7445)
- 30: checkuart(\rp, \rv, 0x72780000, 7278)
- /* No valid UART found */
- 90: mov \rp, #0
- /* fall through */
- /* Record whichever UART we chose */
- 91: str \rp, [\tmp, #4] @ Store in brcmstb_uart_phys
- cmp \rp, #0 @ Valid UART address?
- bne 92f @ Yes, go process it
- str \rp, [\tmp, #8] @ Store 0 in brcmstb_uart_virt
- b 100f @ Done
- 92: and \rv, \rp, #0xffffff @ offset within 16MB section
- add \rv, \rv, #REG_VIRT_BASE
- str \rv, [\tmp, #8] @ Store in brcmstb_uart_virt
- b 100f
- .align
- 99: .word .
- .word brcmstb_uart_config
- .ltorg
- /* Load previously selected UART address */
- 100: ldr \rp, [\tmp, #4] @ Load brcmstb_uart_phys
- ldr \rv, [\tmp, #8] @ Load brcmstb_uart_virt
- .endm
- .macro store, rd, rx:vararg
- ARM_BE8( rev \rd, \rd )
- str \rd, \rx
- .endm
- .macro load, rd, rx:vararg
- ldr \rd, \rx
- ARM_BE8( rev \rd, \rd )
- .endm
- .macro senduart,rd,rx
- store \rd, [\rx, #UART_TX << UART_SHIFT]
- .endm
- .macro busyuart,rd,rx
- 1002: load \rd, [\rx, #UART_LSR << UART_SHIFT]
- and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE
- teq \rd, #UART_LSR_TEMT | UART_LSR_THRE
- bne 1002b
- .endm
- .macro waituart,rd,rx
- .endm
- /*
- * Storage for the state maintained by the macros above.
- *
- * In the kernel proper, this data is located in arch/arm/mach-bcm/brcmstb.c.
- * That's because this header is included from multiple files, and we only
- * want a single copy of the data. In particular, the UART probing code above
- * assumes it's running using physical addresses. This is true when this file
- * is included from head.o, but not when included from debug.o. So we need
- * to share the probe results between the two copies, rather than having
- * to re-run the probing again later.
- *
- * In the decompressor, we put the symbol/storage right here, since common.c
- * isn't included in the decompressor build. This symbol gets put in .text
- * even though it's really data, since .data is discarded from the
- * decompressor. Luckily, .text is writeable in the decompressor, unless
- * CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug.
- */
- #if defined(ZIMAGE)
- brcmstb_uart_config:
- /* Debug UART initialization required */
- .word 1
- /* Debug UART physical address */
- .word 0
- /* Debug UART virtual address */
- .word 0
- #endif
|