1*3374752fSBo-Chen Chen /*
2*3374752fSBo-Chen Chen * Copyright (c) 2020-2022, MediaTek Inc. All rights reserved.
3*3374752fSBo-Chen Chen *
4*3374752fSBo-Chen Chen * SPDX-License-Identifier: BSD-3-Clause
5*3374752fSBo-Chen Chen */
6*3374752fSBo-Chen Chen
7*3374752fSBo-Chen Chen #include <lib/mmio.h>
8*3374752fSBo-Chen Chen #include <uart.h>
9*3374752fSBo-Chen Chen
10*3374752fSBo-Chen Chen static struct mt_uart uart_save_addr[DRV_SUPPORT_UART_PORTS];
11*3374752fSBo-Chen Chen
12*3374752fSBo-Chen Chen static const uint32_t uart_base_addr[DRV_SUPPORT_UART_PORTS] = {
13*3374752fSBo-Chen Chen UART0_BASE,
14*3374752fSBo-Chen Chen UART1_BASE
15*3374752fSBo-Chen Chen };
16*3374752fSBo-Chen Chen
mt_uart_restore(void)17*3374752fSBo-Chen Chen void mt_uart_restore(void)
18*3374752fSBo-Chen Chen {
19*3374752fSBo-Chen Chen int uart_idx = UART_PORT0;
20*3374752fSBo-Chen Chen struct mt_uart *uart;
21*3374752fSBo-Chen Chen unsigned long base;
22*3374752fSBo-Chen Chen
23*3374752fSBo-Chen Chen /* Must NOT print any debug log before UART restore */
24*3374752fSBo-Chen Chen for (uart_idx = UART_PORT0; uart_idx < HW_SUPPORT_UART_PORTS;
25*3374752fSBo-Chen Chen uart_idx++) {
26*3374752fSBo-Chen Chen
27*3374752fSBo-Chen Chen uart = &uart_save_addr[uart_idx];
28*3374752fSBo-Chen Chen base = uart->base;
29*3374752fSBo-Chen Chen
30*3374752fSBo-Chen Chen mmio_write_32(UART_LCR(base), UART_LCR_MODE_B);
31*3374752fSBo-Chen Chen mmio_write_32(UART_EFR(base), uart->registers.efr);
32*3374752fSBo-Chen Chen mmio_write_32(UART_LCR(base), uart->registers.lcr);
33*3374752fSBo-Chen Chen mmio_write_32(UART_FCR(base), uart->registers.fcr);
34*3374752fSBo-Chen Chen
35*3374752fSBo-Chen Chen /* baudrate */
36*3374752fSBo-Chen Chen mmio_write_32(UART_HIGHSPEED(base), uart->registers.highspeed);
37*3374752fSBo-Chen Chen mmio_write_32(UART_FRACDIV_L(base), uart->registers.fracdiv_l);
38*3374752fSBo-Chen Chen mmio_write_32(UART_FRACDIV_M(base), uart->registers.fracdiv_m);
39*3374752fSBo-Chen Chen mmio_write_32(UART_LCR(base),
40*3374752fSBo-Chen Chen uart->registers.lcr | UART_LCR_DLAB);
41*3374752fSBo-Chen Chen mmio_write_32(UART_DLL(base), uart->registers.dll);
42*3374752fSBo-Chen Chen mmio_write_32(UART_DLH(base), uart->registers.dlh);
43*3374752fSBo-Chen Chen mmio_write_32(UART_LCR(base), uart->registers.lcr);
44*3374752fSBo-Chen Chen mmio_write_32(UART_SAMPLE_COUNT(base),
45*3374752fSBo-Chen Chen uart->registers.sample_count);
46*3374752fSBo-Chen Chen mmio_write_32(UART_SAMPLE_POINT(base),
47*3374752fSBo-Chen Chen uart->registers.sample_point);
48*3374752fSBo-Chen Chen mmio_write_32(UART_GUARD(base), uart->registers.guard);
49*3374752fSBo-Chen Chen
50*3374752fSBo-Chen Chen /* flow control */
51*3374752fSBo-Chen Chen mmio_write_32(UART_ESCAPE_EN(base), uart->registers.escape_en);
52*3374752fSBo-Chen Chen mmio_write_32(UART_MCR(base), uart->registers.mcr);
53*3374752fSBo-Chen Chen mmio_write_32(UART_IER(base), uart->registers.ier);
54*3374752fSBo-Chen Chen mmio_write_32(UART_SCR(base), uart->registers.scr);
55*3374752fSBo-Chen Chen }
56*3374752fSBo-Chen Chen }
57*3374752fSBo-Chen Chen
mt_uart_save(void)58*3374752fSBo-Chen Chen void mt_uart_save(void)
59*3374752fSBo-Chen Chen {
60*3374752fSBo-Chen Chen int uart_idx = UART_PORT0;
61*3374752fSBo-Chen Chen struct mt_uart *uart;
62*3374752fSBo-Chen Chen unsigned long base;
63*3374752fSBo-Chen Chen
64*3374752fSBo-Chen Chen for (uart_idx = UART_PORT0; uart_idx < HW_SUPPORT_UART_PORTS;
65*3374752fSBo-Chen Chen uart_idx++) {
66*3374752fSBo-Chen Chen
67*3374752fSBo-Chen Chen uart_save_addr[uart_idx].base = uart_base_addr[uart_idx];
68*3374752fSBo-Chen Chen base = uart_base_addr[uart_idx];
69*3374752fSBo-Chen Chen uart = &uart_save_addr[uart_idx];
70*3374752fSBo-Chen Chen uart->registers.lcr = mmio_read_32(UART_LCR(base));
71*3374752fSBo-Chen Chen
72*3374752fSBo-Chen Chen mmio_write_32(UART_LCR(base), UART_LCR_MODE_B);
73*3374752fSBo-Chen Chen uart->registers.efr = mmio_read_32(UART_EFR(base));
74*3374752fSBo-Chen Chen mmio_write_32(UART_LCR(base), uart->registers.lcr);
75*3374752fSBo-Chen Chen uart->registers.fcr = mmio_read_32(UART_FCR_RD(base));
76*3374752fSBo-Chen Chen
77*3374752fSBo-Chen Chen /* baudrate */
78*3374752fSBo-Chen Chen uart->registers.highspeed = mmio_read_32(UART_HIGHSPEED(base));
79*3374752fSBo-Chen Chen uart->registers.fracdiv_l = mmio_read_32(UART_FRACDIV_L(base));
80*3374752fSBo-Chen Chen uart->registers.fracdiv_m = mmio_read_32(UART_FRACDIV_M(base));
81*3374752fSBo-Chen Chen mmio_write_32(UART_LCR(base),
82*3374752fSBo-Chen Chen uart->registers.lcr | UART_LCR_DLAB);
83*3374752fSBo-Chen Chen uart->registers.dll = mmio_read_32(UART_DLL(base));
84*3374752fSBo-Chen Chen uart->registers.dlh = mmio_read_32(UART_DLH(base));
85*3374752fSBo-Chen Chen mmio_write_32(UART_LCR(base), uart->registers.lcr);
86*3374752fSBo-Chen Chen uart->registers.sample_count = mmio_read_32(
87*3374752fSBo-Chen Chen UART_SAMPLE_COUNT(base));
88*3374752fSBo-Chen Chen uart->registers.sample_point = mmio_read_32(
89*3374752fSBo-Chen Chen UART_SAMPLE_POINT(base));
90*3374752fSBo-Chen Chen uart->registers.guard = mmio_read_32(UART_GUARD(base));
91*3374752fSBo-Chen Chen
92*3374752fSBo-Chen Chen /* flow control */
93*3374752fSBo-Chen Chen uart->registers.escape_en = mmio_read_32(UART_ESCAPE_EN(base));
94*3374752fSBo-Chen Chen uart->registers.mcr = mmio_read_32(UART_MCR(base));
95*3374752fSBo-Chen Chen uart->registers.ier = mmio_read_32(UART_IER(base));
96*3374752fSBo-Chen Chen uart->registers.scr = mmio_read_32(UART_SCR(base));
97*3374752fSBo-Chen Chen }
98*3374752fSBo-Chen Chen }
99*3374752fSBo-Chen Chen
mt_console_uart_cg(int on)100*3374752fSBo-Chen Chen void mt_console_uart_cg(int on)
101*3374752fSBo-Chen Chen {
102*3374752fSBo-Chen Chen if (on == 1) {
103*3374752fSBo-Chen Chen mmio_write_32(UART_CLOCK_GATE_CLR, UART0_CLOCK_GATE_BIT);
104*3374752fSBo-Chen Chen } else {
105*3374752fSBo-Chen Chen mmio_write_32(UART_CLOCK_GATE_SET, UART0_CLOCK_GATE_BIT);
106*3374752fSBo-Chen Chen }
107*3374752fSBo-Chen Chen }
108*3374752fSBo-Chen Chen
mt_console_uart_cg_status(void)109*3374752fSBo-Chen Chen uint32_t mt_console_uart_cg_status(void)
110*3374752fSBo-Chen Chen {
111*3374752fSBo-Chen Chen return mmio_read_32(UART_CLOCK_GATE_STA) & UART0_CLOCK_GATE_BIT;
112*3374752fSBo-Chen Chen }
113