diff options
Diffstat (limited to 'drivers/tty/serial/omap-serial.c')
-rw-r--r-- | drivers/tty/serial/omap-serial.c | 74 |
1 files changed, 73 insertions, 1 deletions
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index d00b38eb268e..d3cda0cb2df0 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c | |||
@@ -44,6 +44,13 @@ | |||
44 | #include <plat/dmtimer.h> | 44 | #include <plat/dmtimer.h> |
45 | #include <plat/omap-serial.h> | 45 | #include <plat/omap-serial.h> |
46 | 46 | ||
47 | #define UART_BUILD_REVISION(x, y) (((x) << 8) | (y)) | ||
48 | |||
49 | #define OMAP_UART_REV_42 0x0402 | ||
50 | #define OMAP_UART_REV_46 0x0406 | ||
51 | #define OMAP_UART_REV_52 0x0502 | ||
52 | #define OMAP_UART_REV_63 0x0603 | ||
53 | |||
47 | #define DEFAULT_CLK_SPEED 48000000 /* 48Mhz*/ | 54 | #define DEFAULT_CLK_SPEED 48000000 /* 48Mhz*/ |
48 | 55 | ||
49 | /* SCR register bitmasks */ | 56 | /* SCR register bitmasks */ |
@@ -53,6 +60,17 @@ | |||
53 | #define OMAP_UART_FCR_RX_FIFO_TRIG_SHIFT 6 | 60 | #define OMAP_UART_FCR_RX_FIFO_TRIG_SHIFT 6 |
54 | #define OMAP_UART_FCR_RX_FIFO_TRIG_MASK (0x3 << 6) | 61 | #define OMAP_UART_FCR_RX_FIFO_TRIG_MASK (0x3 << 6) |
55 | 62 | ||
63 | /* MVR register bitmasks */ | ||
64 | #define OMAP_UART_MVR_SCHEME_SHIFT 30 | ||
65 | |||
66 | #define OMAP_UART_LEGACY_MVR_MAJ_MASK 0xf0 | ||
67 | #define OMAP_UART_LEGACY_MVR_MAJ_SHIFT 4 | ||
68 | #define OMAP_UART_LEGACY_MVR_MIN_MASK 0x0f | ||
69 | |||
70 | #define OMAP_UART_MVR_MAJ_MASK 0x700 | ||
71 | #define OMAP_UART_MVR_MAJ_SHIFT 8 | ||
72 | #define OMAP_UART_MVR_MIN_MASK 0x3f | ||
73 | |||
56 | static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS]; | 74 | static struct uart_omap_port *ui[OMAP_MAX_HSUART_PORTS]; |
57 | 75 | ||
58 | /* Forward declaration of functions */ | 76 | /* Forward declaration of functions */ |
@@ -1346,6 +1364,59 @@ static void uart_tx_dma_callback(int lch, u16 ch_status, void *data) | |||
1346 | return; | 1364 | return; |
1347 | } | 1365 | } |
1348 | 1366 | ||
1367 | static void omap_serial_fill_features_erratas(struct uart_omap_port *up) | ||
1368 | { | ||
1369 | u32 mvr, scheme; | ||
1370 | u16 revision, major, minor; | ||
1371 | |||
1372 | mvr = serial_in(up, UART_OMAP_MVER); | ||
1373 | |||
1374 | /* Check revision register scheme */ | ||
1375 | scheme = mvr >> OMAP_UART_MVR_SCHEME_SHIFT; | ||
1376 | |||
1377 | switch (scheme) { | ||
1378 | case 0: /* Legacy Scheme: OMAP2/3 */ | ||
1379 | /* MINOR_REV[0:4], MAJOR_REV[4:7] */ | ||
1380 | major = (mvr & OMAP_UART_LEGACY_MVR_MAJ_MASK) >> | ||
1381 | OMAP_UART_LEGACY_MVR_MAJ_SHIFT; | ||
1382 | minor = (mvr & OMAP_UART_LEGACY_MVR_MIN_MASK); | ||
1383 | break; | ||
1384 | case 1: | ||
1385 | /* New Scheme: OMAP4+ */ | ||
1386 | /* MINOR_REV[0:5], MAJOR_REV[8:10] */ | ||
1387 | major = (mvr & OMAP_UART_MVR_MAJ_MASK) >> | ||
1388 | OMAP_UART_MVR_MAJ_SHIFT; | ||
1389 | minor = (mvr & OMAP_UART_MVR_MIN_MASK); | ||
1390 | break; | ||
1391 | default: | ||
1392 | dev_warn(&up->pdev->dev, | ||
1393 | "Unknown %s revision, defaulting to highest\n", | ||
1394 | up->name); | ||
1395 | /* highest possible revision */ | ||
1396 | major = 0xff; | ||
1397 | minor = 0xff; | ||
1398 | } | ||
1399 | |||
1400 | /* normalize revision for the driver */ | ||
1401 | revision = UART_BUILD_REVISION(major, minor); | ||
1402 | |||
1403 | switch (revision) { | ||
1404 | case OMAP_UART_REV_46: | ||
1405 | up->errata |= (UART_ERRATA_i202_MDR1_ACCESS | | ||
1406 | UART_ERRATA_i291_DMA_FORCEIDLE); | ||
1407 | break; | ||
1408 | case OMAP_UART_REV_52: | ||
1409 | up->errata |= (UART_ERRATA_i202_MDR1_ACCESS | | ||
1410 | UART_ERRATA_i291_DMA_FORCEIDLE); | ||
1411 | break; | ||
1412 | case OMAP_UART_REV_63: | ||
1413 | up->errata |= UART_ERRATA_i202_MDR1_ACCESS; | ||
1414 | break; | ||
1415 | default: | ||
1416 | break; | ||
1417 | } | ||
1418 | } | ||
1419 | |||
1349 | static struct omap_uart_port_info *of_get_uart_port_info(struct device *dev) | 1420 | static struct omap_uart_port_info *of_get_uart_port_info(struct device *dev) |
1350 | { | 1421 | { |
1351 | struct omap_uart_port_info *omap_up_info; | 1422 | struct omap_uart_port_info *omap_up_info; |
@@ -1439,7 +1510,6 @@ static int serial_omap_probe(struct platform_device *pdev) | |||
1439 | "%d\n", DEFAULT_CLK_SPEED); | 1510 | "%d\n", DEFAULT_CLK_SPEED); |
1440 | } | 1511 | } |
1441 | up->uart_dma.uart_base = mem->start; | 1512 | up->uart_dma.uart_base = mem->start; |
1442 | up->errata = omap_up_info->errata; | ||
1443 | 1513 | ||
1444 | if (omap_up_info->dma_enabled) { | 1514 | if (omap_up_info->dma_enabled) { |
1445 | up->uart_dma.uart_dma_tx = dma_tx->start; | 1515 | up->uart_dma.uart_dma_tx = dma_tx->start; |
@@ -1469,6 +1539,8 @@ static int serial_omap_probe(struct platform_device *pdev) | |||
1469 | pm_runtime_enable(&pdev->dev); | 1539 | pm_runtime_enable(&pdev->dev); |
1470 | pm_runtime_get_sync(&pdev->dev); | 1540 | pm_runtime_get_sync(&pdev->dev); |
1471 | 1541 | ||
1542 | omap_serial_fill_features_erratas(up); | ||
1543 | |||
1472 | ui[up->port.line] = up; | 1544 | ui[up->port.line] = up; |
1473 | serial_omap_add_console_port(up); | 1545 | serial_omap_add_console_port(up); |
1474 | 1546 | ||