174 lines · 5.5 KB · Assembly
RawDownload
/* 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_74165		UARTA_7278#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 contentsARM_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, 0x07416500, 74165)34:		checkuart(\rp, \rv, 0x07437100, 74371)35:		checkuart(\rp, \rv, 0x74390000, 7439)36:		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			@ Done92:		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 		.align99:		.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:varargARM_BE8(	rev	\rd, \rd )		str	\rd, \rx		.endm 		.macro	load, rd, rx:vararg		ldr	\rd, \rxARM_BE8(	rev	\rd, \rd )		.endm 		.macro	senduart,rd,rx		store	\rd, [\rx, #UART_TX << UART_SHIFT]		.endm 		.macro	busyuart,rd,rx1002:		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