serial: Fix io address assign flow with Fintek PCI-to-UART Product
[cascardo/linux.git] / drivers / tty / serial / 8250 / 8250_pci.c
index 4f1cd29..31feeb2 100644 (file)
@@ -25,6 +25,9 @@
 #include <asm/byteorder.h>
 #include <asm/io.h>
 
+#include <linux/dmaengine.h>
+#include <linux/platform_data/dma-dw.h>
+
 #include "8250.h"
 
 /*
@@ -76,29 +79,24 @@ setup_port(struct serial_private *priv, struct uart_8250_port *port,
           int bar, int offset, int regshift)
 {
        struct pci_dev *dev = priv->dev;
-       unsigned long base, len;
 
        if (bar >= PCI_NUM_BAR_RESOURCES)
                return -EINVAL;
 
-       base = pci_resource_start(dev, bar);
-
        if (pci_resource_flags(dev, bar) & IORESOURCE_MEM) {
-               len =  pci_resource_len(dev, bar);
-
                if (!priv->remapped_bar[bar])
-                       priv->remapped_bar[bar] = ioremap_nocache(base, len);
+                       priv->remapped_bar[bar] = pci_ioremap_bar(dev, bar);
                if (!priv->remapped_bar[bar])
                        return -ENOMEM;
 
                port->port.iotype = UPIO_MEM;
                port->port.iobase = 0;
-               port->port.mapbase = base + offset;
+               port->port.mapbase = pci_resource_start(dev, bar) + offset;
                port->port.membase = priv->remapped_bar[bar] + offset;
                port->port.regshift = regshift;
        } else {
                port->port.iotype = UPIO_PORT;
-               port->port.iobase = base + offset;
+               port->port.iobase = pci_resource_start(dev, bar) + offset;
                port->port.mapbase = 0;
                port->port.membase = NULL;
                port->port.regshift = 0;
@@ -314,7 +312,6 @@ static void pci_plx9050_exit(struct pci_dev *dev)
 static void pci_ni8420_exit(struct pci_dev *dev)
 {
        void __iomem *p;
-       unsigned long base, len;
        unsigned int bar = 0;
 
        if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) {
@@ -322,9 +319,7 @@ static void pci_ni8420_exit(struct pci_dev *dev)
                return;
        }
 
-       base = pci_resource_start(dev, bar);
-       len =  pci_resource_len(dev, bar);
-       p = ioremap_nocache(base, len);
+       p = pci_ioremap_bar(dev, bar);
        if (p == NULL)
                return;
 
@@ -346,7 +341,6 @@ static void pci_ni8420_exit(struct pci_dev *dev)
 static void pci_ni8430_exit(struct pci_dev *dev)
 {
        void __iomem *p;
-       unsigned long base, len;
        unsigned int bar = 0;
 
        if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) {
@@ -354,9 +348,7 @@ static void pci_ni8430_exit(struct pci_dev *dev)
                return;
        }
 
-       base = pci_resource_start(dev, bar);
-       len =  pci_resource_len(dev, bar);
-       p = ioremap_nocache(base, len);
+       p = pci_ioremap_bar(dev, bar);
        if (p == NULL)
                return;
 
@@ -679,7 +671,6 @@ static int pci_xircom_init(struct pci_dev *dev)
 static int pci_ni8420_init(struct pci_dev *dev)
 {
        void __iomem *p;
-       unsigned long base, len;
        unsigned int bar = 0;
 
        if ((pci_resource_flags(dev, bar) & IORESOURCE_MEM) == 0) {
@@ -687,9 +678,7 @@ static int pci_ni8420_init(struct pci_dev *dev)
                return 0;
        }
 
-       base = pci_resource_start(dev, bar);
-       len =  pci_resource_len(dev, bar);
-       p = ioremap_nocache(base, len);
+       p = pci_ioremap_bar(dev, bar);
        if (p == NULL)
                return -ENOMEM;
 
@@ -711,7 +700,7 @@ static int pci_ni8420_init(struct pci_dev *dev)
 static int pci_ni8430_init(struct pci_dev *dev)
 {
        void __iomem *p;
-       unsigned long base, len;
+       struct pci_bus_region region;
        u32 device_window;
        unsigned int bar = 0;
 
@@ -720,14 +709,17 @@ static int pci_ni8430_init(struct pci_dev *dev)
                return 0;
        }
 
-       base = pci_resource_start(dev, bar);
-       len =  pci_resource_len(dev, bar);
-       p = ioremap_nocache(base, len);
+       p = pci_ioremap_bar(dev, bar);
        if (p == NULL)
                return -ENOMEM;
 
-       /* Set device window address and size in BAR0 */
-       device_window = ((base + MITE_IOWBSR1_WIN_OFFSET) & 0xffffff00)
+       /*
+        * Set device window address and size in BAR0, while acknowledging that
+        * the resource structure may contain a translated address that differs
+        * from the address the device responds to.
+        */
+       pcibios_resource_to_bus(dev->bus, &region, &dev->resource[bar]);
+       device_window = ((region.start + MITE_IOWBSR1_WIN_OFFSET) & 0xffffff00)
                        | MITE_IOWBSR1_WENAB | MITE_IOWBSR1_WSIZE;
        writel(device_window, p + MITE_IOWBSR1);
 
