Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

serial: 8250_fintek: Enable high speed mode on Fintek F81866

Fintek F81866 supports baud rates higher than 115200 but needs to raise
it's clock speed from 1.84 to 14.76 MHz.
This is eight times faster, so gives 921600 as resulting baud_base.

F81866 clock register 0xf2:
Bit 7-2 reserved
Bit 1-0 00: 1.8432MHz
01: 18.432MHz
10: 24MHz
11: 14.769MHz

Signed-off-by: Lukas Redlinger <rel+kernel@agilox.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Lukas Redlinger and committed by
Greg Kroah-Hartman
fab8a02b 71472fa9

+38 -5
+38 -5
drivers/tty/serial/8250/8250_fintek.c
··· 61 61 * The IRQ setting mode of F81866 is not the same with F81216 series. 62 62 * Level/Low: IRQ_MODE0:0, IRQ_MODE1:0 63 63 * Edge/High: IRQ_MODE0:1, IRQ_MODE1:0 64 + * 65 + * Clock speeds for UART (register F2h) 66 + * 00: 1.8432MHz. 67 + * 01: 18.432MHz. 68 + * 10: 24MHz. 69 + * 11: 14.769MHz. 64 70 */ 65 71 #define F81866_IRQ_MODE 0xf0 66 72 #define F81866_IRQ_SHARE BIT(0) ··· 77 71 78 72 #define F81866_LDN_LOW 0x10 79 73 #define F81866_LDN_HIGH 0x16 74 + 75 + #define F81866_UART_CLK 0xF2 76 + #define F81866_UART_CLK_MASK (BIT(1) | BIT(0)) 77 + #define F81866_UART_CLK_1_8432MHZ 0 78 + #define F81866_UART_CLK_14_769MHZ (BIT(1) | BIT(0)) 79 + #define F81866_UART_CLK_18_432MHZ BIT(0) 80 + #define F81866_UART_CLK_24MHZ BIT(1) 80 81 81 82 struct fintek_8250 { 82 83 u16 pid; ··· 269 256 } 270 257 } 271 258 272 - static int probe_setup_port(struct fintek_8250 *pdata, u16 io_address, 273 - unsigned int irq) 259 + static void fintek_8250_goto_highspeed(struct uart_8250_port *uart, 260 + struct fintek_8250 *pdata) 261 + { 262 + sio_write_reg(pdata, LDN, pdata->index); 263 + 264 + switch (pdata->pid) { 265 + case CHIP_ID_F81866: /* set uart clock for high speed serial mode */ 266 + sio_write_mask_reg(pdata, F81866_UART_CLK, 267 + F81866_UART_CLK_MASK, 268 + F81866_UART_CLK_14_769MHZ); 269 + 270 + uart->port.uartclk = 921600 * 16; 271 + break; 272 + default: /* leave clock speed untouched */ 273 + break; 274 + } 275 + } 276 + 277 + static int probe_setup_port(struct fintek_8250 *pdata, 278 + struct uart_8250_port *uart) 274 279 { 275 280 static const u16 addr[] = {0x4e, 0x2e}; 276 281 static const u8 keys[] = {0x77, 0xa0, 0x87, 0x67}; ··· 315 284 sio_write_reg(pdata, LDN, k); 316 285 aux = sio_read_reg(pdata, IO_ADDR1); 317 286 aux |= sio_read_reg(pdata, IO_ADDR2) << 8; 318 - if (aux != io_address) 287 + if (aux != uart->port.iobase) 319 288 continue; 320 289 321 290 pdata->index = k; 322 291 323 - irq_data = irq_get_irq_data(irq); 292 + irq_data = irq_get_irq_data(uart->port.irq); 324 293 if (irq_data) 325 294 level_mode = 326 295 irqd_is_level_type(irq_data); 327 296 328 297 fintek_8250_set_irq_mode(pdata, level_mode); 329 298 fintek_8250_set_max_fifo(pdata); 299 + fintek_8250_goto_highspeed(uart, pdata); 300 + 330 301 fintek_8250_exit_key(addr[i]); 331 302 332 303 return 0; ··· 363 330 struct fintek_8250 *pdata; 364 331 struct fintek_8250 probe_data; 365 332 366 - if (probe_setup_port(&probe_data, uart->port.iobase, uart->port.irq)) 333 + if (probe_setup_port(&probe_data, uart)) 367 334 return -ENODEV; 368 335 369 336 pdata = devm_kzalloc(uart->port.dev, sizeof(*pdata), GFP_KERNEL);