1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 *
4 * HDF is dual licensed: you can use it either under the terms of
5 * the GPL, or the BSD license, at your option.
6 * See the LICENSE file in the root of this repository for complete details.
7 */
8
9 #include "uart_pl011_sample.h"
10
UartPl011SetLcrBits(struct UartRegisterMap * regMap,uint32_t bits)11 void UartPl011SetLcrBits(struct UartRegisterMap *regMap, uint32_t bits)
12 {
13 bool uartEnabled = UartPl011IsEnabled(regMap);
14 /* UART must be disabled before UARTLCR_H are reprogrammed */
15 UartPl011Disable(regMap);
16 regMap->lcr |= (bits);
17 /* Restore uart enable state */
18 if (uartEnabled) {
19 UartPl011Enable(regMap);
20 }
21 }
22
UartPl011UpdateLcr(struct UartRegisterMap * regMap)23 void UartPl011UpdateLcr(struct UartRegisterMap *regMap)
24 {
25 bool uartEnabled = UartPl011IsEnabled(regMap);
26 /* UART must be disabled before UARTLCR_H are reprogrammed */
27 UartPl011Disable(regMap);
28 regMap->lcr = regMap->lcr;
29 /* restore uart enable state */
30 if (uartEnabled) {
31 UartPl011Enable(regMap);
32 }
33 }
34
UartPl011SetBaudrate(struct UartRegisterMap * regMap,uint32_t clk,uint32_t baudrate)35 UartPl011Error UartPl011SetBaudrate(struct UartRegisterMap *regMap, uint32_t clk, uint32_t baudrate)
36 {
37 if (baudrate == 0) {
38 return UART_PL011_ERR_INVALID_ARG;
39 }
40
41 uint32_t value = SAMPLING_FACTOR * baudrate;
42 uint32_t divider = clk / value;
43 uint32_t remainder = clk % value;
44 uint32_t fraction;
45 value = (SAMPLING_FACTOR * remainder) / baudrate;
46 fraction = (value >> 1) + (value & 1);
47
48 regMap->ibrd = divider;
49 regMap->fbrd = fraction;
50 /* to internally update the contents of UARTIBRD or
51 * UARTFBRD, a UARTLCR_H write must always be performed at the end.
52 */
53 UartPl011UpdateLcr(regMap);
54 return UART_PL011_ERR_NONE;
55 }
56
UartPl011SetDataFormat(struct UartRegisterMap * regMap,uint32_t wordLen,uint32_t parity,uint32_t stopBits)57 void UartPl011SetDataFormat(
58 struct UartRegisterMap *regMap, uint32_t wordLen, uint32_t parity, uint32_t stopBits)
59 {
60 bool uartEnabled = UartPl011IsEnabled(regMap);
61 uint32_t lcr = regMap->lcr & (~UART_PL011_DATA_FORMAT_MASK);
62 lcr |= wordLen & UART_PL011_LCR_H_WLEN_MASK;
63 lcr |= parity & UART_PL011_LCR_H_PARITY_MASK;
64 lcr |= stopBits & UART_PL011_LCR_H_STOPBIT_MASK;
65 /* UART must be disabled before UARTLCR_H are reprogrammed */
66 UartPl011Disable(regMap);
67 regMap->lcr = lcr;
68 if (uartEnabled) {
69 UartPl011Enable(regMap);
70 }
71 }
72
UartPl011ResetRegisters(struct UartRegisterMap * regMap)73 void UartPl011ResetRegisters(struct UartRegisterMap *regMap)
74 {
75 regMap->cr = UART_PL011_DEFAULT_CTRL_REG_VALUE;
76 regMap->dr = UART_PL011_DEFAULT_DATA_REG_VALUE;
77 /* Clear all the errors */
78 regMap->ecr = UART_PL011_DEFAULT_ECR_VALUE;
79 regMap->ilpr = UART_PL011_DEFAULT_ILPR_VALUE;
80 regMap->ibrd = UART_PL011_DEFAULT_IBRD_REG_VALUE;
81 regMap->fbrd = UART_PL011_DEFAULT_FBRD_REG_VALUE;
82 regMap->lcr = UART_PL011_DEFAULT_LCR_H_VALUE;
83 regMap->ifls = UART_PL011_DEFAULT_IFLS_REG_VALUE;
84 /* Clear all interrupt mask */
85 regMap->imsc = UART_PL011_DEFAULT_IMSC_REG_VALUE;
86 /* Clear all interrupts */
87 regMap->icr = UART_PL011_DEFAULT_ICR_VALUE;
88 regMap->dmacr = UART_PL011_DEFAULT_DMACR_VALUE;
89 }
90
91