xref: /aosp_15_r20/external/coreboot/src/superio/fintek/f81866d/f81866d_uart.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #include <console/console.h>
4 #include <device/device.h>
5 #include <device/pnp.h>
6 #include "fintek_internal.h"
7 #include "f81866d.h"
8 
9 #define LDN_REG			0x07
10 #define PORT_SELECT_REGISTER	0x27
11 #define MULTI_FUNC_SEL3_REG	0x29
12 #define IRQ_SHARE_REGISTER	0xF0
13 #define FIFO_SEL_MODE		0xF6
14 
15 /*
16  * f81866d_uart_init enables all necessary registers for UART 3/4
17  * Fintek needs to know if pins are used as GPIO or UART pins
18  * Share interrupt usage needs to be enabled
19  */
f81866d_uart_init(struct device * dev)20 void f81866d_uart_init(struct device *dev)
21 {
22 	struct resource *res = probe_resource(dev, PNP_IDX_IO0);
23 	u8 tmp;
24 
25 	if (!res) {
26 		printk(BIOS_WARNING, "%s: No UART resource found.\n", __func__);
27 		return;
28 	}
29 
30 	pnp_enter_conf_mode(dev);
31 
32 	// Set Port Select Register (Bit 0) = 0
33 	// before accessing Multi Function Select 3 Register
34 	tmp = pnp_read_config(dev, PORT_SELECT_REGISTER);
35 	pnp_write_config(dev, PORT_SELECT_REGISTER, tmp & 0xFE);
36 
37 	// Set UART 3 function (Bit 4/5), otherwise pin 36-43 are GPIO
38 	if (dev->path.pnp.device == F81866D_SP3) {
39 		tmp = pnp_read_config(dev, MULTI_FUNC_SEL3_REG);
40 		pnp_write_config(dev, MULTI_FUNC_SEL3_REG, tmp | 0x30);
41 	}
42 
43 	// Set UART 4 function (Bit 6/7), otherwise pin 44-51 are GPIO
44 	if (dev->path.pnp.device == F81866D_SP4) {
45 		tmp = pnp_read_config(dev, MULTI_FUNC_SEL3_REG);
46 		pnp_write_config(dev, MULTI_FUNC_SEL3_REG, tmp | 0xC0);
47 	}
48 
49 	// Select UART X in LDN register
50 	pnp_write_config(dev, LDN_REG, dev->path.pnp.device & 0xff);
51 	// Set IRQ trigger mode from active low to high (Bit 3)
52 	tmp = pnp_read_config(dev, FIFO_SEL_MODE);
53 	pnp_write_config(dev, FIFO_SEL_MODE, tmp | 0x8);
54 	// Enable share interrupt (Bit 0)
55 	pnp_write_config(dev, IRQ_SHARE_REGISTER, 0x01);
56 
57 	pnp_exit_conf_mode(dev);
58 }
59