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.c69
1 files changed, 40 insertions, 29 deletions
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index d17960a1be25..c64578853a8d 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -40,11 +40,12 @@
40#include <plat/omap_hwmod.h> 40#include <plat/omap_hwmod.h>
41#include <plat/omap_device.h> 41#include <plat/omap_device.h>
42 42
43#include "prm.h" 43#include "prm2xxx_3xxx.h"
44#include "pm.h" 44#include "pm.h"
45#include "cm.h" 45#include "cm2xxx_3xxx.h"
46#include "prm-regbits-34xx.h" 46#include "prm-regbits-34xx.h"
47#include "control.h" 47#include "control.h"
48#include "mux.h"
48 49
49#define UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV 0x52 50#define UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV 0x52
50#define UART_OMAP_WER 0x17 /* Wake-up enable register */ 51#define UART_OMAP_WER 0x17 /* Wake-up enable register */
@@ -106,21 +107,16 @@ struct omap_uart_state {
106static LIST_HEAD(uart_list); 107static LIST_HEAD(uart_list);
107static u8 num_uarts; 108static u8 num_uarts;
108 109
109/*
110 * Since these idle/enable hooks are used in the idle path itself
111 * which has interrupts disabled, use the non-locking versions of
112 * the hwmod enable/disable functions.
113 */
114static int uart_idle_hwmod(struct omap_device *od) 110static int uart_idle_hwmod(struct omap_device *od)
115{ 111{
116 _omap_hwmod_idle(od->hwmods[0]); 112 omap_hwmod_idle(od->hwmods[0]);
117 113
118 return 0; 114 return 0;
119} 115}
120 116
121static int uart_enable_hwmod(struct omap_device *od) 117static int uart_enable_hwmod(struct omap_device *od)
122{ 118{
123 _omap_hwmod_enable(od->hwmods[0]); 119 omap_hwmod_enable(od->hwmods[0]);
124 120
125 return 0; 121 return 0;
126} 122}
@@ -169,9 +165,9 @@ static inline void serial_write_reg(struct omap_uart_state *uart, int offset,
169 165
170static inline void __init omap_uart_reset(struct omap_uart_state *uart) 166static inline void __init omap_uart_reset(struct omap_uart_state *uart)
171{ 167{
172 serial_write_reg(uart, UART_OMAP_MDR1, 0x07); 168 serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
173 serial_write_reg(uart, UART_OMAP_SCR, 0x08); 169 serial_write_reg(uart, UART_OMAP_SCR, 0x08);
174 serial_write_reg(uart, UART_OMAP_MDR1, 0x00); 170 serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE);
175} 171}
176 172
177#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) 173#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3)
@@ -219,7 +215,7 @@ static void omap_uart_save_context(struct omap_uart_state *uart)
219 return; 215 return;
220 216
221 lcr = serial_read_reg(uart, UART_LCR); 217 lcr = serial_read_reg(uart, UART_LCR);
222 serial_write_reg(uart, UART_LCR, 0xBF); 218 serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
223 uart->dll = serial_read_reg(uart, UART_DLL); 219 uart->dll = serial_read_reg(uart, UART_DLL);
224 uart->dlh = serial_read_reg(uart, UART_DLM); 220 uart->dlh = serial_read_reg(uart, UART_DLM);
225 serial_write_reg(uart, UART_LCR, lcr); 221 serial_write_reg(uart, UART_LCR, lcr);
@@ -227,7 +223,7 @@ static void omap_uart_save_context(struct omap_uart_state *uart)
227 uart->sysc = serial_read_reg(uart, UART_OMAP_SYSC); 223 uart->sysc = serial_read_reg(uart, UART_OMAP_SYSC);
228 uart->scr = serial_read_reg(uart, UART_OMAP_SCR); 224 uart->scr = serial_read_reg(uart, UART_OMAP_SCR);
229 uart->wer = serial_read_reg(uart, UART_OMAP_WER); 225 uart->wer = serial_read_reg(uart, UART_OMAP_WER);
230 serial_write_reg(uart, UART_LCR, 0x80); 226 serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_A);
231 uart->mcr = serial_read_reg(uart, UART_MCR); 227 uart->mcr = serial_read_reg(uart, UART_MCR);
232 serial_write_reg(uart, UART_LCR, lcr); 228 serial_write_reg(uart, UART_LCR, lcr);
233 229
@@ -247,32 +243,35 @@ static void omap_uart_restore_context(struct omap_uart_state *uart)
247 uart->context_valid = 0; 243 uart->context_valid = 0;
248 244
249 if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS) 245 if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
250 omap_uart_mdr1_errataset(uart, 0x07, 0xA0); 246 omap_uart_mdr1_errataset(uart, UART_OMAP_MDR1_DISABLE, 0xA0);
251 else 247 else
252 serial_write_reg(uart, UART_OMAP_MDR1, 0x7); 248 serial_write_reg(uart, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
253 serial_write_reg(uart, UART_LCR, 0xBF); /* Config B mode */ 249
250 serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
254 efr = serial_read_reg(uart, UART_EFR); 251 efr = serial_read_reg(uart, UART_EFR);
255 serial_write_reg(uart, UART_EFR, UART_EFR_ECB); 252 serial_write_reg(uart, UART_EFR, UART_EFR_ECB);
256 serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */ 253 serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */
257 serial_write_reg(uart, UART_IER, 0x0); 254 serial_write_reg(uart, UART_IER, 0x0);
258 serial_write_reg(uart, UART_LCR, 0xBF); /* Config B mode */ 255 serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
259 serial_write_reg(uart, UART_DLL, uart->dll); 256 serial_write_reg(uart, UART_DLL, uart->dll);
260 serial_write_reg(uart, UART_DLM, uart->dlh); 257 serial_write_reg(uart, UART_DLM, uart->dlh);
261 serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */ 258 serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */
262 serial_write_reg(uart, UART_IER, uart->ier); 259 serial_write_reg(uart, UART_IER, uart->ier);
263 serial_write_reg(uart, UART_LCR, 0x80); 260 serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_A);
264 serial_write_reg(uart, UART_MCR, uart->mcr); 261 serial_write_reg(uart, UART_MCR, uart->mcr);
265 serial_write_reg(uart, UART_LCR, 0xBF); /* Config B mode */ 262 serial_write_reg(uart, UART_LCR, UART_LCR_CONF_MODE_B);
266 serial_write_reg(uart, UART_EFR, efr); 263 serial_write_reg(uart, UART_EFR, efr);
267 serial_write_reg(uart, UART_LCR, UART_LCR_WLEN8); 264 serial_write_reg(uart, UART_LCR, UART_LCR_WLEN8);
268 serial_write_reg(uart, UART_OMAP_SCR, uart->scr); 265 serial_write_reg(uart, UART_OMAP_SCR, uart->scr);
269 serial_write_reg(uart, UART_OMAP_WER, uart->wer); 266 serial_write_reg(uart, UART_OMAP_WER, uart->wer);
270 serial_write_reg(uart, UART_OMAP_SYSC, uart->sysc); 267 serial_write_reg(uart, UART_OMAP_SYSC, uart->sysc);
268
271 if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS) 269 if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS)
272 omap_uart_mdr1_errataset(uart, 0x00, 0xA1); 270 omap_uart_mdr1_errataset(uart, UART_OMAP_MDR1_16X_MODE, 0xA1);
273 else 271 else
274 /* UART 16x mode */ 272 /* UART 16x mode */
275 serial_write_reg(uart, UART_OMAP_MDR1, 0x00); 273 serial_write_reg(uart, UART_OMAP_MDR1,
274 UART_OMAP_MDR1_16X_MODE);
276} 275}
277#else 276#else
278static inline void omap_uart_save_context(struct omap_uart_state *uart) {} 277static inline void omap_uart_save_context(struct omap_uart_state *uart) {}
@@ -492,6 +491,7 @@ static void omap_uart_idle_init(struct omap_uart_state *uart)
492 u32 wk_mask = 0; 491 u32 wk_mask = 0;
493 u32 padconf = 0; 492 u32 padconf = 0;
494 493
494 /* XXX These PRM accesses do not belong here */
495 uart->wk_en = OMAP34XX_PRM_REGADDR(mod, PM_WKEN1); 495 uart->wk_en = OMAP34XX_PRM_REGADDR(mod, PM_WKEN1);
496 uart->wk_st = OMAP34XX_PRM_REGADDR(mod, PM_WKST1); 496 uart->wk_st = OMAP34XX_PRM_REGADDR(mod, PM_WKST1);
497 switch (uart->num) { 497 switch (uart->num) {
@@ -695,16 +695,16 @@ void __init omap_serial_early_init(void)
695 695
696/** 696/**
697 * omap_serial_init_port() - initialize single serial port 697 * omap_serial_init_port() - initialize single serial port
698 * @port: serial port number (0-3) 698 * @bdata: port specific board data pointer
699 * 699 *
700 * This function initialies serial driver for given @port only. 700 * This function initialies serial driver for given port only.
701 * Platforms can call this function instead of omap_serial_init() 701 * Platforms can call this function instead of omap_serial_init()
702 * if they don't plan to use all available UARTs as serial ports. 702 * if they don't plan to use all available UARTs as serial ports.
703 * 703 *
704 * Don't mix calls to omap_serial_init_port() and omap_serial_init(), 704 * Don't mix calls to omap_serial_init_port() and omap_serial_init(),
705 * use only one of the two. 705 * use only one of the two.
706 */ 706 */
707void __init omap_serial_init_port(int port) 707void __init omap_serial_init_port(struct omap_board_data *bdata)
708{ 708{
709 struct omap_uart_state *uart; 709 struct omap_uart_state *uart;
710 struct omap_hwmod *oh; 710 struct omap_hwmod *oh;
@@ -722,13 +722,15 @@ void __init omap_serial_init_port(int port)
722 struct omap_uart_port_info omap_up; 722 struct omap_uart_port_info omap_up;
723#endif 723#endif
724 724
725 if (WARN_ON(port < 0)) 725 if (WARN_ON(!bdata))
726 return;
727 if (WARN_ON(bdata->id < 0))
726 return; 728 return;
727 if (WARN_ON(port >= num_uarts)) 729 if (WARN_ON(bdata->id >= num_uarts))
728 return; 730 return;
729 731
730 list_for_each_entry(uart, &uart_list, node) 732 list_for_each_entry(uart, &uart_list, node)
731 if (port == uart->num) 733 if (bdata->id == uart->num)
732 break; 734 break;
733 735
734 oh = uart->oh; 736 oh = uart->oh;
@@ -800,6 +802,8 @@ void __init omap_serial_init_port(int port)
800 WARN(IS_ERR(od), "Could not build omap_device for %s: %s.\n", 802 WARN(IS_ERR(od), "Could not build omap_device for %s: %s.\n",
801 name, oh->name); 803 name, oh->name);
802 804
805 oh->mux = omap_hwmod_mux_init(bdata->pads, bdata->pads_cnt);
806
803 uart->irq = oh->mpu_irqs[0].irq; 807 uart->irq = oh->mpu_irqs[0].irq;
804 uart->regshift = 2; 808 uart->regshift = 2;
805 uart->mapbase = oh->slaves[0]->addr->pa_start; 809 uart->mapbase = oh->slaves[0]->addr->pa_start;
@@ -857,7 +861,14 @@ void __init omap_serial_init_port(int port)
857void __init omap_serial_init(void) 861void __init omap_serial_init(void)
858{ 862{
859 struct omap_uart_state *uart; 863 struct omap_uart_state *uart;
864 struct omap_board_data bdata;
860 865
861 list_for_each_entry(uart, &uart_list, node) 866 list_for_each_entry(uart, &uart_list, node) {
862 omap_serial_init_port(uart->num); 867 bdata.id = uart->num;
868 bdata.flags = 0;
869 bdata.pads = NULL;
870 bdata.pads_cnt = 0;
871 omap_serial_init_port(&bdata);
872
873 }
863} 874}