• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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