@@ -754,8 +746,8 @@ pci_ni8430_setup(struct serial_private *priv,
                 const struct pciserial_board *board,
                 struct uart_8250_port *port, int idx)
 {
+       struct pci_dev *dev = priv->dev;
        void __iomem *p;
-       unsigned long base, len;
        unsigned int bar, offset = board->first_offset;
 
        if (idx >= board->num_ports)
@@ -764,9 +756,9 @@ pci_ni8430_setup(struct serial_private *priv,
        bar = FL_GET_BASE(board->flags);
        offset += idx * board->uart_offset;
 
-       base = pci_resource_start(priv->dev, bar);
-       len =  pci_resource_len(priv->dev, bar);
-       p = ioremap_nocache(base, len);
+       p = pci_ioremap_bar(dev, bar);
+       if (!p)
+               return -ENOMEM;
 
        /* enable the transceiver */
        writeb(readb(p + offset + NI8430_PORTCON) | NI8430_PORTCON_TXVR_ENABLE,
@@ -999,6 +991,40 @@ static void pci_ite887x_exit(struct pci_dev *dev)
        release_region(ioport, ITE_887x_IOSIZE);
 }
 
+/*
+ * EndRun Technologies.
+ * Determine the number of ports available on the device.
+ */
+#define PCI_VENDOR_ID_ENDRUN                   0x7401
+#define PCI_DEVICE_ID_ENDRUN_1588      0xe100
+
+static int pci_endrun_init(struct pci_dev *dev)
+{
+       u8 __iomem *p;
+       unsigned long deviceID;
+       unsigned int  number_uarts = 0;
+
+       /* EndRun device is all 0xexxx */
+       if (dev->vendor == PCI_VENDOR_ID_ENDRUN &&
+               (dev->device & 0xf000) != 0xe000)
+               return 0;
+
+       p = pci_iomap(dev, 0, 5);
+       if (p == NULL)
+               return -ENOMEM;
+
+       deviceID = ioread32(p);
+       /* EndRun device */
+       if (deviceID == 0x07000200) {
+               number_uarts = ioread8(p + 4);
+               dev_dbg(&dev->dev,
+                       "%d ports detected on EndRun PCI Express device\n",
+                       number_uarts);
+       }
+       pci_iounmap(dev, p);
+       return number_uarts;
+}
+
 /*
  * Oxford Semiconductor Inc.
  * Check that device is part of the Tornado range of devices, then determine
@@ -1349,6 +1375,9 @@ ce4100_serial_setup(struct serial_private *priv,
 #define PCI_DEVICE_ID_INTEL_BYT_UART1  0x0f0a
 #define PCI_DEVICE_ID_INTEL_BYT_UART2  0x0f0c
 
+#define PCI_DEVICE_ID_INTEL_BSW_UART1  0x228a
+#define PCI_DEVICE_ID_INTEL_BSW_UART2  0x228c
+
 #define BYT_PRV_CLK                    0x800
 #define BYT_PRV_CLK_EN                 (1 << 0)
 #define BYT_PRV_CLK_M_VAL_SHIFT                1
@@ -1414,7 +1443,13 @@ byt_set_termios(struct uart_port *p, struct ktermios *termios,
 
 static bool byt_dma_filter(struct dma_chan *chan, void *param)
 {
-       return chan->chan_id == *(int *)param;
+       struct dw_dma_slave *dws = param;
+
+       if (dws->dma_dev != chan->device->dev)
+               return false;
+
+       chan->private = dws;
+       return true;
 }
 
 static int
@@ -1422,35 +1457,57 @@ byt_serial_setup(struct serial_private *priv,
                 const struct pciserial_board *board,
                 struct uart_8250_port *port, int idx)
 {
+       struct pci_dev *pdev = priv->dev;
+       struct device *dev = port->port.dev;
        struct uart_8250_dma *dma;
+       struct dw_dma_slave *tx_param, *rx_param;
+       struct pci_dev *dma_dev;
        int ret;
 
-       dma = devm_kzalloc(port->port.dev, sizeof(*dma), GFP_KERNEL);
+       dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
        if (!dma)
                return -ENOMEM;
 
-       switch (priv->dev->device) {
+       tx_param = devm_kzalloc(dev, sizeof(*tx_param), GFP_KERNEL);
+       if (!tx_param)
+               return -ENOMEM;
+
+       rx_param = devm_kzalloc(dev, sizeof(*rx_param), GFP_KERNEL);
+       if (!rx_param)
+               return -ENOMEM;
+
+       switch (pdev->device) {
        case PCI_DEVICE_ID_INTEL_BYT_UART1:
-               dma->rx_chan_id = 3;
-               dma->tx_chan_id = 2;
+       case PCI_DEVICE_ID_INTEL_BSW_UART1:
+               rx_param->src_id = 3;
+               tx_param->dst_id = 2;
                break;
        case PCI_DEVICE_ID_INTEL_BYT_UART2:
-               dma->rx_chan_id = 5;
-               dma->tx_chan_id = 4;
+       case PCI_DEVICE_ID_INTEL_BSW_UART2:
+               rx_param->src_id = 5;
+               tx_param->dst_id = 4;
                break;
        default:
                return -EINVAL;
        }
 
-       dma->rxconf.slave_id = dma->rx_chan_id;
+       rx_param->src_master = 1;
+       rx_param->dst_master = 0;
+
        dma->rxconf.src_maxburst = 16;
 
-       dma->txconf.slave_id = dma->tx_chan_id;
+       tx_param->src_master = 1;
+       tx_param->dst_master = 0;
+
        dma->txconf.dst_maxburst = 16;
 
+       dma_dev = pci_get_slot(pdev->bus, PCI_DEVFN(PCI_SLOT(pdev->devfn), 0));
+       rx_param->dma_dev = &dma_dev->dev;
+       tx_param->dma_dev = &dma_dev->dev;
+
        dma->fn = byt_dma_filter;
-       dma->rx_param = &dma->rx_chan_id;
-       dma->tx_param = &dma->tx_chan_id;
+       dma->rx_param = rx_param;
+       dma->tx_param = tx_param;
 
        ret = pci_default_setup(priv, board, port, idx);
        port->port.iotype = UPIO_MEM;
@@ -1497,25 +1554,48 @@ static int pci_fintek_setup(struct serial_private *priv,
        unsigned long iobase;
        unsigned long ciobase = 0;
        u8 config_base;
+       u32 bar_data[3];
 
        /*
-        * We are supposed to be able to read these from the PCI config space,
-        * but the values there don't seem to match what we need to use, so
-        * just use these hard-coded values for now, as they are correct.
+        * Find each UARTs offset in PCI configuraion space
         */
        switch (idx) {
-       case 0: iobase = 0xe000; config_base = 0x40; break;
-       case 1: iobase = 0xe008; config_base = 0x48; break;
-       case 2: iobase = 0xe010; config_base = 0x50; break;
-       case 3: iobase = 0xe018; config_base = 0x58; break;
-       case 4: iobase = 0xe020; config_base = 0x60; break;
-       case 5: iobase = 0xe028; config_base = 0x68; break;
-       case 6: iobase = 0xe030; config_base = 0x70; break;
-       case 7: iobase = 0xe038; config_base = 0x78; break;
-       case 8: iobase = 0xe040; config_base = 0x80; break;
-       case 9: iobase = 0xe048; config_base = 0x88; break;
-       case 10: iobase = 0xe050; config_base = 0x90; break;
-       case 11: iobase = 0xe058; config_base = 0x98; break;
+       case 0:
+               config_base = 0x40;
+               break;
+       case 1:
+               config_base = 0x48;
+               break;
+       case 2:
+               config_base = 0x50;
+               break;
+       case 3:
+               config_base = 0x58;
+               break;
+       case 4:
+               config_base = 0x60;
+               break;
+       case 5:
+               config_base = 0x68;
+               break;
+       case 6:
+               config_base = 0x70;
+               break;
+       case 7:
+               config_base = 0x78;
+               break;
+       case 8:
+               config_base = 0x80;
+               break;
+       case 9:
+               config_base = 0x88;
+               break;
+       case 10:
+               config_base = 0x90;
+               break;
+       case 11:
+               config_base = 0x98;
+               break;
        default:
                /* Unknown number of ports, get out of here */
                return -EINVAL;
@@ -1526,6 +1606,14 @@ static int pci_fintek_setup(struct serial_private *priv,
                ciobase = (int)(base + (0x8 * idx));
        }
 
+       /* Get the io address dispatch from the BIOS */
+       pci_read_config_dword(pdev, 0x24, &bar_data[0]);
+       pci_read_config_dword(pdev, 0x20, &bar_data[1]);
+       pci_read_config_dword(pdev, 0x1c, &bar_data[2]);
+
+       /* Calculate Real IO Port */
+       iobase = (bar_data[idx/4] & 0xffffffe0) + (idx % 4) * 8;
+
        dev_dbg(&pdev->dev, "%s: idx=%d iobase=0x%lx ciobase=0x%lx config_base=0x%2x\n",
                __func__, idx, iobase, ciobase, config_base);
 
@@ -1726,6 +1814,16 @@ pci_wch_ch353_setup(struct serial_private *priv,
        return pci_default_setup(priv, board, port, idx);
 }
 
+static int
+pci_wch_ch382_setup(struct serial_private *priv,
+                    const struct pciserial_board *board,
+                    struct uart_8250_port *port, int idx)
+{
+       port->port.flags |= UPF_FIXED_TYPE;
+       port->port.type = PORT_16850;
+       return pci_default_setup(priv, board, port, idx);
+}
+
 #define PCI_VENDOR_ID_SBSMODULARIO     0x124B
 #define PCI_SUBVENDOR_ID_SBSMODULARIO  0x124B
 #define PCI_DEVICE_ID_OCTPRO           0x0001
@@ -1780,6 +1878,8 @@ pci_wch_ch353_setup(struct serial_private *priv,
 #define PCI_VENDOR_ID_SUNIX            0x1fd4
 #define PCI_DEVICE_ID_SUNIX_1999       0x1999
 
+#define PCIE_VENDOR_ID_WCH             0x1c00
+#define PCIE_DEVICE_ID_WCH_CH382_2S1P  0x3250
 
 /* Unknown vendors/cards - this should not be in linux/pci_ids.h */
 #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584        0x1584
@@ -1893,6 +1993,20 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .subdevice      = PCI_ANY_ID,
                .setup          = pci_default_setup,
        },
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_BSW_UART1,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = byt_serial_setup,
+       },
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_BSW_UART2,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = byt_serial_setup,
+       },
        /*
         * ITE
         */
@@ -2297,6 +2411,17 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .init           = pci_netmos_init,
                .setup          = pci_netmos_9900_setup,
        },
