diff options
author | Heikki Krogerus <heikki.krogerus@linux.intel.com> | 2013-09-27 03:52:59 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-09-27 20:39:11 -0400 |
commit | b15e5691cc98b5e17db8ba8a433a4ac78efbf590 (patch) | |
tree | 3d31013438e0028b30569f49bdd06cedfdf8e0ab /drivers | |
parent | 3415097ff0529eac264b8ccfa06572871e45c090 (diff) |
serial: 8250_pci: add support for Intel BayTrail
Intel BayTrail has two HS-UARTs with 64 byte fifo, support
for DMA and support for 16750 compatible Auto Flow Control.
Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/tty/serial/8250/8250_pci.c | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c index 515fd0ff4e4e..d917bbb30484 100644 --- a/drivers/tty/serial/8250/8250_pci.c +++ b/drivers/tty/serial/8250/8250_pci.c | |||
@@ -1324,6 +1324,120 @@ ce4100_serial_setup(struct serial_private *priv, | |||
1324 | return ret; | 1324 | return ret; |
1325 | } | 1325 | } |
1326 | 1326 | ||
1327 | #define PCI_DEVICE_ID_INTEL_BYT_UART1 0x0f0a | ||
1328 | #define PCI_DEVICE_ID_INTEL_BYT_UART2 0x0f0c | ||
1329 | |||
1330 | #define BYT_PRV_CLK 0x800 | ||
1331 | #define BYT_PRV_CLK_EN (1 << 0) | ||
1332 | #define BYT_PRV_CLK_M_VAL_SHIFT 1 | ||
1333 | #define BYT_PRV_CLK_N_VAL_SHIFT 16 | ||
1334 | #define BYT_PRV_CLK_UPDATE (1 << 31) | ||
1335 | |||
1336 | #define BYT_GENERAL_REG 0x808 | ||
1337 | #define BYT_GENERAL_DIS_RTS_N_OVERRIDE (1 << 3) | ||
1338 | |||
1339 | #define BYT_TX_OVF_INT 0x820 | ||
1340 | #define BYT_TX_OVF_INT_MASK (1 << 1) | ||
1341 | |||
1342 | static void | ||
1343 | byt_set_termios(struct uart_port *p, struct ktermios *termios, | ||
1344 | struct ktermios *old) | ||
1345 | { | ||
1346 | unsigned int baud = tty_termios_baud_rate(termios); | ||
1347 | unsigned int m = 6912; | ||
1348 | unsigned int n = 15625; | ||
1349 | u32 reg; | ||
1350 | |||
1351 | /* For baud rates 1M, 2M, 3M and 4M the dividers must be adjusted. */ | ||
1352 | if (baud == 1000000 || baud == 2000000 || baud == 4000000) { | ||
1353 | m = 64; | ||
1354 | n = 100; | ||
1355 | |||
1356 | p->uartclk = 64000000; | ||
1357 | } else if (baud == 3000000) { | ||
1358 | m = 48; | ||
1359 | n = 100; | ||
1360 | |||
1361 | p->uartclk = 48000000; | ||
1362 | } else { | ||
1363 | p->uartclk = 44236800; | ||
1364 | } | ||
1365 | |||
1366 | /* Reset the clock */ | ||
1367 | reg = (m << BYT_PRV_CLK_M_VAL_SHIFT) | (n << BYT_PRV_CLK_N_VAL_SHIFT); | ||
1368 | writel(reg, p->membase + BYT_PRV_CLK); | ||
1369 | reg |= BYT_PRV_CLK_EN | BYT_PRV_CLK_UPDATE; | ||
1370 | writel(reg, p->membase + BYT_PRV_CLK); | ||
1371 | |||
1372 | /* | ||
1373 | * If auto-handshake mechanism is not enabled, | ||
1374 | * disable rts_n override | ||
1375 | */ | ||
1376 | reg = readl(p->membase + BYT_GENERAL_REG); | ||
1377 | reg &= ~BYT_GENERAL_DIS_RTS_N_OVERRIDE; | ||
1378 | if (termios->c_cflag & CRTSCTS) | ||
1379 | reg |= BYT_GENERAL_DIS_RTS_N_OVERRIDE; | ||
1380 | writel(reg, p->membase + BYT_GENERAL_REG); | ||
1381 | |||
1382 | serial8250_do_set_termios(p, termios, old); | ||
1383 | } | ||
1384 | |||
1385 | static bool byt_dma_filter(struct dma_chan *chan, void *param) | ||
1386 | { | ||
1387 | return chan->chan_id == *(int *)param; | ||
1388 | } | ||
1389 | |||
1390 | static int | ||
1391 | byt_serial_setup(struct serial_private *priv, | ||
1392 | const struct pciserial_board *board, | ||
1393 | struct uart_8250_port *port, int idx) | ||
1394 | { | ||
1395 | struct uart_8250_dma *dma; | ||
1396 | int ret; | ||
1397 | |||
1398 | dma = devm_kzalloc(port->port.dev, sizeof(*dma), GFP_KERNEL); | ||
1399 | if (!dma) | ||
1400 | return -ENOMEM; | ||
1401 | |||
1402 | switch (priv->dev->device) { | ||
1403 | case PCI_DEVICE_ID_INTEL_BYT_UART1: | ||
1404 | dma->rx_chan_id = 3; | ||
1405 | dma->tx_chan_id = 2; | ||
1406 | break; | ||
1407 | case PCI_DEVICE_ID_INTEL_BYT_UART2: | ||
1408 | dma->rx_chan_id = 5; | ||
1409 | dma->tx_chan_id = 4; | ||
1410 | break; | ||
1411 | default: | ||
1412 | return -EINVAL; | ||
1413 | } | ||
1414 | |||
1415 | dma->rxconf.slave_id = dma->rx_chan_id; | ||
1416 | dma->rxconf.src_maxburst = 16; | ||
1417 | |||
1418 | dma->txconf.slave_id = dma->tx_chan_id; | ||
1419 | dma->txconf.dst_maxburst = 16; | ||
1420 | |||
1421 | dma->fn = byt_dma_filter; | ||
1422 | dma->rx_param = &dma->rx_chan_id; | ||
1423 | dma->tx_param = &dma->tx_chan_id; | ||
1424 | |||
1425 | ret = pci_default_setup(priv, board, port, idx); | ||
1426 | port->port.iotype = UPIO_MEM; | ||
1427 | port->port.type = PORT_16550A; | ||
1428 | port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE); | ||
1429 | port->port.set_termios = byt_set_termios; | ||
1430 | port->port.fifosize = 64; | ||
1431 | port->tx_loadsz = 64; | ||
1432 | port->dma = dma; | ||
1433 | port->capabilities = UART_CAP_FIFO | UART_CAP_AFE; | ||
1434 | |||
1435 | /* Disable Tx counter interrupts */ | ||
1436 | writel(BYT_TX_OVF_INT_MASK, port->port.membase + BYT_TX_OVF_INT); | ||
1437 | |||
1438 | return ret; | ||
1439 | } | ||
1440 | |||
1327 | static int | 1441 | static int |
1328 | pci_omegapci_setup(struct serial_private *priv, | 1442 | pci_omegapci_setup(struct serial_private *priv, |
1329 | const struct pciserial_board *board, | 1443 | const struct pciserial_board *board, |
@@ -1662,6 +1776,20 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = { | |||
1662 | .subdevice = PCI_ANY_ID, | 1776 | .subdevice = PCI_ANY_ID, |
1663 | .setup = kt_serial_setup, | 1777 | .setup = kt_serial_setup, |
1664 | }, | 1778 | }, |
1779 | { | ||
1780 | .vendor = PCI_VENDOR_ID_INTEL, | ||
1781 | .device = PCI_DEVICE_ID_INTEL_BYT_UART1, | ||
1782 | .subvendor = PCI_ANY_ID, | ||
1783 | .subdevice = PCI_ANY_ID, | ||
1784 | .setup = byt_serial_setup, | ||
1785 | }, | ||
1786 | { | ||
1787 | .vendor = PCI_VENDOR_ID_INTEL, | ||
1788 | .device = PCI_DEVICE_ID_INTEL_BYT_UART2, | ||
1789 | .subvendor = PCI_ANY_ID, | ||
1790 | .subdevice = PCI_ANY_ID, | ||
1791 | .setup = byt_serial_setup, | ||
1792 | }, | ||
1665 | /* | 1793 | /* |
1666 | * ITE | 1794 | * ITE |
1667 | */ | 1795 | */ |
@@ -2449,6 +2577,7 @@ enum pci_board_num_t { | |||
2449 | pbn_ADDIDATA_PCIe_4_3906250, | 2577 | pbn_ADDIDATA_PCIe_4_3906250, |
2450 | pbn_ADDIDATA_PCIe_8_3906250, | 2578 | pbn_ADDIDATA_PCIe_8_3906250, |
2451 | pbn_ce4100_1_115200, | 2579 | pbn_ce4100_1_115200, |
2580 | pbn_byt, | ||
2452 | pbn_omegapci, | 2581 | pbn_omegapci, |
2453 | pbn_NETMOS9900_2s_115200, | 2582 | pbn_NETMOS9900_2s_115200, |
2454 | pbn_brcm_trumanage, | 2583 | pbn_brcm_trumanage, |
@@ -3185,6 +3314,13 @@ static struct pciserial_board pci_boards[] = { | |||
3185 | .base_baud = 921600, | 3314 | .base_baud = 921600, |
3186 | .reg_shift = 2, | 3315 | .reg_shift = 2, |
3187 | }, | 3316 | }, |
3317 | [pbn_byt] = { | ||
3318 | .flags = FL_BASE0, | ||
3319 | .num_ports = 1, | ||
3320 | .base_baud = 2764800, | ||
3321 | .uart_offset = 0x80, | ||
3322 | .reg_shift = 2, | ||
3323 | }, | ||
3188 | [pbn_omegapci] = { | 3324 | [pbn_omegapci] = { |
3189 | .flags = FL_BASE0, | 3325 | .flags = FL_BASE0, |
3190 | .num_ports = 8, | 3326 | .num_ports = 8, |
@@ -4846,6 +4982,15 @@ static struct pci_device_id serial_pci_tbl[] = { | |||
4846 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CE4100_UART, | 4982 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CE4100_UART, |
4847 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 4983 | PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
4848 | pbn_ce4100_1_115200 }, | 4984 | pbn_ce4100_1_115200 }, |
4985 | /* Intel BayTrail */ | ||
4986 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT_UART1, | ||
4987 | PCI_ANY_ID, PCI_ANY_ID, | ||
4988 | PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000, | ||
4989 | pbn_byt }, | ||
4990 | { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT_UART2, | ||
4991 | PCI_ANY_ID, PCI_ANY_ID, | ||
4992 | PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000, | ||
4993 | pbn_byt }, | ||
4849 | 4994 | ||
4850 | /* | 4995 | /* |
4851 | * Cronyx Omega PCI | 4996 | * Cronyx Omega PCI |