summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/superio/fintek/f81866d/Makefile.inc2
-rw-r--r--src/superio/fintek/f81866d/f81866d_uart.c74
-rw-r--r--src/superio/fintek/f81866d/fintek_internal.h1
-rw-r--r--src/superio/fintek/f81866d/superio.c16
4 files changed, 92 insertions, 1 deletions
diff --git a/src/superio/fintek/f81866d/Makefile.inc b/src/superio/fintek/f81866d/Makefile.inc
index 8654659799..b3fd34fd56 100644
--- a/src/superio/fintek/f81866d/Makefile.inc
+++ b/src/superio/fintek/f81866d/Makefile.inc
@@ -16,5 +16,5 @@
## GNU General Public License for more details.
##
-ramstage-$(CONFIG_SUPERIO_FINTEK_F81866D) += f81866d_hwm.c
+ramstage-$(CONFIG_SUPERIO_FINTEK_F81866D) += f81866d_hwm.c f81866d_uart.c
ramstage-$(CONFIG_SUPERIO_FINTEK_F81866D) += superio.c
diff --git a/src/superio/fintek/f81866d/f81866d_uart.c b/src/superio/fintek/f81866d/f81866d_uart.c
new file mode 100644
index 0000000000..4a198d0aaf
--- /dev/null
+++ b/src/superio/fintek/f81866d/f81866d_uart.c
@@ -0,0 +1,74 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 BAP - Bruhnspace Advanced Projects
+ * (Written by Fabian Kunkel <fabi@adv.bruhnspace.com> for BAP)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <arch/io.h>
+#include <console/console.h>
+#include <device/device.h>
+#include <device/pnp.h>
+#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);
+}
diff --git a/src/superio/fintek/f81866d/fintek_internal.h b/src/superio/fintek/f81866d/fintek_internal.h
index 0405e3e316..977a47d90e 100644
--- a/src/superio/fintek/f81866d/fintek_internal.h
+++ b/src/superio/fintek/f81866d/fintek_internal.h
@@ -23,5 +23,6 @@
#include <device/pnp.h>
void f81866d_hwm_init(struct device *dev);
+void f81866d_uart_init(struct device *dev);
#endif /* SUPERIO_FINTEK_F81866D_INTERNAL_H */
diff --git a/src/superio/fintek/f81866d/superio.c b/src/superio/fintek/f81866d/superio.c
index a61629083d..775e2e8169 100644
--- a/src/superio/fintek/f81866d/superio.c
+++ b/src/superio/fintek/f81866d/superio.c
@@ -40,6 +40,22 @@ static void f81866d_init(struct device *dev)
// Fixing temp sensor read out and init Fan control
f81866d_hwm_init(dev);
break;
+ case F81866D_SP1:
+ // Enable Uart1 and IRQ share register
+ f81866d_uart_init(dev);
+ break;
+ case F81866D_SP2:
+ // Enable Uart2 and IRQ share register
+ f81866d_uart_init(dev);
+ break;
+ case F81866D_SP3:
+ // Enable Uart3 and IRQ share register
+ f81866d_uart_init(dev);
+ break;
+ case F81866D_SP4:
+ // Enable Uart4 and IRQ share register
+ f81866d_uart_init(dev);
+ break;
}
}