+       /*
+        * EndRun Technologies
+       */
+       {
+               .vendor         = PCI_VENDOR_ID_ENDRUN,
+               .device         = PCI_ANY_ID,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .init           = pci_endrun_init,
+               .setup          = pci_default_setup,
+       },
        /*
         * For Oxford Semiconductor Tornado based devices
         */
@@ -2446,6 +2571,14 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .subdevice      = PCI_ANY_ID,
                .setup          = pci_wch_ch353_setup,
        },
+       /* WCH CH382 2S1P card (16750 clone) */
+       {
+               .vendor         = PCIE_VENDOR_ID_WCH,
+               .device         = PCIE_DEVICE_ID_WCH_CH382_2S1P,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_wch_ch382_setup,
+       },
        /*
         * ASIX devices with FIFO bug
         */
@@ -2706,6 +2839,7 @@ enum pci_board_num_t {
        pbn_panacom2,
        pbn_panacom4,
        pbn_plx_romulus,
+       pbn_endrun_2_4000000,
        pbn_oxsemi,
        pbn_oxsemi_1_4000000,
        pbn_oxsemi_2_4000000,
@@ -3250,6 +3384,20 @@ static struct pciserial_board pci_boards[] = {
                .first_offset   = 0x03,
        },
 
+       /*
+        * EndRun Technologies
+       * Uses the size of PCI Base region 0 to
+       * signal now many ports are available
+       * 2 port 952 Uart support
+       */
+       [pbn_endrun_2_4000000] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 2,
+               .base_baud      = 4000000,
+               .uart_offset    = 0x200,
+               .first_offset   = 0x1000,
+       },
+
        /*
         * This board uses the size of PCI Base region 0 to
         * signal now many ports are available
@@ -3538,6 +3686,7 @@ static const struct pci_device_id blacklist[] = {
        /* multi-io cards handled by parport_serial */
        { PCI_DEVICE(0x4348, 0x7053), }, /* WCH CH353 2S1P */
        { PCI_DEVICE(0x4348, 0x5053), }, /* WCH CH353 1S1P */
+       { PCI_DEVICE(0x1c00, 0x3250), }, /* WCH CH382 2S1P */
 };
 
 /*
@@ -4122,6 +4271,13 @@ static struct pci_device_id serial_pci_tbl[] = {
        {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS,
                0x10b5, 0x106a, 0, 0,
                pbn_plx_romulus },
+       /*
+       * EndRun Technologies. PCI express device range.
+       *    EndRun PTP/1588 has 2 Native UARTs.
+       */
+       {       PCI_VENDOR_ID_ENDRUN, PCI_DEVICE_ID_ENDRUN_1588,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_endrun_2_4000000 },
        /*
         * Quatech cards. These actually have configurable clocks but for
         * now we just use the default.
@@ -5192,6 +5348,14 @@ static struct pci_device_id serial_pci_tbl[] = {
                PCI_ANY_ID,  PCI_ANY_ID,
                PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000,
                pbn_byt },
+       {       PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW_UART1,
+               PCI_ANY_ID,  PCI_ANY_ID,
+               PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000,
+               pbn_byt },
+       {       PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BSW_UART2,
+               PCI_ANY_ID,  PCI_ANY_ID,
+               PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000,
+               pbn_byt },
 
        /*
         * Intel Quark x1000