Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 | /* SPDX-License-Identifier: GPL-2.0-only */ /* Copyright (C) 2016 Broadcom */ #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_72116 UARTA_7255 #define UARTA_7250 REG_PHYS_ADDR(0x40b400) #define UARTA_7255 REG_PHYS_ADDR(0x40c000) #define UARTA_7260 UARTA_7255 #define UARTA_7268 UARTA_7255 #define UARTA_7271 UARTA_7268 #define UARTA_7278 REG_PHYS_ADDR_V7(0x40c000) #define UARTA_7216 UARTA_7278 #define UARTA_72164 UARTA_7278 #define UARTA_72165 UARTA_7278 #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, 0x07211600, 72116) 22: checkuart(\rp, \rv, 0x72160000, 7216) 23: checkuart(\rp, \rv, 0x07216400, 72164) 24: checkuart(\rp, \rv, 0x07216500, 72165) 25: checkuart(\rp, \rv, 0x72500000, 7250) 26: checkuart(\rp, \rv, 0x72550000, 7255) 27: checkuart(\rp, \rv, 0x72600000, 7260) 28: checkuart(\rp, \rv, 0x72680000, 7268) 29: checkuart(\rp, \rv, 0x72710000, 7271) 30: checkuart(\rp, \rv, 0x72780000, 7278) 31: checkuart(\rp, \rv, 0x73640000, 7364) 32: checkuart(\rp, \rv, 0x73660000, 7366) 33: checkuart(\rp, \rv, 0x07437100, 74371) 34: checkuart(\rp, \rv, 0x74390000, 7439) 35: checkuart(\rp, \rv, 0x74450000, 7445) /* 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 waituarttxrdy,rd,rx .endm .macro waituartcts,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 |