2016-06-28 12:18:51 -07:00
/ *
* Copyright ( C ) 2 0 1 6 B r o a d c o m
*
* This p r o g r a m i s f r e e s o f t w a r e ; you can redistribute it and/or
* modify i t u n d e r t h e t e r m s o f t h e G N U G e n e r a l P u b l i c L i c e n s e a s
* published b y t h e F r e e S o f t w a r e F o u n d a t i o n v e r s i o n 2 .
*
* This p r o g r a m i s d i s t r i b u t e d " a s i s " W I T H O U T A N Y W A R R A N T Y o f a n y
* kind, w h e t h e r e x p r e s s o r i m p l i e d ; without even the implied warranty
* of M E R C H A N T A B I L I T Y o r F I T N E S S F O R A P A R T I C U L A R P U R P O S E . S e e t h e
* GNU G e n e r a l P u b l i c L i c e n s e f o r m o r e d e t a i l s .
* /
# include < l i n u x / s e r i a l _ r e g . h >
2018-02-23 13:09:23 -08:00
# include < a s m / c p u t y p e . h >
2016-06-28 12:18:51 -07:00
/* Physical register offset and virtual register offset */
# define R E G _ P H Y S _ B A S E 0 x f00 0 0 0 0 0
2018-02-23 13:09:23 -08:00
# define R E G _ P H Y S _ B A S E _ V 7 0 x08 0 0 0 0 0 0
2016-06-28 12:18:51 -07:00
# define R E G _ V I R T _ B A S E 0 x f c00 0 0 0 0
# define R E G _ P H Y S _ A D D R ( x ) ( ( x ) + R E G _ P H Y S _ B A S E )
2018-02-23 13:09:23 -08:00
# define R E G _ P H Y S _ A D D R _ V 7 ( x ) ( ( x ) + R E G _ P H Y S _ B A S E _ V 7 )
2016-06-28 12:18:51 -07:00
/* Product id can be read from here */
# define S U N _ T O P _ C T R L _ B A S E R E G _ P H Y S _ A D D R ( 0 x40 4 0 0 0 )
2018-02-23 13:09:23 -08:00
# define S U N _ T O P _ C T R L _ B A S E _ V 7 R E G _ P H Y S _ A D D R _ V 7 ( 0 x40 4 0 0 0 )
2016-06-28 12:18:51 -07:00
# define U A R T A _ 3 3 9 0 R E G _ P H Y S _ A D D R ( 0 x40 a90 0 )
# define U A R T A _ 7 2 5 0 R E G _ P H Y S _ A D D R ( 0 x40 b40 0 )
2017-11-10 11:54:22 -08:00
# define U A R T A _ 7 2 5 5 R E G _ P H Y S _ A D D R ( 0 x40 c00 0 )
# define U A R T A _ 7 2 6 0 U A R T A _ 7 2 5 5
# define U A R T A _ 7 2 6 8 U A R T A _ 7 2 5 5
2016-06-28 12:18:51 -07:00
# define U A R T A _ 7 2 7 1 U A R T A _ 7 2 6 8
2018-02-23 13:09:23 -08:00
# define U A R T A _ 7 2 7 8 R E G _ P H Y S _ A D D R _ V 7 ( 0 x40 c00 0 )
2016-06-28 12:18:51 -07:00
# define U A R T A _ 7 3 6 4 R E G _ P H Y S _ A D D R ( 0 x40 b00 0 )
# define U A R T A _ 7 3 6 6 U A R T A _ 7 3 6 4
# define U A R T A _ 7 4 3 7 1 R E G _ P H Y S _ A D D R ( 0 x40 6 b00 )
# define U A R T A _ 7 4 3 9 R E G _ P H Y S _ A D D R ( 0 x40 a90 0 )
# define U A R T A _ 7 4 4 5 R E G _ P H Y S _ A D D R ( 0 x40 a b00 )
# define U A R T _ S H I F T 2
# define c h e c k u a r t ( r p , r v , f a m i l y _ i d , f a m i l y ) \
/* Load family id */ \
ldr r p , =family_id ; \
/* Compare SUN_TOP_CTRL value against it */ \
cmp r p , r v ; \
/* Passed test, load address */ \
ldreq r p , =UARTA_ ## f a m i l y ; \
/* Jump to save UART address */ \
beq 9 1 f
.macro addruart, r p , r v , t m p
adr \ r p , 9 9 f @ actual addr of 99f
ldr \ r v , [ \ r p ] @ linked addr is stored there
sub \ r v , \ r v , \ r p @ offset between the two
ldr \ r p , [ \ r p , #4 ] @ linked brcmstb_uart_config
sub \ t m p , \ r p , \ r v @ actual brcmstb_uart_config
ldr \ r p , [ \ t m p ] @ Load brcmstb_uart_config
cmp \ r p , #1 @ needs initialization?
bne 1 0 0 f @ no; go load the addresses
mov \ r v , #0 @ yes; record init is done
str \ r v , [ \ t m p ]
2018-02-23 13:09:23 -08:00
/* Check for V7 memory map if B53 */
mrc p15 , 0 , \ r v , c0 , c0 , 0 @ get Main ID register
ldr \ r p , =ARM_CPU_PART_MASK
and \ r v , \ r v , \ r p
ldr \ r p , =ARM_CPU_PART_BRAHMA_B53 @ check for B53 CPU
cmp \ r v , \ r p
bne 1 0 f
/* if PERIPHBASE doesn't overlap REG_PHYS_BASE use V7 map */
mrc p15 , 1 , \ r v , c15 , c3 , 0 @ get PERIPHBASE from CBAR
ands \ r v , \ r v , #R E G _ P H Y S _ B A S E
ldreq \ r p , =SUN_TOP_CTRL_BASE_V7
2016-06-28 12:18:51 -07:00
/* Check SUN_TOP_CTRL base */
2018-02-23 13:09:23 -08:00
10 : ldrne \ r p , =SUN_TOP_CTRL_BASE @ load SUN_TOP_CTRL PA
2016-06-28 12:18:51 -07:00
ldr \ r v , [ \ r p , #0 ] @ get register contents
2017-08-29 11:03:39 -07:00
ARM_ B E 8 ( r e v \ r v , \ r v )
2016-06-28 12:18:51 -07:00
and \ r v , \ r v , #0xffffff00 @ strip revision bits [7:0]
/* Chip specific detection starts here */
20 : checkuart( \ r p , \ r v , 0 x33 9 0 0 0 0 0 , 3 3 9 0 )
21 : checkuart( \ r p , \ r v , 0 x72 5 0 0 0 0 0 , 7 2 5 0 )
2017-11-10 11:54:22 -08:00
22 : checkuart( \ r p , \ r v , 0 x72 5 5 0 0 0 0 , 7 2 5 5 )
23 : checkuart( \ r p , \ r v , 0 x72 6 0 0 0 0 0 , 7 2 6 0 )
24 : checkuart( \ r p , \ r v , 0 x72 6 8 0 0 0 0 , 7 2 6 8 )
25 : checkuart( \ r p , \ r v , 0 x72 7 1 0 0 0 0 , 7 2 7 1 )
26 : checkuart( \ r p , \ r v , 0 x72 7 8 0 0 0 0 , 7 2 7 8 )
27 : checkuart( \ r p , \ r v , 0 x73 6 4 0 0 0 0 , 7 3 6 4 )
28 : checkuart( \ r p , \ r v , 0 x73 6 6 0 0 0 0 , 7 3 6 6 )
29 : checkuart( \ r p , \ r v , 0 x07 4 3 7 1 0 0 , 7 4 3 7 1 )
30 : checkuart( \ r p , \ r v , 0 x74 3 9 0 0 0 0 , 7 4 3 9 )
31 : checkuart( \ r p , \ r v , 0 x74 4 5 0 0 0 0 , 7 4 4 5 )
2016-06-28 12:18:51 -07:00
/* No valid UART found */
90 : mov \ r p , #0
/* fall through */
/* Record whichever UART we chose */
91 : str \ r p , [ \ t m p , #4 ] @ Store in brcmstb_uart_phys
cmp \ r p , #0 @ Valid UART address?
bne 9 2 f @ Yes, go process it
str \ r p , [ \ t m p , #8 ] @ Store 0 in brcmstb_uart_virt
b 1 0 0 f @ Done
92 : and \ r v , \ r p , #0xffffff @ offset within 16MB section
add \ r v , \ r v , #R E G _ V I R T _ B A S E
str \ r v , [ \ t m p , #8 ] @ Store in brcmstb_uart_virt
b 1 0 0 f
.align
99 : .word .
.word brcmstb_uart_config
.ltorg
/* Load previously selected UART address */
100 : ldr \ r p , [ \ t m p , #4 ] @ Load brcmstb_uart_phys
ldr \ r v , [ \ t m p , #8 ] @ Load brcmstb_uart_virt
.endm
.macro store, r d , r x : v a r a r g
2017-08-29 11:03:39 -07:00
ARM_ B E 8 ( r e v \ r d , \ r d )
2016-06-28 12:18:51 -07:00
str \ r d , \ r x
.endm
.macro load, r d , r x : v a r a r g
ldr \ r d , \ r x
2017-08-29 11:03:39 -07:00
ARM_ B E 8 ( r e v \ r d , \ r d )
2016-06-28 12:18:51 -07:00
.endm
.macro senduart,r d ,r x
store \ r d , [ \ r x , #U A R T _ T X < < U A R T _ S H I F T ]
.endm
.macro busyuart,r d ,r x
1002 : load \ r d , [ \ r x , #U A R T _ L S R < < U A R T _ S H I F T ]
and \ r d , \ r d , #U A R T _ L S R _ T E M T | U A R T _ L S R _ T H R E
teq \ r d , #U A R T _ L S R _ T E M T | U A R T _ L S R _ T H R E
bne 1 0 0 2 b
.endm
.macro waituart,r d ,r x
.endm
/ *
* Storage f o r t h e s t a t e m a i n t a i n e d b y t h e m a c r o s a b o v e .
*
* In t h e k e r n e l p r o p e r , t h i s d a t a i s l o c a t e d i n a r c h / a r m / m a c h - b c m / b r c m s t b . c .
* That' s b e c a u s e t h i s h e a d e r i s i n c l u d e d f r o m m u l t i p l e f i l e s , a n d w e o n l y
* want a s i n g l e c o p y o f t h e d a t a . I n p a r t i c u l a r , t h e U A R T p r o b i n g c o d e a b o v e
* assumes i t ' s r u n n i n g u s i n g p h y s i c a l a d d r e s s e s . T h i s i s t r u e w h e n t h i s f i l e
* is i n c l u d e d f r o m h e a d . o , b u t n o t w h e n i n c l u d e d f r o m d e b u g . o . S o w e n e e d
* to s h a r e t h e p r o b e r e s u l t s b e t w e e n t h e t w o c o p i e s , r a t h e r t h a n h a v i n g
* to r e - r u n t h e p r o b i n g a g a i n l a t e r .
*
* In t h e d e c o m p r e s s o r , w e p u t t h e s y m b o l / s t o r a g e r i g h t h e r e , s i n c e c o m m o n . c
* isn' t i n c l u d e d i n t h e d e c o m p r e s s o r b u i l d . T h i s s y m b o l g e t s p u t i n . t e x t
* even t h o u g h i t ' s r e a l l y d a t a , s i n c e . d a t a i s d i s c a r d e d f r o m t h e
* decompressor. L u c k i l y , . t e x t i s w r i t e a b l e i n t h e d e c o m p r e s s o r , u n l e s s
* CONFIG_ Z B O O T _ R O M . T h a t d e p e n d e n c y i s h a n d l e d i n a r c h / a r m / K c o n f i g . d e b u g .
* /
# if d e f i n e d ( Z I M A G E )
brcmstb_uart_config :
/* Debug UART initialization required */
.word 1
/* Debug UART physical address */
.word 0
/* Debug UART virtual address */
.word 0
# endif