1 // SPDX-License-Identifier: GPL-2.0+ 2 /* Synopsys DesignWare 8250 library. */ 3 4 #include <linux/bitops.h> 5 #include <linux/bitfield.h> 6 #include <linux/delay.h> 7 #include <linux/device.h> 8 #include <linux/kernel.h> 9 #include <linux/math.h> 10 #include <linux/property.h> 11 #include <linux/serial_8250.h> 12 #include <linux/serial_core.h> 13 14 #include "8250_dwlib.h" 15 16 /* 17 * divisor = div(I) + div(F) 18 * "I" means integer, "F" means fractional 19 * quot = div(I) = clk / (16 * baud) 20 * frac = div(F) * 2^dlf_size 21 * 22 * let rem = clk % (16 * baud) 23 * we have: div(F) * (16 * baud) = rem 24 * so frac = 2^dlf_size * rem / (16 * baud) = (rem << dlf_size) / (16 * baud) 25 */ 26 static unsigned int dw8250_get_divisor(struct uart_port *p, unsigned int baud, 27 unsigned int *frac) 28 { 29 unsigned int quot, rem, base_baud = baud * 16; 30 struct dw8250_port_data *d = p->private_data; 31 32 quot = p->uartclk / base_baud; 33 rem = p->uartclk % base_baud; 34 *frac = DIV_ROUND_CLOSEST(rem << d->dlf_size, base_baud); 35 36 return quot; 37 } 38 39 static void dw8250_set_divisor(struct uart_port *p, unsigned int baud, 40 unsigned int quot, unsigned int quot_frac) 41 { 42 dw8250_writel_ext(p, DW_UART_DLF, quot_frac); 43 serial8250_do_set_divisor(p, baud, quot); 44 } 45 46 void dw8250_do_set_termios(struct uart_port *p, struct ktermios *termios, 47 const struct ktermios *old) 48 { 49 p->status &= ~UPSTAT_AUTOCTS; 50 if (termios->c_cflag & CRTSCTS) 51 p->status |= UPSTAT_AUTOCTS; 52 53 serial8250_do_set_termios(p, termios, old); 54 55 /* Filter addresses which have 9th bit set */ 56 p->ignore_status_mask |= DW_UART_LSR_ADDR_RCVD; 57 p->read_status_mask |= DW_UART_LSR_ADDR_RCVD; 58 } 59 EXPORT_SYMBOL_GPL(dw8250_do_set_termios); 60 61 /* 62 * Wait until re is de-asserted for sure. An ongoing receive will keep 63 * re asserted until end of frame. Without BUSY indication available, 64 * only available course of action is to wait for the time it takes to 65 * receive one frame (there might nothing to receive but w/o BUSY the 66 * driver cannot know). 67 */ 68 static void dw8250_wait_re_deassert(struct uart_port *p) 69 { 70 ndelay(p->frame_time); 71 } 72 73 static void dw8250_update_rar(struct uart_port *p, u32 addr) 74 { 75 u32 re_en = dw8250_readl_ext(p, DW_UART_RE_EN); 76 77 /* 78 * RAR shouldn't be changed while receiving. Thus, de-assert RE_EN 79 * if asserted and wait. 80 */ 81 if (re_en) 82 dw8250_writel_ext(p, DW_UART_RE_EN, 0); 83 dw8250_wait_re_deassert(p); 84 dw8250_writel_ext(p, DW_UART_RAR, addr); 85 if (re_en) 86 dw8250_writel_ext(p, DW_UART_RE_EN, re_en); 87 } 88 89 static void dw8250_rs485_set_addr(struct uart_port *p, struct serial_rs485 *rs485, 90 struct ktermios *termios) 91 { 92 u32 lcr = dw8250_readl_ext(p, DW_UART_LCR_EXT); 93 94 if (rs485->flags & SER_RS485_ADDRB) { 95 lcr |= DW_UART_LCR_EXT_DLS_E; 96 if (termios) 97 termios->c_cflag |= ADDRB; 98 99 if (rs485->flags & SER_RS485_ADDR_RECV) { 100 u32 delta = p->rs485.flags ^ rs485->flags; 101 102 /* 103 * rs485 (param) is equal to uart_port's rs485 only during init 104 * (during init, delta is not yet applicable). 105 */ 106 if (unlikely(&p->rs485 == rs485)) 107 delta = rs485->flags; 108 109 if ((delta & SER_RS485_ADDR_RECV) || 110 (p->rs485.addr_recv != rs485->addr_recv)) 111 dw8250_update_rar(p, rs485->addr_recv); 112 lcr |= DW_UART_LCR_EXT_ADDR_MATCH; 113 } else { 114 lcr &= ~DW_UART_LCR_EXT_ADDR_MATCH; 115 } 116 if (rs485->flags & SER_RS485_ADDR_DEST) { 117 /* 118 * Don't skip writes here as another endpoint could 119 * have changed communication line's destination 120 * address in between. 121 */ 122 dw8250_writel_ext(p, DW_UART_TAR, rs485->addr_dest); 123 lcr |= DW_UART_LCR_EXT_SEND_ADDR; 124 } 125 } else { 126 lcr = 0; 127 } 128 dw8250_writel_ext(p, DW_UART_LCR_EXT, lcr); 129 } 130 131 static int dw8250_rs485_config(struct uart_port *p, struct ktermios *termios, 132 struct serial_rs485 *rs485) 133 { 134 u32 tcr; 135 136 tcr = dw8250_readl_ext(p, DW_UART_TCR); 137 tcr &= ~DW_UART_TCR_XFER_MODE; 138 139 if (rs485->flags & SER_RS485_ENABLED) { 140 tcr |= DW_UART_TCR_RS485_EN; 141 142 if (rs485->flags & SER_RS485_RX_DURING_TX) 143 tcr |= DW_UART_TCR_XFER_MODE_DE_DURING_RE; 144 else 145 tcr |= DW_UART_TCR_XFER_MODE_DE_OR_RE; 146 dw8250_writel_ext(p, DW_UART_DE_EN, 1); 147 dw8250_writel_ext(p, DW_UART_RE_EN, 1); 148 } else { 149 if (termios) 150 termios->c_cflag &= ~ADDRB; 151 152 tcr &= ~DW_UART_TCR_RS485_EN; 153 } 154 155 /* Reset to default polarity */ 156 tcr |= DW_UART_TCR_DE_POL; 157 tcr &= ~DW_UART_TCR_RE_POL; 158 159 if (!(rs485->flags & SER_RS485_RTS_ON_SEND)) 160 tcr &= ~DW_UART_TCR_DE_POL; 161 if (device_property_read_bool(p->dev, "rs485-rx-active-high")) 162 tcr |= DW_UART_TCR_RE_POL; 163 164 dw8250_writel_ext(p, DW_UART_TCR, tcr); 165 166 /* Addressing mode can only be set up after TCR */ 167 if (rs485->flags & SER_RS485_ENABLED) 168 dw8250_rs485_set_addr(p, rs485, termios); 169 170 return 0; 171 } 172 173 /* 174 * Tests if RE_EN register can have non-zero value to see if RS-485 HW support 175 * is present. 176 */ 177 static bool dw8250_detect_rs485_hw(struct uart_port *p) 178 { 179 u32 reg; 180 181 dw8250_writel_ext(p, DW_UART_RE_EN, 1); 182 reg = dw8250_readl_ext(p, DW_UART_RE_EN); 183 dw8250_writel_ext(p, DW_UART_RE_EN, 0); 184 return reg; 185 } 186 187 static const struct serial_rs485 dw8250_rs485_supported = { 188 .flags = SER_RS485_ENABLED | SER_RS485_RX_DURING_TX | SER_RS485_RTS_ON_SEND | 189 SER_RS485_RTS_AFTER_SEND | SER_RS485_ADDRB | SER_RS485_ADDR_RECV | 190 SER_RS485_ADDR_DEST, 191 }; 192 193 void dw8250_setup_port(struct uart_port *p) 194 { 195 struct dw8250_port_data *pd = p->private_data; 196 struct uart_8250_port *up = up_to_u8250p(p); 197 u32 reg, old_dlf; 198 199 pd->hw_rs485_support = dw8250_detect_rs485_hw(p); 200 if (pd->hw_rs485_support) { 201 p->rs485_config = dw8250_rs485_config; 202 up->lsr_save_mask = LSR_SAVE_FLAGS | DW_UART_LSR_ADDR_RCVD; 203 p->rs485_supported = dw8250_rs485_supported; 204 } else { 205 p->rs485_config = serial8250_em485_config; 206 p->rs485_supported = serial8250_em485_supported; 207 up->rs485_start_tx = serial8250_em485_start_tx; 208 up->rs485_stop_tx = serial8250_em485_stop_tx; 209 } 210 up->capabilities |= UART_CAP_NOTEMT; 211 212 /* Preserve value written by firmware or bootloader */ 213 old_dlf = dw8250_readl_ext(p, DW_UART_DLF); 214 dw8250_writel_ext(p, DW_UART_DLF, ~0U); 215 reg = dw8250_readl_ext(p, DW_UART_DLF); 216 dw8250_writel_ext(p, DW_UART_DLF, old_dlf); 217 218 if (reg) { 219 pd->dlf_size = fls(reg); 220 p->get_divisor = dw8250_get_divisor; 221 p->set_divisor = dw8250_set_divisor; 222 } 223 224 reg = dw8250_readl_ext(p, DW_UART_UCV); 225 if (reg) 226 dev_dbg(p->dev, "Designware UART version %c.%c%c\n", 227 (reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff); 228 229 reg = dw8250_readl_ext(p, DW_UART_CPR); 230 if (!reg) { 231 reg = pd->cpr_value; 232 dev_dbg(p->dev, "CPR is not available, using 0x%08x instead\n", reg); 233 } 234 if (!reg) 235 return; 236 237 /* Select the type based on FIFO */ 238 if (reg & DW_UART_CPR_FIFO_MODE) { 239 p->type = PORT_16550A; 240 p->flags |= UPF_FIXED_TYPE; 241 p->fifosize = DW_UART_CPR_FIFO_SIZE(reg); 242 up->capabilities = UART_CAP_FIFO | UART_CAP_NOTEMT; 243 } 244 245 if (reg & DW_UART_CPR_AFCE_MODE) 246 up->capabilities |= UART_CAP_AFE; 247 248 if (reg & DW_UART_CPR_SIR_MODE) 249 up->capabilities |= UART_CAP_IRDA; 250 } 251 EXPORT_SYMBOL_GPL(dw8250_setup_port); 252