xref: /openbmc/linux/arch/arm/include/debug/brcmstb.S (revision 4f6cce39)
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
15/* Physical register offset and virtual register offset */
16#define REG_PHYS_BASE		0xf0000000
17#define REG_VIRT_BASE		0xfc000000
18#define REG_PHYS_ADDR(x)	((x) + REG_PHYS_BASE)
19
20/* Product id can be read from here */
21#define SUN_TOP_CTRL_BASE	REG_PHYS_ADDR(0x404000)
22
23#define UARTA_3390		REG_PHYS_ADDR(0x40a900)
24#define UARTA_7250		REG_PHYS_ADDR(0x40b400)
25#define UARTA_7268		REG_PHYS_ADDR(0x40c000)
26#define UARTA_7271		UARTA_7268
27#define UARTA_7364		REG_PHYS_ADDR(0x40b000)
28#define UARTA_7366		UARTA_7364
29#define UARTA_74371		REG_PHYS_ADDR(0x406b00)
30#define UARTA_7439		REG_PHYS_ADDR(0x40a900)
31#define UARTA_7445		REG_PHYS_ADDR(0x40ab00)
32
33#define UART_SHIFT		2
34
35#define checkuart(rp, rv, family_id, family) \
36		/* Load family id */ \
37		ldr	rp, =family_id ; \
38		/* Compare SUN_TOP_CTRL value against it */ \
39		cmp	rp, rv ; \
40		/* Passed test, load address */ \
41		ldreq	rp, =UARTA_##family ; \
42		/* Jump to save UART address */ \
43		beq	91f
44
45		.macro  addruart, rp, rv, tmp
46		adr	\rp, 99f		@ actual addr of 99f
47		ldr	\rv, [\rp]		@ linked addr is stored there
48		sub	\rv, \rv, \rp		@ offset between the two
49		ldr	\rp, [\rp, #4]		@ linked brcmstb_uart_config
50		sub	\tmp, \rp, \rv		@ actual brcmstb_uart_config
51		ldr	\rp, [\tmp]		@ Load brcmstb_uart_config
52		cmp	\rp, #1			@ needs initialization?
53		bne	100f			@ no; go load the addresses
54		mov	\rv, #0			@ yes; record init is done
55		str	\rv, [\tmp]
56
57		/* Check SUN_TOP_CTRL base */
58		ldr	\rp, =SUN_TOP_CTRL_BASE	@ load SUN_TOP_CTRL PA
59		ldr	\rv, [\rp, #0]		@ get register contents
60		and	\rv, \rv, #0xffffff00	@ strip revision bits [7:0]
61
62		/* Chip specific detection starts here */
6320:		checkuart(\rp, \rv, 0x33900000, 3390)
6421:		checkuart(\rp, \rv, 0x72500000, 7250)
6522:		checkuart(\rp, \rv, 0x72680000, 7268)
6623:		checkuart(\rp, \rv, 0x72710000, 7271)
6724:		checkuart(\rp, \rv, 0x73640000, 7364)
6825:		checkuart(\rp, \rv, 0x73660000, 7366)
6926:		checkuart(\rp, \rv, 0x07437100, 74371)
7027:		checkuart(\rp, \rv, 0x74390000, 7439)
7128:		checkuart(\rp, \rv, 0x74450000, 7445)
72
73		/* No valid UART found */
7490:		mov	\rp, #0
75		/* fall through */
76
77		/* Record whichever UART we chose */
7891:		str	\rp, [\tmp, #4]		@ Store in brcmstb_uart_phys
79		cmp	\rp, #0			@ Valid UART address?
80		bne	92f			@ Yes, go process it
81		str	\rp, [\tmp, #8]		@ Store 0 in brcmstb_uart_virt
82		b	100f			@ Done
8392:		and     \rv, \rp, #0xffffff	@ offset within 16MB section
84		add	\rv, \rv, #REG_VIRT_BASE
85		str	\rv, [\tmp, #8]		@ Store in brcmstb_uart_virt
86		b	100f
87
88		.align
8999:		.word	.
90		.word	brcmstb_uart_config
91		.ltorg
92
93		/* Load previously selected UART address */
94100:		ldr	\rp, [\tmp, #4]		@ Load brcmstb_uart_phys
95		ldr	\rv, [\tmp, #8]		@ Load brcmstb_uart_virt
96		.endm
97
98		.macro	store, rd, rx:vararg
99		str	\rd, \rx
100		.endm
101
102		.macro	load, rd, rx:vararg
103		ldr	\rd, \rx
104		.endm
105
106		.macro	senduart,rd,rx
107		store	\rd, [\rx, #UART_TX << UART_SHIFT]
108		.endm
109
110		.macro	busyuart,rd,rx
1111002:		load	\rd, [\rx, #UART_LSR << UART_SHIFT]
112		and	\rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE
113		teq	\rd, #UART_LSR_TEMT | UART_LSR_THRE
114		bne	1002b
115		.endm
116
117		.macro	waituart,rd,rx
118		.endm
119
120/*
121 * Storage for the state maintained by the macros above.
122 *
123 * In the kernel proper, this data is located in arch/arm/mach-bcm/brcmstb.c.
124 * That's because this header is included from multiple files, and we only
125 * want a single copy of the data. In particular, the UART probing code above
126 * assumes it's running using physical addresses. This is true when this file
127 * is included from head.o, but not when included from debug.o. So we need
128 * to share the probe results between the two copies, rather than having
129 * to re-run the probing again later.
130 *
131 * In the decompressor, we put the symbol/storage right here, since common.c
132 * isn't included in the decompressor build. This symbol gets put in .text
133 * even though it's really data, since .data is discarded from the
134 * decompressor. Luckily, .text is writeable in the decompressor, unless
135 * CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug.
136 */
137#if defined(ZIMAGE)
138brcmstb_uart_config:
139	/* Debug UART initialization required */
140	.word 1
141	/* Debug UART physical address */
142	.word 0
143	/* Debug UART virtual address */
144	.word 0
145#endif
146