1 /*
2  * Copyright 2024 Microchip Technology Inc. and its subsidiaries.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 #ifndef _MEC_UART_API_H
7 #define _MEC_UART_API_H
8 
9 #include <stdbool.h>
10 #include <stddef.h>
11 #include <stdint.h>
12 
13 #include "mec_retval.h"
14 
15 /* Interfaces to any C modules */
16 #ifdef __cplusplus
17 extern "C"
18 {
19 #endif
20 
21 /* 16550 compatible UART has TX and RX FIFO' each 16 bytes in size */
22 #define MEC_UART_FIFO_LEN 16
23 
24 enum mec_uart_word_len {
25     MEC_UART_WORD_LEN_5 = 0,
26     MEC_UART_WORD_LEN_6,
27     MEC_UART_WORD_LEN_7,
28     MEC_UART_WORD_LEN_8,
29     MEC_UART_WORD_LEN_MAX,
30 };
31 
32 enum mec_uart_parity {
33     MEC_UART_PARITY_NONE = 0,
34     MEC_UART_PARITY_ODD,
35     MEC_UART_PARITY_EVEN,
36     MEC_UART_PARITY_MARK,
37     MEC_UART_PARITY_SPACE,
38     MEC_UART_PARITY_MAX,
39 };
40 
41 enum mec_uart_stop_bits {
42     MEC_UART_STOP_BITS_1 = 0,
43     MEC_UART_STOP_BITS_2,
44     MEC_UART_STOP_BITS_MAX,
45 };
46 
47 enum mec_uart_sts_reg {
48     MEC_UART_STS_REG_IID = 0,
49     MEC_UART_STS_REG_LINE,
50     MEC_UART_STS_REG_MODEM,
51     MEC_UART_STS_REG_MAX,
52 };
53 
54 enum mec_uart_fifo_mode {
55     MEC_UART_FIFOS_CFG_DIS = 0,
56     MEC_UART_FIFOS_CFG_EN_RX_TRIG_1,
57     MEC_UART_FIFOS_CFG_EN_RX_TRIG_4,
58     MEC_UART_FIFOS_CFG_EN_RX_TRIG_8,
59     MEC_UART_FIFOS_CFG_EN_RX_TRIG_14,
60     MEC_UART_FIFOS_CFG_MAX,
61 };
62 
63 enum mec_uart_ipend {
64     MEC_UART_IPEND_NONE = 0,
65     MEC_UART_IPEND_MODEM, /* lowest priority */
66     MEC_UART_IPEND_TX,
67     MEC_UART_IPEND_RX_DATA,
68     MEC_UART_IPEND_RX_ERR, /* highest priority */
69     MEC_UART_IPEND_UNKOWN,
70     MEC_UART_IPEND_MAX,
71 };
72 
73 #define MEC_UART_CFG_FLAG_SOC_CLK 0
74 #define MEC_UART_CFG_FLAG_LINES_NONINVERT 0
75 #define MEC_UART_CFG_FLAG_EXT_CLK 0x01u
76 #define MEC_UART_CFG_FLAG_INVERT_LINES 0x02u
77 
78 #define MEC_UART_IEN_FLAG_ERDAI 0x01
79 #define MEC_UART_IEN_FLAG_ETHREI 0x02
80 #define MEC_UART_IEN_FLAG_ELSI 0x04
81 #define MEC_UART_IEN_FLAG_EMSI 0x08
82 
83 struct mec_uart_cfg {
84     uint32_t clock_freq;
85     uint32_t baud_rate;
86     uint8_t word_len;
87     uint8_t parity;
88     uint8_t stop_bits;
89     uint8_t cfg_flags;
90     uint8_t fifo_mode;
91     uint8_t ien_flags;
92 };
93 
94 
95 /* UART configuration 32-bit word */
96 #define MEC5_UART_CFG_RESET_HOST_POS 0
97 #define MEC5_UART_CFG_RESET_HOST 0x01u
98 #define MEC5_UART_CFG_INVERT_LINES_POS 1
99 #define MEC5_UART_CFG_INVERT_LINES 0x02u
100 #define MEC5_UART_CFG_FIFO_EN_POS 3
101 #define MEC5_UART_CFG_FIFO_EN 0x08u
102 #define MEC5_UART_CFG_RX_FIFO_TRIG_LVL_POS 4
103 #define MEC5_UART_CFG_RX_FIFO_TRIG_LVL_MSK 0x30u
104 #define MEC5_UART_CFG_RX_FIFO_TRIG_LVL_1 0x00u
105 #define MEC5_UART_CFG_RX_FIFO_TRIG_LVL_4 0x10u
106 #define MEC5_UART_CFG_RX_FIFO_TRIG_LVL_8 0x20u
107 #define MEC5_UART_CFG_RX_FIFO_TRIG_LVL_14 0x30u
108 #define MEC5_UART_CFG_WORD_LEN_POS 6
109 #define MEC5_UART_CFG_WORD_LEN_MSK 0xc0u
110 #define MEC5_UART_CFG_WORD_LEN_5 0x00u
111 #define MEC5_UART_CFG_WORD_LEN_6 0x40u
112 #define MEC5_UART_CFG_WORD_LEN_7 0x80u
113 #define MEC5_UART_CFG_WORD_LEN_8 0xc0u
114 #define MEC5_UART_CFG_STOP_BITS_POS 8
115 #define MEC5_UART_CFG_STOP_BITS_MSK 0x100u
116 #define MEC5_UART_CFG_STOP_BITS_1 0
117 #define MEC5_UART_CFG_STOP_BITS_2 0x100u
118 #define MEC5_UART_CFG_PARITY_POS 9
119 #define MEC5_UART_CFG_PARITY_MSK 0xe00u
120 #define MEC5_UART_CFG_PARITY_NONE 0
121 #define MEC5_UART_CFG_PARITY_ODD 0x200u
122 #define MEC5_UART_CFG_PARITY_EVEN 0x300u
123 #define MEC5_UART_CFG_PARITY_MARK 0xa00u
124 #define MEC5_UART_CFG_PARITY_SPACE 0xe00u
125 #define MEC5_UART_CFG_GIRQ_EN_POS 16
126 
127 #define MEC5_UART_MIN_BAUD 50u
128 #define MEC5_UART_MAX_BAUD 3000000u
129 
130 /* BAUD rate = clock_source / (baud_divisor * 16)
131  * default internal clock source = 1.8432 MHz
132  * alternate internal clock source = 48 MHz
133  * external clock source on UART_CLK alternate GPIO function.
134  */
135 
136 /* forward declaration */
137 struct mec_uart_regs;
138 
139 int mec_hal_uart_init(struct mec_uart_regs *base, uint32_t baud_rate,
140                       uint32_t config, uint32_t extclk_hz);
141 
142 int mec_hal_uart_activate(struct mec_uart_regs *regs, uint8_t enable);
143 
144 int mec_hal_uart_power_on(struct mec_uart_regs *regs, uint32_t cfg_flags);
145 
146 int mec_hal_uart_girq_ctrl(struct mec_uart_regs *regs, uint8_t enable);
147 int mec_hal_uart_girq_clear(struct mec_uart_regs *regs);
148 bool mec_hal_uart_is_girq_status(struct mec_uart_regs *regs);
149 bool mec_hal_uart_is_girq_result(struct mec_uart_regs *regs);
150 
151 int mec_hal_uart_clock_freq_get(struct mec_uart_regs *base, uint32_t *clock_freq);
152 
153 int mec_hal_uart_baud_rate_set(struct mec_uart_regs *base, uint32_t baud, uint32_t extclk_hz);
154 
155 int mec_hal_uart_word_len_set(struct mec_uart_regs *base, uint8_t word_len);
156 int mec_hal_uart_word_len_get(struct mec_uart_regs *base, uint8_t *word_len);
157 
158 int mec_hal_uart_stop_bits_set(struct mec_uart_regs *base, uint8_t stop_bits);
159 int mec_hal_uart_stop_bits_get(struct mec_uart_regs *base, uint8_t *stop_bits);
160 
161 int mec_hal_uart_parity_set(struct mec_uart_regs *base, uint8_t parity);
162 int mec_hal_uart_parity_get(struct mec_uart_regs *base, uint8_t *parity);
163 
164 int mec_hal_uart_fifo_control(struct mec_uart_regs *base, uint8_t fifo_cfg);
165 
166 int mec_hal_uart_intr_control(struct mec_uart_regs *base, uint8_t enmask);
167 
168 int mec_hal_uart_intr_mask(struct mec_uart_regs *base, uint8_t msk, uint8_t val);
169 
170 /* Read selected status and return raw value */
171 int mec_hal_uart_raw_status(struct mec_uart_regs *base, enum mec_uart_sts_reg regid,
172                             uint8_t *status);
173 
174 int mec_hal_uart_pending_status(struct mec_uart_regs *base, enum mec_uart_ipend *ipend);
175 
176 int mec_hal_uart_is_rx_data(struct mec_uart_regs *base);
177 
178 int mec_hal_uart_is_tx_fifo_empty(struct mec_uart_regs *base);
179 int mec_hal_uart_is_tx_empty(struct mec_uart_regs *base);
180 
181 int mec_hal_uart_tx_fifo_size(struct mec_uart_regs *base);
182 int mec_hal_uart_rx_fifo_size(struct mec_uart_regs *base);
183 
184 /* 16550 style UART only has TX Holding Register Empty status. There is no
185  * HW mechanism to determine the amount of data in the TX FIFO.
186  * This routine writes a byte to the HW TX buffer if the TX Holding Register
187  * is empty else it returns MEC_RET_ERR_BUSY.
188  */
189 int mec_hal_uart_tx_byte(struct mec_uart_regs *base, uint8_t data);
190 
191 /* blocking */
192 int mec_hal_uart_tx(struct mec_uart_regs *base, const uint8_t *data, size_t datasz);
193 
194 /* If data is available read the data and store in data buffer.
195  * If data present and overrun, parity, or framing error returns MEC_RET_ERR_BAD_DATA
196  * If no data returns MEC_RET_ERR_NO_DATA.
197  * If base or data is bad returns MEC_RET_ERR_INVAL
198  */
199 int mec_hal_uart_rx_byte(struct mec_uart_regs *base, uint8_t *data);
200 
201 /* Modem: set state of DTR or RTS pin */
202 #define MEC_UART_DTR_SELECT 0
203 #define MEC_UART_RTS_SELECT 1
204 
205 int mec_hal_uart_dtr_rts_set(struct mec_uart_regs *base, uint8_t sel_rts,
206                              uint8_t pin_state);
207 
208 void mec_hal_uart_pm_save_disable(void);
209 void mec_hal_uart_pm_restore(void);
210 
211 #ifdef __cplusplus
212 }
213 #endif
214 
215 #endif /* #ifndef _MEC_UART_API_H */
216