^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Based on meson_uart.c, by AMLOGIC, INC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2014 Carlo Caione <carlo@caione.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/iopoll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/serial_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /* Register offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define AML_UART_WFIFO 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define AML_UART_RFIFO 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define AML_UART_CONTROL 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define AML_UART_STATUS 0x0c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define AML_UART_MISC 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define AML_UART_REG5 0x14
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /* AML_UART_CONTROL bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define AML_UART_TX_EN BIT(12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define AML_UART_RX_EN BIT(13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define AML_UART_TWO_WIRE_EN BIT(15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define AML_UART_STOP_BIT_LEN_MASK (0x03 << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define AML_UART_STOP_BIT_1SB (0x00 << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define AML_UART_STOP_BIT_2SB (0x01 << 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define AML_UART_PARITY_TYPE BIT(18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define AML_UART_PARITY_EN BIT(19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define AML_UART_TX_RST BIT(22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define AML_UART_RX_RST BIT(23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define AML_UART_CLEAR_ERR BIT(24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define AML_UART_RX_INT_EN BIT(27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define AML_UART_TX_INT_EN BIT(28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define AML_UART_DATA_LEN_MASK (0x03 << 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define AML_UART_DATA_LEN_8BIT (0x00 << 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define AML_UART_DATA_LEN_7BIT (0x01 << 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define AML_UART_DATA_LEN_6BIT (0x02 << 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define AML_UART_DATA_LEN_5BIT (0x03 << 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* AML_UART_STATUS bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define AML_UART_PARITY_ERR BIT(16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define AML_UART_FRAME_ERR BIT(17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define AML_UART_TX_FIFO_WERR BIT(18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define AML_UART_RX_EMPTY BIT(20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define AML_UART_TX_FULL BIT(21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define AML_UART_TX_EMPTY BIT(22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define AML_UART_XMIT_BUSY BIT(25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define AML_UART_ERR (AML_UART_PARITY_ERR | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) AML_UART_FRAME_ERR | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) AML_UART_TX_FIFO_WERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* AML_UART_MISC bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define AML_UART_XMIT_IRQ(c) (((c) & 0xff) << 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define AML_UART_RECV_IRQ(c) ((c) & 0xff)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* AML_UART_REG5 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define AML_UART_BAUD_MASK 0x7fffff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define AML_UART_BAUD_USE BIT(23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define AML_UART_BAUD_XTAL BIT(24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define AML_UART_PORT_NUM 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define AML_UART_PORT_OFFSET 6
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define AML_UART_DEV_NAME "ttyAML"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define AML_UART_POLL_USEC 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define AML_UART_TIMEOUT_USEC 10000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) static struct uart_driver meson_uart_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static struct uart_port *meson_ports[AML_UART_PORT_NUM];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) static void meson_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static unsigned int meson_uart_get_mctrl(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return TIOCM_CTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) static unsigned int meson_uart_tx_empty(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) val = readl(port->membase + AML_UART_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) val &= (AML_UART_TX_EMPTY | AML_UART_XMIT_BUSY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return (val == AML_UART_TX_EMPTY) ? TIOCSER_TEMT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) static void meson_uart_stop_tx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) val = readl(port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) val &= ~AML_UART_TX_INT_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) writel(val, port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) static void meson_uart_stop_rx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) val = readl(port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) val &= ~AML_UART_RX_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) writel(val, port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) static void meson_uart_shutdown(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) free_irq(port->irq, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) val = readl(port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) val &= ~AML_UART_RX_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) val &= ~(AML_UART_RX_INT_EN | AML_UART_TX_INT_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) writel(val, port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) static void meson_uart_start_tx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct circ_buf *xmit = &port->state->xmit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) unsigned int ch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (uart_tx_stopped(port)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) meson_uart_stop_tx(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) while (!(readl(port->membase + AML_UART_STATUS) & AML_UART_TX_FULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (port->x_char) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) writel(port->x_char, port->membase + AML_UART_WFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) port->icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) port->x_char = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (uart_circ_empty(xmit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) ch = xmit->buf[xmit->tail];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) writel(ch, port->membase + AML_UART_WFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) xmit->tail = (xmit->tail+1) & (SERIAL_XMIT_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) port->icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (!uart_circ_empty(xmit)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) val = readl(port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) val |= AML_UART_TX_INT_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) writel(val, port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) uart_write_wakeup(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) static void meson_receive_chars(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) struct tty_port *tport = &port->state->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) char flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) u32 ostatus, status, ch, mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) flag = TTY_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) port->icount.rx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) ostatus = status = readl(port->membase + AML_UART_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) if (status & AML_UART_ERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) if (status & AML_UART_TX_FIFO_WERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) port->icount.overrun++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) else if (status & AML_UART_FRAME_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) port->icount.frame++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) else if (status & AML_UART_PARITY_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) port->icount.frame++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) mode = readl(port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) mode |= AML_UART_CLEAR_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) writel(mode, port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) /* It doesn't clear to 0 automatically */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) mode &= ~AML_UART_CLEAR_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) writel(mode, port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) status &= port->read_status_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (status & AML_UART_FRAME_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) flag = TTY_FRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) else if (status & AML_UART_PARITY_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) flag = TTY_PARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ch = readl(port->membase + AML_UART_RFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) ch &= 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if ((ostatus & AML_UART_FRAME_ERR) && (ch == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) port->icount.brk++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) flag = TTY_BREAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (uart_handle_break(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (uart_handle_sysrq_char(port, ch))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if ((status & port->ignore_status_mask) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) tty_insert_flip_char(tport, ch, flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (status & AML_UART_TX_FIFO_WERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) tty_insert_flip_char(tport, 0, TTY_OVERRUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) } while (!(readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) spin_unlock(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) tty_flip_buffer_push(tport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) spin_lock(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) static irqreturn_t meson_uart_interrupt(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct uart_port *port = (struct uart_port *)dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) spin_lock(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) if (!(readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) meson_receive_chars(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (!(readl(port->membase + AML_UART_STATUS) & AML_UART_TX_FULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (readl(port->membase + AML_UART_CONTROL) & AML_UART_TX_INT_EN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) meson_uart_start_tx(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) spin_unlock(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) static const char *meson_uart_type(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return (port->type == PORT_MESON) ? "meson_uart" : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static void meson_uart_reset(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) val = readl(port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) val |= (AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLEAR_ERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) writel(val, port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) val &= ~(AML_UART_RX_RST | AML_UART_TX_RST | AML_UART_CLEAR_ERR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) writel(val, port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) static int meson_uart_startup(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) val = readl(port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) val |= AML_UART_CLEAR_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) writel(val, port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) val &= ~AML_UART_CLEAR_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) writel(val, port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) val |= (AML_UART_RX_EN | AML_UART_TX_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) writel(val, port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) val |= (AML_UART_RX_INT_EN | AML_UART_TX_INT_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) writel(val, port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) val = (AML_UART_RECV_IRQ(1) | AML_UART_XMIT_IRQ(port->fifosize / 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) writel(val, port->membase + AML_UART_MISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) ret = request_irq(port->irq, meson_uart_interrupt, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) port->name, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static void meson_uart_change_speed(struct uart_port *port, unsigned long baud)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) while (!meson_uart_tx_empty(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (port->uartclk == 24000000) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) val = ((port->uartclk / 3) / baud) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) val |= AML_UART_BAUD_XTAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) val = ((port->uartclk * 10 / (baud * 4) + 5) / 10) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) val |= AML_UART_BAUD_USE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) writel(val, port->membase + AML_UART_REG5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static void meson_uart_set_termios(struct uart_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) struct ktermios *termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) struct ktermios *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) unsigned int cflags, iflags, baud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) cflags = termios->c_cflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) iflags = termios->c_iflag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) val = readl(port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) val &= ~AML_UART_DATA_LEN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) switch (cflags & CSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) case CS8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) val |= AML_UART_DATA_LEN_8BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) case CS7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) val |= AML_UART_DATA_LEN_7BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) case CS6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) val |= AML_UART_DATA_LEN_6BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) case CS5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) val |= AML_UART_DATA_LEN_5BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (cflags & PARENB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) val |= AML_UART_PARITY_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) val &= ~AML_UART_PARITY_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (cflags & PARODD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) val |= AML_UART_PARITY_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) val &= ~AML_UART_PARITY_TYPE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) val &= ~AML_UART_STOP_BIT_LEN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (cflags & CSTOPB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) val |= AML_UART_STOP_BIT_2SB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) val |= AML_UART_STOP_BIT_1SB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (cflags & CRTSCTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) val &= ~AML_UART_TWO_WIRE_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) val |= AML_UART_TWO_WIRE_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) writel(val, port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) baud = uart_get_baud_rate(port, termios, old, 50, 4000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) meson_uart_change_speed(port, baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) port->read_status_mask = AML_UART_TX_FIFO_WERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (iflags & INPCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) port->read_status_mask |= AML_UART_PARITY_ERR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) AML_UART_FRAME_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) port->ignore_status_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (iflags & IGNPAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) port->ignore_status_mask |= AML_UART_PARITY_ERR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) AML_UART_FRAME_ERR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) uart_update_timeout(port, termios->c_cflag, baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) static int meson_uart_verify_port(struct uart_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct serial_struct *ser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) if (port->type != PORT_MESON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (port->irq != ser->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) if (ser->baud_base < 9600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) static void meson_uart_release_port(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) devm_iounmap(port->dev, port->membase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) port->membase = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) devm_release_mem_region(port->dev, port->mapbase, port->mapsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) static int meson_uart_request_port(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) if (!devm_request_mem_region(port->dev, port->mapbase, port->mapsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) dev_name(port->dev))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) dev_err(port->dev, "Memory region busy\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) port->membase = devm_ioremap(port->dev, port->mapbase,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) port->mapsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (!port->membase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) static void meson_uart_config_port(struct uart_port *port, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) if (flags & UART_CONFIG_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) port->type = PORT_MESON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) meson_uart_request_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) #ifdef CONFIG_CONSOLE_POLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * Console polling routines for writing and reading from the uart while
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * in an interrupt or debug context (i.e. kgdb).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) static int meson_uart_poll_get_char(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) u32 c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (readl(port->membase + AML_UART_STATUS) & AML_UART_RX_EMPTY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) c = NO_POLL_CHAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) c = readl(port->membase + AML_UART_RFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) static void meson_uart_poll_put_char(struct uart_port *port, unsigned char c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) u32 reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) /* Wait until FIFO is empty or timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) ret = readl_poll_timeout_atomic(port->membase + AML_UART_STATUS, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) reg & AML_UART_TX_EMPTY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) AML_UART_POLL_USEC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) AML_UART_TIMEOUT_USEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) if (ret == -ETIMEDOUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) dev_err(port->dev, "Timeout waiting for UART TX EMPTY\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) /* Write the character */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) writel(c, port->membase + AML_UART_WFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) /* Wait until FIFO is empty or timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) ret = readl_poll_timeout_atomic(port->membase + AML_UART_STATUS, reg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) reg & AML_UART_TX_EMPTY,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) AML_UART_POLL_USEC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) AML_UART_TIMEOUT_USEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) if (ret == -ETIMEDOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) dev_err(port->dev, "Timeout waiting for UART TX EMPTY\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) #endif /* CONFIG_CONSOLE_POLL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) static const struct uart_ops meson_uart_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) .set_mctrl = meson_uart_set_mctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) .get_mctrl = meson_uart_get_mctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) .tx_empty = meson_uart_tx_empty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) .start_tx = meson_uart_start_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) .stop_tx = meson_uart_stop_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) .stop_rx = meson_uart_stop_rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) .startup = meson_uart_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) .shutdown = meson_uart_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) .set_termios = meson_uart_set_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) .type = meson_uart_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) .config_port = meson_uart_config_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) .request_port = meson_uart_request_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) .release_port = meson_uart_release_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) .verify_port = meson_uart_verify_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) #ifdef CONFIG_CONSOLE_POLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) .poll_get_char = meson_uart_poll_get_char,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) .poll_put_char = meson_uart_poll_put_char,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) #ifdef CONFIG_SERIAL_MESON_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) static void meson_uart_enable_tx_engine(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) val = readl(port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) val |= AML_UART_TX_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) writel(val, port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) static void meson_console_putchar(struct uart_port *port, int ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (!port->membase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) while (readl(port->membase + AML_UART_STATUS) & AML_UART_TX_FULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) writel(ch, port->membase + AML_UART_WFIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) static void meson_serial_port_write(struct uart_port *port, const char *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) u_int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) int locked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) u32 val, tmp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) if (port->sysrq) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) locked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) } else if (oops_in_progress) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) locked = spin_trylock(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) spin_lock(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) locked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) val = readl(port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) tmp = val & ~(AML_UART_TX_INT_EN | AML_UART_RX_INT_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) writel(tmp, port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) uart_console_write(port, s, count, meson_console_putchar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) writel(val, port->membase + AML_UART_CONTROL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (locked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) spin_unlock(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) static void meson_serial_console_write(struct console *co, const char *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) u_int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) struct uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) port = meson_ports[co->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) if (!port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) meson_serial_port_write(port, s, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) static int meson_serial_console_setup(struct console *co, char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) struct uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) int baud = 115200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) int bits = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) int parity = 'n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) int flow = 'n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) if (co->index < 0 || co->index >= AML_UART_PORT_NUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) port = meson_ports[co->index];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (!port || !port->membase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) meson_uart_enable_tx_engine(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) uart_parse_options(options, &baud, &parity, &bits, &flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) return uart_set_options(port, co, baud, parity, bits, flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) static struct console meson_serial_console = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) .name = AML_UART_DEV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) .write = meson_serial_console_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) .device = uart_console_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) .setup = meson_serial_console_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) .flags = CON_PRINTBUFFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) .index = -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) .data = &meson_uart_driver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) static int __init meson_serial_console_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) register_console(&meson_serial_console);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) static void meson_serial_early_console_write(struct console *co,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) const char *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) u_int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) struct earlycon_device *dev = co->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) meson_serial_port_write(&dev->port, s, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) static int __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) meson_serial_early_console_setup(struct earlycon_device *device, const char *opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) if (!device->port.membase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) meson_uart_enable_tx_engine(&device->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) device->con->write = meson_serial_early_console_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) /* Legacy bindings, should be removed when no more used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) OF_EARLYCON_DECLARE(meson, "amlogic,meson-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) meson_serial_early_console_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) /* Stable bindings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) OF_EARLYCON_DECLARE(meson, "amlogic,meson-ao-uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) meson_serial_early_console_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) #define MESON_SERIAL_CONSOLE (&meson_serial_console)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) static int __init meson_serial_console_init(void) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) #define MESON_SERIAL_CONSOLE NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) static struct uart_driver meson_uart_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) .driver_name = "meson_uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) .dev_name = AML_UART_DEV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) .nr = AML_UART_PORT_NUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) .cons = MESON_SERIAL_CONSOLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) static inline struct clk *meson_uart_probe_clock(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) const char *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) struct clk *clk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) clk = devm_clk_get(dev, id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) return clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) ret = clk_prepare_enable(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) dev_err(dev, "couldn't enable clk\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return ERR_PTR(ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) devm_add_action_or_reset(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) (void(*)(void *))clk_disable_unprepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) return clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) * This function gets clocks in the legacy non-stable DT bindings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) * This code will be remove once all the platforms switch to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) * new DT bindings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static int meson_uart_probe_clocks_legacy(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) struct clk *clk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) clk = meson_uart_probe_clock(&pdev->dev, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (IS_ERR(clk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) return PTR_ERR(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) port->uartclk = clk_get_rate(clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) static int meson_uart_probe_clocks(struct platform_device *pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) struct clk *clk_xtal = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) struct clk *clk_pclk = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) struct clk *clk_baud = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) clk_pclk = meson_uart_probe_clock(&pdev->dev, "pclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (IS_ERR(clk_pclk))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) return PTR_ERR(clk_pclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) clk_xtal = meson_uart_probe_clock(&pdev->dev, "xtal");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) if (IS_ERR(clk_xtal))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) return PTR_ERR(clk_xtal);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) clk_baud = meson_uart_probe_clock(&pdev->dev, "baud");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) if (IS_ERR(clk_baud))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return PTR_ERR(clk_baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) port->uartclk = clk_get_rate(clk_baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) static int meson_uart_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) struct resource *res_mem, *res_irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) struct uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) int id = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (pdev->dev.of_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) pdev->id = of_alias_get_id(pdev->dev.of_node, "serial");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (pdev->id < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) for (id = AML_UART_PORT_OFFSET; id < AML_UART_PORT_NUM; id++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) if (!meson_ports[id]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) pdev->id = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (pdev->id < 0 || pdev->id >= AML_UART_PORT_NUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (!res_mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) res_irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (!res_irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (meson_ports[pdev->id]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) dev_err(&pdev->dev, "port %d already allocated\n", pdev->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) port = devm_kzalloc(&pdev->dev, sizeof(struct uart_port), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) if (!port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) /* Use legacy way until all platforms switch to new bindings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) if (of_device_is_compatible(pdev->dev.of_node, "amlogic,meson-uart"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) ret = meson_uart_probe_clocks_legacy(pdev, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) ret = meson_uart_probe_clocks(pdev, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) port->iotype = UPIO_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) port->mapbase = res_mem->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) port->mapsize = resource_size(res_mem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) port->irq = res_irq->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) port->flags = UPF_BOOT_AUTOCONF | UPF_LOW_LATENCY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_MESON_CONSOLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) port->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) port->line = pdev->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) port->type = PORT_MESON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) port->x_char = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) port->ops = &meson_uart_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) port->fifosize = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) meson_ports[pdev->id] = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) platform_set_drvdata(pdev, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) /* reset port before registering (and possibly registering console) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) if (meson_uart_request_port(port) >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) meson_uart_reset(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) meson_uart_release_port(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) ret = uart_add_one_port(&meson_uart_driver, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) meson_ports[pdev->id] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) static int meson_uart_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) struct uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) port = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) uart_remove_one_port(&meson_uart_driver, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) meson_ports[pdev->id] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) static const struct of_device_id meson_uart_dt_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) /* Legacy bindings, should be removed when no more used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) { .compatible = "amlogic,meson-uart" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) /* Stable bindings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) { .compatible = "amlogic,meson6-uart" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) { .compatible = "amlogic,meson8-uart" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) { .compatible = "amlogic,meson8b-uart" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) { .compatible = "amlogic,meson-gx-uart" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) { /* sentinel */ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) MODULE_DEVICE_TABLE(of, meson_uart_dt_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) static struct platform_driver meson_uart_platform_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) .probe = meson_uart_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) .remove = meson_uart_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) .name = "meson_uart",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) .of_match_table = meson_uart_dt_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) static int __init meson_uart_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) ret = meson_serial_console_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) ret = uart_register_driver(&meson_uart_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) ret = platform_driver_register(&meson_uart_platform_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) uart_unregister_driver(&meson_uart_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) static void __exit meson_uart_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) platform_driver_unregister(&meson_uart_platform_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) uart_unregister_driver(&meson_uart_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) module_init(meson_uart_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) module_exit(meson_uart_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) MODULE_DESCRIPTION("Amlogic Meson serial port driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) MODULE_LICENSE("GPL v2");