11bd4fe43Sopenharmony_ci/*
21bd4fe43Sopenharmony_ci * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
31bd4fe43Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
41bd4fe43Sopenharmony_ci * you may not use this file except in compliance with the License.
51bd4fe43Sopenharmony_ci * You may obtain a copy of the License at
61bd4fe43Sopenharmony_ci *
71bd4fe43Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
81bd4fe43Sopenharmony_ci *
91bd4fe43Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
101bd4fe43Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
111bd4fe43Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
121bd4fe43Sopenharmony_ci * See the License for the specific language governing permissions and
131bd4fe43Sopenharmony_ci * limitations under the License.
141bd4fe43Sopenharmony_ci */
151bd4fe43Sopenharmony_ci
161bd4fe43Sopenharmony_ci#ifndef UART_PL011_H
171bd4fe43Sopenharmony_ci#define UART_PL011_H
181bd4fe43Sopenharmony_ci
191bd4fe43Sopenharmony_ci#include "console.h"
201bd4fe43Sopenharmony_ci#include "poll.h"
211bd4fe43Sopenharmony_ci#include "uart_if.h"
221bd4fe43Sopenharmony_ci
231bd4fe43Sopenharmony_ci#ifdef __cplusplus
241bd4fe43Sopenharmony_ci#if __cplusplus
251bd4fe43Sopenharmony_ciextern "C" {
261bd4fe43Sopenharmony_ci#endif /* __cplusplus */
271bd4fe43Sopenharmony_ci#endif /* __cplusplus */
281bd4fe43Sopenharmony_ci
291bd4fe43Sopenharmony_ci#define DEFAULT_UART0_BAUDRATE 115200
301bd4fe43Sopenharmony_ci#define DEFAULT_UART1_BAUDRATE 9600
311bd4fe43Sopenharmony_ci#define DEFAULT_UART2_BAUDRATE 115200
321bd4fe43Sopenharmony_ci#define DEFAULT_UART3_BAUDRATE 9600
331bd4fe43Sopenharmony_ci#define DEFAULT_UART4_BAUDRATE 9600
341bd4fe43Sopenharmony_ci#define CONFIG_MAX_BAUDRATE    921600
351bd4fe43Sopenharmony_ci
361bd4fe43Sopenharmony_ci#define UART_DR                0x0  /* data register */
371bd4fe43Sopenharmony_ci#define UART_RSR               0x04
381bd4fe43Sopenharmony_ci#define UART_FR                0x18 /* flag register */
391bd4fe43Sopenharmony_ci#define UART_CLR               0x44 /* interrupt clear register */
401bd4fe43Sopenharmony_ci#define UART_CR                0x30 /* control register */
411bd4fe43Sopenharmony_ci#define UART_IBRD              0x24 /* interge baudrate register */
421bd4fe43Sopenharmony_ci#define UART_FBRD              0x28 /* decimal baudrate register */
431bd4fe43Sopenharmony_ci#define UART_LCR_H             0x2C
441bd4fe43Sopenharmony_ci#define UART_IFLS              0x34 /* fifo register */
451bd4fe43Sopenharmony_ci#define UART_IMSC              0x38 /* interrupt mask register */
461bd4fe43Sopenharmony_ci#define UART_RIS               0x3C /* base interrupt state register */
471bd4fe43Sopenharmony_ci#define UART_MIS               0x40 /* mask interrupt state register */
481bd4fe43Sopenharmony_ci#define UART_ICR               0x44
491bd4fe43Sopenharmony_ci#define UART_DMACR             0x48 /* DMA control register */
501bd4fe43Sopenharmony_ci
511bd4fe43Sopenharmony_ci/* register define */
521bd4fe43Sopenharmony_ci#define UART_IFLS_RX1_8        (0x00 << 3)
531bd4fe43Sopenharmony_ci#define UART_IFLS_RX4_8        (0x02 << 3)
541bd4fe43Sopenharmony_ci#define UART_IFLS_RX7_8        (0x04 << 3)
551bd4fe43Sopenharmony_ci#define UART_IFLS_TX1_8        (0x00 << 0)
561bd4fe43Sopenharmony_ci#define UART_IFLS_TX4_8        (0x02 << 0)
571bd4fe43Sopenharmony_ci#define UART_IFLS_TX7_8        (0x04 << 0)
581bd4fe43Sopenharmony_ci
591bd4fe43Sopenharmony_ci#define UART_CR_CTS            (0x01 << 15)
601bd4fe43Sopenharmony_ci#define UART_CR_RTS            (0x01 << 14)
611bd4fe43Sopenharmony_ci#define UART_CR_RX_EN          (0x01 << 9)
621bd4fe43Sopenharmony_ci#define UART_CR_TX_EN          (0x01 << 8)
631bd4fe43Sopenharmony_ci#define UART_CR_LOOPBACK       (0x01 << 7)
641bd4fe43Sopenharmony_ci#define UART_CR_EN             (0x01 << 0)
651bd4fe43Sopenharmony_ci
661bd4fe43Sopenharmony_ci#define UART_FR_TXFE           (0x01 << 7)
671bd4fe43Sopenharmony_ci#define UART_FR_RXFF           (0x01 << 6)
681bd4fe43Sopenharmony_ci#define UART_FR_TXFF           (0x01 << 5)
691bd4fe43Sopenharmony_ci#define UART_FR_RXFE           (0x01 << 4)
701bd4fe43Sopenharmony_ci#define UART_FR_BUSY           (0x01 << 3)
711bd4fe43Sopenharmony_ci
721bd4fe43Sopenharmony_ci#define UART_LCR_H_BREAK       (0x01 << 0)
731bd4fe43Sopenharmony_ci#define UART_LCR_H_PEN         (0x01 << 1)
741bd4fe43Sopenharmony_ci#define UART_LCR_H_EPS         (0x01 << 2)
751bd4fe43Sopenharmony_ci#define UART_LCR_H_STP2        (0x01 << 3)
761bd4fe43Sopenharmony_ci#define UART_LCR_H_FIFO_EN     (0x01 << 4)
771bd4fe43Sopenharmony_ci#define UART_LCR_H_8_BIT       (0x03 << 5)
781bd4fe43Sopenharmony_ci#define UART_LCR_H_7_BIT       (0x02 << 5)
791bd4fe43Sopenharmony_ci#define UART_LCR_H_6_BIT       (0x01 << 5)
801bd4fe43Sopenharmony_ci#define UART_LCR_H_5_BIT       (0x00 << 5)
811bd4fe43Sopenharmony_ci#define UART_LCR_H_SPS         (0x01 << 7)
821bd4fe43Sopenharmony_ci
831bd4fe43Sopenharmony_ci#define UART_RXDMAE            (0x01 << 0)
841bd4fe43Sopenharmony_ci#define UART_TXDMAE            (0x01 << 1)
851bd4fe43Sopenharmony_ci
861bd4fe43Sopenharmony_ci#define UART_MIS_TIMEOUT       (0x01 << 6)
871bd4fe43Sopenharmony_ci#define UART_MIS_TX            (0x01 << 5)
881bd4fe43Sopenharmony_ci#define UART_MIS_RX            (0x01 << 4)
891bd4fe43Sopenharmony_ci
901bd4fe43Sopenharmony_ci#define UART_IMSC_OVER         (0x01 << 10)
911bd4fe43Sopenharmony_ci#define UART_IMSC_BREAK        (0x01 << 9)
921bd4fe43Sopenharmony_ci#define UART_IMSC_CHK          (0x01 << 8)
931bd4fe43Sopenharmony_ci#define UART_IMSC_ERR          (0x01 << 7)
941bd4fe43Sopenharmony_ci#define UART_IMSC_TIMEOUT      (0x01 << 6)
951bd4fe43Sopenharmony_ci#define UART_IMSC_TX           (0x01 << 5)
961bd4fe43Sopenharmony_ci#define UART_IMSC_RX           (0x01 << 4)
971bd4fe43Sopenharmony_ci
981bd4fe43Sopenharmony_ci#define UART_DMACR_RX          (0x01 << 0)
991bd4fe43Sopenharmony_ci#define UART_DMACR_TX          (0x01 << 1)
1001bd4fe43Sopenharmony_ci#define UART_DMACR_ONERR       (0x01 << 2)
1011bd4fe43Sopenharmony_ci#define UART_INFO              (0x01 << 1)
1021bd4fe43Sopenharmony_ci
1031bd4fe43Sopenharmony_ci/* DMA buf size: 4K */
1041bd4fe43Sopenharmony_ci#define RX_DMA_BUF_SIZE        0x1000
1051bd4fe43Sopenharmony_ci
1061bd4fe43Sopenharmony_ci/* receive buf default size: 16K */
1071bd4fe43Sopenharmony_ci#define BUF_SIZE               0x4000
1081bd4fe43Sopenharmony_ci
1091bd4fe43Sopenharmony_cistruct UartDriverData;
1101bd4fe43Sopenharmony_ci
1111bd4fe43Sopenharmony_cistruct UartOps {
1121bd4fe43Sopenharmony_ci    int32_t (*StartUp)(struct UartDriverData *udd);
1131bd4fe43Sopenharmony_ci    int32_t (*ShutDown)(struct UartDriverData *udd);
1141bd4fe43Sopenharmony_ci    int32_t (*DmaStartUp)(struct UartDriverData *udd, int32_t dir);
1151bd4fe43Sopenharmony_ci    int32_t (*DmaShutDown)(struct UartDriverData *udd, int32_t dir);
1161bd4fe43Sopenharmony_ci#define UART_DMA_DIR_RX 0
1171bd4fe43Sopenharmony_ci#define UART_DMA_DIR_TX 1
1181bd4fe43Sopenharmony_ci    int32_t (*StartTx)(struct UartDriverData *udd, const char *buf, size_t count);
1191bd4fe43Sopenharmony_ci    int32_t (*Config)(struct UartDriverData *udd);
1201bd4fe43Sopenharmony_ci    /* private operation */
1211bd4fe43Sopenharmony_ci    int32_t (*PrivOperator)(struct UartDriverData *udd, void *data);
1221bd4fe43Sopenharmony_ci};
1231bd4fe43Sopenharmony_ci
1241bd4fe43Sopenharmony_cistruct UartTransfer {
1251bd4fe43Sopenharmony_ci    uint32_t rp;
1261bd4fe43Sopenharmony_ci    uint32_t wp;
1271bd4fe43Sopenharmony_ci    uint32_t flags;
1281bd4fe43Sopenharmony_ci#define BUF_CIRCLED    (1 << 0)
1291bd4fe43Sopenharmony_ci#define BUF_OVERFLOWED (1 << 1)
1301bd4fe43Sopenharmony_ci#define BUF_EMPTIED    (1 << 2)
1311bd4fe43Sopenharmony_ci    char data[BUF_SIZE];
1321bd4fe43Sopenharmony_ci};
1331bd4fe43Sopenharmony_ci
1341bd4fe43Sopenharmony_citypedef int32_t (*RecvNotify)(struct UartDriverData *udd, const char *buf, size_t count);
1351bd4fe43Sopenharmony_ci
1361bd4fe43Sopenharmony_cistruct UartDriverData {
1371bd4fe43Sopenharmony_ci    uint32_t num;
1381bd4fe43Sopenharmony_ci    uint32_t baudrate;
1391bd4fe43Sopenharmony_ci    struct UartAttribute attr;
1401bd4fe43Sopenharmony_ci    struct UartTransfer *rxTransfer;
1411bd4fe43Sopenharmony_ci    wait_queue_head_t wait;
1421bd4fe43Sopenharmony_ci    int32_t count;
1431bd4fe43Sopenharmony_ci    int32_t state;
1441bd4fe43Sopenharmony_ci#define UART_STATE_NOT_OPENED 0
1451bd4fe43Sopenharmony_ci#define UART_STATE_OPENING    1
1461bd4fe43Sopenharmony_ci#define UART_STATE_USEABLE    2
1471bd4fe43Sopenharmony_ci#define UART_STATE_SUSPENED   3
1481bd4fe43Sopenharmony_ci    uint32_t flags;
1491bd4fe43Sopenharmony_ci#define UART_FLG_DMA_RX       (1 << 0)
1501bd4fe43Sopenharmony_ci#define UART_FLG_DMA_TX       (1 << 1)
1511bd4fe43Sopenharmony_ci#define UART_FLG_RD_BLOCK     (1 << 2)
1521bd4fe43Sopenharmony_ci    RecvNotify recv;
1531bd4fe43Sopenharmony_ci    struct UartOps *ops;
1541bd4fe43Sopenharmony_ci    void *private;
1551bd4fe43Sopenharmony_ci};
1561bd4fe43Sopenharmony_ci
1571bd4fe43Sopenharmony_cistruct UartDmaTransfer {
1581bd4fe43Sopenharmony_ci    /* dma alloced channel */
1591bd4fe43Sopenharmony_ci    uint32_t channel;
1601bd4fe43Sopenharmony_ci    /* dma created task id */
1611bd4fe43Sopenharmony_ci    uint32_t thread_id;
1621bd4fe43Sopenharmony_ci    /* dma receive buf head */
1631bd4fe43Sopenharmony_ci    uint32_t head;
1641bd4fe43Sopenharmony_ci    /* dma receive buf tail */
1651bd4fe43Sopenharmony_ci    uint32_t tail;
1661bd4fe43Sopenharmony_ci    /* dma receive buf cycled flag */
1671bd4fe43Sopenharmony_ci    uint32_t flags;
1681bd4fe43Sopenharmony_ci#define BUF_CIRCLED (1 << 0)
1691bd4fe43Sopenharmony_ci    /* dma receive buf, shoud be cache aligned */
1701bd4fe43Sopenharmony_ci    char *buf;
1711bd4fe43Sopenharmony_ci};
1721bd4fe43Sopenharmony_ci
1731bd4fe43Sopenharmony_cistruct UartPl011Port {
1741bd4fe43Sopenharmony_ci    int32_t enable;
1751bd4fe43Sopenharmony_ci    unsigned long physBase;
1761bd4fe43Sopenharmony_ci    uint32_t irqNum;
1771bd4fe43Sopenharmony_ci    uint32_t defaultBaudrate;
1781bd4fe43Sopenharmony_ci    uint32_t flags;
1791bd4fe43Sopenharmony_ci#define PL011_FLG_IRQ_REQUESTED    (1 << 0)
1801bd4fe43Sopenharmony_ci#define PL011_FLG_DMA_RX_REQUESTED (1 << 1)
1811bd4fe43Sopenharmony_ci#define PL011_FLG_DMA_TX_REQUESTED (1 << 2)
1821bd4fe43Sopenharmony_ci    struct UartDmaTransfer *rxUdt;
1831bd4fe43Sopenharmony_ci    struct UartDriverData *udd;
1841bd4fe43Sopenharmony_ci    struct PlatformDumper *dumper;
1851bd4fe43Sopenharmony_ci    char *dumperName;
1861bd4fe43Sopenharmony_ci};
1871bd4fe43Sopenharmony_ci
1881bd4fe43Sopenharmony_ci/* read some data from rx_data buf in UartTransfer */
1891bd4fe43Sopenharmony_ciint32_t Pl011Read(struct UartDriverData *udd, char *buf, size_t count);
1901bd4fe43Sopenharmony_ci/* check the buf is empty */
1911bd4fe43Sopenharmony_cibool PL011UartRxBufEmpty(struct UartDriverData *udd);
1921bd4fe43Sopenharmony_ciint32_t PL011UartRecvNotify(struct UartDriverData *udd, const char *buf, size_t count);
1931bd4fe43Sopenharmony_cistruct UartOps *Pl011GetOps(void);
1941bd4fe43Sopenharmony_ci
1951bd4fe43Sopenharmony_ci#ifdef __cplusplus
1961bd4fe43Sopenharmony_ci#if __cplusplus
1971bd4fe43Sopenharmony_ci}
1981bd4fe43Sopenharmony_ci#endif /* __cplusplus */
1991bd4fe43Sopenharmony_ci#endif /* __cplusplus */
2001bd4fe43Sopenharmony_ci
2011bd4fe43Sopenharmony_ci#endif /* UART_PL011_H */
202