drivers: marvell Add support for Armada-37xx UART

Introduce driver for Marvell Armada-37xx UART console

Signed-off-by: Konstantin Porotchkin <kostap@marvell.com>
diff --git a/drivers/marvell/uart/a3700_console.S b/drivers/marvell/uart/a3700_console.S
new file mode 100644
index 0000000..6575af4
--- /dev/null
+++ b/drivers/marvell/uart/a3700_console.S
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2016 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#include <asm_macros.S>
+#include <a3700_console.h>
+
+	.globl	console_core_init
+	.globl	console_core_putc
+	.globl	console_core_getc
+	.globl	console_core_flush
+
+	/* -----------------------------------------------
+	 * int console_core_init(unsigned long base_addr,
+	 * unsigned int uart_clk, unsigned int baud_rate)
+	 * Function to initialize the console without a
+	 * C Runtime to print debug information. This
+	 * function will be accessed by console_init and
+	 * crash reporting.
+	 * In: x0 - console base address
+	 *     w1 - Uart clock in Hz
+	 *     w2 - Baud rate
+	 * Out: return 1 on success
+	 * Clobber list : x1, x2, x3
+	 * -----------------------------------------------
+	 */
+func console_core_init
+	/* Check the input base address */
+	cbz	x0, init_fail
+	/* Check baud rate and uart clock for sanity */
+	cbz	w1, init_fail
+	cbz	w2, init_fail
+
+	/* Program the baudrate */
+	/* Divisor =  Uart clock / (16 * baudrate) */
+	lsl	w2, w2, #4
+	udiv	w2, w1, w2
+	and	w2, w2, #0x3ff
+
+	ldr	w3, [x0, #UART_BAUD_REG]
+	bic	w3, w3, 0x3ff
+	orr	w3, w3, w2
+	str	w3, [x0, #UART_BAUD_REG]/* set baud rate divisor */
+
+	/* Set UART to default 16X scheme */
+	mov	w3, #0
+	str	w3, [x0, #UART_POSSR_REG]
+
+	/*
+	 * Wait for the TX FIFO to be empty. If wait for 20ms, the TX FIFO is
+	 * still not empty, TX FIFO will reset by all means.
+	 */
+	mov	w1, #20				/* max time out 20ms */
+2:
+	/* Check whether TX FIFO is empty */
+	ldr	w3, [x0, #UART_STATUS_REG]
+	and	w3, w3, #UARTLSR_TXFIFOEMPTY
+	cmp	w3, #0
+	b.ne	4f
+
+	/* Delay */
+	mov	w2, #30000
+3:
+	sub     w2, w2, #1
+	cmp	w2, #0
+	b.ne	3b
+
+	/* Check whether 10ms is waited */
+	sub     w1, w1, #1
+	cmp	w1, #0
+	b.ne	2b
+
+4:
+	/* Reset FIFO */
+	mov	w3, #UART_CTRL_RXFIFO_RESET
+	orr	w3, w3, #UART_CTRL_TXFIFO_RESET
+	str	w3, [x0, #UART_CTRL_REG]
+
+	/* Delay */
+	mov	w2, #2000
+1:
+	sub     w2, w2, #1
+	cmp	w2, #0
+	b.ne	1b
+
+	/* No Parity, 1 Stop */
+	mov	w3, #0
+	str	w3, [x0, #UART_CTRL_REG]
+
+	mov	w0, #1
+	ret
+init_fail:
+	mov	w0, #0
+	ret
+endfunc console_core_init
+
+	/* --------------------------------------------------------
+	 * int console_core_putc(int c, unsigned int base_addr)
+	 * Function to output a character over the console. It
+	 * returns the character printed on success or -1 on error.
+	 * In : w0 - character to be printed
+	 *      x1 - console base address
+	 * Out : return -1 on error else return character.
+	 * Clobber list : x2
+	 * --------------------------------------------------------
+	 */
+func console_core_putc
+	/* Check the input parameter */
+	cbz	x1, putc_error
+
+	/* Prepend '\r' to '\n' */
+	cmp	w0, #0xA
+	b.ne	2f
+	/* Check if the transmit FIFO is full */
+1:	ldr	w2, [x1, #UART_STATUS_REG]
+	and	w2, w2, #UARTLSR_TXFIFOFULL
+	cmp	w2, #UARTLSR_TXFIFOFULL
+	b.eq	1b
+	mov	w2, #0xD		/* '\r' */
+	str	w2, [x1, #UART_TX_REG]
+
+	/* Check if the transmit FIFO is full */
+2:	ldr	w2, [x1, #UART_STATUS_REG]
+	and	w2, w2, #UARTLSR_TXFIFOFULL
+	cmp	w2, #UARTLSR_TXFIFOFULL
+	b.eq	2b
+	str	w0, [x1, #UART_TX_REG]
+	ret
+putc_error:
+	mov	w0, #-1
+	ret
+endfunc console_core_putc
+
+	/* ---------------------------------------------
+	 * int console_core_getc(void)
+	 * Function to get a character from the console.
+	 * It returns the character grabbed on success
+	 * or -1 on error.
+	 * In : w0 - console base address
+	 * Out : return -1 on error else return character.
+	 * Clobber list : x0, x1
+	 * ---------------------------------------------
+	 */
+func console_core_getc
+	/* Check if the receive FIFO is empty */
+	ret
+getc_error:
+	mov	w0, #-1
+	ret
+endfunc console_core_getc
+
+	/* ---------------------------------------------
+	 * int console_core_flush(uintptr_t base_addr)
+	 * Function to force a write of all buffered
+	 * data that hasn't been output.
+	 * In : x0 - console base address
+	 * Out : return -1 on error else return 0.
+	 * Clobber list : x0, x1
+	 * ---------------------------------------------
+	 */
+func console_core_flush
+	/* Placeholder */
+	mov	w0, #0
+	ret
+endfunc console_core_flush
diff --git a/drivers/marvell/uart/a3700_console.h b/drivers/marvell/uart/a3700_console.h
new file mode 100644
index 0000000..1831360
--- /dev/null
+++ b/drivers/marvell/uart/a3700_console.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2016 Marvell International Ltd.
+ *
+ * SPDX-License-Identifier:	BSD-3-Clause
+ * https://spdx.org/licenses
+ */
+
+#ifndef __A3700_CONSOLE_H__
+#define __A3700_CONSOLE_H__
+
+/* MVEBU UART Registers */
+#define UART_RX_REG		0x00
+#define UART_TX_REG		0x04
+#define UART_CTRL_REG		0x08
+#define UART_STATUS_REG		0x0c
+#define UART_BAUD_REG		0x10
+#define UART_POSSR_REG		0x14
+
+/* FIFO Control Register bits */
+#define UARTFCR_FIFOMD_16450	(0 << 6)
+#define UARTFCR_FIFOMD_16550	(1 << 6)
+#define UARTFCR_RXTRIG_1	(0 << 6)
+#define UARTFCR_RXTRIG_4	(1 << 6)
+#define UARTFCR_RXTRIG_8	(2 << 6)
+#define UARTFCR_RXTRIG_16	(3 << 6)
+#define UARTFCR_TXTRIG_1	(0 << 4)
+#define UARTFCR_TXTRIG_4	(1 << 4)
+#define UARTFCR_TXTRIG_8	(2 << 4)
+#define UARTFCR_TXTRIG_16	(3 << 4)
+#define UARTFCR_DMAEN		(1 << 3)	/* Enable DMA mode */
+#define UARTFCR_TXCLR		(1 << 2)	/* Clear contents of Tx FIFO */
+#define UARTFCR_RXCLR		(1 << 1)	/* Clear contents of Rx FIFO */
+#define UARTFCR_FIFOEN		(1 << 0)	/* Enable the Tx/Rx FIFO */
+
+/* Line Control Register bits */
+#define UARTLCR_DLAB		(1 << 7)	/* Divisor Latch Access */
+#define UARTLCR_SETB		(1 << 6)	/* Set BREAK Condition */
+#define UARTLCR_SETP		(1 << 5)	/* Set Parity to LCR[4] */
+#define UARTLCR_EVEN		(1 << 4)	/* Even Parity Format */
+#define UARTLCR_PAR		(1 << 3)	/* Parity */
+#define UARTLCR_STOP		(1 << 2)	/* Stop Bit */
+#define UARTLCR_WORDSZ_5	0		/* Word Length of 5 */
+#define UARTLCR_WORDSZ_6	1		/* Word Length of 6 */
+#define UARTLCR_WORDSZ_7	2		/* Word Length of 7 */
+#define UARTLCR_WORDSZ_8	3		/* Word Length of 8 */
+
+/* Line Status Register bits */
+#define UARTLSR_TXFIFOFULL	(1 << 11)	/* Tx Fifo Full */
+
+/* UART Control Register bits */
+#define UART_CTRL_RXFIFO_RESET	(1 << 14)
+#define UART_CTRL_TXFIFO_RESET	(1 << 15)
+#define UARTLSR_TXFIFOEMPTY	(1 << 6)
+
+#endif	/* __A3700_CONSOLE_H__ */