/* SPDX-License-Identifier: GPL-2.0-or-later */ /* This file is part of the coreboot project. */ #include #include #include #include "fintek_internal.h" #include "f81866d.h" #define LDN_REG 0x07 #define PORT_SELECT_REGISTER 0x27 #define MULTI_FUNC_SEL3_REG 0x29 #define IRQ_SHARE_REGISTER 0xF0 #define FIFO_SEL_MODE 0xF6 /* * f81866d_uart_init enables all necessary registers for UART 3/4 * Fintek needs to know if pins are used as GPIO or UART pins * Share interrupt usage needs to be enabled */ void f81866d_uart_init(struct device *dev) { struct resource *res = find_resource(dev, PNP_IDX_IO0); u8 tmp; if (!res) { printk(BIOS_WARNING, "%s: No UART resource found.\n", __func__); return; } pnp_enter_conf_mode(dev); // Set Port Select Register (Bit 0) = 0 // before accessing Multi Function Select 3 Register tmp = pnp_read_config(dev, PORT_SELECT_REGISTER); pnp_write_config(dev, PORT_SELECT_REGISTER, tmp & 0xFE); // Set UART 3 function (Bit 4/5), otherwise pin 36-43 are GPIO if (dev->path.pnp.device == F81866D_SP3) { tmp = pnp_read_config(dev, MULTI_FUNC_SEL3_REG); pnp_write_config(dev, MULTI_FUNC_SEL3_REG, tmp | 0x30); } // Set UART 4 function (Bit 6/7), otherwise pin 44-51 are GPIO if (dev->path.pnp.device == F81866D_SP4) { tmp = pnp_read_config(dev, MULTI_FUNC_SEL3_REG); pnp_write_config(dev, MULTI_FUNC_SEL3_REG, tmp | 0xC0); } // Select UART X in LDN register pnp_write_config(dev, LDN_REG, dev->path.pnp.device & 0xff); // Set IRQ trigger mode from active low to high (Bit 3) tmp = pnp_read_config(dev, FIFO_SEL_MODE); pnp_write_config(dev, FIFO_SEL_MODE, tmp | 0x8); // Enable share interrupt (Bit 0) pnp_write_config(dev, IRQ_SHARE_REGISTER, 0x01); pnp_exit_conf_mode(dev); }