aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/omap-serial.c
diff options
context:
space:
mode:
authorGovindraj.R <govindraj.raja@ti.com>2011-11-07 08:30:33 -0500
committerKevin Hilman <khilman@ti.com>2011-12-14 19:05:22 -0500
commit94734749af794c080f6af6ac3ce8c1c13ee2dbbd (patch)
treefca071b796416579b42860980cd7324ac128d22e /drivers/tty/serial/omap-serial.c
parentec3bebc6ec64aac23500e6b8ef5c0aaaeda735cf (diff)
ARM: OMAP2+: UART: Move errata handling from serial.c to omap-serial
Move the errata handling mechanism from serial.c to omap-serial file and utilise the same func in driver file. Errata i202, i291 are moved to be handled with omap-serial Moving the errata macro from serial.c file to driver header file as from on errata will be handled in driver file itself. Corrected errata id from chapter reference 2.15 to errata id i291. Removed errata and dma_enabled fields from omap_uart_state struct as they are no more needed with errata handling done within omap-serial. Signed-off-by: Govindraj.R <govindraj.raja@ti.com> Acked-by: Alan Cox <alan@linux.intel.com> Acked-by: Greg Kroah-Hartman <gregkh@suse.de> Signed-off-by: Kevin Hilman <khilman@ti.com>
Diffstat (limited to 'drivers/tty/serial/omap-serial.c')
-rw-r--r--drivers/tty/serial/omap-serial.c68
1 files changed, 64 insertions, 4 deletions
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index ea4c24aa8c87..764ac7795694 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -51,6 +51,7 @@ static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS];
51static void uart_tx_dma_callback(int lch, u16 ch_status, void *data); 51static void uart_tx_dma_callback(int lch, u16 ch_status, void *data);
52static void serial_omap_rx_timeout(unsigned long uart_no); 52static void serial_omap_rx_timeout(unsigned long uart_no);
53static int serial_omap_start_rxdma(struct uart_omap_port *up); 53static int serial_omap_start_rxdma(struct uart_omap_port *up);
54static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1);
54 55
55static inline unsigned int serial_in(struct uart_omap_port *up, int offset) 56static inline unsigned int serial_in(struct uart_omap_port *up, int offset)
56{ 57{
@@ -808,7 +809,11 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
808 809
809 /* Protocol, Baud Rate, and Interrupt Settings */ 810 /* Protocol, Baud Rate, and Interrupt Settings */
810 811
811 serial_out(up, UART_OMAP_MDR1, up->mdr1); 812 if (up->errata & UART_ERRATA_i202_MDR1_ACCESS)
813 serial_omap_mdr1_errataset(up, up->mdr1);
814 else
815 serial_out(up, UART_OMAP_MDR1, up->mdr1);
816
812 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); 817 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
813 818
814 up->efr = serial_in(up, UART_EFR); 819 up->efr = serial_in(up, UART_EFR);
@@ -833,7 +838,10 @@ serial_omap_set_termios(struct uart_port *port, struct ktermios *termios,
833 else 838 else
834 up->mdr1 = UART_OMAP_MDR1_16X_MODE; 839 up->mdr1 = UART_OMAP_MDR1_16X_MODE;
835 840
836 serial_out(up, UART_OMAP_MDR1, up->mdr1); 841 if (up->errata & UART_ERRATA_i202_MDR1_ACCESS)
842 serial_omap_mdr1_errataset(up, up->mdr1);
843 else
844 serial_out(up, UART_OMAP_MDR1, up->mdr1);
837 845
838 /* Hardware Flow Control Configuration */ 846 /* Hardware Flow Control Configuration */
839 847
@@ -1362,6 +1370,7 @@ static int serial_omap_probe(struct platform_device *pdev)
1362 up->port.flags = omap_up_info->flags; 1370 up->port.flags = omap_up_info->flags;
1363 up->port.uartclk = omap_up_info->uartclk; 1371 up->port.uartclk = omap_up_info->uartclk;
1364 up->uart_dma.uart_base = mem->start; 1372 up->uart_dma.uart_base = mem->start;
1373 up->errata = omap_up_info->errata;
1365 1374
1366 if (omap_up_info->dma_enabled) { 1375 if (omap_up_info->dma_enabled) {
1367 up->uart_dma.uart_dma_tx = dma_tx->start; 1376 up->uart_dma.uart_dma_tx = dma_tx->start;
@@ -1415,9 +1424,47 @@ static int serial_omap_remove(struct platform_device *dev)
1415 return 0; 1424 return 0;
1416} 1425}
1417 1426
1427/*
1428 * Work Around for Errata i202 (2430, 3430, 3630, 4430 and 4460)
1429 * The access to uart register after MDR1 Access
1430 * causes UART to corrupt data.
1431 *
1432 * Need a delay =
1433 * 5 L4 clock cycles + 5 UART functional clock cycle (@48MHz = ~0.2uS)
1434 * give 10 times as much
1435 */
1436static void serial_omap_mdr1_errataset(struct uart_omap_port *up, u8 mdr1)
1437{
1438 u8 timeout = 255;
1439
1440 serial_out(up, UART_OMAP_MDR1, mdr1);
1441 udelay(2);
1442 serial_out(up, UART_FCR, up->fcr | UART_FCR_CLEAR_XMIT |
1443 UART_FCR_CLEAR_RCVR);
1444 /*
1445 * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and
1446 * TX_FIFO_E bit is 1.
1447 */
1448 while (UART_LSR_THRE != (serial_in(up, UART_LSR) &
1449 (UART_LSR_THRE | UART_LSR_DR))) {
1450 timeout--;
1451 if (!timeout) {
1452 /* Should *never* happen. we warn and carry on */
1453 dev_crit(&up->pdev->dev, "Errata i202: timedout %x\n",
1454 serial_in(up, UART_LSR));
1455 break;
1456 }
1457 udelay(1);
1458 }
1459}
1460
1418static void serial_omap_restore_context(struct uart_omap_port *up) 1461static void serial_omap_restore_context(struct uart_omap_port *up)
1419{ 1462{
1420 serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE); 1463 if (up->errata & UART_ERRATA_i202_MDR1_ACCESS)
1464 serial_omap_mdr1_errataset(up, UART_OMAP_MDR1_DISABLE);
1465 else
1466 serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
1467
1421 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* Config B mode */ 1468 serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); /* Config B mode */
1422 serial_out(up, UART_EFR, UART_EFR_ECB); 1469 serial_out(up, UART_EFR, UART_EFR_ECB);
1423 serial_out(up, UART_LCR, 0x0); /* Operational mode */ 1470 serial_out(up, UART_LCR, 0x0); /* Operational mode */
@@ -1434,7 +1481,10 @@ static void serial_omap_restore_context(struct uart_omap_port *up)
1434 serial_out(up, UART_OMAP_SCR, up->scr); 1481 serial_out(up, UART_OMAP_SCR, up->scr);
1435 serial_out(up, UART_EFR, up->efr); 1482 serial_out(up, UART_EFR, up->efr);
1436 serial_out(up, UART_LCR, up->lcr); 1483 serial_out(up, UART_LCR, up->lcr);
1437 serial_out(up, UART_OMAP_MDR1, up->mdr1); 1484 if (up->errata & UART_ERRATA_i202_MDR1_ACCESS)
1485 serial_omap_mdr1_errataset(up, up->mdr1);
1486 else
1487 serial_out(up, UART_OMAP_MDR1, up->mdr1);
1438} 1488}
1439 1489
1440#ifdef CONFIG_PM_RUNTIME 1490#ifdef CONFIG_PM_RUNTIME
@@ -1449,6 +1499,11 @@ static int serial_omap_runtime_suspend(struct device *dev)
1449 if (pdata->get_context_loss_count) 1499 if (pdata->get_context_loss_count)
1450 up->context_loss_cnt = pdata->get_context_loss_count(dev); 1500 up->context_loss_cnt = pdata->get_context_loss_count(dev);
1451 1501
1502 /* Errata i291 */
1503 if (up->use_dma && pdata->set_forceidle &&
1504 (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE))
1505 pdata->set_forceidle(up->pdev);
1506
1452 return 0; 1507 return 0;
1453} 1508}
1454 1509
@@ -1464,6 +1519,11 @@ static int serial_omap_runtime_resume(struct device *dev)
1464 if (up->context_loss_cnt != loss_cnt) 1519 if (up->context_loss_cnt != loss_cnt)
1465 serial_omap_restore_context(up); 1520 serial_omap_restore_context(up);
1466 } 1521 }
1522
1523 /* Errata i291 */
1524 if (up->use_dma && pdata->set_noidle &&
1525 (up->errata & UART_ERRATA_i291_DMA_FORCEIDLE))
1526 pdata->set_noidle(up->pdev);
1467 } 1527 }
1468 1528
1469 return 0; 1529 return 0;