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 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 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 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 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