From d843fc6e9dc9bee7061b6833594860ea93ad98e1 Mon Sep 17 00:00:00 2001
From: Feng Tang <feng.tang@intel.com>
Date: Tue, 27 Jul 2010 08:20:22 +0100
Subject: hsu: driver for Medfield High Speed UART device

This is a PCI & UART driver, which suppors both PIO and DMA mode
UART operation. It has 3 identical UART ports and one internal
DMA controller.

Current FW will export 4 pci devices for hsu: 3 uart ports and 1
dma controller, each has one IRQ line. And we need to discuss the
device model, one PCI device covering whole HSU should be a better
model, but there is a problem of how to export the 4 IRQs info

Current driver set the highest baud rate to 2746800bps, which is
easy to scale down to 115200/230400.... To suport higher baud rate,
we need add special process, change DLAB/DLH/PS/DIV/MUL registers
all together.

921600 is the highest baud rate that has been tested with Bluetooth
modem connected to HSU port 0. Will test more when there is right
BT firmware.

Current version contains several work around for A0's Silicon bugs

Signed-off-by: Feng Tang <feng.tang@intel.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
 include/linux/serial_core.h |  2 ++
 include/linux/serial_mfd.h  | 47 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/serial_reg.h  | 16 +++++++++++++++
 3 files changed, 65 insertions(+)
 create mode 100644 include/linux/serial_mfd.h

(limited to 'include')

diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 9ddc866ccc09..f8fce351463d 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -189,6 +189,8 @@
 /* MAX3107 */
 #define PORT_MAX3107	94
 
+/* High Speed UART for Medfield */
+#define PORT_MFD	95
 
 #ifdef __KERNEL__
 
diff --git a/include/linux/serial_mfd.h b/include/linux/serial_mfd.h
new file mode 100644
index 000000000000..2b071e0b034d
--- /dev/null
+++ b/include/linux/serial_mfd.h
@@ -0,0 +1,47 @@
+#ifndef _SERIAL_MFD_H_
+#define _SERIAL_MFD_H_
+
+/* HW register offset definition */
+#define UART_FOR	0x08
+#define UART_PS		0x0C
+#define UART_MUL	0x0D
+#define UART_DIV	0x0E
+
+#define HSU_GBL_IEN	0x0
+#define HSU_GBL_IST	0x4
+
+#define HSU_GBL_INT_BIT_PORT0	0x0
+#define HSU_GBL_INT_BIT_PORT1	0x1
+#define HSU_GBL_INT_BIT_PORT2	0x2
+#define HSU_GBL_INT_BIT_IRI	0x3
+#define HSU_GBL_INT_BIT_HDLC	0x4
+#define HSU_GBL_INT_BIT_DMA	0x5
+
+#define HSU_GBL_ISR	0x8
+#define HSU_GBL_DMASR	0x400
+#define HSU_GBL_DMAISR	0x404
+
+#define HSU_PORT_REG_OFFSET	0x80
+#define HSU_PORT0_REG_OFFSET	0x80
+#define HSU_PORT1_REG_OFFSET	0x100
+#define HSU_PORT2_REG_OFFSET	0x180
+#define HSU_PORT_REG_LENGTH	0x80
+
+#define HSU_DMA_CHANS_REG_OFFSET	0x500
+#define HSU_DMA_CHANS_REG_LENGTH	0x40
+
+#define HSU_CH_SR		0x0	/* channel status reg */
+#define HSU_CH_CR		0x4	/* control reg */
+#define HSU_CH_DCR		0x8	/* descriptor control reg */
+#define HSU_CH_BSR		0x10	/* max fifo buffer size reg */
+#define HSU_CH_MOTSR		0x14	/* minimum ocp transfer size */
+#define HSU_CH_D0SAR		0x20	/* desc 0 start addr */
+#define HSU_CH_D0TSR		0x24	/* desc 0 transfer size */
+#define HSU_CH_D1SAR		0x28
+#define HSU_CH_D1TSR		0x2C
+#define HSU_CH_D2SAR		0x30
+#define HSU_CH_D2TSR		0x34
+#define HSU_CH_D3SAR		0x38
+#define HSU_CH_D3TSR		0x3C
+
+#endif
diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h
index cf9327c051ad..c7a0ce11cd47 100644
--- a/include/linux/serial_reg.h
+++ b/include/linux/serial_reg.h
@@ -221,8 +221,24 @@
 #define UART_FCR_PXAR16	0x80	/* receive FIFO threshold = 16 */
 #define UART_FCR_PXAR32	0xc0	/* receive FIFO threshold = 32 */
 
+/*
+ * Intel MID on-chip HSU (High Speed UART) defined bits
+ */
+#define UART_FCR_HSU_64_1B	0x00	/* receive FIFO treshold = 1 */
+#define UART_FCR_HSU_64_16B	0x40	/* receive FIFO treshold = 16 */
+#define UART_FCR_HSU_64_32B	0x80	/* receive FIFO treshold = 32 */
+#define UART_FCR_HSU_64_56B	0xc0	/* receive FIFO treshold = 56 */
+
+#define UART_FCR_HSU_16_1B	0x00	/* receive FIFO treshold = 1 */
+#define UART_FCR_HSU_16_4B	0x40	/* receive FIFO treshold = 4 */
+#define UART_FCR_HSU_16_8B	0x80	/* receive FIFO treshold = 8 */
+#define UART_FCR_HSU_16_14B	0xc0	/* receive FIFO treshold = 14 */
 
+#define UART_FCR_HSU_64B_FIFO	0x20	/* chose 64 bytes FIFO */
+#define UART_FCR_HSU_16B_FIFO	0x00	/* chose 16 bytes FIFO */
 
+#define UART_FCR_HALF_EMPT_TXI	0x00	/* trigger TX_EMPT IRQ for half empty */
+#define UART_FCR_FULL_EMPT_TXI	0x08	/* trigger TX_EMPT IRQ for full empty */
 
 /*
  * These register definitions are for the 16C950
-- 
cgit v1.2.3