/* 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 0 xf0000000
#define REG_PHYS_BASE_V7 0 x08000000
#define REG_VIRT_BASE 0 xfc000000
#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(0 x404000)
#define SUN_TOP_CTRL_BASE_V7 REG_PHYS_ADDR_V7(0 x404000)
#define UARTA_3390 REG_PHYS_ADDR(0 x40a900)
#define UARTA_72116 UARTA_7255
#define UARTA_7250 REG_PHYS_ADDR(0 x40b400)
#define UARTA_7255 REG_PHYS_ADDR(0 x40c000)
#define UARTA_7260 UARTA_7255
#define UARTA_7268 UARTA_7255
#define UARTA_7271 UARTA_7268
#define UARTA_7278 REG_PHYS_ADDR_V7(0 x40c000)
#define UARTA_7216 UARTA_7278
#define UARTA_72164 UARTA_7278
#define UARTA_72165 UARTA_7278
#define UARTA_7364 REG_PHYS_ADDR(0 x40b000)
#define UARTA_7366 UARTA_7364
#define UARTA_74165 UARTA_7278
#define UARTA_74371 REG_PHYS_ADDR(0 x406b00)
#define UARTA_7439 REG_PHYS_ADDR(0 x40a900)
#define UARTA_7445 REG_PHYS_ADDR(0 x40ab00)
#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 91 f
.macro addruart, rp, rv, tmp
adr \rp, 99 f @ actual addr of 99 f
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 100 f @ 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 10 f
/* 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, #0 xffffff00 @ strip revision bits [7 :0 ]
/* Chip specific detection starts here */
20 : checkuart(\rp, \rv, 0 x33900000, 3390 )
21 : checkuart(\rp, \rv, 0 x07211600, 72116 )
22 : checkuart(\rp, \rv, 0 x72160000, 7216 )
23 : checkuart(\rp, \rv, 0 x07216400, 72164 )
24 : checkuart(\rp, \rv, 0 x07216500, 72165 )
25 : checkuart(\rp, \rv, 0 x72500000, 7250 )
26 : checkuart(\rp, \rv, 0 x72550000, 7255 )
27 : checkuart(\rp, \rv, 0 x72600000, 7260 )
28 : checkuart(\rp, \rv, 0 x72680000, 7268 )
29 : checkuart(\rp, \rv, 0 x72710000, 7271 )
30 : checkuart(\rp, \rv, 0 x72780000, 7278 )
31 : checkuart(\rp, \rv, 0 x73640000, 7364 )
32 : checkuart(\rp, \rv, 0 x73660000, 7366 )
33 : checkuart(\rp, \rv, 0 x07416500, 74165 )
34 : checkuart(\rp, \rv, 0 x07437100, 74371 )
35 : checkuart(\rp, \rv, 0 x74390000, 7439 )
36 : checkuart(\rp, \rv, 0 x74450000, 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 92 f @ Yes, go process it
str \rp, [\tmp, #8 ] @ Store 0 in brcmstb_uart_virt
b 100 f @ Done
92 : and \rv, \rp, #0 xffffff @ offset within 16 MB section
add \rv, \rv, #REG_VIRT_BASE
str \rv, [\tmp, #8 ] @ Store in brcmstb_uart_virt
b 100 f
.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 1002 b
.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
Messung V0.5 in Prozent C=89 H=100 G=94
¤ Dauer der Verarbeitung: 0.10 Sekunden
(vorverarbeitet am 2026-09-30)
¤
*© Formatika GbR, Deutschland