• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2009-2022 Huawei Technologies Co., Ltd. All rights reserved.
3  *
4  * UniProton is licensed under Mulan PSL v2.
5  * You can use this software according to the terms and conditions of the Mulan PSL v2.
6  * You may obtain a copy of Mulan PSL v2 at:
7  *          http://license.coscl.org.cn/MulanPSL2
8  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
9  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
10  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
11  * See the Mulan PSL v2 for more details.
12  * Create: 2009-12-22
13  * Description: UniProton hi3093 demo
14  */
15 #include "uart_core.h"
16 #include "common.h"
17 
18 #define UART_REG_READ(addr)          (*(volatile U32 *)(((uintptr_t)addr)))
19 #define UART_REG_WRITE(value, addr)  (*(volatile U32 *)((uintptr_t)addr) = (U32)value)
20 
21 /* Get UART register base address */
uart_core_base_addr(S32 uartno,U32 * reg_base)22 static S32 uart_core_base_addr(S32 uartno, U32 *reg_base)
23 {
24     unsigned long reg_bases[] = {
25         UART0_REG_BASE,
26         UART1_REG_BASE,
27         UART2_REG_BASE,
28         UART3_REG_BASE,
29         UART4_REG_BASE
30     };
31 
32     if (uartno >= MAX_UART_NUM || uartno < 0) {
33         return -1;
34     }
35 
36     *reg_base = reg_bases[uartno];
37 
38     return OS_OK;
39 }
40 
uart_reg_read(S32 uartno,U32 offset,U32 * val)41 S32 uart_reg_read(S32 uartno, U32 offset, U32 *val)
42 {
43     S32 ret;
44     U32 reg_base = 0x0;
45 
46     ret = uart_core_base_addr(uartno, &reg_base);
47     if (ret) {
48         return ret;
49     }
50 
51     *val = UART_REG_READ((unsigned long)(reg_base + offset));
52     return OS_OK;
53 }
54 
uart_reg_write(S32 uartno,U32 offset,U32 val)55 void uart_reg_write(S32 uartno, U32 offset, U32 val)
56 {
57     S32 ret;
58     U32 reg_base = 0x0;
59 
60     ret = uart_core_base_addr(uartno, &reg_base);
61     if (ret) {
62         return;
63     }
64 
65     UART_REG_WRITE(val, (unsigned long)(reg_base + offset));
66     return;
67 }
68 
uart_set_lcr_dlab(S32 uartno,S32 dlab_sel)69 void uart_set_lcr_dlab(S32 uartno, S32 dlab_sel)
70 {
71     S32 ret;
72     U32 lcr = 0;
73 
74     ret = uart_reg_read(uartno, DW_UART_LCR, &lcr);
75     if (ret) {
76         return;
77     }
78 
79     if (dlab_sel) {
80         lcr |= DW_UART_DLAB;
81     } else {
82         lcr &= ~DW_UART_DLAB;
83     }
84 
85     uart_reg_write(uartno, DW_UART_LCR, lcr);
86     return;
87 }
88 
uart_set_dll_dlh(S32 uartno,U32 dll,U32 dlh)89 void uart_set_dll_dlh(S32 uartno, U32 dll, U32 dlh)
90 {
91     /* Enable DLL/DLH/FCR access */
92     uart_set_lcr_dlab(uartno, 1);
93     uart_reg_write(uartno, DW_UART_DLL, dll);
94     uart_reg_write(uartno, DW_UART_DLH, dlh);
95     uart_set_lcr_dlab(uartno, 0);
96     return;
97 }
98 
uart_get_dll_dlh(S32 uartno,U32 * dll,U32 * dlh)99 void uart_get_dll_dlh(S32 uartno, U32 *dll, U32 *dlh)
100 {
101     /* Enable DLL/DLH/FCR access */
102     uart_set_lcr_dlab(uartno, 1);
103     uart_reg_read(uartno, DW_UART_DLL, dll);
104     uart_reg_read(uartno, DW_UART_DLH, dlh);
105     uart_set_lcr_dlab(uartno, 0);
106     return;
107 }
108 
uart_set_fifo_ctrl(S32 uartno,U32 fifo_ctrl)109 void uart_set_fifo_ctrl(S32 uartno, U32 fifo_ctrl)
110 {
111     /* Enable DLL/DLH/FCR access */
112     uart_set_lcr_dlab(uartno, 1);
113     uart_reg_write(uartno, DW_UART_FCR, fifo_ctrl);
114     uart_set_lcr_dlab(uartno, 0);
115     return;
116 }
117 
uart_set_lcr(S32 uartno,U32 lcr)118 void uart_set_lcr(S32 uartno, U32 lcr)
119 {
120     uart_reg_write(uartno, DW_UART_LCR, lcr);
121     return;
122 }
123 
124 /* value: 0:禁止;1:使能 */
uart_set_irq_enable(S32 uartno,U32 value)125 void uart_set_irq_enable(S32 uartno, U32 value)
126 {
127     uart_reg_write(uartno, ELSI, value);
128     return;
129 }
130 
uart_is_txfifo_full(S32 uartno)131 S32 uart_is_txfifo_full(S32 uartno)
132 {
133     S32 ret;
134     U32 usr = 0;
135 
136     ret = uart_reg_read(uartno, DW_UART_USR, &usr);
137     if (ret) {
138         return OS_OK;
139     }
140 
141     return (usr & DW_XFIFO_NOT_FULL) ? 0 : 1;
142 }
143 
uart_is_rx_ready(S32 uartno)144 S32 uart_is_rx_ready(S32 uartno)
145 {
146     U32 lsr = 0;
147 
148     (void)uart_reg_read(uartno, DW_UART_LSR, &lsr);
149     return (lsr & DW_UART_LSR_DDR) ? 1 : 0;
150 }
151 
uart_tx_char(S32 uartno,const S8 c)152 void uart_tx_char(S32 uartno, const S8 c)
153 {
154     uart_reg_write(uartno, DW_UART_THR, (U32)(U8)c);
155     return;
156 }
157 
uart_rx_char(S32 uartno,S8 * c)158 void uart_rx_char(S32 uartno, S8 *c)
159 {
160     U32 rbr = 0;
161 
162     (void)uart_reg_read(uartno, DW_UART_RBR, &rbr);
163     *c = (S8)(rbr & 0xFF);
164 
165     return;
166 }
167 
uart_wait4idle(S32 uartno,U32 timeout)168 S32 uart_wait4idle(S32 uartno, U32 timeout)
169 {
170     U32 usr = 0;
171 
172     while (timeout) {
173         (void)uart_reg_read(uartno, DW_UART_USR, &usr);
174         if ((usr & (DW_UART_BUSY)) == 0) {
175             return OS_OK;
176         }
177 
178         timeout--;
179     }
180 
181     return -1;
182 }
183