All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kevin Hilman <khilman@deeprootsystems.com>
To: linux-omap@vger.kernel.org
Subject: [PATCH 3/3] OMAP3: PM: UART save/restore support for OFF-mode
Date: Wed, 26 Nov 2008 16:30:00 -0800	[thread overview]
Message-ID: <1227745800-5894-4-git-send-email-khilman@deeprootsystems.com> (raw)
In-Reply-To: <1227745800-5894-3-git-send-email-khilman@deeprootsystems.com>

If OFF-mode is enabled, each enabled UART will save its
context whenever clocks are disabled and restore it when
clocks are re-enabled.

Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
---
 arch/arm/mach-omap2/serial.c |   77 ++++++++++++++++++++++++++++++++++++++++++
 include/linux/serial_reg.h   |    1 +
 2 files changed, 78 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
index f93dc52..dd32047 100644
--- a/arch/arm/mach-omap2/serial.c
+++ b/arch/arm/mach-omap2/serial.c
@@ -50,6 +50,18 @@ struct omap_uart_state {
 
 	struct plat_serial8250_port *p;
 	struct list_head node;
+
+#ifdef CONFIG_ARCH_OMAP3
+	int context_valid;
+
+	/* Registers to be saved/restored for OFF-mode */
+	u16 dll;
+	u16 dlh;
+	u16 ier;
+	u16 sysc;
+	u16 scr;
+	u16 wer;
+#endif
 };
 
 static struct omap_uart_state omap_uart[OMAP_MAX_NR_PORTS];
@@ -114,6 +126,69 @@ static inline void __init omap_uart_reset(struct omap_uart_state *uart)
 	serial_write_reg(p, UART_OMAP_SYSC, (0x02 << 3) | (1 << 2) | (1 << 0));
 }
 
+#ifdef CONFIG_ARCH_OMAP3
+/* to be replaced by global with forthcoming OFF-mode patches */
+static int enable_off_mode;
+
+static void omap_uart_save_context(struct omap_uart_state *uart)
+{
+	u16 lcr = 0;
+	struct plat_serial8250_port *p = uart->p;
+
+	if (!enable_off_mode)
+		return;
+
+	lcr = serial_read_reg(p, UART_LCR);
+	serial_write_reg(p, UART_LCR, 0xBF);
+	uart->dll = serial_read_reg(p, UART_DLL);
+	uart->dlh = serial_read_reg(p, UART_DLM);
+	serial_write_reg(p, UART_LCR, lcr);
+	uart->ier = serial_read_reg(p, UART_IER);
+	uart->sysc = serial_read_reg(p, UART_OMAP_SYSC);
+	uart->scr = serial_read_reg(p, UART_OMAP_SCR);
+	uart->wer = serial_read_reg(p, UART_OMAP_WER);
+
+	uart->context_valid = 1;
+}
+
+static void omap_uart_restore_context(struct omap_uart_state *uart)
+{
+	u16 efr = 0;
+	struct plat_serial8250_port *p = uart->p;
+
+	if (!enable_off_mode)
+		return;
+
+	if (!uart->context_valid)
+		return;
+
+	uart->context_valid = 0;
+
+	serial_write_reg(p, UART_OMAP_MDR1, 0x7);
+	serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */
+	efr = serial_read_reg(p, UART_EFR);
+	serial_write_reg(p, UART_EFR, UART_EFR_ECB);
+	serial_write_reg(p, UART_LCR, 0x0); /* Operational mode */
+	serial_write_reg(p, UART_IER, 0x0);
+	serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */
+	serial_write_reg(p, UART_DLL, uart->dll);
+	serial_write_reg(p, UART_DLM, uart->dlh);
+	serial_write_reg(p, UART_LCR, 0x0); /* Operational mode */
+	serial_write_reg(p, UART_IER, uart->ier);
+	serial_write_reg(p, UART_FCR, 0xA1);
+	serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */
+	serial_write_reg(p, UART_EFR, efr);
+	serial_write_reg(p, UART_LCR, UART_LCR_WLEN8);
+	serial_write_reg(p, UART_OMAP_SCR, uart->scr);
+	serial_write_reg(p, UART_OMAP_WER, uart->wer);
+	serial_write_reg(p, UART_OMAP_SYSC, uart->sysc);
+	serial_write_reg(p, UART_OMAP_MDR1, 0x00); /* UART 16x mode */
+}
+#else
+static inline void omap_uart_save_context(struct omap_uart_state *uart) {}
+static inline void omap_uart_restore_context(struct omap_uart_state *uart) {}
+#endif /* CONFIG_ARCH_OMAP3 */
+
 static void omap_uart_smart_idle_enable(struct omap_uart_state *uart,
 					  int enable)
 {
@@ -137,6 +212,7 @@ static inline void omap_uart_enable_clocks(struct omap_uart_state *uart)
 	clk_enable(uart->ick);
 	clk_enable(uart->fck);
 	uart->clocked = 1;
+	omap_uart_restore_context(uart);
 }
 
 static inline void omap_uart_disable_clocks(struct omap_uart_state *uart)
@@ -144,6 +220,7 @@ static inline void omap_uart_disable_clocks(struct omap_uart_state *uart)
 	if (!uart->clocked)
 		return;
 
+	omap_uart_save_context(uart);
 	uart->clocked = 0;
 	clk_disable(uart->ick);
 	clk_disable(uart->fck);
diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h
index 96c0d93..850db2e 100644
--- a/include/linux/serial_reg.h
+++ b/include/linux/serial_reg.h
@@ -323,6 +323,7 @@
 #define UART_OMAP_MVER		0x14	/* Module version register */
 #define UART_OMAP_SYSC		0x15	/* System configuration register */
 #define UART_OMAP_SYSS		0x16	/* System status register */
+#define UART_OMAP_WER		0x17	/* Wake-up enable register */
 
 #endif /* _LINUX_SERIAL_REG_H */
 
-- 
1.6.0.3


  reply	other threads:[~2008-11-27  0:30 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-27  0:29 [PATCH 0/3] OMAP: PM: enable UART clock disabling when idle Kevin Hilman
2008-11-27  0:29 ` [PATCH 1/3] OMAP3: PM: Add wake-up bit defintiions for CONTROL_PADCONF_X Kevin Hilman
2008-11-27  0:29   ` [PATCH 2/3] OMAP3: PM: UART: disable clocks when idle Kevin Hilman
2008-11-27  0:30     ` Kevin Hilman [this message]
2008-11-29 12:52 ` [PATCH 0/3] OMAP: PM: enable UART clock disabling " Felipe Contreras
2008-11-29 13:55   ` Woodruff, Richard
2008-11-29 16:06     ` Igor Stoppa
2008-11-30  3:35       ` Woodruff, Richard
2008-12-01  6:07         ` Igor Stoppa

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1227745800-5894-4-git-send-email-khilman@deeprootsystems.com \
    --to=khilman@deeprootsystems.com \
    --cc=linux-omap@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.