aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/serial.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-omap2/serial.c')
-rw-r--r--arch/arm/mach-omap2/serial.c101
1 files changed, 31 insertions, 70 deletions
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 78ca7e8fc10b..77a25cb1dcca 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -42,8 +42,6 @@
42#include "control.h" 42#include "control.h"
43#include "mux.h" 43#include "mux.h"
44 44
45#define UART_ERRATA_i202_MDR1_ACCESS (0x1 << 1)
46
47/* 45/*
48 * NOTE: By default the serial timeout is disabled as it causes lost characters 46 * NOTE: By default the serial timeout is disabled as it causes lost characters
49 * over the serial ports. This means that the UART clocks will stay on until 47 * over the serial ports. This means that the UART clocks will stay on until
@@ -61,59 +59,17 @@ struct omap_uart_state {
61 void __iomem *wk_st; 59 void __iomem *wk_st;
62 void __iomem *wk_en; 60 void __iomem *wk_en;
63 u32 wk_mask; 61 u32 wk_mask;
64 u32 dma_enabled;
65 62
66 int clocked; 63 int clocked;
67 64
68 struct list_head node; 65 struct list_head node;
69 struct omap_hwmod *oh; 66 struct omap_hwmod *oh;
70 struct platform_device *pdev; 67 struct platform_device *pdev;
71
72 u32 errata;
73}; 68};
74 69
75static LIST_HEAD(uart_list); 70static LIST_HEAD(uart_list);
76static u8 num_uarts; 71static u8 num_uarts;
77 72
78#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
79
80/*
81 * Work Around for Errata i202 (3430 - 1.12, 3630 - 1.6)
82 * The access to uart register after MDR1 Access
83 * causes UART to corrupt data.
84 *
85 * Need a delay =
86 * 5 L4 clock cycles + 5 UART functional clock cycle (@48MHz = ~0.2uS)
87 * give 10 times as much
88 */
89static void omap_uart_mdr1_errataset(struct omap_uart_state *uart, u8 mdr1_val,
90 u8 fcr_val)
91{
92 u8 timeout = 255;
93
94 serial_write_reg(uart, UART_OMAP_MDR1, mdr1_val);
95 udelay(2);
96 serial_write_reg(uart, UART_FCR, fcr_val | UART_FCR_CLEAR_XMIT |
97 UART_FCR_CLEAR_RCVR);
98 /*
99 * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and
100 * TX_FIFO_E bit is 1.
101 */
102 while (UART_LSR_THRE != (serial_read_reg(uart, UART_LSR) &
103 (UART_LSR_THRE | UART_LSR_DR))) {
104 timeout--;
105 if (!timeout) {
106 /* Should *never* happen. we warn and carry on */
107 dev_crit(&uart->pdev->dev, "Errata i202: timedout %x\n",
108 serial_read_reg(uart, UART_LSR));
109 break;
110 }
111 udelay(1);
112 }
113}
114
115#endif /* CONFIG_PM && CONFIG_ARCH_OMAP3 */
116
117static inline void omap_uart_enable_clocks(struct omap_uart_state *uart) 73static inline void omap_uart_enable_clocks(struct omap_uart_state *uart)
118{ 74{
119 if (uart->clocked) 75 if (uart->clocked)
@@ -156,27 +112,6 @@ static void omap_uart_disable_wakeup(struct omap_uart_state *uart)
156 } 112 }
157} 113}
158 114
159static void omap_uart_smart_idle_enable(struct omap_uart_state *uart,
160 int enable)
161{
162 u8 idlemode;
163
164 if (enable) {
165 /**
166 * Errata 2.15: [UART]:Cannot Acknowledge Idle Requests
167 * in Smartidle Mode When Configured for DMA Operations.
168 */
169 if (uart->dma_enabled)
170 idlemode = HWMOD_IDLEMODE_FORCE;
171 else
172 idlemode = HWMOD_IDLEMODE_SMART;
173 } else {
174 idlemode = HWMOD_IDLEMODE_NO;
175 }
176
177 omap_hwmod_set_slave_idlemode(uart->oh, idlemode);
178}
179
180static void omap_uart_block_sleep(struct omap_uart_state *uart) 115static void omap_uart_block_sleep(struct omap_uart_state *uart)
181{ 116{
182 omap_uart_enable_clocks(uart); 117 omap_uart_enable_clocks(uart);
@@ -267,7 +202,28 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
267 } 202 }
268} 203}
269 204
205/*
206 * Errata i291: [UART]:Cannot Acknowledge Idle Requests
207 * in Smartidle Mode When Configured for DMA Operations.
208 * WA: configure uart in force idle mode.
209 */
210static void omap_uart_set_noidle(struct platform_device *pdev)
211{
212 struct omap_device *od = to_omap_device(pdev);
213
214 omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_NO);
215}
216
217static void omap_uart_set_forceidle(struct platform_device *pdev)
218{
219 struct omap_device *od = to_omap_device(pdev);
220
221 omap_hwmod_set_slave_idlemode(od->hwmods[0], HWMOD_IDLEMODE_FORCE);
222}
223
270#else 224#else
225static void omap_uart_set_noidle(struct platform_device *pdev) {}
226static void omap_uart_set_forceidle(struct platform_device *pdev) {}
271static void omap_uart_block_sleep(struct omap_uart_state *uart) 227static void omap_uart_block_sleep(struct omap_uart_state *uart)
272{ 228{
273 /* Needed to enable UART clocks when built without CONFIG_PM */ 229 /* Needed to enable UART clocks when built without CONFIG_PM */
@@ -473,13 +429,22 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
473 break; 429 break;
474 430
475 oh = uart->oh; 431 oh = uart->oh;
476 uart->dma_enabled = 0;
477 name = DRIVER_NAME; 432 name = DRIVER_NAME;
478 433
479 omap_up.dma_enabled = uart->dma_enabled; 434 omap_up.dma_enabled = uart->dma_enabled;
480 omap_up.uartclk = OMAP24XX_BASE_BAUD * 16; 435 omap_up.uartclk = OMAP24XX_BASE_BAUD * 16;
481 omap_up.flags = UPF_BOOT_AUTOCONF; 436 omap_up.flags = UPF_BOOT_AUTOCONF;
482 omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count; 437 omap_up.get_context_loss_count = omap_pm_get_dev_context_loss_count;
438 omap_up.set_forceidle = omap_uart_set_forceidle;
439 omap_up.set_noidle = omap_uart_set_noidle;
440
441 /* Enable the MDR1 Errata i202 for OMAP2430/3xxx/44xx */
442 if (!cpu_is_omap2420() && !cpu_is_ti816x())
443 omap_up.errata |= UART_ERRATA_i202_MDR1_ACCESS;
444
445 /* Enable DMA Mode Force Idle Errata i291 for omap34xx/3630 */
446 if (cpu_is_omap34xx() || cpu_is_omap3630())
447 omap_up.errata |= UART_ERRATA_i291_DMA_FORCEIDLE;
483 448
484 pdata = &omap_up; 449 pdata = &omap_up;
485 pdata_size = sizeof(struct omap_uart_port_info); 450 pdata_size = sizeof(struct omap_uart_port_info);
@@ -519,10 +484,6 @@ void __init omap_serial_init_port(struct omap_board_data *bdata)
519 if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) || 484 if (((cpu_is_omap34xx() || cpu_is_omap44xx()) && bdata->pads) ||
520 (pdata->wk_en && pdata->wk_mask)) 485 (pdata->wk_en && pdata->wk_mask))
521 device_init_wakeup(&pdev->dev, true); 486 device_init_wakeup(&pdev->dev, true);
522
523 /* Enable the MDR1 errata for OMAP3 */
524 if (cpu_is_omap34xx() && !(cpu_is_ti81xx() || cpu_is_am33xx()))
525 uart->errata |= UART_ERRATA_i202_MDR1_ACCESS;
526} 487}
527 488
528/** 489/**