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.c80
1 files changed, 69 insertions, 11 deletions
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index 3771254dfa81..566e991ede81 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -37,6 +37,9 @@
37#define UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV 0x52 37#define UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV 0x52
38#define UART_OMAP_WER 0x17 /* Wake-up enable register */ 38#define UART_OMAP_WER 0x17 /* Wake-up enable register */
39 39
40#define UART_ERRATA_FIFO_FULL_ABORT (0x1 << 0)
41#define UART_ERRATA_i202_MDR1_ACCESS (0x1 << 1)
42
40/* 43/*
41 * NOTE: By default the serial timeout is disabled as it causes lost characters 44 * NOTE: By default the serial timeout is disabled as it causes lost characters
42 * over the serial ports. This means that the UART clocks will stay on until 45 * over the serial ports. This means that the UART clocks will stay on until
@@ -64,6 +67,7 @@ struct omap_uart_state {
64 struct list_head node; 67 struct list_head node;
65 struct platform_device pdev; 68 struct platform_device pdev;
66 69
70 u32 errata;
67#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) 71#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
68 int context_valid; 72 int context_valid;
69 73
@@ -74,6 +78,7 @@ struct omap_uart_state {
74 u16 sysc; 78 u16 sysc;
75 u16 scr; 79 u16 scr;
76 u16 wer; 80 u16 wer;
81 u16 mcr;
77#endif 82#endif
78}; 83};
79 84
@@ -180,6 +185,42 @@ static inline void __init omap_uart_reset(struct omap_uart_state *uart)
180 185
181#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) 186#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
182 187
188/*
189 * Work Around for Errata i202 (3430 - 1.12, 3630 - 1.6)
190 * The access to uart register after MDR1 Access
191 * causes UART to corrupt data.
192 *
193 * Need a delay =
194 * 5 L4 clock cycles + 5 UART functional clock cycle (@48MHz = ~0.2uS)
195 * give 10 times as much
196 */
197static void omap_uart_mdr1_errataset(struct omap_uart_state *uart, u8 mdr1_val,
198 u8 fcr_val)
199{
200 struct plat_serial8250_port *p = uart->p;
201 u8 timeout = 255;
202
203 serial_write_reg(p, UART_OMAP_MDR1, mdr1_val);
204 udelay(2);
205 serial_write_reg(p, UART_FCR, fcr_val | UART_FCR_CLEAR_XMIT |
206 UART_FCR_CLEAR_RCVR);
207 /*
208 * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and
209 * TX_FIFO_E bit is 1.
210 */
211 while (UART_LSR_THRE != (serial_read_reg(p, UART_LSR) &
212 (UART_LSR_THRE | UART_LSR_DR))) {
213 timeout--;
214 if (!timeout) {
215 /* Should *never* happen. we warn and carry on */
216 dev_crit(&uart->pdev.dev, "Errata i202: timedout %x\n",
217 serial_read_reg(p, UART_LSR));
218 break;
219 }
220 udelay(1);
221 }
222}
223
183static void omap_uart_save_context(struct omap_uart_state *uart) 224static void omap_uart_save_context(struct omap_uart_state *uart)
184{ 225{
185 u16 lcr = 0; 226 u16 lcr = 0;
@@ -197,6 +238,9 @@ static void omap_uart_save_context(struct omap_uart_state *uart)
197 uart->sysc = serial_read_reg(p, UART_OMAP_SYSC); 238 uart->sysc = serial_read_reg(p, UART_OMAP_SYSC);
198 uart->scr = serial_read_reg(p, UART_OMAP_SCR); 239 uart->scr = serial_read_reg(p, UART_OMAP_SCR);
199 uart->wer = serial_read_reg(p, UART_OMAP_WER); 240 uart->wer = serial_read_reg(p, UART_OMAP_WER);
241 serial_write_reg(p, UART_LCR, 0x80);
242 uart->mcr = serial_read_reg(p, UART_MCR);
243 serial_write_reg(p, UART_LCR, lcr);
200 244
201 uart->context_valid = 1; 245 uart->context_valid = 1;
202} 246}
@@ -214,7 +258,10 @@ static void omap_uart_restore_context(struct omap_uart_state *uart)
214 258
215 uart->context_valid = 0; 259 uart->context_valid = 0;
216 260
217 serial_write_reg(p, UART_OMAP_MDR1, 0x7); 261 if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
262 omap_uart_mdr1_errataset(uart, 0x07, 0xA0);
263 else
264 serial_write_reg(p, UART_OMAP_MDR1, 0x7);
218 serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */ 265 serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */
219 efr = serial_read_reg(p, UART_EFR); 266 efr = serial_read_reg(p, UART_EFR);
220 serial_write_reg(p, UART_EFR, UART_EFR_ECB); 267 serial_write_reg(p, UART_EFR, UART_EFR_ECB);
@@ -225,14 +272,18 @@ static void omap_uart_restore_context(struct omap_uart_state *uart)
225 serial_write_reg(p, UART_DLM, uart->dlh); 272 serial_write_reg(p, UART_DLM, uart->dlh);
226 serial_write_reg(p, UART_LCR, 0x0); /* Operational mode */ 273 serial_write_reg(p, UART_LCR, 0x0); /* Operational mode */
227 serial_write_reg(p, UART_IER, uart->ier); 274 serial_write_reg(p, UART_IER, uart->ier);
228 serial_write_reg(p, UART_FCR, 0xA1); 275 serial_write_reg(p, UART_LCR, 0x80);
276 serial_write_reg(p, UART_MCR, uart->mcr);
229 serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */ 277 serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */
230 serial_write_reg(p, UART_EFR, efr); 278 serial_write_reg(p, UART_EFR, efr);
231 serial_write_reg(p, UART_LCR, UART_LCR_WLEN8); 279 serial_write_reg(p, UART_LCR, UART_LCR_WLEN8);
232 serial_write_reg(p, UART_OMAP_SCR, uart->scr); 280 serial_write_reg(p, UART_OMAP_SCR, uart->scr);
233 serial_write_reg(p, UART_OMAP_WER, uart->wer); 281 serial_write_reg(p, UART_OMAP_WER, uart->wer);
234 serial_write_reg(p, UART_OMAP_SYSC, uart->sysc); 282 serial_write_reg(p, UART_OMAP_SYSC, uart->sysc);
235 serial_write_reg(p, UART_OMAP_MDR1, 0x00); /* UART 16x mode */ 283 if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
284 omap_uart_mdr1_errataset(uart, 0x00, 0xA1);
285 else
286 serial_write_reg(p, UART_OMAP_MDR1, 0x00); /* UART 16x mode */
236} 287}
237#else 288#else
238static inline void omap_uart_save_context(struct omap_uart_state *uart) {} 289static inline void omap_uart_save_context(struct omap_uart_state *uart) {}
@@ -489,8 +540,8 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
489 } 540 }
490 uart->wk_mask = wk_mask; 541 uart->wk_mask = wk_mask;
491 } else { 542 } else {
492 uart->wk_en = 0; 543 uart->wk_en = NULL;
493 uart->wk_st = 0; 544 uart->wk_st = NULL;
494 uart->wk_mask = 0; 545 uart->wk_mask = 0;
495 uart->padconf = 0; 546 uart->padconf = 0;
496 } 547 }
@@ -552,7 +603,8 @@ static ssize_t sleep_timeout_store(struct device *dev,
552 return n; 603 return n;
553} 604}
554 605
555DEVICE_ATTR(sleep_timeout, 0644, sleep_timeout_show, sleep_timeout_store); 606static DEVICE_ATTR(sleep_timeout, 0644, sleep_timeout_show,
607 sleep_timeout_store);
556#define DEV_CREATE_FILE(dev, attr) WARN_ON(device_create_file(dev, attr)) 608#define DEV_CREATE_FILE(dev, attr) WARN_ON(device_create_file(dev, attr))
557#else 609#else
558static inline void omap_uart_idle_init(struct omap_uart_state *uart) {} 610static inline void omap_uart_idle_init(struct omap_uart_state *uart) {}
@@ -749,14 +801,20 @@ void __init omap_serial_init_port(int port)
749 * omap3xxx: Never read empty UART fifo on UARTs 801 * omap3xxx: Never read empty UART fifo on UARTs
750 * with IP rev >=0x52 802 * with IP rev >=0x52
751 */ 803 */
752 if (cpu_is_omap44xx()) { 804 if (cpu_is_omap44xx())
753 uart->p->serial_in = serial_in_override; 805 uart->errata |= UART_ERRATA_FIFO_FULL_ABORT;
754 uart->p->serial_out = serial_out_override; 806 else if ((serial_read_reg(uart->p, UART_OMAP_MVER) & 0xFF)
755 } else if ((serial_read_reg(uart->p, UART_OMAP_MVER) & 0xFF) 807 >= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV)
756 >= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV) { 808 uart->errata |= UART_ERRATA_FIFO_FULL_ABORT;
809
810 if (uart->errata & UART_ERRATA_FIFO_FULL_ABORT) {
757 uart->p->serial_in = serial_in_override; 811 uart->p->serial_in = serial_in_override;
758 uart->p->serial_out = serial_out_override; 812 uart->p->serial_out = serial_out_override;
759 } 813 }
814
815 /* Enable the MDR1 errata for OMAP3 */
816 if (cpu_is_omap34xx())
817 uart->errata |= UART_ERRATA_i202_MDR1_ACCESS;
760} 818}
761 819
762/** 820/**