cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

8250_fintek.c (10608B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 *  Probe for F81216A LPC to 4 UART
      4 *
      5 *  Copyright (C) 2014-2016 Ricardo Ribalda, Qtechnology A/S
      6 */
      7#include <linux/module.h>
      8#include <linux/pci.h>
      9#include <linux/pnp.h>
     10#include <linux/kernel.h>
     11#include <linux/serial_core.h>
     12#include <linux/irq.h>
     13#include  "8250.h"
     14
     15#define ADDR_PORT 0
     16#define DATA_PORT 1
     17#define EXIT_KEY 0xAA
     18#define CHIP_ID1  0x20
     19#define CHIP_ID2  0x21
     20#define CHIP_ID_F81865 0x0407
     21#define CHIP_ID_F81866 0x1010
     22#define CHIP_ID_F81966 0x0215
     23#define CHIP_ID_F81216AD 0x1602
     24#define CHIP_ID_F81216H 0x0501
     25#define CHIP_ID_F81216 0x0802
     26#define VENDOR_ID1 0x23
     27#define VENDOR_ID1_VAL 0x19
     28#define VENDOR_ID2 0x24
     29#define VENDOR_ID2_VAL 0x34
     30#define IO_ADDR1 0x61
     31#define IO_ADDR2 0x60
     32#define LDN 0x7
     33
     34#define FINTEK_IRQ_MODE	0x70
     35#define IRQ_SHARE	BIT(4)
     36#define IRQ_MODE_MASK	(BIT(6) | BIT(5))
     37#define IRQ_LEVEL_LOW	0
     38#define IRQ_EDGE_HIGH	BIT(5)
     39
     40/*
     41 * F81216H clock source register, the value and mask is the same with F81866,
     42 * but it's on F0h.
     43 *
     44 * Clock speeds for UART (register F0h)
     45 * 00: 1.8432MHz.
     46 * 01: 18.432MHz.
     47 * 10: 24MHz.
     48 * 11: 14.769MHz.
     49 */
     50#define RS485  0xF0
     51#define RTS_INVERT BIT(5)
     52#define RS485_URA BIT(4)
     53#define RXW4C_IRA BIT(3)
     54#define TXW4C_IRA BIT(2)
     55
     56#define FIFO_CTRL		0xF6
     57#define FIFO_MODE_MASK		(BIT(1) | BIT(0))
     58#define FIFO_MODE_128		(BIT(1) | BIT(0))
     59#define RXFTHR_MODE_MASK	(BIT(5) | BIT(4))
     60#define RXFTHR_MODE_4X		BIT(5)
     61
     62#define F81216_LDN_LOW	0x0
     63#define F81216_LDN_HIGH	0x4
     64
     65/*
     66 * F81866/966 registers
     67 *
     68 * The IRQ setting mode of F81866/966 is not the same with F81216 series.
     69 *	Level/Low: IRQ_MODE0:0, IRQ_MODE1:0
     70 *	Edge/High: IRQ_MODE0:1, IRQ_MODE1:0
     71 *
     72 * Clock speeds for UART (register F2h)
     73 * 00: 1.8432MHz.
     74 * 01: 18.432MHz.
     75 * 10: 24MHz.
     76 * 11: 14.769MHz.
     77 */
     78#define F81866_IRQ_MODE		0xf0
     79#define F81866_IRQ_SHARE	BIT(0)
     80#define F81866_IRQ_MODE0	BIT(1)
     81
     82#define F81866_FIFO_CTRL	FIFO_CTRL
     83#define F81866_IRQ_MODE1	BIT(3)
     84
     85#define F81866_LDN_LOW		0x10
     86#define F81866_LDN_HIGH		0x16
     87
     88#define F81866_UART_CLK 0xF2
     89#define F81866_UART_CLK_MASK (BIT(1) | BIT(0))
     90#define F81866_UART_CLK_1_8432MHZ 0
     91#define F81866_UART_CLK_14_769MHZ (BIT(1) | BIT(0))
     92#define F81866_UART_CLK_18_432MHZ BIT(0)
     93#define F81866_UART_CLK_24MHZ BIT(1)
     94
     95struct fintek_8250 {
     96	u16 pid;
     97	u16 base_port;
     98	u8 index;
     99	u8 key;
    100};
    101
    102static u8 sio_read_reg(struct fintek_8250 *pdata, u8 reg)
    103{
    104	outb(reg, pdata->base_port + ADDR_PORT);
    105	return inb(pdata->base_port + DATA_PORT);
    106}
    107
    108static void sio_write_reg(struct fintek_8250 *pdata, u8 reg, u8 data)
    109{
    110	outb(reg, pdata->base_port + ADDR_PORT);
    111	outb(data, pdata->base_port + DATA_PORT);
    112}
    113
    114static void sio_write_mask_reg(struct fintek_8250 *pdata, u8 reg, u8 mask,
    115			       u8 data)
    116{
    117	u8 tmp;
    118
    119	tmp = (sio_read_reg(pdata, reg) & ~mask) | (mask & data);
    120	sio_write_reg(pdata, reg, tmp);
    121}
    122
    123static int fintek_8250_enter_key(u16 base_port, u8 key)
    124{
    125	if (!request_muxed_region(base_port, 2, "8250_fintek"))
    126		return -EBUSY;
    127
    128	/* Force to deactive all SuperIO in this base_port */
    129	outb(EXIT_KEY, base_port + ADDR_PORT);
    130
    131	outb(key, base_port + ADDR_PORT);
    132	outb(key, base_port + ADDR_PORT);
    133	return 0;
    134}
    135
    136static void fintek_8250_exit_key(u16 base_port)
    137{
    138
    139	outb(EXIT_KEY, base_port + ADDR_PORT);
    140	release_region(base_port + ADDR_PORT, 2);
    141}
    142
    143static int fintek_8250_check_id(struct fintek_8250 *pdata)
    144{
    145	u16 chip;
    146
    147	if (sio_read_reg(pdata, VENDOR_ID1) != VENDOR_ID1_VAL)
    148		return -ENODEV;
    149
    150	if (sio_read_reg(pdata, VENDOR_ID2) != VENDOR_ID2_VAL)
    151		return -ENODEV;
    152
    153	chip = sio_read_reg(pdata, CHIP_ID1);
    154	chip |= sio_read_reg(pdata, CHIP_ID2) << 8;
    155
    156	switch (chip) {
    157	case CHIP_ID_F81865:
    158	case CHIP_ID_F81866:
    159	case CHIP_ID_F81966:
    160	case CHIP_ID_F81216AD:
    161	case CHIP_ID_F81216H:
    162	case CHIP_ID_F81216:
    163		break;
    164	default:
    165		return -ENODEV;
    166	}
    167
    168	pdata->pid = chip;
    169	return 0;
    170}
    171
    172static int fintek_8250_get_ldn_range(struct fintek_8250 *pdata, int *min,
    173				     int *max)
    174{
    175	switch (pdata->pid) {
    176	case CHIP_ID_F81966:
    177	case CHIP_ID_F81865:
    178	case CHIP_ID_F81866:
    179		*min = F81866_LDN_LOW;
    180		*max = F81866_LDN_HIGH;
    181		return 0;
    182
    183	case CHIP_ID_F81216AD:
    184	case CHIP_ID_F81216H:
    185	case CHIP_ID_F81216:
    186		*min = F81216_LDN_LOW;
    187		*max = F81216_LDN_HIGH;
    188		return 0;
    189	}
    190
    191	return -ENODEV;
    192}
    193
    194static int fintek_8250_rs485_config(struct uart_port *port,
    195			      struct serial_rs485 *rs485)
    196{
    197	uint8_t config = 0;
    198	struct fintek_8250 *pdata = port->private_data;
    199
    200	if (!pdata)
    201		return -EINVAL;
    202
    203
    204	if (rs485->flags & SER_RS485_ENABLED) {
    205		/* Hardware do not support same RTS level on send and receive */
    206		if (!(rs485->flags & SER_RS485_RTS_ON_SEND) ==
    207		    !(rs485->flags & SER_RS485_RTS_AFTER_SEND))
    208			return -EINVAL;
    209		memset(rs485->padding, 0, sizeof(rs485->padding));
    210		config |= RS485_URA;
    211	} else {
    212		memset(rs485, 0, sizeof(*rs485));
    213	}
    214
    215	rs485->flags &= SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND |
    216			SER_RS485_RTS_AFTER_SEND;
    217
    218	/* Only the first port supports delays */
    219	if (pdata->index) {
    220		rs485->delay_rts_before_send = 0;
    221		rs485->delay_rts_after_send = 0;
    222	}
    223
    224	if (rs485->delay_rts_before_send) {
    225		rs485->delay_rts_before_send = 1;
    226		config |= TXW4C_IRA;
    227	}
    228
    229	if (rs485->delay_rts_after_send) {
    230		rs485->delay_rts_after_send = 1;
    231		config |= RXW4C_IRA;
    232	}
    233
    234	if (rs485->flags & SER_RS485_RTS_ON_SEND)
    235		config |= RTS_INVERT;
    236
    237	if (fintek_8250_enter_key(pdata->base_port, pdata->key))
    238		return -EBUSY;
    239
    240	sio_write_reg(pdata, LDN, pdata->index);
    241	sio_write_reg(pdata, RS485, config);
    242	fintek_8250_exit_key(pdata->base_port);
    243
    244	port->rs485 = *rs485;
    245
    246	return 0;
    247}
    248
    249static void fintek_8250_set_irq_mode(struct fintek_8250 *pdata, bool is_level)
    250{
    251	sio_write_reg(pdata, LDN, pdata->index);
    252
    253	switch (pdata->pid) {
    254	case CHIP_ID_F81966:
    255	case CHIP_ID_F81866:
    256		sio_write_mask_reg(pdata, F81866_FIFO_CTRL, F81866_IRQ_MODE1,
    257				   0);
    258		fallthrough;
    259	case CHIP_ID_F81865:
    260		sio_write_mask_reg(pdata, F81866_IRQ_MODE, F81866_IRQ_SHARE,
    261				   F81866_IRQ_SHARE);
    262		sio_write_mask_reg(pdata, F81866_IRQ_MODE, F81866_IRQ_MODE0,
    263				   is_level ? 0 : F81866_IRQ_MODE0);
    264		break;
    265
    266	case CHIP_ID_F81216AD:
    267	case CHIP_ID_F81216H:
    268	case CHIP_ID_F81216:
    269		sio_write_mask_reg(pdata, FINTEK_IRQ_MODE, IRQ_SHARE,
    270				   IRQ_SHARE);
    271		sio_write_mask_reg(pdata, FINTEK_IRQ_MODE, IRQ_MODE_MASK,
    272				   is_level ? IRQ_LEVEL_LOW : IRQ_EDGE_HIGH);
    273		break;
    274	}
    275}
    276
    277static void fintek_8250_set_max_fifo(struct fintek_8250 *pdata)
    278{
    279	switch (pdata->pid) {
    280	case CHIP_ID_F81216H: /* 128Bytes FIFO */
    281	case CHIP_ID_F81966:
    282	case CHIP_ID_F81866:
    283		sio_write_mask_reg(pdata, FIFO_CTRL,
    284				   FIFO_MODE_MASK | RXFTHR_MODE_MASK,
    285				   FIFO_MODE_128 | RXFTHR_MODE_4X);
    286		break;
    287
    288	default: /* Default 16Bytes FIFO */
    289		break;
    290	}
    291}
    292
    293static void fintek_8250_set_termios(struct uart_port *port,
    294				    struct ktermios *termios,
    295				    struct ktermios *old)
    296{
    297	struct fintek_8250 *pdata = port->private_data;
    298	unsigned int baud = tty_termios_baud_rate(termios);
    299	int i;
    300	u8 reg;
    301	static u32 baudrate_table[] = {115200, 921600, 1152000, 1500000};
    302	static u8 clock_table[] = { F81866_UART_CLK_1_8432MHZ,
    303			F81866_UART_CLK_14_769MHZ, F81866_UART_CLK_18_432MHZ,
    304			F81866_UART_CLK_24MHZ };
    305
    306	/*
    307	 * We'll use serial8250_do_set_termios() for baud = 0, otherwise It'll
    308	 * crash on baudrate_table[i] % baud with "division by zero".
    309	 */
    310	if (!baud)
    311		goto exit;
    312
    313	switch (pdata->pid) {
    314	case CHIP_ID_F81216H:
    315		reg = RS485;
    316		break;
    317	case CHIP_ID_F81966:
    318	case CHIP_ID_F81866:
    319		reg = F81866_UART_CLK;
    320		break;
    321	default:
    322		/* Don't change clocksource with unknown PID */
    323		dev_warn(port->dev,
    324			"%s: pid: %x Not support. use default set_termios.\n",
    325			__func__, pdata->pid);
    326		goto exit;
    327	}
    328
    329	for (i = 0; i < ARRAY_SIZE(baudrate_table); ++i) {
    330		if (baud > baudrate_table[i] || baudrate_table[i] % baud != 0)
    331			continue;
    332
    333		if (port->uartclk == baudrate_table[i] * 16)
    334			break;
    335
    336		if (fintek_8250_enter_key(pdata->base_port, pdata->key))
    337			continue;
    338
    339		port->uartclk = baudrate_table[i] * 16;
    340
    341		sio_write_reg(pdata, LDN, pdata->index);
    342		sio_write_mask_reg(pdata, reg, F81866_UART_CLK_MASK,
    343				clock_table[i]);
    344
    345		fintek_8250_exit_key(pdata->base_port);
    346		break;
    347	}
    348
    349	if (i == ARRAY_SIZE(baudrate_table)) {
    350		baud = tty_termios_baud_rate(old);
    351		tty_termios_encode_baud_rate(termios, baud, baud);
    352	}
    353
    354exit:
    355	serial8250_do_set_termios(port, termios, old);
    356}
    357
    358static void fintek_8250_set_termios_handler(struct uart_8250_port *uart)
    359{
    360	struct fintek_8250 *pdata = uart->port.private_data;
    361
    362	switch (pdata->pid) {
    363	case CHIP_ID_F81216H:
    364	case CHIP_ID_F81966:
    365	case CHIP_ID_F81866:
    366		uart->port.set_termios = fintek_8250_set_termios;
    367		break;
    368
    369	default:
    370		break;
    371	}
    372}
    373
    374static int probe_setup_port(struct fintek_8250 *pdata,
    375					struct uart_8250_port *uart)
    376{
    377	static const u16 addr[] = {0x4e, 0x2e};
    378	static const u8 keys[] = {0x77, 0xa0, 0x87, 0x67};
    379	struct irq_data *irq_data;
    380	bool level_mode = false;
    381	int i, j, k, min, max;
    382
    383	for (i = 0; i < ARRAY_SIZE(addr); i++) {
    384		for (j = 0; j < ARRAY_SIZE(keys); j++) {
    385			pdata->base_port = addr[i];
    386			pdata->key = keys[j];
    387
    388			if (fintek_8250_enter_key(addr[i], keys[j]))
    389				continue;
    390			if (fintek_8250_check_id(pdata) ||
    391			    fintek_8250_get_ldn_range(pdata, &min, &max)) {
    392				fintek_8250_exit_key(addr[i]);
    393				continue;
    394			}
    395
    396			for (k = min; k < max; k++) {
    397				u16 aux;
    398
    399				sio_write_reg(pdata, LDN, k);
    400				aux = sio_read_reg(pdata, IO_ADDR1);
    401				aux |= sio_read_reg(pdata, IO_ADDR2) << 8;
    402				if (aux != uart->port.iobase)
    403					continue;
    404
    405				pdata->index = k;
    406
    407				irq_data = irq_get_irq_data(uart->port.irq);
    408				if (irq_data)
    409					level_mode =
    410						irqd_is_level_type(irq_data);
    411
    412				fintek_8250_set_irq_mode(pdata, level_mode);
    413				fintek_8250_set_max_fifo(pdata);
    414
    415				fintek_8250_exit_key(addr[i]);
    416
    417				return 0;
    418			}
    419
    420			fintek_8250_exit_key(addr[i]);
    421		}
    422	}
    423
    424	return -ENODEV;
    425}
    426
    427static void fintek_8250_set_rs485_handler(struct uart_8250_port *uart)
    428{
    429	struct fintek_8250 *pdata = uart->port.private_data;
    430
    431	switch (pdata->pid) {
    432	case CHIP_ID_F81216AD:
    433	case CHIP_ID_F81216H:
    434	case CHIP_ID_F81966:
    435	case CHIP_ID_F81866:
    436	case CHIP_ID_F81865:
    437		uart->port.rs485_config = fintek_8250_rs485_config;
    438		break;
    439
    440	default: /* No RS485 Auto direction functional */
    441		break;
    442	}
    443}
    444
    445int fintek_8250_probe(struct uart_8250_port *uart)
    446{
    447	struct fintek_8250 *pdata;
    448	struct fintek_8250 probe_data;
    449
    450	if (probe_setup_port(&probe_data, uart))
    451		return -ENODEV;
    452
    453	pdata = devm_kzalloc(uart->port.dev, sizeof(*pdata), GFP_KERNEL);
    454	if (!pdata)
    455		return -ENOMEM;
    456
    457	memcpy(pdata, &probe_data, sizeof(probe_data));
    458	uart->port.private_data = pdata;
    459	fintek_8250_set_rs485_handler(uart);
    460	fintek_8250_set_termios_handler(uart);
    461
    462	return 0;
    463}