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