18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * 16550 compatible uart based serial debug support for zboot
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include <linux/types.h>
78c2ecf20Sopenharmony_ci#include <linux/serial_reg.h>
88c2ecf20Sopenharmony_ci
98c2ecf20Sopenharmony_ci#include <asm/addrspace.h>
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#define UART_BASE 0x1fe001e0
128c2ecf20Sopenharmony_ci#define PORT(offset) (TO_UNCACHE(UART_BASE) + (offset))
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#ifndef IOTYPE
158c2ecf20Sopenharmony_ci#define IOTYPE char
168c2ecf20Sopenharmony_ci#endif
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#ifndef PORT
198c2ecf20Sopenharmony_ci#error please define the serial port address for your own machine
208c2ecf20Sopenharmony_ci#endif
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_cistatic inline unsigned int serial_in(int offset)
238c2ecf20Sopenharmony_ci{
248c2ecf20Sopenharmony_ci	return *((volatile IOTYPE *)PORT(offset)) & 0xFF;
258c2ecf20Sopenharmony_ci}
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_cistatic inline void serial_out(int offset, int value)
288c2ecf20Sopenharmony_ci{
298c2ecf20Sopenharmony_ci	*((volatile IOTYPE *)PORT(offset)) = value & 0xFF;
308c2ecf20Sopenharmony_ci}
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_civoid putc(char c)
338c2ecf20Sopenharmony_ci{
348c2ecf20Sopenharmony_ci	int timeout = 1000000;
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci	while (((serial_in(UART_LSR) & UART_LSR_THRE) == 0) && (timeout-- > 0))
378c2ecf20Sopenharmony_ci		;
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	serial_out(UART_TX, c);
408c2ecf20Sopenharmony_ci}
41