1/*
2 * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved.
3 * Copyright (c) 2018,2020 The Linux Foundation. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8#include <asm_macros.S>
9#include <console_macros.S>
10
11#include <platform_def.h>
12#include <qti_uart_console.h>
13
14/*
15 * This driver implements console logging into a ring buffer.
16 */
17
18	.globl qti_console_uart_register
19
20	/* -----------------------------------------------
21	 * int qti_console_uart_register(console_t *console,
22	 *				 uintptr_t uart_base_addr)
23	 * Registers uart console instance.
24	 * In:  x0 - pointer to empty console_t struct
25	 *      x1 - start address of uart block.
26	 * Out: x0 - 1 to indicate success
27	 * Clobber list: x0, x1, x14
28	 * -----------------------------------------------
29	 */
30func qti_console_uart_register
31	str	x1, [x0, #CONSOLE_T_BASE]	/* Save UART base. */
32	finish_console_register uart putc=1, flush=1
33endfunc qti_console_uart_register
34
35	/* -----------------------------------------------
36	 * int qti_console_uart_puts(int c, console_t *console)
37	 * Writes a character to the UART console.
38	 * The character must be preserved in x0.
39	 * In: x0 - character to be stored
40	 *     x1 - pointer to console_t struct
41	 * Clobber list: x1, x2
42	 * -----------------------------------------------
43	 */
44func console_uart_putc
45	/* set x1 = UART base. */
46	ldr	x1, [x1, #CONSOLE_T_BASE]
47
48	/* Loop until M_GENI_CMD_ACTIVE bit not clear. */
491:	ldr	w2, [x1, #GENI_STATUS_REG]
50	and	w2, w2, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
51	cmp	w2, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
52	b.eq	1b
53
54	/* Transmit data. */
55	cmp	w0, #0xA
56	b.ne	3f
57
58	/* Add '\r' when input char is '\n' */
59	mov	w2, #0x1
60	mov	w0, #0xD
61	str	w2, [x1, #UART_TX_TRANS_LEN_REG]
62	mov	w2, #GENI_M_CMD_TX
63	str	w2, [x1, #GENI_M_CMD0_REG]
64	str	w0, [x1, #GENI_TX_FIFOn_REG]
65	mov	w0, #0xA
66
67	/* Loop until M_GENI_CMD_ACTIVE bit not clear. */
682:	ldr	w2, [x1, #GENI_STATUS_REG]
69	and	w2, w2, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
70	cmp	w2, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
71	b.eq	2b
72
73	/* Transmit i/p data. */
743:	mov	w2, #0x1
75	str	w2, [x1, #UART_TX_TRANS_LEN_REG]
76	mov	w2, #GENI_M_CMD_TX
77	str	w2, [x1, #GENI_M_CMD0_REG]
78	str	w0, [x1, #GENI_TX_FIFOn_REG]
79
80	ret
81endfunc	console_uart_putc
82
83	/* -----------------------------------------------
84	 * int qti_console_uart_flush(console_t *console)
85	 * In:  x0 - pointer to console_t struct
86	 * Out: x0 - 0 for success
87	 * Clobber list: x0, x1
88	 * -----------------------------------------------
89	 */
90func console_uart_flush
91	/* set x0 = UART base. */
92	ldr	x0, [x0, #CONSOLE_T_BASE]
93
94	/* Loop until M_GENI_CMD_ACTIVE bit not clear. */
951:	ldr	w1, [x0, #GENI_STATUS_REG]
96	and	w1, w1, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
97	cmp	w1, #GENI_STATUS_M_GENI_CMD_ACTIVE_MASK
98	b.eq	1b
99
100	mov	w0, #0
101	ret
102endfunc console_uart_flush
103