1 #include "bflb_uart.h"
2 #include "bflb_clock.h"
3 #include "hardware/uart_reg.h"
4
bflb_uart_init(struct bflb_device_s * dev,const struct bflb_uart_config_s * config)5 void bflb_uart_init(struct bflb_device_s *dev, const struct bflb_uart_config_s *config)
6 {
7 uint32_t div = 0;
8 uint32_t tx_cfg;
9 uint32_t rx_cfg;
10 uint32_t reg_base;
11 uint32_t regval;
12
13 reg_base = dev->reg_base;
14 /* Cal the baud rate divisor */
15 div = (bflb_clk_get_peripheral_clock(BFLB_DEVICE_TYPE_UART, dev->idx) * 10 / config->baudrate + 5) / 10;
16
17 tx_cfg = getreg32(reg_base + UART_UTX_CONFIG_OFFSET);
18 rx_cfg = getreg32(reg_base + UART_URX_CONFIG_OFFSET);
19 tx_cfg &= ~UART_CR_UTX_EN;
20 rx_cfg &= ~UART_CR_URX_EN;
21 putreg32(tx_cfg, reg_base + UART_UTX_CONFIG_OFFSET);
22 putreg32(rx_cfg, reg_base + UART_URX_CONFIG_OFFSET);
23
24 putreg32(((div - 1) << 0x10) | ((div - 1) & 0xFFFF), reg_base + UART_BIT_PRD_OFFSET);
25
26 /* configure parity type */
27
28 tx_cfg = getreg32(reg_base + UART_UTX_CONFIG_OFFSET);
29 rx_cfg = getreg32(reg_base + UART_URX_CONFIG_OFFSET);
30
31 switch (config->parity) {
32 case UART_PARITY_NONE:
33 tx_cfg &= ~UART_CR_UTX_PRT_EN;
34 rx_cfg &= ~UART_CR_URX_PRT_EN;
35 break;
36 case UART_PARITY_ODD:
37 tx_cfg |= UART_CR_UTX_PRT_EN;
38 tx_cfg |= UART_CR_UTX_PRT_SEL;
39 rx_cfg |= UART_CR_URX_PRT_EN;
40 rx_cfg |= UART_CR_URX_PRT_SEL;
41 break;
42 case UART_PARITY_EVEN:
43 tx_cfg |= UART_CR_UTX_PRT_EN;
44 tx_cfg &= ~UART_CR_UTX_PRT_SEL;
45 rx_cfg |= UART_CR_URX_PRT_EN;
46 rx_cfg &= ~UART_CR_URX_PRT_SEL;
47 break;
48 default:
49 break;
50 }
51
52 /* Configure data bits */
53 tx_cfg &= ~UART_CR_UTX_BIT_CNT_D_MASK;
54 tx_cfg |= (config->data_bits + 4) << UART_CR_UTX_BIT_CNT_D_SHIFT;
55 rx_cfg &= ~UART_CR_URX_BIT_CNT_D_MASK;
56 rx_cfg |= (config->data_bits + 4) << UART_CR_URX_BIT_CNT_D_SHIFT;
57
58 /* Configure tx stop bits */
59 tx_cfg &= ~UART_CR_UTX_BIT_CNT_P_MASK;
60 tx_cfg |= config->stop_bits << UART_CR_UTX_BIT_CNT_P_SHIFT;
61
62 /* Configure tx cts flow control function */
63 if (config->flow_ctrl & UART_FLOWCTRL_CTS) {
64 tx_cfg |= UART_CR_UTX_CTS_EN;
65 } else {
66 tx_cfg &= ~UART_CR_UTX_CTS_EN;
67 }
68
69 rx_cfg &= ~UART_CR_URX_DEG_EN;
70
71 /* Write back */
72 putreg32(tx_cfg, reg_base + UART_UTX_CONFIG_OFFSET);
73 putreg32(rx_cfg, reg_base + UART_URX_CONFIG_OFFSET);
74 #if defined(BL602)
75 regval = getreg32(reg_base + UART_URX_CONFIG_OFFSET);
76 regval &= ~UART_CR_URX_RTS_SW_MODE;
77 putreg32(regval, reg_base + UART_URX_CONFIG_OFFSET);
78
79 #else
80 regval = getreg32(reg_base + UART_SW_MODE_OFFSET);
81 regval &= ~UART_CR_URX_RTS_SW_MODE;
82 putreg32(regval, reg_base + UART_SW_MODE_OFFSET);
83 #endif
84 regval = getreg32(reg_base + UART_DATA_CONFIG_OFFSET);
85 regval &= ~UART_CR_UART_BIT_INV;
86 putreg32(regval, reg_base + UART_DATA_CONFIG_OFFSET);
87
88 /* Enable tx free run mode */
89 regval = getreg32(reg_base + UART_UTX_CONFIG_OFFSET);
90 regval |= UART_CR_UTX_FRM_EN;
91 putreg32(regval, reg_base + UART_UTX_CONFIG_OFFSET);
92
93 /* Configure FIFO thresholds */
94 regval = getreg32(reg_base + UART_FIFO_CONFIG_1_OFFSET);
95 regval &= ~UART_TX_FIFO_TH_MASK;
96 regval &= ~UART_RX_FIFO_TH_MASK;
97 regval |= (config->tx_fifo_threshold << UART_TX_FIFO_TH_SHIFT) & UART_TX_FIFO_TH_MASK;
98 regval |= (config->rx_fifo_threshold << UART_RX_FIFO_TH_SHIFT) & UART_RX_FIFO_TH_MASK;
99 putreg32(regval, reg_base + UART_FIFO_CONFIG_1_OFFSET);
100
101 /* Clear FIFO */
102 regval = getreg32(reg_base + UART_FIFO_CONFIG_0_OFFSET);
103 regval |= UART_TX_FIFO_CLR;
104 regval |= UART_RX_FIFO_CLR;
105 regval &= ~UART_DMA_TX_EN;
106 regval &= ~UART_DMA_RX_EN;
107 putreg32(regval, reg_base + UART_FIFO_CONFIG_0_OFFSET);
108
109 putreg32(0xFFFFFFFF, reg_base + UART_INT_MASK_OFFSET);
110
111 /* Enable UART tx rx unit */
112 tx_cfg = getreg32(reg_base + UART_UTX_CONFIG_OFFSET);
113 rx_cfg = getreg32(reg_base + UART_URX_CONFIG_OFFSET);
114 tx_cfg |= UART_CR_UTX_EN;
115 rx_cfg |= UART_CR_URX_EN;
116 putreg32(tx_cfg, reg_base + UART_UTX_CONFIG_OFFSET);
117 putreg32(rx_cfg, reg_base + UART_URX_CONFIG_OFFSET);
118 }
119
bflb_uart_deinit(struct bflb_device_s * dev)120 void bflb_uart_deinit(struct bflb_device_s *dev)
121 {
122 uint32_t reg_base;
123 uint32_t tx_cfg;
124 uint32_t rx_cfg;
125
126 reg_base = dev->reg_base;
127 tx_cfg = getreg32(reg_base + UART_UTX_CONFIG_OFFSET);
128 rx_cfg = getreg32(reg_base + UART_URX_CONFIG_OFFSET);
129 tx_cfg &= ~UART_CR_UTX_EN;
130 rx_cfg &= ~UART_CR_URX_EN;
131 putreg32(tx_cfg, reg_base + UART_UTX_CONFIG_OFFSET);
132 putreg32(rx_cfg, reg_base + UART_URX_CONFIG_OFFSET);
133 }
134
bflb_uart_enable(struct bflb_device_s * dev)135 void bflb_uart_enable(struct bflb_device_s *dev)
136 {
137 uint32_t reg_base;
138 uint32_t tx_cfg;
139 uint32_t rx_cfg;
140
141 reg_base = dev->reg_base;
142 tx_cfg = getreg32(reg_base + UART_UTX_CONFIG_OFFSET);
143 rx_cfg = getreg32(reg_base + UART_URX_CONFIG_OFFSET);
144 tx_cfg |= UART_CR_UTX_EN;
145 rx_cfg |= UART_CR_URX_EN;
146 putreg32(tx_cfg, reg_base + UART_UTX_CONFIG_OFFSET);
147 putreg32(rx_cfg, reg_base + UART_URX_CONFIG_OFFSET);
148 }
149
bflb_uart_disable(struct bflb_device_s * dev)150 void bflb_uart_disable(struct bflb_device_s *dev)
151 {
152 uint32_t reg_base;
153 uint32_t tx_cfg;
154 uint32_t rx_cfg;
155
156 reg_base = dev->reg_base;
157 tx_cfg = getreg32(reg_base + UART_UTX_CONFIG_OFFSET);
158 rx_cfg = getreg32(reg_base + UART_URX_CONFIG_OFFSET);
159 tx_cfg &= ~UART_CR_UTX_EN;
160 rx_cfg &= ~UART_CR_URX_EN;
161 putreg32(tx_cfg, reg_base + UART_UTX_CONFIG_OFFSET);
162 putreg32(rx_cfg, reg_base + UART_URX_CONFIG_OFFSET);
163 }
164
bflb_uart_link_txdma(struct bflb_device_s * dev,bool enable)165 void bflb_uart_link_txdma(struct bflb_device_s *dev, bool enable)
166 {
167 uint32_t reg_base;
168 uint32_t regval;
169
170 reg_base = dev->reg_base;
171 regval = getreg32(reg_base + UART_FIFO_CONFIG_0_OFFSET);
172 if (enable) {
173 regval |= UART_DMA_TX_EN;
174 } else {
175 regval &= ~UART_DMA_TX_EN;
176 }
177 putreg32(regval, reg_base + UART_FIFO_CONFIG_0_OFFSET);
178 }
179
bflb_uart_link_rxdma(struct bflb_device_s * dev,bool enable)180 void bflb_uart_link_rxdma(struct bflb_device_s *dev, bool enable)
181 {
182 uint32_t reg_base;
183 uint32_t regval;
184
185 reg_base = dev->reg_base;
186 regval = getreg32(reg_base + UART_FIFO_CONFIG_0_OFFSET);
187 if (enable) {
188 regval |= UART_DMA_RX_EN;
189 } else {
190 regval &= ~UART_DMA_RX_EN;
191 }
192 putreg32(regval, reg_base + UART_FIFO_CONFIG_0_OFFSET);
193 }
194
bflb_uart_putchar(struct bflb_device_s * dev,int ch)195 ATTR_TCM_SECTION int bflb_uart_putchar(struct bflb_device_s *dev, int ch)
196 {
197 uint64_t start_time;
198 uint32_t reg_base;
199
200 reg_base = dev->reg_base;
201 // start_time = bflb_mtimer_get_time_ms();
202 while ((getreg32(reg_base + UART_FIFO_CONFIG_1_OFFSET) & UART_TX_FIFO_CNT_MASK) == 0) {
203 // if ((bflb_mtimer_get_time_ms() - start_time) > 100) {
204 // return -ETIMEDOUT;
205 // }
206 }
207 putreg8(ch, reg_base + UART_FIFO_WDATA_OFFSET);
208 return 0;
209 }
210
bflb_uart_getchar(struct bflb_device_s * dev)211 ATTR_TCM_SECTION int bflb_uart_getchar(struct bflb_device_s *dev)
212 {
213 int ch = -1;
214 uint32_t reg_base;
215
216 reg_base = dev->reg_base;
217 if ((getreg32(reg_base + UART_FIFO_CONFIG_1_OFFSET) & UART_RX_FIFO_CNT_MASK) != 0) {
218 ch = getreg8(reg_base + UART_FIFO_RDATA_OFFSET);
219 }
220
221 return ch;
222 }
223
bflb_uart_put(struct bflb_device_s * dev,uint8_t * data,uint32_t len)224 ATTR_TCM_SECTION int bflb_uart_put(struct bflb_device_s *dev, uint8_t *data, uint32_t len)
225 {
226 int ret;
227 for (uint32_t i = 0; i < len; i++) {
228 ret = bflb_uart_putchar(dev, data[i]);
229 if (ret < 0) {
230 return ret;
231 }
232 }
233 return 0;
234 }
235
bflb_uart_get(struct bflb_device_s * dev,uint8_t * data,uint32_t len)236 ATTR_TCM_SECTION int bflb_uart_get(struct bflb_device_s *dev, uint8_t *data, uint32_t len)
237 {
238 int ch = -1;
239 uint32_t count = 0;
240
241 while (count < len) {
242 if ((ch = bflb_uart_getchar(dev)) < 0) {
243 break;
244 }
245 data[count] = ch;
246 count++;
247 }
248 return count;
249 }
250
bflb_uart_txready(struct bflb_device_s * dev)251 bool bflb_uart_txready(struct bflb_device_s *dev)
252 {
253 uint32_t reg_base;
254
255 reg_base = dev->reg_base;
256 if ((getreg32(reg_base + UART_FIFO_CONFIG_1_OFFSET) & UART_TX_FIFO_CNT_MASK) != 0) {
257 return true;
258 } else {
259 return false;
260 }
261 }
262
bflb_uart_txempty(struct bflb_device_s * dev)263 bool bflb_uart_txempty(struct bflb_device_s *dev)
264 {
265 uint32_t reg_base;
266
267 reg_base = dev->reg_base;
268 if ((getreg32(reg_base + UART_FIFO_CONFIG_1_OFFSET) & UART_TX_FIFO_CNT_MASK) == (UART_TX_FIFO_CNT_MASK >> 1) + 1) {
269 return true;
270 } else {
271 return false;
272 }
273 }
274
bflb_uart_rxavailable(struct bflb_device_s * dev)275 bool bflb_uart_rxavailable(struct bflb_device_s *dev)
276 {
277 uint32_t reg_base;
278
279 reg_base = dev->reg_base;
280 return ((getreg32(reg_base + UART_FIFO_CONFIG_1_OFFSET) & UART_RX_FIFO_CNT_MASK) != 0);
281 }
282
bflb_uart_txint_mask(struct bflb_device_s * dev,bool mask)283 void bflb_uart_txint_mask(struct bflb_device_s *dev, bool mask)
284 {
285 uint32_t reg_base;
286 uint32_t int_mask;
287
288 reg_base = dev->reg_base;
289 int_mask = getreg32(reg_base + UART_INT_MASK_OFFSET);
290 if (mask) {
291 int_mask |= UART_CR_UTX_FIFO_MASK;
292 } else {
293 int_mask &= ~UART_CR_UTX_FIFO_MASK;
294 }
295 putreg32(int_mask, reg_base + UART_INT_MASK_OFFSET);
296 }
297
bflb_uart_rxint_mask(struct bflb_device_s * dev,bool mask)298 void bflb_uart_rxint_mask(struct bflb_device_s *dev, bool mask)
299 {
300 uint32_t reg_base;
301 uint32_t int_mask;
302
303 reg_base = dev->reg_base;
304 int_mask = getreg32(reg_base + UART_INT_MASK_OFFSET);
305 if (mask) {
306 int_mask |= UART_CR_URX_FIFO_MASK;
307 int_mask |= UART_CR_URX_RTO_MASK;
308 } else {
309 int_mask &= ~UART_CR_URX_FIFO_MASK;
310 int_mask &= ~UART_CR_URX_RTO_MASK;
311 }
312 putreg32(int_mask, reg_base + UART_INT_MASK_OFFSET);
313 }
314
bflb_uart_errint_mask(struct bflb_device_s * dev,bool mask)315 void bflb_uart_errint_mask(struct bflb_device_s *dev, bool mask)
316 {
317 uint32_t reg_base;
318 uint32_t int_mask;
319
320 reg_base = dev->reg_base;
321 int_mask = getreg32(reg_base + UART_INT_MASK_OFFSET);
322 if (mask) {
323 int_mask |= UART_CR_URX_PCE_MASK;
324 int_mask |= UART_CR_UTX_FER_MASK;
325 int_mask |= UART_CR_URX_FER_MASK;
326 #if !defined(BL602)
327 int_mask |= UART_CR_URX_LSE_MASK;
328 #endif
329 } else {
330 int_mask &= ~UART_CR_URX_PCE_MASK;
331 int_mask &= ~UART_CR_UTX_FER_MASK;
332 int_mask &= ~UART_CR_URX_FER_MASK;
333 #if !defined(BL602)
334 int_mask &= ~UART_CR_URX_LSE_MASK;
335 #endif
336 }
337 putreg32(int_mask, reg_base + UART_INT_MASK_OFFSET);
338 }
339
bflb_uart_get_intstatus(struct bflb_device_s * dev)340 uint32_t bflb_uart_get_intstatus(struct bflb_device_s *dev)
341 {
342 uint32_t reg_base;
343 uint32_t int_status;
344 uint32_t int_mask;
345
346 reg_base = dev->reg_base;
347 int_status = getreg32(reg_base + UART_INT_STS_OFFSET);
348 int_mask = getreg32(reg_base + UART_INT_MASK_OFFSET);
349 return (int_status & ~int_mask);
350 }
351
bflb_uart_int_clear(struct bflb_device_s * dev,uint32_t int_clear)352 void bflb_uart_int_clear(struct bflb_device_s *dev, uint32_t int_clear)
353 {
354 uint32_t reg_base;
355
356 reg_base = dev->reg_base;
357 putreg32(int_clear, reg_base + UART_INT_CLEAR_OFFSET);
358 }
359
bflb_uart_feature_control(struct bflb_device_s * dev,int cmd,size_t arg)360 int bflb_uart_feature_control(struct bflb_device_s *dev, int cmd, size_t arg)
361 {
362 int ret = 0;
363 uint32_t reg_base;
364 uint32_t tmp;
365 uint32_t tx_tmp;
366 uint32_t rx_tmp;
367 uint32_t int_mask;
368
369 reg_base = dev->reg_base;
370
371 switch (cmd) {
372 case UART_CMD_SET_BAUD_RATE:
373 /* Cal the baud rate divisor */
374 tmp = (bflb_clk_get_peripheral_clock(BFLB_DEVICE_TYPE_UART, dev->idx) * 10 / arg + 5) / 10;
375
376 putreg32(((tmp - 1) << 0x10) | ((tmp - 1) & 0xFFFF), reg_base + UART_BIT_PRD_OFFSET);
377 break;
378
379 case UART_CMD_SET_DATA_BITS:
380 /* Set data bits */
381 tx_tmp = getreg32(reg_base + UART_UTX_CONFIG_OFFSET);
382 rx_tmp = getreg32(reg_base + UART_URX_CONFIG_OFFSET);
383
384 tx_tmp &= ~UART_CR_UTX_BIT_CNT_D_MASK;
385 tx_tmp |= (arg + 4) << UART_CR_UTX_BIT_CNT_D_SHIFT;
386
387 rx_tmp &= ~UART_CR_URX_BIT_CNT_D_MASK;
388 rx_tmp |= (arg + 4) << UART_CR_URX_BIT_CNT_D_SHIFT;
389
390 putreg32(tx_tmp, reg_base + UART_UTX_CONFIG_OFFSET);
391 putreg32(rx_tmp, reg_base + UART_URX_CONFIG_OFFSET);
392 break;
393
394 case UART_CMD_SET_STOP_BITS:
395 /* Set stop bits */
396 tx_tmp = getreg32(reg_base + UART_UTX_CONFIG_OFFSET);
397
398 tx_tmp &= ~UART_CR_UTX_BIT_CNT_P_MASK;
399 tx_tmp |= arg << UART_CR_UTX_BIT_CNT_P_SHIFT;
400
401 putreg32(tx_tmp, reg_base + UART_UTX_CONFIG_OFFSET);
402 break;
403
404 case UART_CMD_SET_PARITY_BITS:
405 /* Set parity mode */
406 tx_tmp = getreg32(reg_base + UART_UTX_CONFIG_OFFSET);
407 rx_tmp = getreg32(reg_base + UART_URX_CONFIG_OFFSET);
408
409 if (arg == UART_PARITY_NONE) {
410 tx_tmp &= ~UART_CR_UTX_PRT_EN;
411 rx_tmp &= ~UART_CR_URX_PRT_EN;
412 } else if (arg == UART_PARITY_ODD) {
413 tx_tmp |= UART_CR_UTX_PRT_EN;
414 tx_tmp |= UART_CR_UTX_PRT_SEL;
415 rx_tmp |= UART_CR_URX_PRT_EN;
416 rx_tmp |= UART_CR_URX_PRT_SEL;
417 } else if (arg == UART_PARITY_EVEN) {
418 tx_tmp |= UART_CR_UTX_PRT_EN;
419 tx_tmp &= ~UART_CR_UTX_PRT_SEL;
420 rx_tmp |= UART_CR_URX_PRT_EN;
421 rx_tmp &= ~UART_CR_URX_PRT_SEL;
422 }
423
424 putreg32(tx_tmp, reg_base + UART_UTX_CONFIG_OFFSET);
425 putreg32(rx_tmp, reg_base + UART_URX_CONFIG_OFFSET);
426 break;
427
428 case UART_CMD_CLR_TX_FIFO:
429 /* Clear tx fifo */
430 tmp = getreg32(reg_base + UART_FIFO_CONFIG_0_OFFSET);
431 tmp |= UART_TX_FIFO_CLR;
432 putreg32(tmp, reg_base + UART_FIFO_CONFIG_0_OFFSET);
433 break;
434
435 case UART_CMD_CLR_RX_FIFO:
436 /* Clear rx fifo */
437 tmp = getreg32(reg_base + UART_FIFO_CONFIG_0_OFFSET);
438 tmp |= UART_RX_FIFO_CLR;
439 putreg32(tmp, reg_base + UART_FIFO_CONFIG_0_OFFSET);
440 break;
441
442 case UART_CMD_SET_RTO_VALUE:
443 /* Set rx time-out value */
444 putreg32(arg, reg_base + UART_URX_RTO_TIMER_OFFSET);
445 break;
446
447 case UART_CMD_SET_RTS_VALUE:
448 #if defined(BL602)
449 #else
450 /* Set rx rts output software control value */
451 tmp = getreg32(reg_base + UART_SW_MODE_OFFSET);
452 tmp &= ~UART_CR_URX_RTS_SW_VAL;
453 if (arg) {
454 tmp |= UART_CR_URX_RTS_SW_VAL;
455 }
456 putreg32(tmp, reg_base + UART_SW_MODE_OFFSET);
457 #endif
458 break;
459
460 case UART_CMD_GET_TX_FIFO_CNT:
461 /* Get tx fifo count */
462 return (getreg32(reg_base + UART_FIFO_CONFIG_1_OFFSET) & UART_TX_FIFO_CNT_MASK) >> UART_TX_FIFO_CNT_SHIFT;
463
464 case UART_CMD_GET_RX_FIFO_CNT:
465 /* Get rx fifo count */
466 return (getreg32(reg_base + UART_FIFO_CONFIG_1_OFFSET) & UART_RX_FIFO_CNT_MASK) >> UART_RX_FIFO_CNT_SHIFT;
467
468 case UART_CMD_SET_AUTO_BAUD:
469 /* Set auto baudrate detection */
470 tmp = getreg32(reg_base + UART_URX_CONFIG_OFFSET);
471 rx_tmp = getreg32(reg_base + UART_INT_MASK_OFFSET);
472 tmp &= ~UART_CR_URX_ABR_EN;
473 if (arg == UART_AUTO_BAUD_0X55) {
474 tmp |= UART_CR_URX_ABR_EN;
475 #if !defined(BL602) && !defined(BL702)
476 rx_tmp &= ~UART_CR_URX_AD5_MASK;
477 #endif
478 } else {
479 tmp |= UART_CR_URX_ABR_EN;
480 #if !defined(BL602) && !defined(BL702)
481 rx_tmp &= ~UART_CR_URX_ADS_MASK;
482 #endif
483 }
484
485 putreg32(tmp, reg_base + UART_URX_CONFIG_OFFSET);
486 putreg32(rx_tmp, reg_base + UART_INT_MASK_OFFSET);
487 break;
488
489 case UART_CMD_GET_AUTO_BAUD:
490 /* Get auto baudrate detection count value */
491 tmp = getreg32(reg_base + UART_STS_URX_ABR_PRD_OFFSET);
492 if (arg == UART_AUTO_BAUD_START) {
493 return (tmp & UART_STS_URX_ABR_PRD_START_MASK);
494 } else {
495 return ((tmp & UART_STS_URX_ABR_PRD_0X55_MASK) >> UART_STS_URX_ABR_PRD_0X55_SHIFT);
496 }
497 #if !defined(BL602)
498 case UART_CMD_SET_BREAK_VALUE:
499 /* Set lin mode break value */
500 tx_tmp = getreg32(reg_base + UART_UTX_CONFIG_OFFSET);
501
502 tx_tmp &= ~UART_CR_UTX_BIT_CNT_B_MASK;
503 tx_tmp |= arg << UART_CR_UTX_BIT_CNT_B_SHIFT;
504
505 putreg32(tx_tmp, reg_base + UART_UTX_CONFIG_OFFSET);
506 break;
507
508 case UART_CMD_SET_TX_LIN_VALUE:
509 /* Set tx lin mode */
510 tx_tmp = getreg32(reg_base + UART_UTX_CONFIG_OFFSET);
511 tx_tmp &= ~UART_CR_UTX_LIN_EN;
512 if (arg) {
513 tx_tmp |= UART_CR_UTX_LIN_EN;
514 }
515
516 putreg32(tx_tmp, reg_base + UART_UTX_CONFIG_OFFSET);
517 break;
518
519 case UART_CMD_SET_RX_LIN_VALUE:
520 /* Set rx lin mode */
521 rx_tmp = getreg32(reg_base + UART_URX_CONFIG_OFFSET);
522 rx_tmp &= ~UART_CR_URX_LIN_EN;
523 if (arg) {
524 rx_tmp |= UART_CR_URX_LIN_EN;
525 }
526
527 putreg32(rx_tmp, reg_base + UART_URX_CONFIG_OFFSET);
528 break;
529 #endif
530 case UART_CMD_SET_GLITCH_VALUE:
531 rx_tmp = getreg32(reg_base + UART_URX_CONFIG_OFFSET);
532 rx_tmp &= ~UART_CR_URX_DEG_CNT_MASK;
533 rx_tmp &= ~UART_CR_URX_DEG_EN;
534 if (arg) {
535 rx_tmp |= (arg << UART_CR_URX_DEG_CNT_SHIFT) & UART_CR_URX_DEG_CNT_MASK;
536 rx_tmp |= UART_CR_URX_DEG_EN;
537 }
538 putreg32(rx_tmp, reg_base + UART_URX_CONFIG_OFFSET);
539 break;
540 #if !defined(BL602) && !defined(BL702)
541 case UART_CMD_SET_TX_RS485_EN:
542 /* Set tx rs485 transceiver enable */
543 tx_tmp = getreg32(reg_base + UART_UTX_RS485_CFG_OFFSET);
544 tx_tmp &= ~UART_CR_UTX_RS485_EN;
545
546 if (arg) {
547 tx_tmp |= UART_CR_UTX_RS485_EN;
548 }
549
550 putreg32(tx_tmp, reg_base + UART_UTX_RS485_CFG_OFFSET);
551 break;
552
553 case UART_CMD_SET_TX_RS485_POLARITY:
554 /* Set tx rs485 de pin polarity */
555 tx_tmp = getreg32(reg_base + UART_UTX_RS485_CFG_OFFSET);
556 tx_tmp &= ~UART_CR_UTX_RS485_POL;
557
558 if (arg) {
559 tx_tmp |= UART_CR_UTX_RS485_POL;
560 }
561
562 putreg32(tx_tmp, reg_base + UART_UTX_RS485_CFG_OFFSET);
563 break;
564
565 case UART_CMD_SET_ABR_ALLOWABLE_ERROR:
566 /* Set auto baudrate detection mode pulse-width tolerance value for codeword 0x55 */
567 rx_tmp = getreg32(reg_base + UART_URX_ABR_PW_TOL_OFFSET);
568 rx_tmp &= ~UART_CR_URX_ABR_PW_TOL_MASK;
569 rx_tmp |= arg << UART_CR_URX_ABR_PW_TOL_SHIFT;
570
571 putreg32(rx_tmp, reg_base + UART_URX_ABR_PW_TOL_OFFSET);
572 break;
573 #endif
574 case UART_CMD_SET_SW_RTS_CONTROL:
575 #if defined(BL602)
576 if (arg) {
577 rx_tmp = getreg32(reg_base + UART_URX_CONFIG_OFFSET);
578 rx_tmp |= UART_CR_URX_RTS_SW_MODE;
579 putreg32(rx_tmp, reg_base + UART_URX_CONFIG_OFFSET);
580 } else {
581 rx_tmp = getreg32(reg_base + UART_URX_CONFIG_OFFSET);
582 rx_tmp &= ~UART_CR_URX_RTS_SW_MODE;
583 putreg32(rx_tmp, reg_base + UART_URX_CONFIG_OFFSET);
584 }
585 #else
586 if (arg) {
587 rx_tmp = getreg32(reg_base + UART_SW_MODE_OFFSET);
588 rx_tmp |= UART_CR_URX_RTS_SW_MODE;
589 putreg32(rx_tmp, reg_base + UART_SW_MODE_OFFSET);
590
591 } else {
592 rx_tmp = getreg32(reg_base + UART_SW_MODE_OFFSET);
593 rx_tmp &= ~UART_CR_URX_RTS_SW_MODE;
594 putreg32(rx_tmp, reg_base + UART_SW_MODE_OFFSET);
595 }
596 #endif
597 break;
598 #if !defined(BL702L)
599 case UART_CMD_IR_CONFIG: {
600 struct bflb_uart_ir_config_s *ir_config = (struct bflb_uart_ir_config_s *)arg;
601 tx_tmp = getreg32(reg_base + UART_UTX_CONFIG_OFFSET);
602 if (ir_config->tx_en) {
603 tx_tmp |= UART_CR_UTX_IR_EN;
604 } else {
605 tx_tmp &= ~UART_CR_UTX_IR_EN;
606 }
607 if (ir_config->tx_inverse) {
608 tx_tmp |= UART_CR_UTX_IR_INV;
609 } else {
610 tx_tmp &= ~UART_CR_UTX_IR_INV;
611 }
612 putreg32(tx_tmp, reg_base + UART_UTX_CONFIG_OFFSET);
613
614 rx_tmp = getreg32(reg_base + UART_URX_CONFIG_OFFSET);
615 if (ir_config->rx_en) {
616 rx_tmp |= UART_CR_URX_IR_EN;
617 } else {
618 rx_tmp &= ~UART_CR_URX_IR_EN;
619 }
620 if (ir_config->rx_inverse) {
621 rx_tmp |= UART_CR_URX_IR_INV;
622 } else {
623 rx_tmp &= ~UART_CR_URX_IR_INV;
624 }
625 putreg32(rx_tmp, reg_base + UART_URX_CONFIG_OFFSET);
626 /* Configure tx ir pulse start and stop position */
627 putreg32((ir_config->tx_pluse_stop << 16) | ir_config->tx_pluse_start, reg_base + UART_UTX_IR_POSITION_OFFSET);
628 /* Configure rx ir pulse start position */
629 putreg32(ir_config->rx_pluse_start, reg_base + UART_URX_IR_POSITION_OFFSET);
630 } break;
631 #endif
632 case UART_CMD_SET_TX_FREERUN:
633 /* Set tx freerun */
634 tx_tmp = getreg32(reg_base + UART_UTX_CONFIG_OFFSET);
635
636 if (arg) {
637 tx_tmp |= UART_CR_UTX_FRM_EN;
638 } else {
639 tx_tmp &= ~UART_CR_UTX_FRM_EN;
640 }
641
642 putreg32(tx_tmp, reg_base + UART_UTX_CONFIG_OFFSET);
643 break;
644 case UART_CMD_SET_TX_END_INTERRUPT:
645 /* Set tx end interrupt */
646 int_mask = getreg32(reg_base + UART_INT_MASK_OFFSET);
647 if (arg) {
648 int_mask &= ~UART_CR_UTX_END_MASK;
649 } else {
650 int_mask |= UART_CR_UTX_END_MASK;
651 }
652 putreg32(int_mask, reg_base + UART_INT_MASK_OFFSET);
653 break;
654 case UART_CMD_SET_RX_END_INTERRUPT:
655 /* Set rx end interrupt */
656 int_mask = getreg32(reg_base + UART_INT_MASK_OFFSET);
657 if (arg) {
658 int_mask &= ~UART_CR_URX_END_MASK;
659 } else {
660 int_mask |= UART_CR_URX_END_MASK;
661 }
662 putreg32(int_mask, reg_base + UART_INT_MASK_OFFSET);
663 break;
664 case UART_CMD_SET_TX_TRANSFER_LEN:
665 /* Set tx transfer length */
666 tx_tmp = getreg32(reg_base + UART_UTX_CONFIG_OFFSET);
667 tx_tmp &= ~UART_CR_UTX_LEN_MASK;
668 tx_tmp |= ((arg - 1) << UART_CR_UTX_LEN_SHIFT);
669 putreg32(tx_tmp, reg_base + UART_UTX_CONFIG_OFFSET);
670 break;
671 case UART_CMD_SET_RX_TRANSFER_LEN:
672 /* Set rx transfer length */
673 rx_tmp = getreg32(reg_base + UART_URX_CONFIG_OFFSET);
674 rx_tmp &= ~UART_CR_URX_LEN_MASK;
675 rx_tmp |= ((arg - 1) << UART_CR_URX_LEN_SHIFT);
676 putreg32(rx_tmp, reg_base + UART_URX_CONFIG_OFFSET);
677 break;
678 case UART_CMD_SET_TX_EN:
679 /* Set tx enable */
680 tx_tmp = getreg32(reg_base + UART_UTX_CONFIG_OFFSET);
681
682 if (arg) {
683 tx_tmp |= UART_CR_UTX_EN;
684 } else {
685 tx_tmp &= ~UART_CR_UTX_EN;
686 }
687
688 putreg32(tx_tmp, reg_base + UART_UTX_CONFIG_OFFSET);
689 break;
690 #if !defined(BL602) && !defined(BL702)
691 case UART_CMD_SET_BCR_END_INTERRUPT:
692 /* Set bcr value */
693 int_mask = getreg32(reg_base + UART_INT_MASK_OFFSET);
694 int_mask &= ~UART_CR_URX_BCR_MASK;
695 putreg32(int_mask, reg_base + UART_INT_MASK_OFFSET);
696
697 rx_tmp = getreg32(reg_base + UART_URX_BCR_INT_CFG_OFFSET);
698 rx_tmp &= ~UART_CR_URX_BCR_VALUE_MASK;
699 rx_tmp |= (arg << UART_CR_URX_BCR_VALUE_SHIFT);
700 putreg32(rx_tmp, reg_base + UART_URX_BCR_INT_CFG_OFFSET);
701 break;
702 case UART_CMD_GET_BCR_COUNT:
703 /* Get bcr value */
704 rx_tmp = getreg32(reg_base + UART_URX_BCR_INT_CFG_OFFSET);
705 return ((rx_tmp & UART_STS_URX_BCR_COUNT_MASK) >> UART_STS_URX_BCR_COUNT_SHIFT);
706 break;
707 #endif
708 case UART_CMD_SET_CTS_EN:
709 tx_tmp = getreg32(reg_base + UART_UTX_CONFIG_OFFSET);
710 if (arg) {
711 tx_tmp |= UART_CR_UTX_CTS_EN;
712 } else {
713 tx_tmp &= ~UART_CR_UTX_CTS_EN;
714 }
715 putreg32(tx_tmp, reg_base + UART_UTX_CONFIG_OFFSET);
716 case UART_CMD_SET_TX_FIFO_THREHOLD:
717 tx_tmp = getreg32(reg_base + UART_FIFO_CONFIG_1_OFFSET);
718 tx_tmp &= ~UART_TX_FIFO_TH_MASK;
719 tx_tmp |= (arg << UART_TX_FIFO_TH_SHIFT) & UART_TX_FIFO_TH_MASK;
720 putreg32(tx_tmp, reg_base + UART_FIFO_CONFIG_1_OFFSET);
721 case UART_CMD_SET_RX_FIFO_THREHOLD:
722 rx_tmp = getreg32(reg_base + UART_FIFO_CONFIG_1_OFFSET);
723 rx_tmp &= ~UART_RX_FIFO_TH_MASK;
724 rx_tmp |= (arg << UART_RX_FIFO_TH_SHIFT) & UART_RX_FIFO_TH_MASK;
725 putreg32(rx_tmp, reg_base + UART_FIFO_CONFIG_1_OFFSET);
726 default:
727 ret = -EPERM;
728 break;
729 }
730 return ret;
731 }
732