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 25extern "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 /* integer 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 109struct UartDriverData; 110 111struct 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 124struct 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 134typedef int32_t (*RecvNotify)(struct UartDriverData *udd, const char *buf, size_t count); 135 136struct 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 157struct UartDmaTransfer { 158 /* dma allocated 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, should be cache aligned */ 170 char *buf; 171}; 172 173struct 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 */ 187int32_t Pl011Read(struct UartDriverData *udd, char *buf, size_t count); 188/* check the buf is empty */ 189bool PL011UartRxBufEmpty(struct UartDriverData *udd); 190int32_t PL011UartRecvNotify(struct UartDriverData *udd, const char *buf, size_t count); 191struct UartOps *Pl011GetOps(void); 192 193#ifdef __cplusplus 194#if __cplusplus 195} 196#endif /* __cplusplus */ 197#endif /* __cplusplus */ 198 199#endif /* UART_PL011_H */ 200