2019-06-04 10:11:33 +02:00
// SPDX-License-Identifier: GPL-2.0-only
2013-01-20 22:02:55 +01:00
/*
*
* Copyright ( C ) 2011 - 2012 Gabor Juhos < juhosg @ openwrt . org >
*/
# include <linux/io.h>
# include <linux/serial_reg.h>
# include <asm/addrspace.h>
2018-07-13 17:51:56 +02:00
# include <asm/setup.h>
2013-01-20 22:02:55 +01:00
2013-04-09 18:31:15 +02:00
# ifdef CONFIG_SOC_RT288X
2014-01-24 17:01:17 +01:00
# define EARLY_UART_BASE 0x300c00
# define CHIPID_BASE 0x300004
# elif defined(CONFIG_SOC_MT7621)
# define EARLY_UART_BASE 0x1E000c00
# define CHIPID_BASE 0x1E000004
2013-04-09 18:31:15 +02:00
# else
2014-01-24 17:01:17 +01:00
# define EARLY_UART_BASE 0x10000c00
# define CHIPID_BASE 0x10000004
2013-04-09 18:31:15 +02:00
# endif
2013-01-20 22:02:55 +01:00
2014-01-24 17:01:17 +01:00
# define MT7628_CHIP_NAME1 0x20203832
# define UART_REG_TX 0x04
2015-11-05 03:59:58 +01:00
# define UART_REG_LCR 0x0c
2014-01-24 17:01:17 +01:00
# define UART_REG_LSR 0x14
# define UART_REG_LSR_RT2880 0x1c
2013-01-20 22:02:55 +01:00
static __iomem void * uart_membase = ( __iomem void * ) KSEG1ADDR ( EARLY_UART_BASE ) ;
2014-01-24 17:01:17 +01:00
static __iomem void * chipid_membase = ( __iomem void * ) KSEG1ADDR ( CHIPID_BASE ) ;
2015-11-05 03:59:58 +01:00
static int init_complete ;
2013-01-20 22:02:55 +01:00
static inline void uart_w32 ( u32 val , unsigned reg )
{
__raw_writel ( val , uart_membase + reg ) ;
}
static inline u32 uart_r32 ( unsigned reg )
{
return __raw_readl ( uart_membase + reg ) ;
}
2014-01-24 17:01:17 +01:00
static inline int soc_is_mt7628 ( void )
{
return IS_ENABLED ( CONFIG_SOC_MT7620 ) & &
( __raw_readl ( chipid_membase ) = = MT7628_CHIP_NAME1 ) ;
}
2015-11-05 03:59:58 +01:00
static void find_uart_base ( void )
{
int i ;
if ( ! soc_is_mt7628 ( ) )
return ;
for ( i = 0 ; i < 3 ; i + + ) {
u32 reg = uart_r32 ( UART_REG_LCR + ( 0x100 * i ) ) ;
if ( ! reg )
continue ;
uart_membase = ( __iomem void * ) KSEG1ADDR ( EARLY_UART_BASE +
( 0x100 * i ) ) ;
break ;
}
}
2018-07-13 17:51:56 +02:00
void prom_putchar ( char ch )
2013-01-20 22:02:55 +01:00
{
2015-11-05 03:59:58 +01:00
if ( ! init_complete ) {
find_uart_base ( ) ;
init_complete = 1 ;
}
2014-01-24 17:01:17 +01:00
if ( IS_ENABLED ( CONFIG_SOC_MT7621 ) | | soc_is_mt7628 ( ) ) {
2018-07-13 17:51:56 +02:00
uart_w32 ( ( unsigned char ) ch , UART_TX ) ;
2014-01-24 17:01:17 +01:00
while ( ( uart_r32 ( UART_REG_LSR ) & UART_LSR_THRE ) = = 0 )
;
} else {
while ( ( uart_r32 ( UART_REG_LSR_RT2880 ) & UART_LSR_THRE ) = = 0 )
;
2018-07-13 17:51:56 +02:00
uart_w32 ( ( unsigned char ) ch , UART_REG_TX ) ;
2014-01-24 17:01:17 +01:00
while ( ( uart_r32 ( UART_REG_LSR_RT2880 ) & UART_LSR_THRE ) = = 0 )
;
}
2013-01-20 22:02:55 +01:00
}