@ -5,133 +5,149 @@
* SPDX - License - Identifier : GPL - 2.0 +
*/
# include <common.h>
# include <watchdog.h>
# include <dm.h>
# include <errno.h>
# include <asm/io.h>
# include <linux/compiler.h>
# include <serial.h>
typedef volatile struct {
unsigned rxdata ; /* Rx data reg */
unsigned txdata ; /* Tx data reg */
unsigned status ; /* Status reg */
unsigned control ; /* Control reg */
unsigned divisor ; /* Baud rate divisor reg */
unsigned endofpacket ; /* End-of-packet reg */
} nios_uart_t ;
struct altera_uart_regs {
u32 rxdata ; /* Rx data reg */
u32 txdata ; /* Tx data reg */
u32 status ; /* Status reg */
u32 control ; /* Control reg */
u32 divisor ; /* Baud rate divisor reg */
u32 endofpacket ; /* End-of-packet reg */
} ;
struct altera_uart_platdata {
struct altera_uart_regs * regs ;
unsigned int uartclk ;
} ;
/* status register */
# define NIOS_UART_PE (1 << 0) /* parity error */
# define NIOS_UART_FE (1 << 1) /* frame error */
# define NIOS_UART_BRK (1 << 2) /* break detect */
# define NIOS_UART_ROE (1 << 3) /* rx overrun */
# define NIOS_UART_TOE (1 << 4) /* tx overrun */
# define NIOS_UART_TMT (1 << 5) /* tx empty */
# define NIOS_UART_TRDY (1 << 6) /* tx ready */
# define NIOS_UART_RRDY (1 << 7) /* rx ready */
# define NIOS_UART_E (1 << 8) /* exception */
# define NIOS_UART_DCTS (1 << 10) /* cts change */
# define NIOS_UART_CTS (1 << 11) /* cts */
# define NIOS_UART_EOP (1 << 12) /* eop detected */
/* control register */
# define NIOS_UART_IPE (1 << 0) /* parity error int ena*/
# define NIOS_UART_IFE (1 << 1) /* frame error int ena */
# define NIOS_UART_IBRK (1 << 2) /* break detect int ena */
# define NIOS_UART_IROE (1 << 3) /* rx overrun int ena */
# define NIOS_UART_ITOE (1 << 4) /* tx overrun int ena */
# define NIOS_UART_ITMT (1 << 5) /* tx empty int ena */
# define NIOS_UART_ITRDY (1 << 6) /* tx ready int ena */
# define NIOS_UART_IRRDY (1 << 7) /* rx ready int ena */
# define NIOS_UART_IE (1 << 8) /* exception int ena */
# define NIOS_UART_TBRK (1 << 9) /* transmit break */
# define NIOS_UART_IDCTS (1 << 10) /* cts change int ena */
# define NIOS_UART_RTS (1 << 11) /* rts */
# define NIOS_UART_IEOP (1 << 12) /* eop detected int ena */
# define ALTERA_UART_TMT (1 << 5) /* tx empty */
# define ALTERA_UART_TRDY (1 << 6) /* tx ready */
# define ALTERA_UART_RRDY (1 << 7) /* rx ready */
DECLARE_GLOBAL_DATA_PTR ;
/*------------------------------------------------------------------
* UART the serial port
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
static nios_uart_t * uart = ( nios_uart_t * ) CONFIG_SYS_NIOS_CONSOLE ;
static int altera_uart_setbrg ( struct udevice * dev , int baudrate )
{
struct altera_uart_platdata * plat = dev - > platdata ;
struct altera_uart_regs * const regs = plat - > regs ;
u32 div ;
# if defined(CONFIG_SYS_NIOS_FIXEDBAUD)
div = ( plat - > uartclk / baudrate ) - 1 ;
writel ( div , & regs - > divisor ) ;
/*
* Everything ' s already setup for fixed - baud PTF
* assignment
*/
static void altera_serial_setbrg ( void )
{
return 0 ;
}
static int altera_serial_init ( void )
static int altera_uart_putc ( struct udevice * dev , const char ch )
{
return 0 ;
}
struct altera_uart_platdata * plat = dev - > platdata ;
struct altera_uart_regs * const regs = plat - > regs ;
# else
if ( ! ( readl ( & regs - > status ) & ALTERA_UART_TRDY ) )
return - EAGAIN ;
static void altera_serial_setbrg ( void )
{
unsigned div ;
writel ( ch , & regs - > txdata ) ;
div = ( CONFIG_SYS_CLK_FREQ / gd - > baudrate ) - 1 ;
writel ( div , & uart - > divisor ) ;
return 0 ;
}
static int altera_serial_init ( void )
static int altera_uart_pending ( struct udevice * dev , bool input )
{
serial_setbrg ( ) ;
return 0 ;
struct altera_uart_platdata * plat = dev - > platdata ;
struct altera_uart_regs * const regs = plat - > regs ;
u32 st = readl ( & regs - > status ) ;
if ( input )
return st & ALTERA_UART_RRDY ? 1 : 0 ;
else
return ! ( st & ALTERA_UART_TMT ) ;
}
# endif /* CONFIG_SYS_NIOS_FIXEDBAUD */
/*-----------------------------------------------------------------------
* UART CONSOLE
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
static void altera_serial_putc ( char c )
static int altera_uart_getc ( struct udevice * dev )
{
if ( c = = ' \n ' )
serial_putc ( ' \r ' ) ;
while ( ( readl ( & uart - > status ) & NIOS_UART_TRDY ) = = 0 )
WATCHDOG_RESET ( ) ;
writel ( ( unsigned char ) c , & uart - > txdata ) ;
struct altera_uart_platdata * plat = dev - > platdata ;
struct altera_uart_regs * const regs = plat - > regs ;
if ( ! ( readl ( & regs - > status ) & ALTERA_UART_RRDY ) )
return - EAGAIN ;
return readl ( & regs - > rxdata ) & 0xff ;
}
static int altera_serial_tstc ( void )
static int altera_uart_probe ( struct udevice * dev )
{
return ( readl ( & uart - > status ) & NIOS_UART_RRDY ) ;
return 0 ;
}
static int altera_serial_getc ( void )
static int altera_uart_ofdata_to_platdata ( struct udevice * dev )
{
while ( serial_tstc ( ) = = 0 )
WATCHDOG_RESET ( ) ;
return ( readl ( & uart - > rxdata ) & 0x00ff ) ;
struct altera_uart_platdata * plat = dev_get_platdata ( dev ) ;
plat - > regs = ioremap ( dev_get_addr ( dev ) ,
sizeof ( struct altera_uart_regs ) ) ;
plat - > uartclk = fdtdec_get_int ( gd - > fdt_blob , dev - > of_offset ,
" clock-frequency " , 0 ) ;
return 0 ;
}
static struct serial_device altera_serial_drv = {
. name = " altera_serial " ,
. start = altera_serial_init ,
. stop = NULL ,
. setbrg = altera_serial_setbrg ,
. putc = altera_serial_putc ,
. puts = default_serial_puts ,
. getc = altera_serial_getc ,
. tstc = altera_serial_tstc ,
static const struct dm_serial_ops altera_uart_ops = {
. putc = altera_uart_putc ,
. pending = altera_uart_pending ,
. getc = altera_uart_getc ,
. setbrg = altera_uart_setbrg ,
} ;
static const struct udevice_id altera_uart_ids [ ] = {
{ . compatible = " altr,uart-1.0 " , } ,
{ }
} ;
U_BOOT_DRIVER ( altera_uart ) = {
. name = " altera_uart " ,
. id = UCLASS_SERIAL ,
. of_match = altera_uart_ids ,
. ofdata_to_platdata = altera_uart_ofdata_to_platdata ,
. platdata_auto_alloc_size = sizeof ( struct altera_uart_platdata ) ,
. probe = altera_uart_probe ,
. ops = & altera_uart_ops ,
. flags = DM_FLAG_PRE_RELOC ,
} ;
void altera_serial_initialize ( void )
# ifdef CONFIG_DEBUG_UART_ALTERA_UART
# include <debug_uart.h>
void debug_uart_init ( void )
{
serial_register ( & altera_serial_drv ) ;
struct altera_uart_regs * regs = ( void * ) CONFIG_DEBUG_UART_BASE ;
u32 div ;
div = ( CONFIG_DEBUG_UART_CLOCK / CONFIG_BAUDRATE ) - 1 ;
writel ( div , & regs - > divisor ) ;
}
__weak struct serial_device * default_serial_console ( void )
static inline void _debug_uart_putc ( int ch )
{
return & altera_serial_drv ;
struct altera_uart_regs * regs = ( void * ) CONFIG_DEBUG_UART_BASE ;
while ( 1 ) {
u32 st = readl ( & regs - > status ) ;
if ( st & ALTERA_UART_TRDY )
break ;
}
writel ( ch , & regs - > txdata ) ;
}
DEBUG_UART_FUNCS
# endif