blob: a76527a4fa91be116bb9ebbeff7ec44a847caf93 [file] [log] [blame]
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
/*
* arch/arm/cpu/armv8/gxl/firmware/scp_task/uart.c
*
* Copyright (C) 2020 Amlogic, Inc. All rights reserved.
*
*/
#include "registers.h"
#include <stdint.h>
#include "task_apis.h"
/* #define P_AO_UART_WFIFO (0xc81004c0) */
/* #define P_AO_RTI_PIN_MUX_REG (0xc8100014) */
#define UART_PORT_CONS AO_UART_WFIFO
#define UART_STP_BIT UART_MODE_MASK_STP_1BIT
#define UART_PRTY_BIT 0
#define UART_CHAR_LEN UART_MODE_MASK_CHAR_8BIT
#define UART_MODE_RESET_MASK \
(UART_MODE_MASK_RST_TX \
| UART_MODE_MASK_RST_RX \
| UART_MODE_MASK_CLR_ERR)
#define UART_WFIFO (0<<2)
#define UART_RFIFO (1<<2)
#define UART_MODE (2<<2)
#define UART_STATUS (3<<2)
#define UART_IRQCTL (4<<2)
#define UART_CTRL (5<<2)
#define UART_MODE_MASK_STP_1BIT (0<<16)
#define UART_MODE_MASK_CHAR_8BIT (0<<20)
#define UART_MODE_MASK_TX_EN (1<<12)
#define UART_MODE_MASK_RX_EN (1<<13)
#define UART_MODE_MASK_RST_TX (1<<22)
#define UART_MODE_MASK_RST_RX (1<<23)
#define UART_MODE_MASK_CLR_ERR (1<<24)
#define UART_CTRL_USE_XTAL_CLK (1<<24)
#define UART_CTRL_USE_NEW_BAUD_RATE (1<<23)
#define UART_STAT_MASK_RFIFO_FULL (1<<19)
#define UART_STAT_MASK_RFIFO_EMPTY (1<<20)
#define UART_STAT_MASK_TFIFO_FULL (1<<21)
#define UART_STAT_MASK_TFIFO_EMPTY (1<<22)
#define P_UART(uart_base, reg) (uart_base+reg)
#define P_UART_WFIFO(uart_base) P_UART(uart_base, UART_WFIFO)
#define P_UART_MODE(uart_base) P_UART(uart_base, UART_MODE)
#define P_UART_CTRL(uart_base) P_UART(uart_base, UART_CTRL)
#define P_UART_STATUS(uart_base) P_UART(uart_base, UART_STATUS)
static int uart_tx_isfull(void)
{
return readl(P_UART_STATUS(UART_PORT_CONS)) &
UART_STAT_MASK_TFIFO_FULL;
}
void wait_uart_empty(void)
{
#if 0
while (!(readl(P_UART_STATUS(UART_PORT_CONS)) & (1 << 22)))
;
#else
unsigned int count=0;
do {
if ((readl(P_UART_STATUS(UART_PORT_CONS)) & (1 << 22)) == 0)
_udelay(4);
else
break;
count++;
} while ( count < 20000);
#endif
}
void uart_tx_flush(void)
{
while (!(readl(P_UART_STATUS(UART_PORT_CONS)) &
UART_STAT_MASK_TFIFO_EMPTY))
;
}
int uart_putc(int c)
{
if (c == '\n')
uart_putc('\r');
/* Wait until TX is not full */
while (uart_tx_isfull())
;
writel((char)c, P_UART_WFIFO(UART_PORT_CONS));
/*wait_uart_empty();*/
uart_tx_flush();
return c;
}
int uart_puts(const char *s)
{
while (*s)
uart_putc(*s++);
return 1;
}
void uart_put_hex(unsigned int data, unsigned bitlen)
{
int i;
unsigned char s;
for (i = bitlen - 4; i >= 0; i -= 4) {
if ((data >> i) == 0) {
uart_putc(0x30);
continue;
}
s = (data >> i) & 0xf;
if (s < 10)
uart_putc(0x30 + s);
else
uart_putc(0x61 + s - 10);
}
}