1*4882a593Smuzhiyun/* 2*4882a593Smuzhiyun * Copyright (C) 2016 Broadcom 3*4882a593Smuzhiyun * 4*4882a593Smuzhiyun * This program is free software; you can redistribute it and/or 5*4882a593Smuzhiyun * modify it under the terms of the GNU General Public License as 6*4882a593Smuzhiyun * published by the Free Software Foundation version 2. 7*4882a593Smuzhiyun * 8*4882a593Smuzhiyun * This program is distributed "as is" WITHOUT ANY WARRANTY of any 9*4882a593Smuzhiyun * kind, whether express or implied; without even the implied warranty 10*4882a593Smuzhiyun * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11*4882a593Smuzhiyun * GNU General Public License for more details. 12*4882a593Smuzhiyun */ 13*4882a593Smuzhiyun#include <linux/serial_reg.h> 14*4882a593Smuzhiyun#include <asm/cputype.h> 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun/* Physical register offset and virtual register offset */ 17*4882a593Smuzhiyun#define REG_PHYS_BASE 0xf0000000 18*4882a593Smuzhiyun#define REG_PHYS_BASE_V7 0x08000000 19*4882a593Smuzhiyun#define REG_VIRT_BASE 0xfc000000 20*4882a593Smuzhiyun#define REG_PHYS_ADDR(x) ((x) + REG_PHYS_BASE) 21*4882a593Smuzhiyun#define REG_PHYS_ADDR_V7(x) ((x) + REG_PHYS_BASE_V7) 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun/* Product id can be read from here */ 24*4882a593Smuzhiyun#define SUN_TOP_CTRL_BASE REG_PHYS_ADDR(0x404000) 25*4882a593Smuzhiyun#define SUN_TOP_CTRL_BASE_V7 REG_PHYS_ADDR_V7(0x404000) 26*4882a593Smuzhiyun 27*4882a593Smuzhiyun#define UARTA_3390 REG_PHYS_ADDR(0x40a900) 28*4882a593Smuzhiyun#define UARTA_7250 REG_PHYS_ADDR(0x40b400) 29*4882a593Smuzhiyun#define UARTA_7255 REG_PHYS_ADDR(0x40c000) 30*4882a593Smuzhiyun#define UARTA_7260 UARTA_7255 31*4882a593Smuzhiyun#define UARTA_7268 UARTA_7255 32*4882a593Smuzhiyun#define UARTA_7271 UARTA_7268 33*4882a593Smuzhiyun#define UARTA_7278 REG_PHYS_ADDR_V7(0x40c000) 34*4882a593Smuzhiyun#define UARTA_7216 UARTA_7278 35*4882a593Smuzhiyun#define UARTA_72164 UARTA_7278 36*4882a593Smuzhiyun#define UARTA_72165 UARTA_7278 37*4882a593Smuzhiyun#define UARTA_7364 REG_PHYS_ADDR(0x40b000) 38*4882a593Smuzhiyun#define UARTA_7366 UARTA_7364 39*4882a593Smuzhiyun#define UARTA_74371 REG_PHYS_ADDR(0x406b00) 40*4882a593Smuzhiyun#define UARTA_7439 REG_PHYS_ADDR(0x40a900) 41*4882a593Smuzhiyun#define UARTA_7445 REG_PHYS_ADDR(0x40ab00) 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun#define UART_SHIFT 2 44*4882a593Smuzhiyun 45*4882a593Smuzhiyun#define checkuart(rp, rv, family_id, family) \ 46*4882a593Smuzhiyun /* Load family id */ \ 47*4882a593Smuzhiyun ldr rp, =family_id ; \ 48*4882a593Smuzhiyun /* Compare SUN_TOP_CTRL value against it */ \ 49*4882a593Smuzhiyun cmp rp, rv ; \ 50*4882a593Smuzhiyun /* Passed test, load address */ \ 51*4882a593Smuzhiyun ldreq rp, =UARTA_##family ; \ 52*4882a593Smuzhiyun /* Jump to save UART address */ \ 53*4882a593Smuzhiyun beq 91f 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun .macro addruart, rp, rv, tmp 56*4882a593Smuzhiyun adr \rp, 99f @ actual addr of 99f 57*4882a593Smuzhiyun ldr \rv, [\rp] @ linked addr is stored there 58*4882a593Smuzhiyun sub \rv, \rv, \rp @ offset between the two 59*4882a593Smuzhiyun ldr \rp, [\rp, #4] @ linked brcmstb_uart_config 60*4882a593Smuzhiyun sub \tmp, \rp, \rv @ actual brcmstb_uart_config 61*4882a593Smuzhiyun ldr \rp, [\tmp] @ Load brcmstb_uart_config 62*4882a593Smuzhiyun cmp \rp, #1 @ needs initialization? 63*4882a593Smuzhiyun bne 100f @ no; go load the addresses 64*4882a593Smuzhiyun mov \rv, #0 @ yes; record init is done 65*4882a593Smuzhiyun str \rv, [\tmp] 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun /* Check for V7 memory map if B53 */ 68*4882a593Smuzhiyun mrc p15, 0, \rv, c0, c0, 0 @ get Main ID register 69*4882a593Smuzhiyun ldr \rp, =ARM_CPU_PART_MASK 70*4882a593Smuzhiyun and \rv, \rv, \rp 71*4882a593Smuzhiyun ldr \rp, =ARM_CPU_PART_BRAHMA_B53 @ check for B53 CPU 72*4882a593Smuzhiyun cmp \rv, \rp 73*4882a593Smuzhiyun bne 10f 74*4882a593Smuzhiyun 75*4882a593Smuzhiyun /* if PERIPHBASE doesn't overlap REG_PHYS_BASE use V7 map */ 76*4882a593Smuzhiyun mrc p15, 1, \rv, c15, c3, 0 @ get PERIPHBASE from CBAR 77*4882a593Smuzhiyun ands \rv, \rv, #REG_PHYS_BASE 78*4882a593Smuzhiyun ldreq \rp, =SUN_TOP_CTRL_BASE_V7 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun /* Check SUN_TOP_CTRL base */ 81*4882a593Smuzhiyun10: ldrne \rp, =SUN_TOP_CTRL_BASE @ load SUN_TOP_CTRL PA 82*4882a593Smuzhiyun ldr \rv, [\rp, #0] @ get register contents 83*4882a593SmuzhiyunARM_BE8( rev \rv, \rv ) 84*4882a593Smuzhiyun and \rv, \rv, #0xffffff00 @ strip revision bits [7:0] 85*4882a593Smuzhiyun 86*4882a593Smuzhiyun /* Chip specific detection starts here */ 87*4882a593Smuzhiyun20: checkuart(\rp, \rv, 0x33900000, 3390) 88*4882a593Smuzhiyun21: checkuart(\rp, \rv, 0x72160000, 7216) 89*4882a593Smuzhiyun22: checkuart(\rp, \rv, 0x07216400, 72164) 90*4882a593Smuzhiyun23: checkuart(\rp, \rv, 0x07216500, 72165) 91*4882a593Smuzhiyun24: checkuart(\rp, \rv, 0x72500000, 7250) 92*4882a593Smuzhiyun25: checkuart(\rp, \rv, 0x72550000, 7255) 93*4882a593Smuzhiyun26: checkuart(\rp, \rv, 0x72600000, 7260) 94*4882a593Smuzhiyun27: checkuart(\rp, \rv, 0x72680000, 7268) 95*4882a593Smuzhiyun28: checkuart(\rp, \rv, 0x72710000, 7271) 96*4882a593Smuzhiyun29: checkuart(\rp, \rv, 0x72780000, 7278) 97*4882a593Smuzhiyun30: checkuart(\rp, \rv, 0x73640000, 7364) 98*4882a593Smuzhiyun31: checkuart(\rp, \rv, 0x73660000, 7366) 99*4882a593Smuzhiyun32: checkuart(\rp, \rv, 0x07437100, 74371) 100*4882a593Smuzhiyun33: checkuart(\rp, \rv, 0x74390000, 7439) 101*4882a593Smuzhiyun34: checkuart(\rp, \rv, 0x74450000, 7445) 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun /* No valid UART found */ 104*4882a593Smuzhiyun90: mov \rp, #0 105*4882a593Smuzhiyun /* fall through */ 106*4882a593Smuzhiyun 107*4882a593Smuzhiyun /* Record whichever UART we chose */ 108*4882a593Smuzhiyun91: str \rp, [\tmp, #4] @ Store in brcmstb_uart_phys 109*4882a593Smuzhiyun cmp \rp, #0 @ Valid UART address? 110*4882a593Smuzhiyun bne 92f @ Yes, go process it 111*4882a593Smuzhiyun str \rp, [\tmp, #8] @ Store 0 in brcmstb_uart_virt 112*4882a593Smuzhiyun b 100f @ Done 113*4882a593Smuzhiyun92: and \rv, \rp, #0xffffff @ offset within 16MB section 114*4882a593Smuzhiyun add \rv, \rv, #REG_VIRT_BASE 115*4882a593Smuzhiyun str \rv, [\tmp, #8] @ Store in brcmstb_uart_virt 116*4882a593Smuzhiyun b 100f 117*4882a593Smuzhiyun 118*4882a593Smuzhiyun .align 119*4882a593Smuzhiyun99: .word . 120*4882a593Smuzhiyun .word brcmstb_uart_config 121*4882a593Smuzhiyun .ltorg 122*4882a593Smuzhiyun 123*4882a593Smuzhiyun /* Load previously selected UART address */ 124*4882a593Smuzhiyun100: ldr \rp, [\tmp, #4] @ Load brcmstb_uart_phys 125*4882a593Smuzhiyun ldr \rv, [\tmp, #8] @ Load brcmstb_uart_virt 126*4882a593Smuzhiyun .endm 127*4882a593Smuzhiyun 128*4882a593Smuzhiyun .macro store, rd, rx:vararg 129*4882a593SmuzhiyunARM_BE8( rev \rd, \rd ) 130*4882a593Smuzhiyun str \rd, \rx 131*4882a593Smuzhiyun .endm 132*4882a593Smuzhiyun 133*4882a593Smuzhiyun .macro load, rd, rx:vararg 134*4882a593Smuzhiyun ldr \rd, \rx 135*4882a593SmuzhiyunARM_BE8( rev \rd, \rd ) 136*4882a593Smuzhiyun .endm 137*4882a593Smuzhiyun 138*4882a593Smuzhiyun .macro senduart,rd,rx 139*4882a593Smuzhiyun store \rd, [\rx, #UART_TX << UART_SHIFT] 140*4882a593Smuzhiyun .endm 141*4882a593Smuzhiyun 142*4882a593Smuzhiyun .macro busyuart,rd,rx 143*4882a593Smuzhiyun1002: load \rd, [\rx, #UART_LSR << UART_SHIFT] 144*4882a593Smuzhiyun and \rd, \rd, #UART_LSR_TEMT | UART_LSR_THRE 145*4882a593Smuzhiyun teq \rd, #UART_LSR_TEMT | UART_LSR_THRE 146*4882a593Smuzhiyun bne 1002b 147*4882a593Smuzhiyun .endm 148*4882a593Smuzhiyun 149*4882a593Smuzhiyun .macro waituarttxrdy,rd,rx 150*4882a593Smuzhiyun .endm 151*4882a593Smuzhiyun 152*4882a593Smuzhiyun .macro waituartcts,rd,rx 153*4882a593Smuzhiyun .endm 154*4882a593Smuzhiyun 155*4882a593Smuzhiyun/* 156*4882a593Smuzhiyun * Storage for the state maintained by the macros above. 157*4882a593Smuzhiyun * 158*4882a593Smuzhiyun * In the kernel proper, this data is located in arch/arm/mach-bcm/brcmstb.c. 159*4882a593Smuzhiyun * That's because this header is included from multiple files, and we only 160*4882a593Smuzhiyun * want a single copy of the data. In particular, the UART probing code above 161*4882a593Smuzhiyun * assumes it's running using physical addresses. This is true when this file 162*4882a593Smuzhiyun * is included from head.o, but not when included from debug.o. So we need 163*4882a593Smuzhiyun * to share the probe results between the two copies, rather than having 164*4882a593Smuzhiyun * to re-run the probing again later. 165*4882a593Smuzhiyun * 166*4882a593Smuzhiyun * In the decompressor, we put the symbol/storage right here, since common.c 167*4882a593Smuzhiyun * isn't included in the decompressor build. This symbol gets put in .text 168*4882a593Smuzhiyun * even though it's really data, since .data is discarded from the 169*4882a593Smuzhiyun * decompressor. Luckily, .text is writeable in the decompressor, unless 170*4882a593Smuzhiyun * CONFIG_ZBOOT_ROM. That dependency is handled in arch/arm/Kconfig.debug. 171*4882a593Smuzhiyun */ 172*4882a593Smuzhiyun#if defined(ZIMAGE) 173*4882a593Smuzhiyunbrcmstb_uart_config: 174*4882a593Smuzhiyun /* Debug UART initialization required */ 175*4882a593Smuzhiyun .word 1 176*4882a593Smuzhiyun /* Debug UART physical address */ 177*4882a593Smuzhiyun .word 0 178*4882a593Smuzhiyun /* Debug UART virtual address */ 179*4882a593Smuzhiyun .word 0 180*4882a593Smuzhiyun#endif 181