mediatek: mt8192: add uart save and restore api

When system resume, we want to print log as soon as possible.
So we add uart save and restore api, and they will be called
when systtem suspend and resume.

Change-Id: I83b477fd2b39567c9c6b70534ef186993f7053ae
diff --git a/plat/mediatek/common/drivers/uart/uart.c b/plat/mediatek/common/drivers/uart/uart.c
new file mode 100644
index 0000000..b940eb3
--- /dev/null
+++ b/plat/mediatek/common/drivers/uart/uart.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2020, MediaTek Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <lib/mmio.h>
+#include <uart.h>
+
+static struct mt_uart uart_save_addr[DRV_SUPPORT_UART_PORTS];
+
+static const uint32_t uart_base_addr[DRV_SUPPORT_UART_PORTS] = {
+	UART0_BASE,
+	UART1_BASE
+};
+
+void mt_uart_restore(void)
+{
+	int uart_idx = UART_PORT0;
+	struct mt_uart *uart;
+	unsigned long base;
+
+	/* Must NOT print any debug log before UART restore */
+	for (uart_idx = UART_PORT0; uart_idx < HW_SUPPORT_UART_PORTS;
+	     uart_idx++) {
+
+		uart = &uart_save_addr[uart_idx];
+		base = uart->base;
+
+		mmio_write_32(UART_LCR(base), UART_LCR_MODE_B);
+		mmio_write_32(UART_EFR(base), uart->registers.efr);
+		mmio_write_32(UART_LCR(base), uart->registers.lcr);
+		mmio_write_32(UART_FCR(base), uart->registers.fcr);
+
+		/* baudrate */
+		mmio_write_32(UART_HIGHSPEED(base), uart->registers.highspeed);
+		mmio_write_32(UART_FRACDIV_L(base), uart->registers.fracdiv_l);
+		mmio_write_32(UART_FRACDIV_M(base), uart->registers.fracdiv_m);
+		mmio_write_32(UART_LCR(base),
+			      uart->registers.lcr | UART_LCR_DLAB);
+		mmio_write_32(UART_DLL(base), uart->registers.dll);
+		mmio_write_32(UART_DLH(base), uart->registers.dlh);
+		mmio_write_32(UART_LCR(base), uart->registers.lcr);
+		mmio_write_32(UART_SAMPLE_COUNT(base),
+			      uart->registers.sample_count);
+		mmio_write_32(UART_SAMPLE_POINT(base),
+			      uart->registers.sample_point);
+		mmio_write_32(UART_GUARD(base), uart->registers.guard);
+
+		/* flow control */
+		mmio_write_32(UART_ESCAPE_EN(base), uart->registers.escape_en);
+		mmio_write_32(UART_MCR(base), uart->registers.mcr);
+		mmio_write_32(UART_IER(base), uart->registers.ier);
+		mmio_write_32(UART_SCR(base), uart->registers.scr);
+	}
+}
+
+void mt_uart_save(void)
+{
+	int uart_idx = UART_PORT0;
+	struct mt_uart *uart;
+	unsigned long base;
+
+	for (uart_idx = UART_PORT0; uart_idx < HW_SUPPORT_UART_PORTS;
+	     uart_idx++) {
+
+		uart_save_addr[uart_idx].base = uart_base_addr[uart_idx];
+		base = uart_base_addr[uart_idx];
+		uart = &uart_save_addr[uart_idx];
+		uart->registers.lcr = mmio_read_32(UART_LCR(base));
+
+		mmio_write_32(UART_LCR(base), UART_LCR_MODE_B);
+		uart->registers.efr = mmio_read_32(UART_EFR(base));
+		mmio_write_32(UART_LCR(base), uart->registers.lcr);
+		uart->registers.fcr = mmio_read_32(UART_FCR_RD(base));
+
+		/* baudrate */
+		uart->registers.highspeed = mmio_read_32(UART_HIGHSPEED(base));
+		uart->registers.fracdiv_l = mmio_read_32(UART_FRACDIV_L(base));
+		uart->registers.fracdiv_m = mmio_read_32(UART_FRACDIV_M(base));
+		mmio_write_32(UART_LCR(base),
+			      uart->registers.lcr | UART_LCR_DLAB);
+		uart->registers.dll = mmio_read_32(UART_DLL(base));
+		uart->registers.dlh = mmio_read_32(UART_DLH(base));
+		mmio_write_32(UART_LCR(base), uart->registers.lcr);
+		uart->registers.sample_count = mmio_read_32(
+						UART_SAMPLE_COUNT(base));
+		uart->registers.sample_point = mmio_read_32(
+						UART_SAMPLE_POINT(base));
+		uart->registers.guard = mmio_read_32(UART_GUARD(base));
+
+		/* flow control */
+		uart->registers.escape_en = mmio_read_32(UART_ESCAPE_EN(base));
+		uart->registers.mcr = mmio_read_32(UART_MCR(base));
+		uart->registers.ier = mmio_read_32(UART_IER(base));
+		uart->registers.scr = mmio_read_32(UART_SCR(base));
+	}
+}
+
+void mt_console_uart_cg(int on)
+{
+	if (on == 1) {
+		mmio_write_32(UART_CLOCK_GATE_CLR, UART0_CLOCK_GATE_BIT);
+	} else {
+		mmio_write_32(UART_CLOCK_GATE_SET, UART0_CLOCK_GATE_BIT);
+	}
+}
+
+uint32_t mt_console_uart_cg_status(void)
+{
+	return mmio_read_32(UART_CLOCK_GATE_STA) & UART0_CLOCK_GATE_BIT;
+}