1 /* 2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef UART_PL011_H 17 #define UART_PL011_H 18 19 #include "console.h" 20 #include "poll.h" 21 #include "uart_if.h" 22 23 #ifdef __cplusplus 24 #if __cplusplus 25 extern "C" { 26 #endif /* __cplusplus */ 27 #endif /* __cplusplus */ 28 29 #define DEFAULT_UART0_BAUDRATE 115200 30 #define DEFAULT_UART1_BAUDRATE 9600 31 #define DEFAULT_UART2_BAUDRATE 115200 32 #define DEFAULT_UART3_BAUDRATE 9600 33 #define DEFAULT_UART4_BAUDRATE 9600 34 #define CONFIG_MAX_BAUDRATE 921600 35 36 #define UART_DR 0x0 /* data register */ 37 #define UART_RSR 0x04 38 #define UART_FR 0x18 /* flag register */ 39 #define UART_CLR 0x44 /* interrupt clear register */ 40 #define UART_CR 0x30 /* control register */ 41 #define UART_IBRD 0x24 /* interge baudrate register */ 42 #define UART_FBRD 0x28 /* decimal baudrate register */ 43 #define UART_LCR_H 0x2C 44 #define UART_IFLS 0x34 /* fifo register */ 45 #define UART_IMSC 0x38 /* interrupt mask register */ 46 #define UART_RIS 0x3C /* base interrupt state register */ 47 #define UART_MIS 0x40 /* mask interrupt state register */ 48 #define UART_ICR 0x44 49 #define UART_DMACR 0x48 /* DMA control register */ 50 51 /* register define */ 52 #define UART_IFLS_RX1_8 (0x00 << 3) 53 #define UART_IFLS_RX4_8 (0x02 << 3) 54 #define UART_IFLS_RX7_8 (0x04 << 3) 55 #define UART_IFLS_TX1_8 (0x00 << 0) 56 #define UART_IFLS_TX4_8 (0x02 << 0) 57 #define UART_IFLS_TX7_8 (0x04 << 0) 58 59 #define UART_CR_CTS (0x01 << 15) 60 #define UART_CR_RTS (0x01 << 14) 61 #define UART_CR_RX_EN (0x01 << 9) 62 #define UART_CR_TX_EN (0x01 << 8) 63 #define UART_CR_LOOPBACK (0x01 << 7) 64 #define UART_CR_EN (0x01 << 0) 65 66 #define UART_FR_TXFE (0x01 << 7) 67 #define UART_FR_RXFF (0x01 << 6) 68 #define UART_FR_TXFF (0x01 << 5) 69 #define UART_FR_RXFE (0x01 << 4) 70 #define UART_FR_BUSY (0x01 << 3) 71 72 #define UART_LCR_H_BREAK (0x01 << 0) 73 #define UART_LCR_H_PEN (0x01 << 1) 74 #define UART_LCR_H_EPS (0x01 << 2) 75 #define UART_LCR_H_STP2 (0x01 << 3) 76 #define UART_LCR_H_FIFO_EN (0x01 << 4) 77 #define UART_LCR_H_8_BIT (0x03 << 5) 78 #define UART_LCR_H_7_BIT (0x02 << 5) 79 #define UART_LCR_H_6_BIT (0x01 << 5) 80 #define UART_LCR_H_5_BIT (0x00 << 5) 81 #define UART_LCR_H_SPS (0x01 << 7) 82 83 #define UART_RXDMAE (0x01 << 0) 84 #define UART_TXDMAE (0x01 << 1) 85 86 #define UART_MIS_TIMEOUT (0x01 << 6) 87 #define UART_MIS_TX (0x01 << 5) 88 #define UART_MIS_RX (0x01 << 4) 89 90 #define UART_IMSC_OVER (0x01 << 10) 91 #define UART_IMSC_BREAK (0x01 << 9) 92 #define UART_IMSC_CHK (0x01 << 8) 93 #define UART_IMSC_ERR (0x01 << 7) 94 #define UART_IMSC_TIMEOUT (0x01 << 6) 95 #define UART_IMSC_TX (0x01 << 5) 96 #define UART_IMSC_RX (0x01 << 4) 97 98 #define UART_DMACR_RX (0x01 << 0) 99 #define UART_DMACR_TX (0x01 << 1) 100 #define UART_DMACR_ONERR (0x01 << 2) 101 #define UART_INFO (0x01 << 1) 102 103 /* DMA buf size: 4K */ 104 #define RX_DMA_BUF_SIZE 0x1000 105 106 /* receive buf default size: 16K */ 107 #define BUF_SIZE 0x4000 108 109 struct UartDriverData; 110 111 struct UartOps { 112 int32_t (*StartUp)(struct UartDriverData *udd); 113 int32_t (*ShutDown)(struct UartDriverData *udd); 114 int32_t (*DmaStartUp)(struct UartDriverData *udd, int32_t dir); 115 int32_t (*DmaShutDown)(struct UartDriverData *udd, int32_t dir); 116 #define UART_DMA_DIR_RX 0 117 #define UART_DMA_DIR_TX 1 118 int32_t (*StartTx)(struct UartDriverData *udd, const char *buf, size_t count); 119 int32_t (*Config)(struct UartDriverData *udd); 120 /* private operation */ 121 int32_t (*PrivOperator)(struct UartDriverData *udd, void *data); 122 }; 123 124 struct UartTransfer { 125 uint32_t rp; 126 uint32_t wp; 127 uint32_t flags; 128 #define BUF_CIRCLED (1 << 0) 129 #define BUF_OVERFLOWED (1 << 1) 130 #define BUF_EMPTIED (1 << 2) 131 char data[BUF_SIZE]; 132 }; 133 134 typedef int32_t (*RecvNotify)(struct UartDriverData *udd, const char *buf, size_t count); 135 136 struct UartDriverData { 137 uint32_t num; 138 uint32_t baudrate; 139 struct UartAttribute attr; 140 struct UartTransfer *rxTransfer; 141 wait_queue_head_t wait; 142 int32_t count; 143 int32_t state; 144 #define UART_STATE_NOT_OPENED 0 145 #define UART_STATE_OPENING 1 146 #define UART_STATE_USEABLE 2 147 #define UART_STATE_SUSPENED 3 148 uint32_t flags; 149 #define UART_FLG_DMA_RX (1 << 0) 150 #define UART_FLG_DMA_TX (1 << 1) 151 #define UART_FLG_RD_BLOCK (1 << 2) 152 RecvNotify recv; 153 struct UartOps *ops; 154 void *private; 155 }; 156 157 struct UartDmaTransfer { 158 /* dma alloced channel */ 159 uint32_t channel; 160 /* dma created task id */ 161 uint32_t thread_id; 162 /* dma receive buf head */ 163 uint32_t head; 164 /* dma receive buf tail */ 165 uint32_t tail; 166 /* dma receive buf cycled flag */ 167 uint32_t flags; 168 #define BUF_CIRCLED (1 << 0) 169 /* dma receive buf, shoud be cache aligned */ 170 char *buf; 171 }; 172 173 struct UartPl011Port { 174 int32_t enable; 175 unsigned long physBase; 176 uint32_t irqNum; 177 uint32_t defaultBaudrate; 178 uint32_t flags; 179 #define PL011_FLG_IRQ_REQUESTED (1 << 0) 180 #define PL011_FLG_DMA_RX_REQUESTED (1 << 1) 181 #define PL011_FLG_DMA_TX_REQUESTED (1 << 2) 182 struct UartDmaTransfer *rxUdt; 183 struct UartDriverData *udd; 184 }; 185 186 /* read some data from rx_data buf in UartTransfer */ 187 int32_t Pl011Read(struct UartDriverData *udd, char *buf, size_t count); 188 /* check the buf is empty */ 189 bool PL011UartRxBufEmpty(struct UartDriverData *udd); 190 int32_t PL011UartRecvNotify(struct UartDriverData *udd, const char *buf, size_t count); 191 struct UartOps *Pl011GetOps(void); 192 193 #ifdef __cplusplus 194 #if __cplusplus 195 } 196 #endif /* __cplusplus */ 197 #endif /* __cplusplus */ 198 199 #endif /* UART_PL011_H */ 200