blob: ff83e91e6109a131e61ba72842f4c9ed99315fad [file] [log] [blame]
Tony Lindgren1dbae812005-11-10 14:26:51 +00001/*
Uwe Zeisbergerf30c2262006-10-03 23:01:26 +02002 * arch/arm/mach-omap2/serial.c
Tony Lindgren1dbae812005-11-10 14:26:51 +00003 *
4 * OMAP2 serial support.
5 *
Jouni Hogander6e811762008-10-06 15:49:15 +03006 * Copyright (C) 2005-2008 Nokia Corporation
Tony Lindgren1dbae812005-11-10 14:26:51 +00007 * Author: Paul Mundt <paul.mundt@nokia.com>
8 *
Kevin Hilman4af40162009-02-04 10:51:40 -08009 * Major rework for PM support by Kevin Hilman
10 *
Tony Lindgren1dbae812005-11-10 14:26:51 +000011 * Based off of arch/arm/mach-omap/omap1/serial.c
12 *
Santosh Shilimkar44169072009-05-28 14:16:04 -070013 * Copyright (C) 2009 Texas Instruments
14 * Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com
15 *
Tony Lindgren1dbae812005-11-10 14:26:51 +000016 * This file is subject to the terms and conditions of the GNU General Public
17 * License. See the file "COPYING" in the main directory of this archive
18 * for more details.
19 */
20#include <linux/kernel.h>
21#include <linux/init.h>
Tony Lindgren1dbae812005-11-10 14:26:51 +000022#include <linux/serial_reg.h>
Russell Kingf8ce2542006-01-07 16:15:52 +000023#include <linux/clk.h>
Russell Kingfced80c2008-09-06 12:10:45 +010024#include <linux/io.h>
Santosh Shilimkare03d37d2010-02-18 08:59:06 +000025#include <linux/delay.h>
Kevin Hilman6f251e92010-09-27 20:19:38 +053026#include <linux/platform_device.h>
27#include <linux/slab.h>
28#include <linux/serial_8250.h>
Kevin Hilman3244fcd2010-09-27 20:19:53 +053029#include <linux/pm_runtime.h>
Kevin Hilman6f251e92010-09-27 20:19:38 +053030
31#ifdef CONFIG_SERIAL_OMAP
32#include <plat/omap-serial.h>
33#endif
Tony Lindgren1dbae812005-11-10 14:26:51 +000034
Tony Lindgrence491cf2009-10-20 09:40:47 -070035#include <plat/common.h>
36#include <plat/board.h>
37#include <plat/clock.h>
38#include <plat/control.h>
Kevin Hilman6f251e92010-09-27 20:19:38 +053039#include <plat/dma.h>
40#include <plat/omap_hwmod.h>
41#include <plat/omap_device.h>
Tony Lindgren1dbae812005-11-10 14:26:51 +000042
Kevin Hilman4af40162009-02-04 10:51:40 -080043#include "prm.h"
44#include "pm.h"
Kevin Hilman6f251e92010-09-27 20:19:38 +053045#include "cm.h"
Kevin Hilman4af40162009-02-04 10:51:40 -080046#include "prm-regbits-34xx.h"
47
vikram panditace13d472009-12-11 16:16:37 -080048#define UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV 0x52
Kevin Hilman4af40162009-02-04 10:51:40 -080049#define UART_OMAP_WER 0x17 /* Wake-up enable register */
50
Nishanth Menon5a927b32010-08-02 13:18:12 +030051#define UART_ERRATA_FIFO_FULL_ABORT (0x1 << 0)
Deepak K00034502010-08-02 13:18:12 +030052#define UART_ERRATA_i202_MDR1_ACCESS (0x1 << 1)
Nishanth Menon5a927b32010-08-02 13:18:12 +030053
Tony Lindgren301fe8e2010-02-01 12:34:31 -080054/*
55 * NOTE: By default the serial timeout is disabled as it causes lost characters
56 * over the serial ports. This means that the UART clocks will stay on until
57 * disabled via sysfs. This also causes that any deeper omap sleep states are
58 * blocked.
59 */
60#define DEFAULT_TIMEOUT 0
Kevin Hilman4af40162009-02-04 10:51:40 -080061
Kevin Hilman6f251e92010-09-27 20:19:38 +053062#define MAX_UART_HWMOD_NAME_LEN 16
63
Kevin Hilman4af40162009-02-04 10:51:40 -080064struct omap_uart_state {
65 int num;
66 int can_sleep;
67 struct timer_list timer;
68 u32 timeout;
69
70 void __iomem *wk_st;
71 void __iomem *wk_en;
72 u32 wk_mask;
73 u32 padconf;
Kevin Hilman6f251e92010-09-27 20:19:38 +053074 u32 dma_enabled;
Kevin Hilman4af40162009-02-04 10:51:40 -080075
76 struct clk *ick;
77 struct clk *fck;
78 int clocked;
79
Kevin Hilman6f251e92010-09-27 20:19:38 +053080 int irq;
81 int regshift;
82 int irqflags;
83 void __iomem *membase;
84 resource_size_t mapbase;
85
Kevin Hilman4af40162009-02-04 10:51:40 -080086 struct list_head node;
Kevin Hilman6f251e92010-09-27 20:19:38 +053087 struct omap_hwmod *oh;
88 struct platform_device *pdev;
Kevin Hilman4af40162009-02-04 10:51:40 -080089
Nishanth Menon5a927b32010-08-02 13:18:12 +030090 u32 errata;
Kevin Hilman4af40162009-02-04 10:51:40 -080091#if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM)
92 int context_valid;
93
94 /* Registers to be saved/restored for OFF-mode */
95 u16 dll;
96 u16 dlh;
97 u16 ier;
98 u16 sysc;
99 u16 scr;
100 u16 wer;
Govindraj R5ade4ff2010-08-02 13:18:11 +0300101 u16 mcr;
Kevin Hilman4af40162009-02-04 10:51:40 -0800102#endif
103};
104
Kevin Hilman4af40162009-02-04 10:51:40 -0800105static LIST_HEAD(uart_list);
Kevin Hilman6f251e92010-09-27 20:19:38 +0530106static u8 num_uarts;
Tony Lindgren1dbae812005-11-10 14:26:51 +0000107
Kevin Hilman6f251e92010-09-27 20:19:38 +0530108static struct omap_device_pm_latency omap_uart_latency[] = {
109 {
110 .deactivate_func = omap_device_idle_hwmods,
111 .activate_func = omap_device_enable_hwmods,
112 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST,
113 },
114};
115
Alexander Shishkin92303722010-01-08 10:29:06 -0800116static inline unsigned int __serial_read_reg(struct uart_port *up,
Kevin Hilman6f251e92010-09-27 20:19:38 +0530117 int offset)
Alexander Shishkin92303722010-01-08 10:29:06 -0800118{
119 offset <<= up->regshift;
120 return (unsigned int)__raw_readb(up->membase + offset);
121}
122
Kevin Hilman6f251e92010-09-27 20:19:38 +0530123static inline unsigned int serial_read_reg(struct omap_uart_state *uart,
Tony Lindgren1dbae812005-11-10 14:26:51 +0000124 int offset)
125{
Kevin Hilman6f251e92010-09-27 20:19:38 +0530126 offset <<= uart->regshift;
127 return (unsigned int)__raw_readb(uart->membase + offset);
Tony Lindgren1dbae812005-11-10 14:26:51 +0000128}
129
Santosh Shilimkare03d37d2010-02-18 08:59:06 +0000130static inline void __serial_write_reg(struct uart_port *up, int offset,
131 int value)
132{
133 offset <<= up->regshift;
134 __raw_writeb(value, up->membase + offset);
135}
136
Kevin Hilman6f251e92010-09-27 20:19:38 +0530137static inline void serial_write_reg(struct omap_uart_state *uart, int offset,
Tony Lindgren1dbae812005-11-10 14:26:51 +0000138 int value)
139{
Kevin Hilman6f251e92010-09-27 20:19:38 +0530140 offset <<= uart->regshift;
141 __raw_writeb(value, uart->membase + offset);
Tony Lindgren1dbae812005-11-10 14:26:51 +0000142}
143
144/*
145 * Internal UARTs need to be initialized for the 8250 autoconfig to work
146 * properly. Note that the TX watermark initialization may not be needed
147 * once the 8250.c watermark handling code is merged.
148 */
Kevin Hilman6f251e92010-09-27 20:19:38 +0530149
Kevin Hilman4af40162009-02-04 10:51:40 -0800150static inline void __init omap_uart_reset(struct omap_uart_state *uart)
Tony Lindgren1dbae812005-11-10 14:26:51 +0000151{
Kevin Hilman6f251e92010-09-27 20:19:38 +0530152 serial_write_reg(uart, UART_OMAP_MDR1, 0x07);
153 serial_write_reg(uart, UART_OMAP_SCR, 0x08);
154 serial_write_reg(uart, UART_OMAP_MDR1, 0x00);
Tony Lindgren1dbae812005-11-10 14:26:51 +0000155}
156
Kevin Hilman4af40162009-02-04 10:51:40 -0800157#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
158
Deepak K00034502010-08-02 13:18:12 +0300159/*
160 * Work Around for Errata i202 (3430 - 1.12, 3630 - 1.6)
161 * The access to uart register after MDR1 Access
162 * causes UART to corrupt data.
163 *
164 * Need a delay =
165 * 5 L4 clock cycles + 5 UART functional clock cycle (@48MHz = ~0.2uS)
166 * give 10 times as much
167 */
168static void omap_uart_mdr1_errataset(struct omap_uart_state *uart, u8 mdr1_val,
169 u8 fcr_val)
170{
Deepak K00034502010-08-02 13:18:12 +0300171 u8 timeout = 255;
172
Kevin Hilman6f251e92010-09-27 20:19:38 +0530173 serial_write_reg(uart, UART_OMAP_MDR1, mdr1_val);
Deepak K00034502010-08-02 13:18:12 +0300174 udelay(2);
Kevin Hilman6f251e92010-09-27 20:19:38 +0530175 serial_write_reg(uart, UART_FCR, fcr_val | UART_FCR_CLEAR_XMIT |
Deepak K00034502010-08-02 13:18:12 +0300176 UART_FCR_CLEAR_RCVR);
177 /*
178 * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and
179 * TX_FIFO_E bit is 1.
180 */
Kevin Hilman6f251e92010-09-27 20:19:38 +0530181 while (UART_LSR_THRE != (serial_read_reg(uart, UART_LSR) &
Deepak K00034502010-08-02 13:18:12 +0300182 (UART_LSR_THRE | UART_LSR_DR))) {
183 timeout--;
184 if (!timeout) {
185 /* Should *never* happen. we warn and carry on */
Kevin Hilman6f251e92010-09-27 20:19:38 +0530186 dev_crit(&uart->pdev->dev, "Errata i202: timedout %x\n",
187 serial_read_reg(uart, UART_LSR));
Deepak K00034502010-08-02 13:18:12 +0300188 break;
189 }
190 udelay(1);
191 }
192}
193
Kevin Hilman4af40162009-02-04 10:51:40 -0800194static void omap_uart_save_context(struct omap_uart_state *uart)
Jouni Hogander6e811762008-10-06 15:49:15 +0300195{
Kevin Hilman4af40162009-02-04 10:51:40 -0800196 u16 lcr = 0;
Kevin Hilman4af40162009-02-04 10:51:40 -0800197
198 if (!enable_off_mode)
199 return;
200
Kevin Hilman6f251e92010-09-27 20:19:38 +0530201 lcr = serial_read_reg(uart, UART_LCR);
202 serial_write_reg(uart, UART_LCR, 0xBF);
203 uart->dll = serial_read_reg(uart, UART_DLL);
204 uart->dlh = serial_read_reg(uart, UART_DLM);
205 serial_write_reg(uart, UART_LCR, lcr);
206 uart->ier = serial_read_reg(uart, UART_IER);
207 uart->sysc = serial_read_reg(uart, UART_OMAP_SYSC);
208 uart->scr = serial_read_reg(uart, UART_OMAP_SCR);
209 uart->wer = serial_read_reg(uart, UART_OMAP_WER);
210 serial_write_reg(uart, UART_LCR, 0x80);
211 uart->mcr = serial_read_reg(uart, UART_MCR);
212 serial_write_reg(uart, UART_LCR, lcr);
Kevin Hilman4af40162009-02-04 10:51:40 -0800213
214 uart->context_valid = 1;
215}
216
217static void omap_uart_restore_context(struct omap_uart_state *uart)
218{
219 u16 efr = 0;
Kevin Hilman4af40162009-02-04 10:51:40 -0800220
221 if (!enable_off_mode)
222 return;
223
224 if (!uart->context_valid)
225 return;
226
227 uart->context_valid = 0;
228
Deepak K00034502010-08-02 13:18:12 +0300229 if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
230 omap_uart_mdr1_errataset(uart, 0x07, 0xA0);
231 else
Kevin Hilman6f251e92010-09-27 20:19:38 +0530232 serial_write_reg(uart, UART_OMAP_MDR1, 0x7);
233 serial_write_reg(uart, UART_LCR, 0xBF); /* Config B mode */
234 efr = serial_read_reg(uart, UART_EFR);
235 serial_write_reg(uart, UART_EFR, UART_EFR_ECB);
236 serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */
237 serial_write_reg(uart, UART_IER, 0x0);
238 serial_write_reg(uart, UART_LCR, 0xBF); /* Config B mode */
239 serial_write_reg(uart, UART_DLL, uart->dll);
240 serial_write_reg(uart, UART_DLM, uart->dlh);
241 serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */
242 serial_write_reg(uart, UART_IER, uart->ier);
243 serial_write_reg(uart, UART_LCR, 0x80);
244 serial_write_reg(uart, UART_MCR, uart->mcr);
245 serial_write_reg(uart, UART_LCR, 0xBF); /* Config B mode */
246 serial_write_reg(uart, UART_EFR, efr);
247 serial_write_reg(uart, UART_LCR, UART_LCR_WLEN8);
248 serial_write_reg(uart, UART_OMAP_SCR, uart->scr);
249 serial_write_reg(uart, UART_OMAP_WER, uart->wer);
250 serial_write_reg(uart, UART_OMAP_SYSC, uart->sysc);
Deepak K00034502010-08-02 13:18:12 +0300251 if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
252 omap_uart_mdr1_errataset(uart, 0x00, 0xA1);
253 else
Kevin Hilman6f251e92010-09-27 20:19:38 +0530254 /* UART 16x mode */
255 serial_write_reg(uart, UART_OMAP_MDR1, 0x00);
Kevin Hilman4af40162009-02-04 10:51:40 -0800256}
257#else
258static inline void omap_uart_save_context(struct omap_uart_state *uart) {}
259static inline void omap_uart_restore_context(struct omap_uart_state *uart) {}
260#endif /* CONFIG_PM && CONFIG_ARCH_OMAP3 */
261
262static inline void omap_uart_enable_clocks(struct omap_uart_state *uart)
263{
264 if (uart->clocked)
265 return;
266
Kevin Hilman6f251e92010-09-27 20:19:38 +0530267 omap_device_enable(uart->pdev);
Kevin Hilman4af40162009-02-04 10:51:40 -0800268 uart->clocked = 1;
269 omap_uart_restore_context(uart);
270}
271
272#ifdef CONFIG_PM
273
274static inline void omap_uart_disable_clocks(struct omap_uart_state *uart)
275{
276 if (!uart->clocked)
277 return;
278
279 omap_uart_save_context(uart);
280 uart->clocked = 0;
Kevin Hilman6f251e92010-09-27 20:19:38 +0530281 omap_device_idle(uart->pdev);
Kevin Hilman4af40162009-02-04 10:51:40 -0800282}
283
Kevin Hilmanfd455ea2009-04-27 12:27:36 -0700284static void omap_uart_enable_wakeup(struct omap_uart_state *uart)
285{
286 /* Set wake-enable bit */
287 if (uart->wk_en && uart->wk_mask) {
288 u32 v = __raw_readl(uart->wk_en);
289 v |= uart->wk_mask;
290 __raw_writel(v, uart->wk_en);
291 }
292
293 /* Ensure IOPAD wake-enables are set */
294 if (cpu_is_omap34xx() && uart->padconf) {
295 u16 v = omap_ctrl_readw(uart->padconf);
296 v |= OMAP3_PADCONF_WAKEUPENABLE0;
297 omap_ctrl_writew(v, uart->padconf);
298 }
299}
300
301static void omap_uart_disable_wakeup(struct omap_uart_state *uart)
302{
303 /* Clear wake-enable bit */
304 if (uart->wk_en && uart->wk_mask) {
305 u32 v = __raw_readl(uart->wk_en);
306 v &= ~uart->wk_mask;
307 __raw_writel(v, uart->wk_en);
308 }
309
310 /* Ensure IOPAD wake-enables are cleared */
311 if (cpu_is_omap34xx() && uart->padconf) {
312 u16 v = omap_ctrl_readw(uart->padconf);
313 v &= ~OMAP3_PADCONF_WAKEUPENABLE0;
314 omap_ctrl_writew(v, uart->padconf);
315 }
316}
317
Kevin Hilman4af40162009-02-04 10:51:40 -0800318static void omap_uart_smart_idle_enable(struct omap_uart_state *uart,
Kevin Hilman6f251e92010-09-27 20:19:38 +0530319 int enable)
Kevin Hilman4af40162009-02-04 10:51:40 -0800320{
Kevin Hilman6f251e92010-09-27 20:19:38 +0530321 u8 idlemode;
Kevin Hilman4af40162009-02-04 10:51:40 -0800322
Kevin Hilman6f251e92010-09-27 20:19:38 +0530323 if (enable) {
324 /**
325 * Errata 2.15: [UART]:Cannot Acknowledge Idle Requests
326 * in Smartidle Mode When Configured for DMA Operations.
327 */
328 if (uart->dma_enabled)
329 idlemode = HWMOD_IDLEMODE_FORCE;
330 else
331 idlemode = HWMOD_IDLEMODE_SMART;
332 } else {
333 idlemode = HWMOD_IDLEMODE_NO;
334 }
Kevin Hilman4af40162009-02-04 10:51:40 -0800335
Kevin Hilman6f251e92010-09-27 20:19:38 +0530336 omap_hwmod_set_slave_idlemode(uart->oh, idlemode);
Kevin Hilman4af40162009-02-04 10:51:40 -0800337}
338
339static void omap_uart_block_sleep(struct omap_uart_state *uart)
340{
341 omap_uart_enable_clocks(uart);
342
343 omap_uart_smart_idle_enable(uart, 0);
344 uart->can_sleep = 0;
Jouni Hoganderba87a9b2008-12-09 13:36:50 +0200345 if (uart->timeout)
346 mod_timer(&uart->timer, jiffies + uart->timeout);
347 else
348 del_timer(&uart->timer);
Kevin Hilman4af40162009-02-04 10:51:40 -0800349}
350
351static void omap_uart_allow_sleep(struct omap_uart_state *uart)
352{
Kevin Hilman6f251e92010-09-27 20:19:38 +0530353 if (device_may_wakeup(&uart->pdev->dev))
Kevin Hilmanfd455ea2009-04-27 12:27:36 -0700354 omap_uart_enable_wakeup(uart);
355 else
356 omap_uart_disable_wakeup(uart);
357
Kevin Hilman4af40162009-02-04 10:51:40 -0800358 if (!uart->clocked)
359 return;
360
361 omap_uart_smart_idle_enable(uart, 1);
362 uart->can_sleep = 1;
363 del_timer(&uart->timer);
364}
365
366static void omap_uart_idle_timer(unsigned long data)
367{
368 struct omap_uart_state *uart = (struct omap_uart_state *)data;
369
370 omap_uart_allow_sleep(uart);
371}
372
373void omap_uart_prepare_idle(int num)
374{
375 struct omap_uart_state *uart;
376
377 list_for_each_entry(uart, &uart_list, node) {
378 if (num == uart->num && uart->can_sleep) {
379 omap_uart_disable_clocks(uart);
380 return;
Jouni Hogander6e811762008-10-06 15:49:15 +0300381 }
382 }
383}
384
Kevin Hilman4af40162009-02-04 10:51:40 -0800385void omap_uart_resume_idle(int num)
386{
387 struct omap_uart_state *uart;
388
389 list_for_each_entry(uart, &uart_list, node) {
390 if (num == uart->num) {
391 omap_uart_enable_clocks(uart);
392
393 /* Check for IO pad wakeup */
394 if (cpu_is_omap34xx() && uart->padconf) {
395 u16 p = omap_ctrl_readw(uart->padconf);
396
397 if (p & OMAP3_PADCONF_WAKEUPEVENT0)
398 omap_uart_block_sleep(uart);
399 }
400
401 /* Check for normal UART wakeup */
402 if (__raw_readl(uart->wk_st) & uart->wk_mask)
403 omap_uart_block_sleep(uart);
Kevin Hilman4af40162009-02-04 10:51:40 -0800404 return;
405 }
406 }
407}
408
409void omap_uart_prepare_suspend(void)
410{
411 struct omap_uart_state *uart;
412
413 list_for_each_entry(uart, &uart_list, node) {
414 omap_uart_allow_sleep(uart);
415 }
416}
417
418int omap_uart_can_sleep(void)
419{
420 struct omap_uart_state *uart;
421 int can_sleep = 1;
422
423 list_for_each_entry(uart, &uart_list, node) {
424 if (!uart->clocked)
425 continue;
426
427 if (!uart->can_sleep) {
428 can_sleep = 0;
429 continue;
430 }
431
432 /* This UART can now safely sleep. */
433 omap_uart_allow_sleep(uart);
434 }
435
436 return can_sleep;
437}
438
439/**
440 * omap_uart_interrupt()
441 *
442 * This handler is used only to detect that *any* UART interrupt has
443 * occurred. It does _nothing_ to handle the interrupt. Rather,
444 * any UART interrupt will trigger the inactivity timer so the
445 * UART will not idle or sleep for its timeout period.
446 *
447 **/
Kevin Hilman6f251e92010-09-27 20:19:38 +0530448/* static int first_interrupt; */
Kevin Hilman4af40162009-02-04 10:51:40 -0800449static irqreturn_t omap_uart_interrupt(int irq, void *dev_id)
450{
451 struct omap_uart_state *uart = dev_id;
452
453 omap_uart_block_sleep(uart);
454
455 return IRQ_NONE;
456}
457
458static void omap_uart_idle_init(struct omap_uart_state *uart)
459{
Kevin Hilman4af40162009-02-04 10:51:40 -0800460 int ret;
461
462 uart->can_sleep = 0;
Kevin Hilmanfd455ea2009-04-27 12:27:36 -0700463 uart->timeout = DEFAULT_TIMEOUT;
Kevin Hilman4af40162009-02-04 10:51:40 -0800464 setup_timer(&uart->timer, omap_uart_idle_timer,
465 (unsigned long) uart);
Tony Lindgren301fe8e2010-02-01 12:34:31 -0800466 if (uart->timeout)
467 mod_timer(&uart->timer, jiffies + uart->timeout);
Kevin Hilman4af40162009-02-04 10:51:40 -0800468 omap_uart_smart_idle_enable(uart, 0);
469
470 if (cpu_is_omap34xx()) {
471 u32 mod = (uart->num == 2) ? OMAP3430_PER_MOD : CORE_MOD;
472 u32 wk_mask = 0;
473 u32 padconf = 0;
474
475 uart->wk_en = OMAP34XX_PRM_REGADDR(mod, PM_WKEN1);
476 uart->wk_st = OMAP34XX_PRM_REGADDR(mod, PM_WKST1);
477 switch (uart->num) {
478 case 0:
479 wk_mask = OMAP3430_ST_UART1_MASK;
480 padconf = 0x182;
481 break;
482 case 1:
483 wk_mask = OMAP3430_ST_UART2_MASK;
484 padconf = 0x17a;
485 break;
486 case 2:
487 wk_mask = OMAP3430_ST_UART3_MASK;
488 padconf = 0x19e;
489 break;
490 }
491 uart->wk_mask = wk_mask;
492 uart->padconf = padconf;
493 } else if (cpu_is_omap24xx()) {
494 u32 wk_mask = 0;
495
496 if (cpu_is_omap2430()) {
497 uart->wk_en = OMAP2430_PRM_REGADDR(CORE_MOD, PM_WKEN1);
498 uart->wk_st = OMAP2430_PRM_REGADDR(CORE_MOD, PM_WKST1);
499 } else if (cpu_is_omap2420()) {
500 uart->wk_en = OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKEN1);
501 uart->wk_st = OMAP2420_PRM_REGADDR(CORE_MOD, PM_WKST1);
502 }
503 switch (uart->num) {
504 case 0:
505 wk_mask = OMAP24XX_ST_UART1_MASK;
506 break;
507 case 1:
508 wk_mask = OMAP24XX_ST_UART2_MASK;
509 break;
510 case 2:
511 wk_mask = OMAP24XX_ST_UART3_MASK;
512 break;
513 }
514 uart->wk_mask = wk_mask;
515 } else {
Nishanth Menonc54bae12010-08-02 13:18:11 +0300516 uart->wk_en = NULL;
517 uart->wk_st = NULL;
Kevin Hilman4af40162009-02-04 10:51:40 -0800518 uart->wk_mask = 0;
519 uart->padconf = 0;
520 }
521
Kevin Hilman6f251e92010-09-27 20:19:38 +0530522 uart->irqflags |= IRQF_SHARED;
523 ret = request_threaded_irq(uart->irq, NULL, omap_uart_interrupt,
524 IRQF_SHARED, "serial idle", (void *)uart);
Kevin Hilman4af40162009-02-04 10:51:40 -0800525 WARN_ON(ret);
526}
527
Tero Kristo24662112009-03-05 16:32:23 +0200528void omap_uart_enable_irqs(int enable)
Jouni Hoganderba87a9b2008-12-09 13:36:50 +0200529{
Tero Kristo24662112009-03-05 16:32:23 +0200530 int ret;
531 struct omap_uart_state *uart;
532
533 list_for_each_entry(uart, &uart_list, node) {
Kevin Hilman3244fcd2010-09-27 20:19:53 +0530534 if (enable) {
535 pm_runtime_put_sync(&uart->pdev->dev);
Kevin Hilman6f251e92010-09-27 20:19:38 +0530536 ret = request_threaded_irq(uart->irq, NULL,
537 omap_uart_interrupt,
538 IRQF_SHARED,
539 "serial idle",
540 (void *)uart);
Kevin Hilman3244fcd2010-09-27 20:19:53 +0530541 } else {
542 pm_runtime_get_noresume(&uart->pdev->dev);
Kevin Hilman6f251e92010-09-27 20:19:38 +0530543 free_irq(uart->irq, (void *)uart);
Kevin Hilman3244fcd2010-09-27 20:19:53 +0530544 }
Tero Kristo24662112009-03-05 16:32:23 +0200545 }
Jouni Hoganderba87a9b2008-12-09 13:36:50 +0200546}
547
Kevin Hilmanfd455ea2009-04-27 12:27:36 -0700548static ssize_t sleep_timeout_show(struct device *dev,
549 struct device_attribute *attr,
Jouni Hoganderba87a9b2008-12-09 13:36:50 +0200550 char *buf)
551{
Kevin Hilman6f251e92010-09-27 20:19:38 +0530552 struct platform_device *pdev = to_platform_device(dev);
553 struct omap_device *odev = to_omap_device(pdev);
554 struct omap_uart_state *uart = odev->hwmods[0]->dev_attr;
Kevin Hilmanfd455ea2009-04-27 12:27:36 -0700555
556 return sprintf(buf, "%u\n", uart->timeout / HZ);
Jouni Hoganderba87a9b2008-12-09 13:36:50 +0200557}
558
Kevin Hilmanfd455ea2009-04-27 12:27:36 -0700559static ssize_t sleep_timeout_store(struct device *dev,
560 struct device_attribute *attr,
Jouni Hoganderba87a9b2008-12-09 13:36:50 +0200561 const char *buf, size_t n)
562{
Kevin Hilman6f251e92010-09-27 20:19:38 +0530563 struct platform_device *pdev = to_platform_device(dev);
564 struct omap_device *odev = to_omap_device(pdev);
565 struct omap_uart_state *uart = odev->hwmods[0]->dev_attr;
Jouni Hoganderba87a9b2008-12-09 13:36:50 +0200566 unsigned int value;
567
568 if (sscanf(buf, "%u", &value) != 1) {
Sergio Aguirre10c805e2010-03-09 13:22:14 -0600569 dev_err(dev, "sleep_timeout_store: Invalid value\n");
Jouni Hoganderba87a9b2008-12-09 13:36:50 +0200570 return -EINVAL;
571 }
Kevin Hilmanfd455ea2009-04-27 12:27:36 -0700572
573 uart->timeout = value * HZ;
574 if (uart->timeout)
575 mod_timer(&uart->timer, jiffies + uart->timeout);
576 else
577 /* A zero value means disable timeout feature */
578 omap_uart_block_sleep(uart);
579
Jouni Hoganderba87a9b2008-12-09 13:36:50 +0200580 return n;
581}
582
Nishanth Menonbfe69772010-08-02 13:18:12 +0300583static DEVICE_ATTR(sleep_timeout, 0644, sleep_timeout_show,
584 sleep_timeout_store);
Kevin Hilmanfd455ea2009-04-27 12:27:36 -0700585#define DEV_CREATE_FILE(dev, attr) WARN_ON(device_create_file(dev, attr))
Kevin Hilman4af40162009-02-04 10:51:40 -0800586#else
587static inline void omap_uart_idle_init(struct omap_uart_state *uart) {}
Kevin Hilman6f251e92010-09-27 20:19:38 +0530588static void omap_uart_block_sleep(struct omap_uart_state *uart) {}
Kevin Hilmanfd455ea2009-04-27 12:27:36 -0700589#define DEV_CREATE_FILE(dev, attr)
Kevin Hilman4af40162009-02-04 10:51:40 -0800590#endif /* CONFIG_PM */
591
Kevin Hilman6f251e92010-09-27 20:19:38 +0530592#ifndef CONFIG_SERIAL_OMAP
vikram panditace13d472009-12-11 16:16:37 -0800593/*
594 * Override the default 8250 read handler: mem_serial_in()
595 * Empty RX fifo read causes an abort on omap3630 and omap4
596 * This function makes sure that an empty rx fifo is not read on these silicons
597 * (OMAP1/2/3430 are not affected)
598 */
599static unsigned int serial_in_override(struct uart_port *up, int offset)
600{
601 if (UART_RX == offset) {
602 unsigned int lsr;
Alexander Shishkin92303722010-01-08 10:29:06 -0800603 lsr = __serial_read_reg(up, UART_LSR);
vikram panditace13d472009-12-11 16:16:37 -0800604 if (!(lsr & UART_LSR_DR))
605 return -EPERM;
606 }
Alexander Shishkin92303722010-01-08 10:29:06 -0800607
608 return __serial_read_reg(up, offset);
vikram panditace13d472009-12-11 16:16:37 -0800609}
610
Santosh Shilimkare03d37d2010-02-18 08:59:06 +0000611static void serial_out_override(struct uart_port *up, int offset, int value)
612{
613 unsigned int status, tmout = 10000;
614
615 status = __serial_read_reg(up, UART_LSR);
616 while (!(status & UART_LSR_THRE)) {
617 /* Wait up to 10ms for the character(s) to be sent. */
618 if (--tmout == 0)
619 break;
620 udelay(1);
621 status = __serial_read_reg(up, UART_LSR);
622 }
623 __serial_write_reg(up, offset, value);
624}
Kevin Hilman6f251e92010-09-27 20:19:38 +0530625#endif
626
Paul Walmsleyb3c6df32009-09-03 20:14:02 +0300627void __init omap_serial_early_init(void)
Tony Lindgren1dbae812005-11-10 14:26:51 +0000628{
Kevin Hilman6f251e92010-09-27 20:19:38 +0530629 int i = 0;
Tony Lindgren1dbae812005-11-10 14:26:51 +0000630
Kevin Hilman6f251e92010-09-27 20:19:38 +0530631 do {
632 char oh_name[MAX_UART_HWMOD_NAME_LEN];
633 struct omap_hwmod *oh;
634 struct omap_uart_state *uart;
Thomas Weber21b90342010-02-25 09:40:19 +0000635
Kevin Hilman6f251e92010-09-27 20:19:38 +0530636 snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN,
637 "uart%d", i + 1);
638 oh = omap_hwmod_lookup(oh_name);
639 if (!oh)
640 break;
Tony Lindgren1dbae812005-11-10 14:26:51 +0000641
Kevin Hilman6f251e92010-09-27 20:19:38 +0530642 uart = kzalloc(sizeof(struct omap_uart_state), GFP_KERNEL);
643 if (WARN_ON(!uart))
644 return;
Tony Lindgren1dbae812005-11-10 14:26:51 +0000645
Kevin Hilman6f251e92010-09-27 20:19:38 +0530646 uart->oh = oh;
647 uart->num = i++;
648 list_add_tail(&uart->node, &uart_list);
649 num_uarts++;
650
Tony Lindgren84f90c92009-10-16 09:53:00 -0700651 /*
Kevin Hilman6f251e92010-09-27 20:19:38 +0530652 * NOTE: omap_hwmod_init() has not yet been called,
653 * so no hwmod functions will work yet.
Tony Lindgren84f90c92009-10-16 09:53:00 -0700654 */
Tony Lindgren84f90c92009-10-16 09:53:00 -0700655
Kevin Hilman6f251e92010-09-27 20:19:38 +0530656 /*
657 * During UART early init, device need to be probed
658 * to determine SoC specific init before omap_device
659 * is ready. Therefore, don't allow idle here
660 */
661 uart->oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET;
662 } while (1);
Paul Walmsleyb3c6df32009-09-03 20:14:02 +0300663}
664
Mika Westerbergf62349e2009-12-11 16:16:35 -0800665/**
666 * omap_serial_init_port() - initialize single serial port
667 * @port: serial port number (0-3)
668 *
669 * This function initialies serial driver for given @port only.
670 * Platforms can call this function instead of omap_serial_init()
671 * if they don't plan to use all available UARTs as serial ports.
672 *
673 * Don't mix calls to omap_serial_init_port() and omap_serial_init(),
674 * use only one of the two.
675 */
676void __init omap_serial_init_port(int port)
677{
678 struct omap_uart_state *uart;
Kevin Hilman6f251e92010-09-27 20:19:38 +0530679 struct omap_hwmod *oh;
680 struct omap_device *od;
681 void *pdata = NULL;
682 u32 pdata_size = 0;
683 char *name;
684#ifndef CONFIG_SERIAL_OMAP
685 struct plat_serial8250_port ports[2] = {
686 {},
687 {.flags = 0},
688 };
689 struct plat_serial8250_port *p = &ports[0];
690#else
691 struct omap_uart_port_info omap_up;
692#endif
Mika Westerbergf62349e2009-12-11 16:16:35 -0800693
Kevin Hilman6f251e92010-09-27 20:19:38 +0530694 if (WARN_ON(port < 0))
Sergio Aguirree88d5562010-02-27 14:13:43 -0600695 return;
Kevin Hilman6f251e92010-09-27 20:19:38 +0530696 if (WARN_ON(port >= num_uarts))
Mika Westerbergf62349e2009-12-11 16:16:35 -0800697 return;
698
Kevin Hilman6f251e92010-09-27 20:19:38 +0530699 list_for_each_entry(uart, &uart_list, node)
700 if (port == uart->num)
701 break;
702
703 oh = uart->oh;
704 uart->dma_enabled = 0;
705#ifndef CONFIG_SERIAL_OMAP
706 name = "serial8250";
707
708 /*
709 * !! 8250 driver does not use standard IORESOURCE* It
710 * has it's own custom pdata that can be taken from
711 * the hwmod resource data. But, this needs to be
712 * done after the build.
713 *
714 * ?? does it have to be done before the register ??
715 * YES, because platform_device_data_add() copies
716 * pdata, it does not use a pointer.
717 */
718 p->flags = UPF_BOOT_AUTOCONF;
719 p->iotype = UPIO_MEM;
720 p->regshift = 2;
721 p->uartclk = OMAP24XX_BASE_BAUD * 16;
722 p->irq = oh->mpu_irqs[0].irq;
723 p->mapbase = oh->slaves[0]->addr->pa_start;
724 p->membase = omap_hwmod_get_mpu_rt_va(oh);
725 p->irqflags = IRQF_SHARED;
726 p->private_data = uart;
Mika Westerbergf62349e2009-12-11 16:16:35 -0800727
vikram pandita30e53bc2010-02-15 10:03:33 -0800728 /*
729 * omap44xx: Never read empty UART fifo
730 * omap3xxx: Never read empty UART fifo on UARTs
731 * with IP rev >=0x52
732 */
Kevin Hilman6f251e92010-09-27 20:19:38 +0530733 uart->regshift = p->regshift;
734 uart->membase = p->membase;
Nishanth Menon5a927b32010-08-02 13:18:12 +0300735 if (cpu_is_omap44xx())
736 uart->errata |= UART_ERRATA_FIFO_FULL_ABORT;
Kevin Hilman6f251e92010-09-27 20:19:38 +0530737 else if ((serial_read_reg(uart, UART_OMAP_MVER) & 0xFF)
Nishanth Menon5a927b32010-08-02 13:18:12 +0300738 >= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV)
739 uart->errata |= UART_ERRATA_FIFO_FULL_ABORT;
740
741 if (uart->errata & UART_ERRATA_FIFO_FULL_ABORT) {
Kevin Hilman6f251e92010-09-27 20:19:38 +0530742 p->serial_in = serial_in_override;
743 p->serial_out = serial_out_override;
744 }
745
746 pdata = &ports[0];
747 pdata_size = 2 * sizeof(struct plat_serial8250_port);
748#else
749
750 name = DRIVER_NAME;
751
752 omap_up.dma_enabled = uart->dma_enabled;
753 omap_up.uartclk = OMAP24XX_BASE_BAUD * 16;
754 omap_up.mapbase = oh->slaves[0]->addr->pa_start;
755 omap_up.membase = omap_hwmod_get_mpu_rt_va(oh);
756 omap_up.irqflags = IRQF_SHARED;
757 omap_up.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
758
759 pdata = &omap_up;
760 pdata_size = sizeof(struct omap_uart_port_info);
761#endif
762
763 if (WARN_ON(!oh))
764 return;
765
766 od = omap_device_build(name, uart->num, oh, pdata, pdata_size,
767 omap_uart_latency,
768 ARRAY_SIZE(omap_uart_latency), false);
769 WARN(IS_ERR(od), "Could not build omap_device for %s: %s.\n",
770 name, oh->name);
771
772 uart->irq = oh->mpu_irqs[0].irq;
773 uart->regshift = 2;
774 uart->mapbase = oh->slaves[0]->addr->pa_start;
775 uart->membase = omap_hwmod_get_mpu_rt_va(oh);
776 uart->pdev = &od->pdev;
777
778 oh->dev_attr = uart;
779
780 /*
781 * Because of early UART probing, UART did not get idled
782 * on init. Now that omap_device is ready, ensure full idle
783 * before doing omap_device_enable().
784 */
785 omap_hwmod_idle(uart->oh);
786
787 omap_device_enable(uart->pdev);
788 omap_uart_idle_init(uart);
789 omap_uart_reset(uart);
790 omap_hwmod_enable_wakeup(uart->oh);
791 omap_device_idle(uart->pdev);
792
793 /*
794 * Need to block sleep long enough for interrupt driven
795 * driver to start. Console driver is in polling mode
796 * so device needs to be kept enabled while polling driver
797 * is in use.
798 */
799 if (uart->timeout)
800 uart->timeout = (30 * HZ);
801 omap_uart_block_sleep(uart);
802 uart->timeout = DEFAULT_TIMEOUT;
803
804 if ((cpu_is_omap34xx() && uart->padconf) ||
805 (uart->wk_en && uart->wk_mask)) {
806 device_init_wakeup(&od->pdev.dev, true);
807 DEV_CREATE_FILE(&od->pdev.dev, &dev_attr_sleep_timeout);
Santosh Shilimkare03d37d2010-02-18 08:59:06 +0000808 }
Deepak K00034502010-08-02 13:18:12 +0300809
810 /* Enable the MDR1 errata for OMAP3 */
811 if (cpu_is_omap34xx())
812 uart->errata |= UART_ERRATA_i202_MDR1_ACCESS;
Mika Westerbergf62349e2009-12-11 16:16:35 -0800813}
814
815/**
816 * omap_serial_init() - intialize all supported serial ports
817 *
818 * Initializes all available UARTs as serial ports. Platforms
819 * can call this function when they want to have default behaviour
820 * for serial ports (e.g initialize them all as serial ports).
821 */
Paul Walmsleyb3c6df32009-09-03 20:14:02 +0300822void __init omap_serial_init(void)
823{
Kevin Hilman6f251e92010-09-27 20:19:38 +0530824 struct omap_uart_state *uart;
Paul Walmsleyb3c6df32009-09-03 20:14:02 +0300825
Kevin Hilman6f251e92010-09-27 20:19:38 +0530826 list_for_each_entry(uart, &uart_list, node)
827 omap_serial_init_port(uart->num);
Tony Lindgren1dbae812005-11-10 14:26:51 +0000828}