^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) * Cadence UART driver (found in Xilinx Zynq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * 2011 - 2014 (C) Xilinx Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * This driver has originally been pushed by Xilinx using a Zynq-branding. This
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * still shows in the naming of this file, the kconfig symbols and some symbols
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * in the code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/console.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/serial_core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/iopoll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define CDNS_UART_TTY_NAME "ttyPS"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define CDNS_UART_NAME "xuartps"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define CDNS_UART_MAJOR 0 /* use dynamic node allocation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define CDNS_UART_MINOR 0 /* works best with devtmpfs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define CDNS_UART_NR_PORTS 16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define CDNS_UART_FIFO_SIZE 64 /* FIFO size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define CDNS_UART_REGISTER_SPACE 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define TX_TIMEOUT 500000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* Rx Trigger level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) static int rx_trigger_level = 56;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) module_param(rx_trigger_level, uint, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) MODULE_PARM_DESC(rx_trigger_level, "Rx trigger level, 1-63 bytes");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* Rx Timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static int rx_timeout = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) module_param(rx_timeout, uint, 0444);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) MODULE_PARM_DESC(rx_timeout, "Rx timeout, 1-255");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* Register offsets for the UART. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define CDNS_UART_CR 0x00 /* Control Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define CDNS_UART_MR 0x04 /* Mode Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define CDNS_UART_IER 0x08 /* Interrupt Enable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define CDNS_UART_IDR 0x0C /* Interrupt Disable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define CDNS_UART_IMR 0x10 /* Interrupt Mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define CDNS_UART_ISR 0x14 /* Interrupt Status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define CDNS_UART_BAUDGEN 0x18 /* Baud Rate Generator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define CDNS_UART_RXTOUT 0x1C /* RX Timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define CDNS_UART_RXWM 0x20 /* RX FIFO Trigger Level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define CDNS_UART_MODEMCR 0x24 /* Modem Control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define CDNS_UART_MODEMSR 0x28 /* Modem Status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define CDNS_UART_SR 0x2C /* Channel Status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define CDNS_UART_FIFO 0x30 /* FIFO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define CDNS_UART_BAUDDIV 0x34 /* Baud Rate Divider */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define CDNS_UART_FLOWDEL 0x38 /* Flow Delay */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define CDNS_UART_IRRX_PWIDTH 0x3C /* IR Min Received Pulse Width */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define CDNS_UART_IRTX_PWIDTH 0x40 /* IR Transmitted pulse Width */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define CDNS_UART_TXWM 0x44 /* TX FIFO Trigger Level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define CDNS_UART_RXBS 0x48 /* RX FIFO byte status register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* Control Register Bit Definitions */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define CDNS_UART_CR_STOPBRK 0x00000100 /* Stop TX break */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define CDNS_UART_CR_STARTBRK 0x00000080 /* Set TX break */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define CDNS_UART_CR_TX_DIS 0x00000020 /* TX disabled. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define CDNS_UART_CR_TX_EN 0x00000010 /* TX enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define CDNS_UART_CR_RX_DIS 0x00000008 /* RX disabled. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) #define CDNS_UART_CR_RX_EN 0x00000004 /* RX enabled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define CDNS_UART_CR_TXRST 0x00000002 /* TX logic reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define CDNS_UART_CR_RXRST 0x00000001 /* RX logic reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define CDNS_UART_CR_RST_TO 0x00000040 /* Restart Timeout Counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define CDNS_UART_RXBS_PARITY 0x00000001 /* Parity error status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define CDNS_UART_RXBS_FRAMING 0x00000002 /* Framing error status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define CDNS_UART_RXBS_BRK 0x00000004 /* Overrun error status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * Mode Register:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) * The mode register (MR) defines the mode of transfer as well as the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * format. If this register is modified during transmission or reception,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * data validity cannot be guaranteed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define CDNS_UART_MR_CLKSEL 0x00000001 /* Pre-scalar selection */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define CDNS_UART_MR_CHMODE_L_LOOP 0x00000200 /* Local loop back mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define CDNS_UART_MR_CHMODE_NORM 0x00000000 /* Normal mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define CDNS_UART_MR_CHMODE_MASK 0x00000300 /* Mask for mode bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define CDNS_UART_MR_STOPMODE_2_BIT 0x00000080 /* 2 stop bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define CDNS_UART_MR_STOPMODE_1_BIT 0x00000000 /* 1 stop bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define CDNS_UART_MR_PARITY_NONE 0x00000020 /* No parity mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define CDNS_UART_MR_PARITY_MARK 0x00000018 /* Mark parity mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) #define CDNS_UART_MR_PARITY_SPACE 0x00000010 /* Space parity mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define CDNS_UART_MR_PARITY_ODD 0x00000008 /* Odd parity mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) #define CDNS_UART_MR_PARITY_EVEN 0x00000000 /* Even parity mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) #define CDNS_UART_MR_CHARLEN_6_BIT 0x00000006 /* 6 bits data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) #define CDNS_UART_MR_CHARLEN_7_BIT 0x00000004 /* 7 bits data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define CDNS_UART_MR_CHARLEN_8_BIT 0x00000000 /* 8 bits data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) * Interrupt Registers:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * Interrupt control logic uses the interrupt enable register (IER) and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * interrupt disable register (IDR) to set the value of the bits in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * interrupt mask register (IMR). The IMR determines whether to pass an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * interrupt to the interrupt status register (ISR).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) * Writing a 1 to IER Enables an interrupt, writing a 1 to IDR disables an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * interrupt. IMR and ISR are read only, and IER and IDR are write only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * Reading either IER or IDR returns 0x00.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * All four registers have the same bit definitions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) #define CDNS_UART_IXR_TOUT 0x00000100 /* RX Timeout error interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) #define CDNS_UART_IXR_PARITY 0x00000080 /* Parity error interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #define CDNS_UART_IXR_FRAMING 0x00000040 /* Framing error interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) #define CDNS_UART_IXR_OVERRUN 0x00000020 /* Overrun error interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) #define CDNS_UART_IXR_TXFULL 0x00000010 /* TX FIFO Full interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define CDNS_UART_IXR_TXEMPTY 0x00000008 /* TX FIFO empty interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) #define CDNS_UART_ISR_RXEMPTY 0x00000002 /* RX FIFO empty interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) #define CDNS_UART_IXR_RXTRIG 0x00000001 /* RX FIFO trigger interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) #define CDNS_UART_IXR_RXFULL 0x00000004 /* RX FIFO full interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) #define CDNS_UART_IXR_RXEMPTY 0x00000002 /* RX FIFO empty interrupt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) #define CDNS_UART_IXR_RXMASK 0x000021e7 /* Valid RX bit mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * Do not enable parity error interrupt for the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) * reason: When parity error interrupt is enabled, each Rx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * parity error always results in 2 events. The first one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * being parity error interrupt and the second one with a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * proper Rx interrupt with the incoming data. Disabling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * parity error interrupt ensures better handling of parity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * error events. With this change, for a parity error case, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * get a Rx interrupt with parity error set in ISR register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * and we still handle parity errors in the desired way.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) #define CDNS_UART_RX_IRQS (CDNS_UART_IXR_FRAMING | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) CDNS_UART_IXR_OVERRUN | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) CDNS_UART_IXR_RXTRIG | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) CDNS_UART_IXR_TOUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /* Goes in read_status_mask for break detection as the HW doesn't do it*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) #define CDNS_UART_IXR_BRK 0x00002000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define CDNS_UART_RXBS_SUPPORT BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * Modem Control register:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * The read/write Modem Control register controls the interface with the modem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * or data set, or a peripheral device emulating a modem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define CDNS_UART_MODEMCR_FCM 0x00000020 /* Automatic flow control mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) #define CDNS_UART_MODEMCR_RTS 0x00000002 /* Request to send output control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define CDNS_UART_MODEMCR_DTR 0x00000001 /* Data Terminal Ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * Modem Status register:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * The read/write Modem Status register reports the interface with the modem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) * or data set, or a peripheral device emulating a modem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define CDNS_UART_MODEMSR_DCD BIT(7) /* Data Carrier Detect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define CDNS_UART_MODEMSR_RI BIT(6) /* Ting Indicator */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define CDNS_UART_MODEMSR_DSR BIT(5) /* Data Set Ready */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) #define CDNS_UART_MODEMSR_CTS BIT(4) /* Clear To Send */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) * Channel Status Register:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * The channel status register (CSR) is provided to enable the control logic
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * to monitor the status of bits in the channel interrupt status register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * even if these are masked out by the interrupt mask register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define CDNS_UART_SR_RXEMPTY 0x00000002 /* RX FIFO empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #define CDNS_UART_SR_TXEMPTY 0x00000008 /* TX FIFO empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define CDNS_UART_SR_TXFULL 0x00000010 /* TX FIFO full */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) #define CDNS_UART_SR_RXTRIG 0x00000001 /* Rx Trigger */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #define CDNS_UART_SR_TACTIVE 0x00000800 /* TX state machine active */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* baud dividers min/max values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) #define CDNS_UART_BDIV_MIN 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define CDNS_UART_BDIV_MAX 255
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #define CDNS_UART_CD_MAX 65535
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define UART_AUTOSUSPEND_TIMEOUT 3000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * struct cdns_uart - device data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * @port: Pointer to the UART port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * @uartclk: Reference clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * @pclk: APB clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * @cdns_uart_driver: Pointer to UART driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) * @baud: Current baud rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * @clk_rate_change_nb: Notifier block for clock changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * @quirks: Flags for RXBS support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) struct cdns_uart {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) struct uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) struct clk *uartclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) struct clk *pclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) struct uart_driver *cdns_uart_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) unsigned int baud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) struct notifier_block clk_rate_change_nb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u32 quirks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) bool cts_override;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) struct cdns_platform_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) u32 quirks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) #define to_cdns_uart(_nb) container_of(_nb, struct cdns_uart, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) clk_rate_change_nb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * cdns_uart_handle_rx - Handle the received bytes along with Rx errors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) * @dev_id: Id of the UART port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * @isrstatus: The interrupt status register value as read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) * Return: None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static void cdns_uart_handle_rx(void *dev_id, unsigned int isrstatus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct uart_port *port = (struct uart_port *)dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct cdns_uart *cdns_uart = port->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) unsigned int data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) unsigned int rxbs_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) unsigned int status_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) unsigned int framerrprocessed = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) char status = TTY_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) bool is_rxbs_support;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) is_rxbs_support = cdns_uart->quirks & CDNS_UART_RXBS_SUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) while ((readl(port->membase + CDNS_UART_SR) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) CDNS_UART_SR_RXEMPTY) != CDNS_UART_SR_RXEMPTY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (is_rxbs_support)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) rxbs_status = readl(port->membase + CDNS_UART_RXBS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) data = readl(port->membase + CDNS_UART_FIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) port->icount.rx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * There is no hardware break detection in Zynq, so we interpret
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * framing error with all-zeros data as a break sequence.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * Most of the time, there's another non-zero byte at the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * end of the sequence.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (!is_rxbs_support && (isrstatus & CDNS_UART_IXR_FRAMING)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) if (!data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) port->read_status_mask |= CDNS_UART_IXR_BRK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) framerrprocessed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) if (is_rxbs_support && (rxbs_status & CDNS_UART_RXBS_BRK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) port->icount.brk++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) status = TTY_BREAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (uart_handle_break(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) isrstatus &= port->read_status_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) isrstatus &= ~port->ignore_status_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) status_mask = port->read_status_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) status_mask &= ~port->ignore_status_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) if (data &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) (port->read_status_mask & CDNS_UART_IXR_BRK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) port->read_status_mask &= ~CDNS_UART_IXR_BRK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) port->icount.brk++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) if (uart_handle_break(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) continue;
^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) if (uart_handle_sysrq_char(port, data))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (is_rxbs_support) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if ((rxbs_status & CDNS_UART_RXBS_PARITY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) && (status_mask & CDNS_UART_IXR_PARITY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) port->icount.parity++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) status = TTY_PARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if ((rxbs_status & CDNS_UART_RXBS_FRAMING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) && (status_mask & CDNS_UART_IXR_PARITY)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) port->icount.frame++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) status = TTY_FRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (isrstatus & CDNS_UART_IXR_PARITY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) port->icount.parity++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) status = TTY_PARITY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) if ((isrstatus & CDNS_UART_IXR_FRAMING) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) !framerrprocessed) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) port->icount.frame++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) status = TTY_FRAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) if (isrstatus & CDNS_UART_IXR_OVERRUN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) port->icount.overrun++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) tty_insert_flip_char(&port->state->port, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) TTY_OVERRUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) tty_insert_flip_char(&port->state->port, data, status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) isrstatus = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) spin_unlock(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) tty_flip_buffer_push(&port->state->port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) spin_lock(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * cdns_uart_handle_tx - Handle the bytes to be Txed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * @dev_id: Id of the UART port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * Return: None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) static void cdns_uart_handle_tx(void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) struct uart_port *port = (struct uart_port *)dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) unsigned int numbytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (uart_circ_empty(&port->state->xmit)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) writel(CDNS_UART_IXR_TXEMPTY, port->membase + CDNS_UART_IDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) numbytes = port->fifosize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) while (numbytes && !uart_circ_empty(&port->state->xmit) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) !(readl(port->membase + CDNS_UART_SR) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) CDNS_UART_SR_TXFULL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * Get the data from the UART circular buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) * and write it to the cdns_uart's TX_FIFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * register.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) writel(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) port->state->xmit.buf[port->state->xmit.tail],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) port->membase + CDNS_UART_FIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) port->icount.tx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * Adjust the tail of the UART buffer and wrap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) * the buffer if it reaches limit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) port->state->xmit.tail =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) (port->state->xmit.tail + 1) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) (UART_XMIT_SIZE - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) numbytes--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) if (uart_circ_chars_pending(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) &port->state->xmit) < WAKEUP_CHARS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) uart_write_wakeup(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * cdns_uart_isr - Interrupt handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * @irq: Irq number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) * @dev_id: Id of the port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) * Return: IRQHANDLED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) static irqreturn_t cdns_uart_isr(int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) struct uart_port *port = (struct uart_port *)dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) unsigned int isrstatus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) spin_lock(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) /* Read the interrupt status register to determine which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * interrupt(s) is/are active and clear them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) isrstatus = readl(port->membase + CDNS_UART_ISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) writel(isrstatus, port->membase + CDNS_UART_ISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) if (isrstatus & CDNS_UART_IXR_TXEMPTY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) cdns_uart_handle_tx(dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) isrstatus &= ~CDNS_UART_IXR_TXEMPTY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * Skip RX processing if RX is disabled as RXEMPTY will never be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * as read bytes will not be removed from the FIFO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) if (isrstatus & CDNS_UART_IXR_RXMASK &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) !(readl(port->membase + CDNS_UART_CR) & CDNS_UART_CR_RX_DIS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) cdns_uart_handle_rx(dev_id, isrstatus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) spin_unlock(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) * cdns_uart_calc_baud_divs - Calculate baud rate divisors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) * @clk: UART module input clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) * @baud: Desired baud rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) * @rbdiv: BDIV value (return value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * @rcd: CD value (return value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * @div8: Value for clk_sel bit in mod (return value)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) * Return: baud rate, requested baud when possible, or actual baud when there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * was too much error, zero if no valid divisors are found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * Formula to obtain baud rate is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * baud_tx/rx rate = clk/CD * (BDIV + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) * input_clk = (Uart User Defined Clock or Apb Clock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * depends on UCLKEN in MR Reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * clk = input_clk or input_clk/8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * depends on CLKS in MR reg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * CD and BDIV depends on values in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) * baud rate generate register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * baud rate clock divisor register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) static unsigned int cdns_uart_calc_baud_divs(unsigned int clk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) unsigned int baud, u32 *rbdiv, u32 *rcd, int *div8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) u32 cd, bdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) unsigned int calc_baud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) unsigned int bestbaud = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) unsigned int bauderror;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) unsigned int besterror = ~0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (baud < clk / ((CDNS_UART_BDIV_MAX + 1) * CDNS_UART_CD_MAX)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) *div8 = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) clk /= 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) *div8 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) for (bdiv = CDNS_UART_BDIV_MIN; bdiv <= CDNS_UART_BDIV_MAX; bdiv++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) cd = DIV_ROUND_CLOSEST(clk, baud * (bdiv + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (cd < 1 || cd > CDNS_UART_CD_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) calc_baud = clk / (cd * (bdiv + 1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (baud > calc_baud)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) bauderror = baud - calc_baud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) bauderror = calc_baud - baud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) if (besterror > bauderror) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) *rbdiv = bdiv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) *rcd = cd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) bestbaud = calc_baud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) besterror = bauderror;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) /* use the values when percent error is acceptable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (((besterror * 100) / baud) < 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) bestbaud = baud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return bestbaud;
^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) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * cdns_uart_set_baud_rate - Calculate and set the baud rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) * @port: Handle to the uart port structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * @baud: Baud rate to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * Return: baud rate, requested baud when possible, or actual baud when there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * was too much error, zero if no valid divisors are found.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) static unsigned int cdns_uart_set_baud_rate(struct uart_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) unsigned int baud)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) unsigned int calc_baud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) u32 cd = 0, bdiv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) u32 mreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) int div8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) struct cdns_uart *cdns_uart = port->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) calc_baud = cdns_uart_calc_baud_divs(port->uartclk, baud, &bdiv, &cd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) &div8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) /* Write new divisors to hardware */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) mreg = readl(port->membase + CDNS_UART_MR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) if (div8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) mreg |= CDNS_UART_MR_CLKSEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) mreg &= ~CDNS_UART_MR_CLKSEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) writel(mreg, port->membase + CDNS_UART_MR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) writel(cd, port->membase + CDNS_UART_BAUDGEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) writel(bdiv, port->membase + CDNS_UART_BAUDDIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) cdns_uart->baud = baud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return calc_baud;
^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) #ifdef CONFIG_COMMON_CLK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * cdns_uart_clk_notitifer_cb - Clock notifier callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * @nb: Notifier block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) * @event: Notify event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) * @data: Notifier data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * Return: NOTIFY_OK or NOTIFY_DONE on success, NOTIFY_BAD on error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) static int cdns_uart_clk_notifier_cb(struct notifier_block *nb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) unsigned long event, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) u32 ctrl_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) struct uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) int locked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) struct clk_notifier_data *ndata = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) struct cdns_uart *cdns_uart = to_cdns_uart(nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) port = cdns_uart->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) if (port->suspended)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) switch (event) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) case PRE_RATE_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) u32 bdiv, cd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) int div8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) * Find out if current baud-rate can be achieved with new clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * frequency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (!cdns_uart_calc_baud_divs(ndata->new_rate, cdns_uart->baud,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) &bdiv, &cd, &div8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) dev_warn(port->dev, "clock rate change rejected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) return NOTIFY_BAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) spin_lock_irqsave(&cdns_uart->port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) /* Disable the TX and RX to set baud rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) ctrl_reg = readl(port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) ctrl_reg |= CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) writel(ctrl_reg, port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) spin_unlock_irqrestore(&cdns_uart->port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) case POST_RATE_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * Set clk dividers to generate correct baud with new clock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * frequency.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) spin_lock_irqsave(&cdns_uart->port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) locked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) port->uartclk = ndata->new_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) cdns_uart->baud = cdns_uart_set_baud_rate(cdns_uart->port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) cdns_uart->baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) case ABORT_RATE_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) if (!locked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) spin_lock_irqsave(&cdns_uart->port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) /* Set TX/RX Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) ctrl_reg = readl(port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) ctrl_reg |= CDNS_UART_CR_TXRST | CDNS_UART_CR_RXRST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) writel(ctrl_reg, port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) while (readl(port->membase + CDNS_UART_CR) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) (CDNS_UART_CR_TXRST | CDNS_UART_CR_RXRST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) * Clear the RX disable and TX disable bits and then set the TX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) * enable bit and RX enable bit to enable the transmitter and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) * receiver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) writel(rx_timeout, port->membase + CDNS_UART_RXTOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) ctrl_reg = readl(port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) ctrl_reg &= ~(CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) ctrl_reg |= CDNS_UART_CR_TX_EN | CDNS_UART_CR_RX_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) writel(ctrl_reg, port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) spin_unlock_irqrestore(&cdns_uart->port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) * cdns_uart_start_tx - Start transmitting bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) * @port: Handle to the uart port structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) static void cdns_uart_start_tx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (uart_tx_stopped(port))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) * Set the TX enable bit and clear the TX disable bit to enable the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) * transmitter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) status = readl(port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) status &= ~CDNS_UART_CR_TX_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) status |= CDNS_UART_CR_TX_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) writel(status, port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (uart_circ_empty(&port->state->xmit))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) writel(CDNS_UART_IXR_TXEMPTY, port->membase + CDNS_UART_ISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) cdns_uart_handle_tx(port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) /* Enable the TX Empty interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) writel(CDNS_UART_IXR_TXEMPTY, port->membase + CDNS_UART_IER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * cdns_uart_stop_tx - Stop TX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * @port: Handle to the uart port structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) static void cdns_uart_stop_tx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) unsigned int regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) regval = readl(port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) regval |= CDNS_UART_CR_TX_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) /* Disable the transmitter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) writel(regval, port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) * cdns_uart_stop_rx - Stop RX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) * @port: Handle to the uart port structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) static void cdns_uart_stop_rx(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) unsigned int regval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) /* Disable RX IRQs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) writel(CDNS_UART_RX_IRQS, port->membase + CDNS_UART_IDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /* Disable the receiver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) regval = readl(port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) regval |= CDNS_UART_CR_RX_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) writel(regval, port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * cdns_uart_tx_empty - Check whether TX is empty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) * @port: Handle to the uart port structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * Return: TIOCSER_TEMT on success, 0 otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) static unsigned int cdns_uart_tx_empty(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) status = readl(port->membase + CDNS_UART_SR) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) (CDNS_UART_SR_TXEMPTY | CDNS_UART_SR_TACTIVE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) return (status == CDNS_UART_SR_TXEMPTY) ? TIOCSER_TEMT : 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) * cdns_uart_break_ctl - Based on the input ctl we have to start or stop
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) * transmitting char breaks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) * @port: Handle to the uart port structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) * @ctl: Value based on which start or stop decision is taken
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) static void cdns_uart_break_ctl(struct uart_port *port, int ctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) unsigned int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) status = readl(port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) if (ctl == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) writel(CDNS_UART_CR_STARTBRK | status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) if ((status & CDNS_UART_CR_STOPBRK) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) writel(CDNS_UART_CR_STOPBRK | status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) * cdns_uart_set_termios - termios operations, handling data length, parity,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) * stop bits, flow control, baud rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) * @port: Handle to the uart port structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) * @termios: Handle to the input termios structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) * @old: Values of the previously saved termios structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) static void cdns_uart_set_termios(struct uart_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) struct ktermios *termios, struct ktermios *old)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) u32 cval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) unsigned int baud, minbaud, maxbaud;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) unsigned int ctrl_reg, mode_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) /* Disable the TX and RX to set baud rate */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) ctrl_reg = readl(port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) ctrl_reg |= CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) writel(ctrl_reg, port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) * Min baud rate = 6bps and Max Baud Rate is 10Mbps for 100Mhz clk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) * min and max baud should be calculated here based on port->uartclk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) * this way we get a valid baud and can safely call set_baud()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) minbaud = port->uartclk /
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) ((CDNS_UART_BDIV_MAX + 1) * CDNS_UART_CD_MAX * 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) maxbaud = port->uartclk / (CDNS_UART_BDIV_MIN + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) baud = uart_get_baud_rate(port, termios, old, minbaud, maxbaud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) baud = cdns_uart_set_baud_rate(port, baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) if (tty_termios_baud_rate(termios))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) tty_termios_encode_baud_rate(termios, baud, baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) /* Update the per-port timeout. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) uart_update_timeout(port, termios->c_cflag, baud);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) /* Set TX/RX Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) ctrl_reg = readl(port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) ctrl_reg |= CDNS_UART_CR_TXRST | CDNS_UART_CR_RXRST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) writel(ctrl_reg, port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) while (readl(port->membase + CDNS_UART_CR) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) (CDNS_UART_CR_TXRST | CDNS_UART_CR_RXRST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) * Clear the RX disable and TX disable bits and then set the TX enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) * bit and RX enable bit to enable the transmitter and receiver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) ctrl_reg = readl(port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) ctrl_reg &= ~(CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) ctrl_reg |= CDNS_UART_CR_TX_EN | CDNS_UART_CR_RX_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) writel(ctrl_reg, port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) writel(rx_timeout, port->membase + CDNS_UART_RXTOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) port->read_status_mask = CDNS_UART_IXR_TXEMPTY | CDNS_UART_IXR_RXTRIG |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) CDNS_UART_IXR_OVERRUN | CDNS_UART_IXR_TOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) port->ignore_status_mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) if (termios->c_iflag & INPCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) port->read_status_mask |= CDNS_UART_IXR_PARITY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) CDNS_UART_IXR_FRAMING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) if (termios->c_iflag & IGNPAR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) port->ignore_status_mask |= CDNS_UART_IXR_PARITY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) CDNS_UART_IXR_FRAMING | CDNS_UART_IXR_OVERRUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) /* ignore all characters if CREAD is not set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if ((termios->c_cflag & CREAD) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) port->ignore_status_mask |= CDNS_UART_IXR_RXTRIG |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) CDNS_UART_IXR_TOUT | CDNS_UART_IXR_PARITY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) CDNS_UART_IXR_FRAMING | CDNS_UART_IXR_OVERRUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) mode_reg = readl(port->membase + CDNS_UART_MR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) /* Handling Data Size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) switch (termios->c_cflag & CSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) case CS6:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) cval |= CDNS_UART_MR_CHARLEN_6_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) case CS7:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) cval |= CDNS_UART_MR_CHARLEN_7_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) case CS8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) cval |= CDNS_UART_MR_CHARLEN_8_BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) termios->c_cflag &= ~CSIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) termios->c_cflag |= CS8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) /* Handling Parity and Stop Bits length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) if (termios->c_cflag & CSTOPB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) cval |= CDNS_UART_MR_STOPMODE_2_BIT; /* 2 STOP bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) cval |= CDNS_UART_MR_STOPMODE_1_BIT; /* 1 STOP bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (termios->c_cflag & PARENB) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) /* Mark or Space parity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (termios->c_cflag & CMSPAR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) if (termios->c_cflag & PARODD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) cval |= CDNS_UART_MR_PARITY_MARK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) cval |= CDNS_UART_MR_PARITY_SPACE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (termios->c_cflag & PARODD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) cval |= CDNS_UART_MR_PARITY_ODD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) cval |= CDNS_UART_MR_PARITY_EVEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) cval |= CDNS_UART_MR_PARITY_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) cval |= mode_reg & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) writel(cval, port->membase + CDNS_UART_MR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) cval = readl(port->membase + CDNS_UART_MODEMCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) if (termios->c_cflag & CRTSCTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) cval |= CDNS_UART_MODEMCR_FCM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) cval &= ~CDNS_UART_MODEMCR_FCM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) writel(cval, port->membase + CDNS_UART_MODEMCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) * cdns_uart_startup - Called when an application opens a cdns_uart port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) * @port: Handle to the uart port structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) * Return: 0 on success, negative errno otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) static int cdns_uart_startup(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) struct cdns_uart *cdns_uart = port->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) bool is_brk_support;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) unsigned int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) is_brk_support = cdns_uart->quirks & CDNS_UART_RXBS_SUPPORT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) /* Disable the TX and RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) writel(CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) /* Set the Control Register with TX/RX Enable, TX/RX Reset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) * no break chars.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) writel(CDNS_UART_CR_TXRST | CDNS_UART_CR_RXRST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) while (readl(port->membase + CDNS_UART_CR) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) (CDNS_UART_CR_TXRST | CDNS_UART_CR_RXRST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) * Clear the RX disable bit and then set the RX enable bit to enable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) * the receiver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) status = readl(port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) status &= ~CDNS_UART_CR_RX_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) status |= CDNS_UART_CR_RX_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) writel(status, port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) /* Set the Mode Register with normal mode,8 data bits,1 stop bit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) * no parity.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) writel(CDNS_UART_MR_CHMODE_NORM | CDNS_UART_MR_STOPMODE_1_BIT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) | CDNS_UART_MR_PARITY_NONE | CDNS_UART_MR_CHARLEN_8_BIT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) port->membase + CDNS_UART_MR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) * Set the RX FIFO Trigger level to use most of the FIFO, but it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) * can be tuned with a module parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) writel(rx_trigger_level, port->membase + CDNS_UART_RXWM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) * Receive Timeout register is enabled but it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) * can be tuned with a module parameter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) writel(rx_timeout, port->membase + CDNS_UART_RXTOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) /* Clear out any pending interrupts before enabling them */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) writel(readl(port->membase + CDNS_UART_ISR),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) port->membase + CDNS_UART_ISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) ret = request_irq(port->irq, cdns_uart_isr, 0, CDNS_UART_NAME, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) dev_err(port->dev, "request_irq '%d' failed with %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) port->irq, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) /* Set the Interrupt Registers with desired interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) if (is_brk_support)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) writel(CDNS_UART_RX_IRQS | CDNS_UART_IXR_BRK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) port->membase + CDNS_UART_IER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) writel(CDNS_UART_RX_IRQS, port->membase + CDNS_UART_IER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) * cdns_uart_shutdown - Called when an application closes a cdns_uart port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) * @port: Handle to the uart port structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) static void cdns_uart_shutdown(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) /* Disable interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) status = readl(port->membase + CDNS_UART_IMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) writel(status, port->membase + CDNS_UART_IDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) writel(0xffffffff, port->membase + CDNS_UART_ISR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) /* Disable the TX and RX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) writel(CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) free_irq(port->irq, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) * cdns_uart_type - Set UART type to cdns_uart port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) * @port: Handle to the uart port structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * Return: string on success, NULL otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) static const char *cdns_uart_type(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) return port->type == PORT_XUARTPS ? CDNS_UART_NAME : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) * cdns_uart_verify_port - Verify the port params
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) * @port: Handle to the uart port structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) * @ser: Handle to the structure whose members are compared
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) * Return: 0 on success, negative errno otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) static int cdns_uart_verify_port(struct uart_port *port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) struct serial_struct *ser)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if (ser->type != PORT_UNKNOWN && ser->type != PORT_XUARTPS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) if (port->irq != ser->irq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) if (ser->io_type != UPIO_MEM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) if (port->iobase != ser->port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) if (ser->hub6 != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) * cdns_uart_request_port - Claim the memory region attached to cdns_uart port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) * called when the driver adds a cdns_uart port via
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) * uart_add_one_port()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) * @port: Handle to the uart port structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) * Return: 0 on success, negative errno otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) static int cdns_uart_request_port(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) if (!request_mem_region(port->mapbase, CDNS_UART_REGISTER_SPACE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) CDNS_UART_NAME)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) port->membase = ioremap(port->mapbase, CDNS_UART_REGISTER_SPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (!port->membase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) dev_err(port->dev, "Unable to map registers\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) release_mem_region(port->mapbase, CDNS_UART_REGISTER_SPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) * cdns_uart_release_port - Release UART port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) * @port: Handle to the uart port structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) * Release the memory region attached to a cdns_uart port. Called when the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) * driver removes a cdns_uart port via uart_remove_one_port().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) static void cdns_uart_release_port(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) release_mem_region(port->mapbase, CDNS_UART_REGISTER_SPACE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) iounmap(port->membase);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) port->membase = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) * cdns_uart_config_port - Configure UART port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) * @port: Handle to the uart port structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) * @flags: If any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) static void cdns_uart_config_port(struct uart_port *port, int flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) if (flags & UART_CONFIG_TYPE && cdns_uart_request_port(port) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) port->type = PORT_XUARTPS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) * cdns_uart_get_mctrl - Get the modem control state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) * @port: Handle to the uart port structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) * Return: the modem control state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) static unsigned int cdns_uart_get_mctrl(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) unsigned int mctrl = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) struct cdns_uart *cdns_uart_data = port->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) if (cdns_uart_data->cts_override)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) val = readl(port->membase + CDNS_UART_MODEMSR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) if (val & CDNS_UART_MODEMSR_CTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) mctrl |= TIOCM_CTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) if (val & CDNS_UART_MODEMSR_DSR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) mctrl |= TIOCM_DSR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) if (val & CDNS_UART_MODEMSR_RI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) mctrl |= TIOCM_RNG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) if (val & CDNS_UART_MODEMSR_DCD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) mctrl |= TIOCM_CAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) return mctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) static void cdns_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) u32 mode_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) struct cdns_uart *cdns_uart_data = port->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) if (cdns_uart_data->cts_override)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) val = readl(port->membase + CDNS_UART_MODEMCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) mode_reg = readl(port->membase + CDNS_UART_MR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) val &= ~(CDNS_UART_MODEMCR_RTS | CDNS_UART_MODEMCR_DTR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) mode_reg &= ~CDNS_UART_MR_CHMODE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) if (mctrl & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) val |= CDNS_UART_MODEMCR_RTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) if (mctrl & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) val |= CDNS_UART_MODEMCR_DTR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) if (mctrl & TIOCM_LOOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) mode_reg |= CDNS_UART_MR_CHMODE_L_LOOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) mode_reg |= CDNS_UART_MR_CHMODE_NORM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) writel(val, port->membase + CDNS_UART_MODEMCR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) writel(mode_reg, port->membase + CDNS_UART_MR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) #ifdef CONFIG_CONSOLE_POLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) static int cdns_uart_poll_get_char(struct uart_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) int c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) /* Check if FIFO is empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) if (readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_RXEMPTY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) c = NO_POLL_CHAR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) else /* Read a character */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) c = (unsigned char) readl(port->membase + CDNS_UART_FIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) return c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) static void cdns_uart_poll_put_char(struct uart_port *port, unsigned char c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) /* Wait until FIFO is empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) while (!(readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_TXEMPTY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) /* Write a character */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) writel(c, port->membase + CDNS_UART_FIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) /* Wait until FIFO is empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) while (!(readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_TXEMPTY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) static void cdns_uart_pm(struct uart_port *port, unsigned int state,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) unsigned int oldstate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) switch (state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) case UART_PM_STATE_OFF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) pm_runtime_mark_last_busy(port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) pm_runtime_put_autosuspend(port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) pm_runtime_get_sync(port->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) static const struct uart_ops cdns_uart_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) .set_mctrl = cdns_uart_set_mctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) .get_mctrl = cdns_uart_get_mctrl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) .start_tx = cdns_uart_start_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) .stop_tx = cdns_uart_stop_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) .stop_rx = cdns_uart_stop_rx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) .tx_empty = cdns_uart_tx_empty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) .break_ctl = cdns_uart_break_ctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) .set_termios = cdns_uart_set_termios,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) .startup = cdns_uart_startup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) .shutdown = cdns_uart_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) .pm = cdns_uart_pm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) .type = cdns_uart_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) .verify_port = cdns_uart_verify_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) .request_port = cdns_uart_request_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) .release_port = cdns_uart_release_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) .config_port = cdns_uart_config_port,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) #ifdef CONFIG_CONSOLE_POLL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) .poll_get_char = cdns_uart_poll_get_char,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) .poll_put_char = cdns_uart_poll_put_char,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) static struct uart_driver cdns_uart_uart_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) * cdns_uart_console_putchar - write the character to the FIFO buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) * @port: Handle to the uart port structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) * @ch: Character to be written
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) static void cdns_uart_console_putchar(struct uart_port *port, int ch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) while (readl(port->membase + CDNS_UART_SR) & CDNS_UART_SR_TXFULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) writel(ch, port->membase + CDNS_UART_FIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) static void cdns_early_write(struct console *con, const char *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) unsigned n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) struct earlycon_device *dev = con->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) uart_console_write(&dev->port, s, n, cdns_uart_console_putchar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) static int __init cdns_early_console_setup(struct earlycon_device *device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) const char *opt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) struct uart_port *port = &device->port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) if (!port->membase)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) /* initialise control register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) writel(CDNS_UART_CR_TX_EN|CDNS_UART_CR_TXRST|CDNS_UART_CR_RXRST,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) /* only set baud if specified on command line - otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) * assume it has been initialized by a boot loader.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) if (port->uartclk && device->baud) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) u32 cd = 0, bdiv = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) u32 mr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) int div8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) cdns_uart_calc_baud_divs(port->uartclk, device->baud,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) &bdiv, &cd, &div8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) mr = CDNS_UART_MR_PARITY_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) if (div8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) mr |= CDNS_UART_MR_CLKSEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) writel(mr, port->membase + CDNS_UART_MR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) writel(cd, port->membase + CDNS_UART_BAUDGEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) writel(bdiv, port->membase + CDNS_UART_BAUDDIV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) device->con->write = cdns_early_write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) OF_EARLYCON_DECLARE(cdns, "xlnx,xuartps", cdns_early_console_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) OF_EARLYCON_DECLARE(cdns, "cdns,uart-r1p8", cdns_early_console_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) OF_EARLYCON_DECLARE(cdns, "cdns,uart-r1p12", cdns_early_console_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) OF_EARLYCON_DECLARE(cdns, "xlnx,zynqmp-uart", cdns_early_console_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) /* Static pointer to console port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) static struct uart_port *console_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) * cdns_uart_console_write - perform write operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) * @co: Console handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) * @s: Pointer to character array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) * @count: No of characters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) static void cdns_uart_console_write(struct console *co, const char *s,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) unsigned int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) struct uart_port *port = console_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) unsigned int imr, ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) int locked = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) if (port->sysrq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) locked = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) else if (oops_in_progress)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) locked = spin_trylock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) /* save and disable interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) imr = readl(port->membase + CDNS_UART_IMR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) writel(imr, port->membase + CDNS_UART_IDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) * Make sure that the tx part is enabled. Set the TX enable bit and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) * clear the TX disable bit to enable the transmitter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) ctrl = readl(port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) ctrl &= ~CDNS_UART_CR_TX_DIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) ctrl |= CDNS_UART_CR_TX_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) writel(ctrl, port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) uart_console_write(port, s, count, cdns_uart_console_putchar);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) while (cdns_uart_tx_empty(port) != TIOCSER_TEMT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) /* restore interrupt state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) writel(imr, port->membase + CDNS_UART_IER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) if (locked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) * cdns_uart_console_setup - Initialize the uart to default config
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) * @co: Console handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) * @options: Initial settings of uart
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) * Return: 0 on success, negative errno otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) static int cdns_uart_console_setup(struct console *co, char *options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) struct uart_port *port = console_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) int baud = 9600;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) int bits = 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) int parity = 'n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) int flow = 'n';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) unsigned long time_out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) if (!port->membase) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) pr_debug("console on " CDNS_UART_TTY_NAME "%i not present\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) co->index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) if (options)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) uart_parse_options(options, &baud, &parity, &bits, &flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) /* Wait for tx_empty before setting up the console */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) time_out = jiffies + usecs_to_jiffies(TX_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) while (time_before(jiffies, time_out) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) cdns_uart_tx_empty(port) != TIOCSER_TEMT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) return uart_set_options(port, co, baud, parity, bits, flow);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) static struct console cdns_uart_console = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) .name = CDNS_UART_TTY_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) .write = cdns_uart_console_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) .device = uart_console_device,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) .setup = cdns_uart_console_setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) .flags = CON_PRINTBUFFER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) .index = -1, /* Specified on the cmdline (e.g. console=ttyPS ) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) .data = &cdns_uart_uart_driver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) #endif /* CONFIG_SERIAL_XILINX_PS_UART_CONSOLE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) * cdns_uart_suspend - suspend event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) * @device: Pointer to the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) * Return: 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) static int cdns_uart_suspend(struct device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) struct uart_port *port = dev_get_drvdata(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) struct cdns_uart *cdns_uart = port->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) int may_wake;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) may_wake = device_may_wakeup(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) if (console_suspend_enabled && uart_console(port) && may_wake) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) /* Empty the receive FIFO 1st before making changes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) while (!(readl(port->membase + CDNS_UART_SR) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) CDNS_UART_SR_RXEMPTY))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) readl(port->membase + CDNS_UART_FIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) /* set RX trigger level to 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) writel(1, port->membase + CDNS_UART_RXWM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) /* disable RX timeout interrups */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) writel(CDNS_UART_IXR_TOUT, port->membase + CDNS_UART_IDR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) * Call the API provided in serial_core.c file which handles
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) * the suspend.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) return uart_suspend_port(cdns_uart->cdns_uart_driver, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) * cdns_uart_resume - Resume after a previous suspend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) * @device: Pointer to the device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) * Return: 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) static int cdns_uart_resume(struct device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) struct uart_port *port = dev_get_drvdata(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) struct cdns_uart *cdns_uart = port->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) unsigned long flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) u32 ctrl_reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) int may_wake;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) may_wake = device_may_wakeup(device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) if (console_suspend_enabled && uart_console(port) && !may_wake) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) clk_enable(cdns_uart->pclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) clk_enable(cdns_uart->uartclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) /* Set TX/RX Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) ctrl_reg = readl(port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) ctrl_reg |= CDNS_UART_CR_TXRST | CDNS_UART_CR_RXRST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) writel(ctrl_reg, port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) while (readl(port->membase + CDNS_UART_CR) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) (CDNS_UART_CR_TXRST | CDNS_UART_CR_RXRST))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) cpu_relax();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) /* restore rx timeout value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) writel(rx_timeout, port->membase + CDNS_UART_RXTOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) /* Enable Tx/Rx */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) ctrl_reg = readl(port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) ctrl_reg &= ~(CDNS_UART_CR_TX_DIS | CDNS_UART_CR_RX_DIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) ctrl_reg |= CDNS_UART_CR_TX_EN | CDNS_UART_CR_RX_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) writel(ctrl_reg, port->membase + CDNS_UART_CR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) clk_disable(cdns_uart->uartclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) clk_disable(cdns_uart->pclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) spin_lock_irqsave(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) /* restore original rx trigger level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) writel(rx_trigger_level, port->membase + CDNS_UART_RXWM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) /* enable RX timeout interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) writel(CDNS_UART_IXR_TOUT, port->membase + CDNS_UART_IER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) spin_unlock_irqrestore(&port->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) return uart_resume_port(cdns_uart->cdns_uart_driver, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) #endif /* ! CONFIG_PM_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) static int __maybe_unused cdns_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) struct uart_port *port = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) struct cdns_uart *cdns_uart = port->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) clk_disable(cdns_uart->uartclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) clk_disable(cdns_uart->pclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) static int __maybe_unused cdns_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) struct uart_port *port = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) struct cdns_uart *cdns_uart = port->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) clk_enable(cdns_uart->pclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) clk_enable(cdns_uart->uartclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) static const struct dev_pm_ops cdns_uart_dev_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) SET_SYSTEM_SLEEP_PM_OPS(cdns_uart_suspend, cdns_uart_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) SET_RUNTIME_PM_OPS(cdns_runtime_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) cdns_runtime_resume, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) static const struct cdns_platform_data zynqmp_uart_def = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) .quirks = CDNS_UART_RXBS_SUPPORT, };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) /* Match table for of_platform binding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) static const struct of_device_id cdns_uart_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) { .compatible = "xlnx,xuartps", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) { .compatible = "cdns,uart-r1p8", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) { .compatible = "cdns,uart-r1p12", .data = &zynqmp_uart_def },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) { .compatible = "xlnx,zynqmp-uart", .data = &zynqmp_uart_def },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) MODULE_DEVICE_TABLE(of, cdns_uart_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) /* Temporary variable for storing number of instances */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) static int instances;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) * cdns_uart_probe - Platform driver probe
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) * @pdev: Pointer to the platform device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) * Return: 0 on success, negative errno otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) static int cdns_uart_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) int rc, id, irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) struct uart_port *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) struct cdns_uart *cdns_uart_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) const struct of_device_id *match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) cdns_uart_data = devm_kzalloc(&pdev->dev, sizeof(*cdns_uart_data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) if (!cdns_uart_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) if (!port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) /* Look for a serialN alias */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) id = of_alias_get_id(pdev->dev.of_node, "serial");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) if (id < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) if (id >= CDNS_UART_NR_PORTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) dev_err(&pdev->dev, "Cannot get uart_port structure\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) if (!cdns_uart_uart_driver.state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) cdns_uart_uart_driver.owner = THIS_MODULE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) cdns_uart_uart_driver.driver_name = CDNS_UART_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) cdns_uart_uart_driver.dev_name = CDNS_UART_TTY_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) cdns_uart_uart_driver.major = CDNS_UART_MAJOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) cdns_uart_uart_driver.minor = CDNS_UART_MINOR;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) cdns_uart_uart_driver.nr = CDNS_UART_NR_PORTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) cdns_uart_uart_driver.cons = &cdns_uart_console;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) rc = uart_register_driver(&cdns_uart_uart_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) dev_err(&pdev->dev, "Failed to register driver\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) cdns_uart_data->cdns_uart_driver = &cdns_uart_uart_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) match = of_match_node(cdns_uart_of_match, pdev->dev.of_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) if (match && match->data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) const struct cdns_platform_data *data = match->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) cdns_uart_data->quirks = data->quirks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) cdns_uart_data->pclk = devm_clk_get(&pdev->dev, "pclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) if (PTR_ERR(cdns_uart_data->pclk) == -EPROBE_DEFER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) rc = PTR_ERR(cdns_uart_data->pclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) goto err_out_unregister_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) if (IS_ERR(cdns_uart_data->pclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) cdns_uart_data->pclk = devm_clk_get(&pdev->dev, "aper_clk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) if (IS_ERR(cdns_uart_data->pclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) rc = PTR_ERR(cdns_uart_data->pclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) goto err_out_unregister_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) dev_err(&pdev->dev, "clock name 'aper_clk' is deprecated.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) cdns_uart_data->uartclk = devm_clk_get(&pdev->dev, "uart_clk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) if (PTR_ERR(cdns_uart_data->uartclk) == -EPROBE_DEFER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) rc = PTR_ERR(cdns_uart_data->uartclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) goto err_out_unregister_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) if (IS_ERR(cdns_uart_data->uartclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) cdns_uart_data->uartclk = devm_clk_get(&pdev->dev, "ref_clk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) if (IS_ERR(cdns_uart_data->uartclk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) rc = PTR_ERR(cdns_uart_data->uartclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) goto err_out_unregister_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) dev_err(&pdev->dev, "clock name 'ref_clk' is deprecated.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) rc = clk_prepare_enable(cdns_uart_data->pclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) dev_err(&pdev->dev, "Unable to enable pclk clock.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) goto err_out_unregister_driver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) rc = clk_prepare_enable(cdns_uart_data->uartclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) dev_err(&pdev->dev, "Unable to enable device clock.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) goto err_out_clk_dis_pclk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) if (!res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) goto err_out_clk_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) irq = platform_get_irq(pdev, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) if (irq <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) rc = -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) goto err_out_clk_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) #ifdef CONFIG_COMMON_CLK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) cdns_uart_data->clk_rate_change_nb.notifier_call =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) cdns_uart_clk_notifier_cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) if (clk_notifier_register(cdns_uart_data->uartclk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) &cdns_uart_data->clk_rate_change_nb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) dev_warn(&pdev->dev, "Unable to register clock notifier.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) /* At this point, we've got an empty uart_port struct, initialize it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) spin_lock_init(&port->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) port->type = PORT_UNKNOWN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) port->iotype = UPIO_MEM32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) port->flags = UPF_BOOT_AUTOCONF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) port->ops = &cdns_uart_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) port->fifosize = CDNS_UART_FIFO_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_XILINX_PS_UART_CONSOLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) port->line = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) * Register the port.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) * This function also registers this device with the tty layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) * and triggers invocation of the config_port() entry point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) port->mapbase = res->start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) port->irq = irq;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) port->dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) port->uartclk = clk_get_rate(cdns_uart_data->uartclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) port->private_data = cdns_uart_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) cdns_uart_data->port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) platform_set_drvdata(pdev, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) pm_runtime_use_autosuspend(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) pm_runtime_set_autosuspend_delay(&pdev->dev, UART_AUTOSUSPEND_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) pm_runtime_set_active(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) pm_runtime_enable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) device_init_wakeup(port->dev, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) * If console hasn't been found yet try to assign this port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) * because it is required to be assigned for console setup function.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) * If register_console() don't assign value, then console_port pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) * is cleanup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) if (!console_port) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) cdns_uart_console.index = id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) console_port = port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) rc = uart_add_one_port(&cdns_uart_uart_driver, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) dev_err(&pdev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) "uart_add_one_port() failed; err=%i\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) goto err_out_pm_disable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) /* This is not port which is used for console that's why clean it up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) if (console_port == port &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) !(cdns_uart_uart_driver.cons->flags & CON_ENABLED)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) console_port = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) cdns_uart_console.index = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) cdns_uart_data->cts_override = of_property_read_bool(pdev->dev.of_node,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) "cts-override");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) instances++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) err_out_pm_disable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) pm_runtime_set_suspended(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) pm_runtime_dont_use_autosuspend(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) #ifdef CONFIG_COMMON_CLK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) clk_notifier_unregister(cdns_uart_data->uartclk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) &cdns_uart_data->clk_rate_change_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) err_out_clk_disable:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) clk_disable_unprepare(cdns_uart_data->uartclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) err_out_clk_dis_pclk:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) clk_disable_unprepare(cdns_uart_data->pclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) err_out_unregister_driver:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) if (!instances)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) * cdns_uart_remove - called when the platform driver is unregistered
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) * @pdev: Pointer to the platform device structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) * Return: 0 on success, negative errno otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) static int cdns_uart_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) struct uart_port *port = platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) struct cdns_uart *cdns_uart_data = port->private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) /* Remove the cdns_uart port from the serial core */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) #ifdef CONFIG_COMMON_CLK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) clk_notifier_unregister(cdns_uart_data->uartclk,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) &cdns_uart_data->clk_rate_change_nb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) rc = uart_remove_one_port(cdns_uart_data->cdns_uart_driver, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) port->mapbase = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) clk_disable_unprepare(cdns_uart_data->uartclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) clk_disable_unprepare(cdns_uart_data->pclk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) pm_runtime_disable(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) pm_runtime_set_suspended(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) pm_runtime_dont_use_autosuspend(&pdev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) device_init_wakeup(&pdev->dev, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) if (console_port == port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) console_port = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) if (!--instances)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) uart_unregister_driver(cdns_uart_data->cdns_uart_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) static struct platform_driver cdns_uart_platform_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) .probe = cdns_uart_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) .remove = cdns_uart_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) .name = CDNS_UART_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) .of_match_table = cdns_uart_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) .pm = &cdns_uart_dev_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) .suppress_bind_attrs = IS_BUILTIN(CONFIG_SERIAL_XILINX_PS_UART),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) static int __init cdns_uart_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) /* Register the platform driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) return platform_driver_register(&cdns_uart_platform_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) static void __exit cdns_uart_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) /* Unregister the platform driver */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) platform_driver_unregister(&cdns_uart_platform_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) arch_initcall(cdns_uart_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) module_exit(cdns_uart_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) MODULE_DESCRIPTION("Driver for Cadence UART");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) MODULE_AUTHOR("Xilinx Inc.");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) MODULE_LICENSE("GPL");