All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC v2 00/18] ARM: OMAP2+: AM33XX: Add suspend-resume support
@ 2012-12-31 13:06 ` Vaibhav Bedia
  0 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:06 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, tony, khilman; +Cc: Vaibhav Bedia

Hi,

This is the second version of the patch series for adding suspend-resume
support for AM33XX. Based on the feedback received on the previous patch
series [1] almost all the patches have undergone a bit a rework.

The 1st two patches depend on the changes for mailbox code migration
from arch/arm/*-omap*/ to drivers/mailbox/ [2].

The patch series also depends on recent changes to the OMAP PM framework
by Paul Walmsley.

I found it easiest to apply the AM33XX suspend-resume patches on top of
Paul's TEST_pwrdm_post_fpwrst_devel_a_3.9 branch + the patches @ [2].

With these dependencies met, the PM code uses the firmware interface
and expects the userspace to load the WKUP_M3 binary before the
suspend-resume functionality is made available. The binary file (and
the source-code for WKUP_M3) can be obtained from the 'next' branch at
[3]. The WKUP_M3 binary can either be loaded post bootup via
the sysfs entry './sys/devices/ocp.2/wkup_m3.4/firmware' or
it can be included in the kernel image as part of the build process.

DDR3 specific changes have been skipped for now since mainline U-Boot
exhibited stability issues on all the DDR3 based AM335x boards that i could
lay my hands on.

I have done basic testing along with power measurments on the different
power rails on the AM335x EVM. PER domain transition on the BeagleBone fails
if the CPSW driver is included in the kernel and is yet to be root caused.
Along with this issue more extensive testing on other OMAP platforms is also
pending right now.

For more details on the AM335x suspend-resume support please refer to the
changelog in the different patches.

Regards,
Vaibhav

[1] http://marc.info/?l=linux-arm-kernel&m=135185970731607&w=4
[2] http://marc.info/?l=linux-omap&m=135583648827089&w=4
[3] http://arago-project.org/git/projects/?p=am33x-cm3.git;a=shortlog;h=refs/heads/next

Vaibhav Bedia (18):
  mailbox: OMAP2+: Add support for AM33XX
  mailbox: Add an API for flushing the FIFO
  memory: emif: Move EMIF related header file to include/linux/
  ARM: OMAP2+: AM33XX: CM: Get rid of unncessary header inclusions
  ARM: OMAP2+: AM33XX: CM/PRM: Use __ASSEMBLER__ macros in header files
  ARM: OMAP2+: AM33XX: hwmod: Register OCMC RAM hwmod
  ARM: OMAP2+: AM33XX: hwmod: Update TPTC0 hwmod with the right flags
  ARM: OMAP2+: AM33XX: hwmod: Fixup cpgmac0 hwmod entry
  ARM: OMAP2+: AM33XX: Update the hardreset API
  ARM: OMAP2+: AM33XX: hwmod: Update the WKUP-M3 hwmod with reset
    status bit
  ARM: DTS: AM33XX: Add nodes for OCMC RAM and WKUP-M3
  ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent
    device
  ARM: OMAP2+: AM33XX: timer: Interchance clkevt and clksrc timers
  ARM: OMAP2+: AM33XX: control: Add some control module registers and
    APIs
  ARM: OMAP2+: AM33XX: Add assembly code for PM operations
  ARM: OMAP2+: AM33XX: Basic suspend resume support
  ARM: OMAP2+: AM33XX: Select Mailbox when PM is enabled
  ARM: OMAP2+: AM33XX: Hookup AM33XX PM code into OMAP builds

 .../devicetree/bindings/arm/omap/timer.txt         |    2 +
 arch/arm/boot/dts/am33xx.dtsi                      |   12 +
 arch/arm/mach-omap2/Kconfig                        |    4 +-
 arch/arm/mach-omap2/Makefile                       |    2 +
 arch/arm/mach-omap2/board-generic.c                |    1 +
 arch/arm/mach-omap2/cm33xx.h                       |   10 +-
 arch/arm/mach-omap2/common.h                       |   10 +
 arch/arm/mach-omap2/control.c                      |   20 +
 arch/arm/mach-omap2/control.h                      |   41 ++
 arch/arm/mach-omap2/io.c                           |    7 +
 arch/arm/mach-omap2/omap_hwmod.c                   |    5 +-
 arch/arm/mach-omap2/omap_hwmod_33xx_data.c         |   50 +-
 arch/arm/mach-omap2/pm.h                           |    7 +
 arch/arm/mach-omap2/pm33xx.c                       |  469 ++++++++++++++++
 arch/arm/mach-omap2/pm33xx.h                       |   56 ++
 arch/arm/mach-omap2/prm33xx.c                      |   11 +-
 arch/arm/mach-omap2/prm33xx.h                      |    5 +-
 arch/arm/mach-omap2/sleep33xx.S                    |  584 +++++++++++++++++++
 arch/arm/mach-omap2/sram.c                         |   10 +-
 arch/arm/mach-omap2/sram.h                         |    2 +
 arch/arm/mach-omap2/timer.c                        |   39 ++-
 drivers/mailbox/mailbox-omap2.c                    |   54 ++-
 drivers/mailbox/mailbox.c                          |   36 ++
 drivers/mailbox/mailbox.h                          |    3 +
 drivers/memory/emif.c                              |    2 +-
 drivers/memory/emif.h                              |  589 --------------------
 include/linux/mailbox.h                            |    1 +
 include/linux/ti_emif.h                            |  589 ++++++++++++++++++++
 28 files changed, 1989 insertions(+), 632 deletions(-)
 create mode 100644 arch/arm/mach-omap2/pm33xx.c
 create mode 100644 arch/arm/mach-omap2/pm33xx.h
 create mode 100644 arch/arm/mach-omap2/sleep33xx.S
 delete mode 100644 drivers/memory/emif.h
 create mode 100644 include/linux/ti_emif.h


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 00/18] ARM: OMAP2+: AM33XX: Add suspend-resume support
@ 2012-12-31 13:06 ` Vaibhav Bedia
  0 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

This is the second version of the patch series for adding suspend-resume
support for AM33XX. Based on the feedback received on the previous patch
series [1] almost all the patches have undergone a bit a rework.

The 1st two patches depend on the changes for mailbox code migration
from arch/arm/*-omap*/ to drivers/mailbox/ [2].

The patch series also depends on recent changes to the OMAP PM framework
by Paul Walmsley.

I found it easiest to apply the AM33XX suspend-resume patches on top of
Paul's TEST_pwrdm_post_fpwrst_devel_a_3.9 branch + the patches @ [2].

With these dependencies met, the PM code uses the firmware interface
and expects the userspace to load the WKUP_M3 binary before the
suspend-resume functionality is made available. The binary file (and
the source-code for WKUP_M3) can be obtained from the 'next' branch at
[3]. The WKUP_M3 binary can either be loaded post bootup via
the sysfs entry './sys/devices/ocp.2/wkup_m3.4/firmware' or
it can be included in the kernel image as part of the build process.

DDR3 specific changes have been skipped for now since mainline U-Boot
exhibited stability issues on all the DDR3 based AM335x boards that i could
lay my hands on.

I have done basic testing along with power measurments on the different
power rails on the AM335x EVM. PER domain transition on the BeagleBone fails
if the CPSW driver is included in the kernel and is yet to be root caused.
Along with this issue more extensive testing on other OMAP platforms is also
pending right now.

For more details on the AM335x suspend-resume support please refer to the
changelog in the different patches.

Regards,
Vaibhav

[1] http://marc.info/?l=linux-arm-kernel&m=135185970731607&w=4
[2] http://marc.info/?l=linux-omap&m=135583648827089&w=4
[3] http://arago-project.org/git/projects/?p=am33x-cm3.git;a=shortlog;h=refs/heads/next

Vaibhav Bedia (18):
  mailbox: OMAP2+: Add support for AM33XX
  mailbox: Add an API for flushing the FIFO
  memory: emif: Move EMIF related header file to include/linux/
  ARM: OMAP2+: AM33XX: CM: Get rid of unncessary header inclusions
  ARM: OMAP2+: AM33XX: CM/PRM: Use __ASSEMBLER__ macros in header files
  ARM: OMAP2+: AM33XX: hwmod: Register OCMC RAM hwmod
  ARM: OMAP2+: AM33XX: hwmod: Update TPTC0 hwmod with the right flags
  ARM: OMAP2+: AM33XX: hwmod: Fixup cpgmac0 hwmod entry
  ARM: OMAP2+: AM33XX: Update the hardreset API
  ARM: OMAP2+: AM33XX: hwmod: Update the WKUP-M3 hwmod with reset
    status bit
  ARM: DTS: AM33XX: Add nodes for OCMC RAM and WKUP-M3
  ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent
    device
  ARM: OMAP2+: AM33XX: timer: Interchance clkevt and clksrc timers
  ARM: OMAP2+: AM33XX: control: Add some control module registers and
    APIs
  ARM: OMAP2+: AM33XX: Add assembly code for PM operations
  ARM: OMAP2+: AM33XX: Basic suspend resume support
  ARM: OMAP2+: AM33XX: Select Mailbox when PM is enabled
  ARM: OMAP2+: AM33XX: Hookup AM33XX PM code into OMAP builds

 .../devicetree/bindings/arm/omap/timer.txt         |    2 +
 arch/arm/boot/dts/am33xx.dtsi                      |   12 +
 arch/arm/mach-omap2/Kconfig                        |    4 +-
 arch/arm/mach-omap2/Makefile                       |    2 +
 arch/arm/mach-omap2/board-generic.c                |    1 +
 arch/arm/mach-omap2/cm33xx.h                       |   10 +-
 arch/arm/mach-omap2/common.h                       |   10 +
 arch/arm/mach-omap2/control.c                      |   20 +
 arch/arm/mach-omap2/control.h                      |   41 ++
 arch/arm/mach-omap2/io.c                           |    7 +
 arch/arm/mach-omap2/omap_hwmod.c                   |    5 +-
 arch/arm/mach-omap2/omap_hwmod_33xx_data.c         |   50 +-
 arch/arm/mach-omap2/pm.h                           |    7 +
 arch/arm/mach-omap2/pm33xx.c                       |  469 ++++++++++++++++
 arch/arm/mach-omap2/pm33xx.h                       |   56 ++
 arch/arm/mach-omap2/prm33xx.c                      |   11 +-
 arch/arm/mach-omap2/prm33xx.h                      |    5 +-
 arch/arm/mach-omap2/sleep33xx.S                    |  584 +++++++++++++++++++
 arch/arm/mach-omap2/sram.c                         |   10 +-
 arch/arm/mach-omap2/sram.h                         |    2 +
 arch/arm/mach-omap2/timer.c                        |   39 ++-
 drivers/mailbox/mailbox-omap2.c                    |   54 ++-
 drivers/mailbox/mailbox.c                          |   36 ++
 drivers/mailbox/mailbox.h                          |    3 +
 drivers/memory/emif.c                              |    2 +-
 drivers/memory/emif.h                              |  589 --------------------
 include/linux/mailbox.h                            |    1 +
 include/linux/ti_emif.h                            |  589 ++++++++++++++++++++
 28 files changed, 1989 insertions(+), 632 deletions(-)
 create mode 100644 arch/arm/mach-omap2/pm33xx.c
 create mode 100644 arch/arm/mach-omap2/pm33xx.h
 create mode 100644 arch/arm/mach-omap2/sleep33xx.S
 delete mode 100644 drivers/memory/emif.h
 create mode 100644 include/linux/ti_emif.h

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 01/18] mailbox: OMAP2+: Add support for AM33XX
  2012-12-31 13:06 ` Vaibhav Bedia
@ 2012-12-31 13:06   ` Vaibhav Bedia
  -1 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:06 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, tony, khilman
  Cc: Vaibhav Bedia, Russ Dill, Santosh Shilimkar

Mailbox IP on AM33XX is the same as that present in OMAP4.
The single instance of Mailbox IP on AM33XX contains
8 sub-modules and facilitates communication between MPU,
PRUs and WKUP_M3.

The first mailbox sub-module is assigned for communication
between MPU and WKUP-M3.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Russ Dill <russ.dill@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
v1->v2:
	Address the comment on operator usage from Russ Dill

 drivers/mailbox/mailbox-omap2.c |   35 ++++++++++++++++++++++++++++++++++-
 1 files changed, 34 insertions(+), 1 deletions(-)

diff --git a/drivers/mailbox/mailbox-omap2.c b/drivers/mailbox/mailbox-omap2.c
index 7c26bed..6d61159 100644
--- a/drivers/mailbox/mailbox-omap2.c
+++ b/drivers/mailbox/mailbox-omap2.c
@@ -151,7 +151,7 @@ static void omap2_mbox_disable_irq(struct mailbox *mbox,
 	struct omap_mbox2_priv *p = mbox->priv;
 	u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
 
-	if (!cpu_is_omap44xx())
+	if (!cpu_is_omap44xx() && !soc_is_am33xx())
 		bit = mbox_read_reg(p->irqdisable) & ~bit;
 
 	mbox_write_reg(bit, p->irqdisable);
@@ -352,6 +352,32 @@ struct mailbox mbox_2_info = {
 struct mailbox *omap4_mboxes[] = { &mbox_1_info, &mbox_2_info, NULL };
 #endif
 
+#if defined(CONFIG_SOC_AM33XX)
+static struct omap_mbox2_priv omap2_mbox_wkup_m3_priv = {
+	.tx_fifo = {
+		.msg		= MAILBOX_MESSAGE(0),
+		.fifo_stat	= MAILBOX_FIFOSTATUS(0),
+		.msg_stat	= MAILBOX_MSGSTATUS(0),
+	},
+	.rx_fifo = {
+		.msg		= MAILBOX_MESSAGE(1),
+		.msg_stat	= MAILBOX_MSGSTATUS(1),
+	},
+	.irqenable	= OMAP4_MAILBOX_IRQENABLE(3),
+	.irqstatus	= OMAP4_MAILBOX_IRQSTATUS(3),
+	.irqdisable	= OMAP4_MAILBOX_IRQENABLE_CLR(3),
+	.notfull_bit	= MAILBOX_IRQ_NOTFULL(0),
+	.newmsg_bit	= MAILBOX_IRQ_NEWMSG(0),
+};
+
+struct mailbox mbox_wkup_m3_info = {
+	.name	= "wkup_m3",
+	.ops	= &omap2_mbox_ops,
+	.priv	= &omap2_mbox_wkup_m3_priv,
+};
+struct mailbox *am33xx_mboxes[] = { &mbox_wkup_m3_info, NULL };
+#endif
+
 static int __devinit omap2_mbox_probe(struct platform_device *pdev)
 {
 	struct resource *mem;
@@ -386,6 +412,13 @@ static int __devinit omap2_mbox_probe(struct platform_device *pdev)
 		list[0]->irq = list[1]->irq = platform_get_irq(pdev, 0);
 	}
 #endif
+#if defined(CONFIG_SOC_AM33XX)
+	else if (soc_is_am33xx()) {
+		list = am33xx_mboxes;
+
+		list[0]->irq = platform_get_irq(pdev, 0);
+	}
+#endif
 	else {
 		pr_err("%s: platform not supported\n", __func__);
 		return -ENODEV;
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 01/18] mailbox: OMAP2+: Add support for AM33XX
@ 2012-12-31 13:06   ` Vaibhav Bedia
  0 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:06 UTC (permalink / raw)
  To: linux-arm-kernel

Mailbox IP on AM33XX is the same as that present in OMAP4.
The single instance of Mailbox IP on AM33XX contains
8 sub-modules and facilitates communication between MPU,
PRUs and WKUP_M3.

The first mailbox sub-module is assigned for communication
between MPU and WKUP-M3.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Russ Dill <russ.dill@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
v1->v2:
	Address the comment on operator usage from Russ Dill

 drivers/mailbox/mailbox-omap2.c |   35 ++++++++++++++++++++++++++++++++++-
 1 files changed, 34 insertions(+), 1 deletions(-)

diff --git a/drivers/mailbox/mailbox-omap2.c b/drivers/mailbox/mailbox-omap2.c
index 7c26bed..6d61159 100644
--- a/drivers/mailbox/mailbox-omap2.c
+++ b/drivers/mailbox/mailbox-omap2.c
@@ -151,7 +151,7 @@ static void omap2_mbox_disable_irq(struct mailbox *mbox,
 	struct omap_mbox2_priv *p = mbox->priv;
 	u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
 
-	if (!cpu_is_omap44xx())
+	if (!cpu_is_omap44xx() && !soc_is_am33xx())
 		bit = mbox_read_reg(p->irqdisable) & ~bit;
 
 	mbox_write_reg(bit, p->irqdisable);
@@ -352,6 +352,32 @@ struct mailbox mbox_2_info = {
 struct mailbox *omap4_mboxes[] = { &mbox_1_info, &mbox_2_info, NULL };
 #endif
 
+#if defined(CONFIG_SOC_AM33XX)
+static struct omap_mbox2_priv omap2_mbox_wkup_m3_priv = {
+	.tx_fifo = {
+		.msg		= MAILBOX_MESSAGE(0),
+		.fifo_stat	= MAILBOX_FIFOSTATUS(0),
+		.msg_stat	= MAILBOX_MSGSTATUS(0),
+	},
+	.rx_fifo = {
+		.msg		= MAILBOX_MESSAGE(1),
+		.msg_stat	= MAILBOX_MSGSTATUS(1),
+	},
+	.irqenable	= OMAP4_MAILBOX_IRQENABLE(3),
+	.irqstatus	= OMAP4_MAILBOX_IRQSTATUS(3),
+	.irqdisable	= OMAP4_MAILBOX_IRQENABLE_CLR(3),
+	.notfull_bit	= MAILBOX_IRQ_NOTFULL(0),
+	.newmsg_bit	= MAILBOX_IRQ_NEWMSG(0),
+};
+
+struct mailbox mbox_wkup_m3_info = {
+	.name	= "wkup_m3",
+	.ops	= &omap2_mbox_ops,
+	.priv	= &omap2_mbox_wkup_m3_priv,
+};
+struct mailbox *am33xx_mboxes[] = { &mbox_wkup_m3_info, NULL };
+#endif
+
 static int __devinit omap2_mbox_probe(struct platform_device *pdev)
 {
 	struct resource *mem;
@@ -386,6 +412,13 @@ static int __devinit omap2_mbox_probe(struct platform_device *pdev)
 		list[0]->irq = list[1]->irq = platform_get_irq(pdev, 0);
 	}
 #endif
+#if defined(CONFIG_SOC_AM33XX)
+	else if (soc_is_am33xx()) {
+		list = am33xx_mboxes;
+
+		list[0]->irq = platform_get_irq(pdev, 0);
+	}
+#endif
 	else {
 		pr_err("%s: platform not supported\n", __func__);
 		return -ENODEV;
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 02/18] mailbox: Add an API for flushing the FIFO
  2012-12-31 13:06 ` Vaibhav Bedia
@ 2012-12-31 13:06   ` Vaibhav Bedia
  -1 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:06 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, tony, khilman
  Cc: Vaibhav Bedia, Santosh Shilimkar

On AM33XX, the mailbox module between the MPU and the
WKUP-M3 co-processor facilitates a one-way communication.
MPU uses the assigned mailbox sub-module to issue the
interrupt to the WKUP-M3 co-processor which then goes
and reads the the IPC data from registers in the control
module.

WKUP-M3 is in the L4_WKUP and does not have any access to
the mailbox module. Due to this limitation, the MPU is
completely responsible for FIFO maintenance and interrupt
generation. MPU needs to ensure that the FIFO does not
overflow by reading back the assigned mailbox sub-module.

This patch adds an API in the mailbox code which the MPU
can use to empty the FIFO by issuing a readback command.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
Note: This patch which will be slightly reworked once the mailbox
driver changes are finalized.

 drivers/mailbox/mailbox-omap2.c |   19 +++++++++++++++++++
 drivers/mailbox/mailbox.c       |   36 ++++++++++++++++++++++++++++++++++++
 drivers/mailbox/mailbox.h       |    3 +++
 include/linux/mailbox.h         |    1 +
 4 files changed, 59 insertions(+), 0 deletions(-)

diff --git a/drivers/mailbox/mailbox-omap2.c b/drivers/mailbox/mailbox-omap2.c
index 6d61159..c732be1 100644
--- a/drivers/mailbox/mailbox-omap2.c
+++ b/drivers/mailbox/mailbox-omap2.c
@@ -125,6 +125,23 @@ static int omap2_mbox_fifo_full(struct mailbox *mbox)
 	return mbox_read_reg(fifo->fifo_stat);
 }
 
+static int omap2_mbox_fifo_needs_flush(struct mailbox *mbox)
+{
+	struct omap_mbox2_priv *p = mbox->priv;
+	struct omap_mbox2_fifo *fifo = &p->tx_fifo;
+
+	return mbox_read_reg(fifo->msg_stat);
+}
+
+static void omap2_mbox_fifo_readback(struct mailbox *mbox,
+			struct mailbox_msg *msg)
+{
+	struct omap_mbox2_priv *p = mbox->priv;
+	struct omap_mbox2_fifo *fifo = &p->tx_fifo;
+
+	msg->header = mbox_read_reg(fifo->msg);
+}
+
 static int ompa2_mbox_poll_for_space(struct mailbox *mbox)
 {
 	if (omap2_mbox_fifo_full(mbox))
@@ -221,6 +238,8 @@ static struct mailbox_ops omap2_mbox_ops = {
 	.read           = omap2_mbox_fifo_read,
 	.write          = omap2_mbox_fifo_write,
 	.empty          = omap2_mbox_fifo_empty,
+	.fifo_needs_flush	= omap2_mbox_fifo_needs_flush,
+	.fifo_readback		= omap2_mbox_fifo_readback,
 	.poll_for_space = ompa2_mbox_poll_for_space,
 	.enable_irq     = omap2_mbox_enable_irq,
 	.disable_irq    = omap2_mbox_disable_irq,
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
index 2f50226..92c9f68 100644
--- a/drivers/mailbox/mailbox.c
+++ b/drivers/mailbox/mailbox.c
@@ -57,6 +57,15 @@ static inline int mbox_empty(struct mailbox *mbox)
 {
 	return mbox->ops->empty(mbox);
 }
+static inline int mbox_fifo_needs_flush(struct mailbox *mbox)
+{
+	return mbox->ops->fifo_needs_flush(mbox);
+}
+static inline void mbox_fifo_readback(struct mailbox *mbox,
+				struct mailbox_msg *msg)
+{
+	mbox->ops->fifo_readback(mbox, msg);
+}
 
 /* Mailbox IRQ handle functions */
 static inline void ack_mbox_irq(struct mailbox *mbox, mailbox_irq_t irq)
@@ -110,6 +119,33 @@ out:
 }
 EXPORT_SYMBOL(mailbox_msg_send);
 
+/*
+ * Flush the Rx FIFO by reading back the messages
+ * Since the normal expectation is that the Rx will do the
+ * reading, add a debug message to indicate if we really flush
+ *
+ * Returns the no. of messages read back
+ */
+int mailbox_rx_flush(struct mailbox *mbox)
+{
+	int ret = 0;
+	struct mailbox_msg readback_msg;
+
+	while (mbox_fifo_needs_flush(mbox)) {
+		mbox_fifo_readback(mbox, &readback_msg);
+		ret++;
+	}
+
+	if (ret) {
+		/* no more messages in the fifo. clear IRQ source. */
+		ack_mbox_irq(mbox, IRQ_RX);
+		pr_debug("Flushed %s Rx FIFO by reading back\n", mbox->name);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(mailbox_rx_flush);
+
 #define TRANSFER_TIMEOUT 30000 /* Becomes ~3s timeout */
 
 static struct mailbox_msg no_irq_msg_res;
diff --git a/drivers/mailbox/mailbox.h b/drivers/mailbox/mailbox.h
index f103194..b841ae1 100644
--- a/drivers/mailbox/mailbox.h
+++ b/drivers/mailbox/mailbox.h
@@ -24,6 +24,9 @@ struct mailbox_ops {
 	int             (*write)(struct mailbox *mbox, struct mailbox_msg *msg);
 	int             (*empty)(struct mailbox *mbox);
 	int             (*poll_for_space)(struct mailbox *mbox);
+	int		(*fifo_needs_flush)(struct mailbox *mbox);
+	void		(*fifo_readback)(struct mailbox *mbox,
+				struct mailbox_msg *msg);
 	/* irq */
 	void            (*enable_irq)(struct mailbox *mbox,
 			mailbox_irq_t irq);
diff --git a/include/linux/mailbox.h b/include/linux/mailbox.h
index 3f9ec1e..705def9 100644
--- a/include/linux/mailbox.h
+++ b/include/linux/mailbox.h
@@ -22,6 +22,7 @@ struct mailbox_msg {
 #define MAILBOX_FILL_HEADER_MSG(_msg, _header) \
 	MAILBOX_FILL_MSG(_msg, _header, NULL, 0);
 
+int mailbox_rx_flush(struct mailbox *);
 int mailbox_msg_send(struct mailbox *, struct mailbox_msg *msg);
 struct mailbox_msg *mailbox_msg_send_receive_no_irq(struct mailbox *,
 		struct mailbox_msg *msg);
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 02/18] mailbox: Add an API for flushing the FIFO
@ 2012-12-31 13:06   ` Vaibhav Bedia
  0 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:06 UTC (permalink / raw)
  To: linux-arm-kernel

On AM33XX, the mailbox module between the MPU and the
WKUP-M3 co-processor facilitates a one-way communication.
MPU uses the assigned mailbox sub-module to issue the
interrupt to the WKUP-M3 co-processor which then goes
and reads the the IPC data from registers in the control
module.

WKUP-M3 is in the L4_WKUP and does not have any access to
the mailbox module. Due to this limitation, the MPU is
completely responsible for FIFO maintenance and interrupt
generation. MPU needs to ensure that the FIFO does not
overflow by reading back the assigned mailbox sub-module.

This patch adds an API in the mailbox code which the MPU
can use to empty the FIFO by issuing a readback command.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
---
Note: This patch which will be slightly reworked once the mailbox
driver changes are finalized.

 drivers/mailbox/mailbox-omap2.c |   19 +++++++++++++++++++
 drivers/mailbox/mailbox.c       |   36 ++++++++++++++++++++++++++++++++++++
 drivers/mailbox/mailbox.h       |    3 +++
 include/linux/mailbox.h         |    1 +
 4 files changed, 59 insertions(+), 0 deletions(-)

diff --git a/drivers/mailbox/mailbox-omap2.c b/drivers/mailbox/mailbox-omap2.c
index 6d61159..c732be1 100644
--- a/drivers/mailbox/mailbox-omap2.c
+++ b/drivers/mailbox/mailbox-omap2.c
@@ -125,6 +125,23 @@ static int omap2_mbox_fifo_full(struct mailbox *mbox)
 	return mbox_read_reg(fifo->fifo_stat);
 }
 
+static int omap2_mbox_fifo_needs_flush(struct mailbox *mbox)
+{
+	struct omap_mbox2_priv *p = mbox->priv;
+	struct omap_mbox2_fifo *fifo = &p->tx_fifo;
+
+	return mbox_read_reg(fifo->msg_stat);
+}
+
+static void omap2_mbox_fifo_readback(struct mailbox *mbox,
+			struct mailbox_msg *msg)
+{
+	struct omap_mbox2_priv *p = mbox->priv;
+	struct omap_mbox2_fifo *fifo = &p->tx_fifo;
+
+	msg->header = mbox_read_reg(fifo->msg);
+}
+
 static int ompa2_mbox_poll_for_space(struct mailbox *mbox)
 {
 	if (omap2_mbox_fifo_full(mbox))
@@ -221,6 +238,8 @@ static struct mailbox_ops omap2_mbox_ops = {
 	.read           = omap2_mbox_fifo_read,
 	.write          = omap2_mbox_fifo_write,
 	.empty          = omap2_mbox_fifo_empty,
+	.fifo_needs_flush	= omap2_mbox_fifo_needs_flush,
+	.fifo_readback		= omap2_mbox_fifo_readback,
 	.poll_for_space = ompa2_mbox_poll_for_space,
 	.enable_irq     = omap2_mbox_enable_irq,
 	.disable_irq    = omap2_mbox_disable_irq,
diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
index 2f50226..92c9f68 100644
--- a/drivers/mailbox/mailbox.c
+++ b/drivers/mailbox/mailbox.c
@@ -57,6 +57,15 @@ static inline int mbox_empty(struct mailbox *mbox)
 {
 	return mbox->ops->empty(mbox);
 }
+static inline int mbox_fifo_needs_flush(struct mailbox *mbox)
+{
+	return mbox->ops->fifo_needs_flush(mbox);
+}
+static inline void mbox_fifo_readback(struct mailbox *mbox,
+				struct mailbox_msg *msg)
+{
+	mbox->ops->fifo_readback(mbox, msg);
+}
 
 /* Mailbox IRQ handle functions */
 static inline void ack_mbox_irq(struct mailbox *mbox, mailbox_irq_t irq)
@@ -110,6 +119,33 @@ out:
 }
 EXPORT_SYMBOL(mailbox_msg_send);
 
+/*
+ * Flush the Rx FIFO by reading back the messages
+ * Since the normal expectation is that the Rx will do the
+ * reading, add a debug message to indicate if we really flush
+ *
+ * Returns the no. of messages read back
+ */
+int mailbox_rx_flush(struct mailbox *mbox)
+{
+	int ret = 0;
+	struct mailbox_msg readback_msg;
+
+	while (mbox_fifo_needs_flush(mbox)) {
+		mbox_fifo_readback(mbox, &readback_msg);
+		ret++;
+	}
+
+	if (ret) {
+		/* no more messages in the fifo. clear IRQ source. */
+		ack_mbox_irq(mbox, IRQ_RX);
+		pr_debug("Flushed %s Rx FIFO by reading back\n", mbox->name);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL(mailbox_rx_flush);
+
 #define TRANSFER_TIMEOUT 30000 /* Becomes ~3s timeout */
 
 static struct mailbox_msg no_irq_msg_res;
diff --git a/drivers/mailbox/mailbox.h b/drivers/mailbox/mailbox.h
index f103194..b841ae1 100644
--- a/drivers/mailbox/mailbox.h
+++ b/drivers/mailbox/mailbox.h
@@ -24,6 +24,9 @@ struct mailbox_ops {
 	int             (*write)(struct mailbox *mbox, struct mailbox_msg *msg);
 	int             (*empty)(struct mailbox *mbox);
 	int             (*poll_for_space)(struct mailbox *mbox);
+	int		(*fifo_needs_flush)(struct mailbox *mbox);
+	void		(*fifo_readback)(struct mailbox *mbox,
+				struct mailbox_msg *msg);
 	/* irq */
 	void            (*enable_irq)(struct mailbox *mbox,
 			mailbox_irq_t irq);
diff --git a/include/linux/mailbox.h b/include/linux/mailbox.h
index 3f9ec1e..705def9 100644
--- a/include/linux/mailbox.h
+++ b/include/linux/mailbox.h
@@ -22,6 +22,7 @@ struct mailbox_msg {
 #define MAILBOX_FILL_HEADER_MSG(_msg, _header) \
 	MAILBOX_FILL_MSG(_msg, _header, NULL, 0);
 
+int mailbox_rx_flush(struct mailbox *);
 int mailbox_msg_send(struct mailbox *, struct mailbox_msg *msg);
 struct mailbox_msg *mailbox_msg_send_receive_no_irq(struct mailbox *,
 		struct mailbox_msg *msg);
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 03/18] memory: emif: Move EMIF related header file to include/linux/
  2012-12-31 13:06 ` Vaibhav Bedia
@ 2012-12-31 13:06   ` Vaibhav Bedia
  -1 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:06 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, tony, khilman
  Cc: Vaibhav Bedia, Santosh Shilimkar, Benoit Cousson, Aneesh V

OMAP4 and AM33XX share the same EMIF controller IP. Although there
are significant differences in the IP integration due to which
AM33XX can't reuse the EMIF driver DVFS similar to OMAP4,
it can definitely benefit by reusing the EMIF related macros
defined in drivers/memory/emif.h.

In the current OMAP PM framework the PM code resides under
arch/arm/mach-omap2/. To enable reuse of the register defines move
the emif header file to include/linux so that both the EMIF driver
and the AM33XX PM code can benefit.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Aneesh V <aneesh@ti.com>
---
v1->v2:
	This is a new patch in the series to enable code reuse
	between the EMIF driver and AM33XX PM code

 drivers/memory/emif.c   |    2 +-
 drivers/memory/emif.h   |  589 -----------------------------------------------
 include/linux/ti_emif.h |  589 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 590 insertions(+), 590 deletions(-)
 delete mode 100644 drivers/memory/emif.h
 create mode 100644 include/linux/ti_emif.h

diff --git a/drivers/memory/emif.c b/drivers/memory/emif.c
index 06d31c9..a3d893d 100644
--- a/drivers/memory/emif.c
+++ b/drivers/memory/emif.c
@@ -24,8 +24,8 @@
 #include <linux/module.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
+#include <linux/ti_emif.h>
 #include <memory/jedec_ddr.h>
-#include "emif.h"
 #include "of_memory.h"
 
 /**
diff --git a/drivers/memory/emif.h b/drivers/memory/emif.h
deleted file mode 100644
index bfe08ba..0000000
--- a/drivers/memory/emif.h
+++ /dev/null
@@ -1,589 +0,0 @@
-/*
- * Defines for the EMIF driver
- *
- * Copyright (C) 2012 Texas Instruments, Inc.
- *
- * Benoit Cousson (b-cousson@ti.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __EMIF_H
-#define __EMIF_H
-
-/*
- * Maximum number of different frequencies supported by EMIF driver
- * Determines the number of entries in the pointer array for register
- * cache
- */
-#define EMIF_MAX_NUM_FREQUENCIES			6
-
-/* State of the core voltage */
-#define DDR_VOLTAGE_STABLE				0
-#define DDR_VOLTAGE_RAMPING				1
-
-/* Defines for timing De-rating */
-#define EMIF_NORMAL_TIMINGS				0
-#define EMIF_DERATED_TIMINGS				1
-
-/* Length of the forced read idle period in terms of cycles */
-#define EMIF_READ_IDLE_LEN_VAL				5
-
-/*
- * forced read idle interval to be used when voltage
- * is changed as part of DVFS/DPS - 1ms
- */
-#define READ_IDLE_INTERVAL_DVFS				(1*1000000)
-
-/*
- * Forced read idle interval to be used when voltage is stable
- * 50us - or maximum value will do
- */
-#define READ_IDLE_INTERVAL_NORMAL			(50*1000000)
-
-/* DLL calibration interval when voltage is NOT stable - 1us */
-#define DLL_CALIB_INTERVAL_DVFS				(1*1000000)
-
-#define DLL_CALIB_ACK_WAIT_VAL				5
-
-/* Interval between ZQCS commands - hw team recommended value */
-#define EMIF_ZQCS_INTERVAL_US				(50*1000)
-/* Enable ZQ Calibration on exiting Self-refresh */
-#define ZQ_SFEXITEN_ENABLE				1
-/*
- * ZQ Calibration simultaneously on both chip-selects:
- * Needs one calibration resistor per CS
- */
-#define	ZQ_DUALCALEN_DISABLE				0
-#define	ZQ_DUALCALEN_ENABLE				1
-
-#define T_ZQCS_DEFAULT_NS				90
-#define T_ZQCL_DEFAULT_NS				360
-#define T_ZQINIT_DEFAULT_NS				1000
-
-/* DPD_EN */
-#define DPD_DISABLE					0
-#define DPD_ENABLE					1
-
-/*
- * Default values for the low-power entry to be used if not provided by user.
- * OMAP4/5 has a hw bug(i735) due to which this value can not be less than 512
- * Timeout values are in DDR clock 'cycles' and frequency threshold in Hz
- */
-#define EMIF_LP_MODE_TIMEOUT_PERFORMANCE		2048
-#define EMIF_LP_MODE_TIMEOUT_POWER			512
-#define EMIF_LP_MODE_FREQ_THRESHOLD			400000000
-
-/* DDR_PHY_CTRL_1 values for EMIF4D - ATTILA PHY combination */
-#define EMIF_DDR_PHY_CTRL_1_BASE_VAL_ATTILAPHY		0x049FF000
-#define EMIF_DLL_SLAVE_DLY_CTRL_400_MHZ_ATTILAPHY	0x41
-#define EMIF_DLL_SLAVE_DLY_CTRL_200_MHZ_ATTILAPHY	0x80
-#define EMIF_DLL_SLAVE_DLY_CTRL_100_MHZ_AND_LESS_ATTILAPHY 0xFF
-
-/* DDR_PHY_CTRL_1 values for EMIF4D5 INTELLIPHY combination */
-#define EMIF_DDR_PHY_CTRL_1_BASE_VAL_INTELLIPHY		0x0E084200
-#define EMIF_PHY_TOTAL_READ_LATENCY_INTELLIPHY_PS	10000
-
-/* TEMP_ALERT_CONFIG - corresponding to temp gradient 5 C/s */
-#define TEMP_ALERT_POLL_INTERVAL_DEFAULT_MS		360
-
-#define EMIF_T_CSTA					3
-#define EMIF_T_PDLL_UL					128
-
-/* External PHY control registers magic values */
-#define EMIF_EXT_PHY_CTRL_1_VAL				0x04020080
-#define EMIF_EXT_PHY_CTRL_5_VAL				0x04010040
-#define EMIF_EXT_PHY_CTRL_6_VAL				0x01004010
-#define EMIF_EXT_PHY_CTRL_7_VAL				0x00001004
-#define EMIF_EXT_PHY_CTRL_8_VAL				0x04010040
-#define EMIF_EXT_PHY_CTRL_9_VAL				0x01004010
-#define EMIF_EXT_PHY_CTRL_10_VAL			0x00001004
-#define EMIF_EXT_PHY_CTRL_11_VAL			0x00000000
-#define EMIF_EXT_PHY_CTRL_12_VAL			0x00000000
-#define EMIF_EXT_PHY_CTRL_13_VAL			0x00000000
-#define EMIF_EXT_PHY_CTRL_14_VAL			0x80080080
-#define EMIF_EXT_PHY_CTRL_15_VAL			0x00800800
-#define EMIF_EXT_PHY_CTRL_16_VAL			0x08102040
-#define EMIF_EXT_PHY_CTRL_17_VAL			0x00000001
-#define EMIF_EXT_PHY_CTRL_18_VAL			0x540A8150
-#define EMIF_EXT_PHY_CTRL_19_VAL			0xA81502A0
-#define EMIF_EXT_PHY_CTRL_20_VAL			0x002A0540
-#define EMIF_EXT_PHY_CTRL_21_VAL			0x00000000
-#define EMIF_EXT_PHY_CTRL_22_VAL			0x00000000
-#define EMIF_EXT_PHY_CTRL_23_VAL			0x00000000
-#define EMIF_EXT_PHY_CTRL_24_VAL			0x00000077
-
-#define EMIF_INTELLI_PHY_DQS_GATE_OPENING_DELAY_PS	1200
-
-/* Registers offset */
-#define EMIF_MODULE_ID_AND_REVISION			0x0000
-#define EMIF_STATUS					0x0004
-#define EMIF_SDRAM_CONFIG				0x0008
-#define EMIF_SDRAM_CONFIG_2				0x000c
-#define EMIF_SDRAM_REFRESH_CONTROL			0x0010
-#define EMIF_SDRAM_REFRESH_CTRL_SHDW			0x0014
-#define EMIF_SDRAM_TIMING_1				0x0018
-#define EMIF_SDRAM_TIMING_1_SHDW			0x001c
-#define EMIF_SDRAM_TIMING_2				0x0020
-#define EMIF_SDRAM_TIMING_2_SHDW			0x0024
-#define EMIF_SDRAM_TIMING_3				0x0028
-#define EMIF_SDRAM_TIMING_3_SHDW			0x002c
-#define EMIF_LPDDR2_NVM_TIMING				0x0030
-#define EMIF_LPDDR2_NVM_TIMING_SHDW			0x0034
-#define EMIF_POWER_MANAGEMENT_CONTROL			0x0038
-#define EMIF_POWER_MANAGEMENT_CTRL_SHDW			0x003c
-#define EMIF_LPDDR2_MODE_REG_DATA			0x0040
-#define EMIF_LPDDR2_MODE_REG_CONFIG			0x0050
-#define EMIF_OCP_CONFIG					0x0054
-#define EMIF_OCP_CONFIG_VALUE_1				0x0058
-#define EMIF_OCP_CONFIG_VALUE_2				0x005c
-#define EMIF_IODFT_TEST_LOGIC_GLOBAL_CONTROL		0x0060
-#define EMIF_IODFT_TEST_LOGIC_CTRL_MISR_RESULT		0x0064
-#define EMIF_IODFT_TEST_LOGIC_ADDRESS_MISR_RESULT	0x0068
-#define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_1	0x006c
-#define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_2	0x0070
-#define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_3	0x0074
-#define EMIF_PERFORMANCE_COUNTER_1			0x0080
-#define EMIF_PERFORMANCE_COUNTER_2			0x0084
-#define EMIF_PERFORMANCE_COUNTER_CONFIG			0x0088
-#define EMIF_PERFORMANCE_COUNTER_MASTER_REGION_SELECT	0x008c
-#define EMIF_PERFORMANCE_COUNTER_TIME			0x0090
-#define EMIF_MISC_REG					0x0094
-#define EMIF_DLL_CALIB_CTRL				0x0098
-#define EMIF_DLL_CALIB_CTRL_SHDW			0x009c
-#define EMIF_END_OF_INTERRUPT				0x00a0
-#define EMIF_SYSTEM_OCP_INTERRUPT_RAW_STATUS		0x00a4
-#define EMIF_LL_OCP_INTERRUPT_RAW_STATUS		0x00a8
-#define EMIF_SYSTEM_OCP_INTERRUPT_STATUS		0x00ac
-#define EMIF_LL_OCP_INTERRUPT_STATUS			0x00b0
-#define EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_SET		0x00b4
-#define EMIF_LL_OCP_INTERRUPT_ENABLE_SET		0x00b8
-#define EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_CLEAR		0x00bc
-#define EMIF_LL_OCP_INTERRUPT_ENABLE_CLEAR		0x00c0
-#define EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG	0x00c8
-#define EMIF_TEMPERATURE_ALERT_CONFIG			0x00cc
-#define EMIF_OCP_ERROR_LOG				0x00d0
-#define EMIF_READ_WRITE_LEVELING_RAMP_WINDOW		0x00d4
-#define EMIF_READ_WRITE_LEVELING_RAMP_CONTROL		0x00d8
-#define EMIF_READ_WRITE_LEVELING_CONTROL		0x00dc
-#define EMIF_DDR_PHY_CTRL_1				0x00e4
-#define EMIF_DDR_PHY_CTRL_1_SHDW			0x00e8
-#define EMIF_DDR_PHY_CTRL_2				0x00ec
-#define EMIF_PRIORITY_TO_CLASS_OF_SERVICE_MAPPING	0x0100
-#define EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_1_MAPPING 0x0104
-#define EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_2_MAPPING 0x0108
-#define EMIF_READ_WRITE_EXECUTION_THRESHOLD		0x0120
-#define EMIF_COS_CONFIG					0x0124
-#define EMIF_PHY_STATUS_1				0x0140
-#define EMIF_PHY_STATUS_2				0x0144
-#define EMIF_PHY_STATUS_3				0x0148
-#define EMIF_PHY_STATUS_4				0x014c
-#define EMIF_PHY_STATUS_5				0x0150
-#define EMIF_PHY_STATUS_6				0x0154
-#define EMIF_PHY_STATUS_7				0x0158
-#define EMIF_PHY_STATUS_8				0x015c
-#define EMIF_PHY_STATUS_9				0x0160
-#define EMIF_PHY_STATUS_10				0x0164
-#define EMIF_PHY_STATUS_11				0x0168
-#define EMIF_PHY_STATUS_12				0x016c
-#define EMIF_PHY_STATUS_13				0x0170
-#define EMIF_PHY_STATUS_14				0x0174
-#define EMIF_PHY_STATUS_15				0x0178
-#define EMIF_PHY_STATUS_16				0x017c
-#define EMIF_PHY_STATUS_17				0x0180
-#define EMIF_PHY_STATUS_18				0x0184
-#define EMIF_PHY_STATUS_19				0x0188
-#define EMIF_PHY_STATUS_20				0x018c
-#define EMIF_PHY_STATUS_21				0x0190
-#define EMIF_EXT_PHY_CTRL_1				0x0200
-#define EMIF_EXT_PHY_CTRL_1_SHDW			0x0204
-#define EMIF_EXT_PHY_CTRL_2				0x0208
-#define EMIF_EXT_PHY_CTRL_2_SHDW			0x020c
-#define EMIF_EXT_PHY_CTRL_3				0x0210
-#define EMIF_EXT_PHY_CTRL_3_SHDW			0x0214
-#define EMIF_EXT_PHY_CTRL_4				0x0218
-#define EMIF_EXT_PHY_CTRL_4_SHDW			0x021c
-#define EMIF_EXT_PHY_CTRL_5				0x0220
-#define EMIF_EXT_PHY_CTRL_5_SHDW			0x0224
-#define EMIF_EXT_PHY_CTRL_6				0x0228
-#define EMIF_EXT_PHY_CTRL_6_SHDW			0x022c
-#define EMIF_EXT_PHY_CTRL_7				0x0230
-#define EMIF_EXT_PHY_CTRL_7_SHDW			0x0234
-#define EMIF_EXT_PHY_CTRL_8				0x0238
-#define EMIF_EXT_PHY_CTRL_8_SHDW			0x023c
-#define EMIF_EXT_PHY_CTRL_9				0x0240
-#define EMIF_EXT_PHY_CTRL_9_SHDW			0x0244
-#define EMIF_EXT_PHY_CTRL_10				0x0248
-#define EMIF_EXT_PHY_CTRL_10_SHDW			0x024c
-#define EMIF_EXT_PHY_CTRL_11				0x0250
-#define EMIF_EXT_PHY_CTRL_11_SHDW			0x0254
-#define EMIF_EXT_PHY_CTRL_12				0x0258
-#define EMIF_EXT_PHY_CTRL_12_SHDW			0x025c
-#define EMIF_EXT_PHY_CTRL_13				0x0260
-#define EMIF_EXT_PHY_CTRL_13_SHDW			0x0264
-#define EMIF_EXT_PHY_CTRL_14				0x0268
-#define EMIF_EXT_PHY_CTRL_14_SHDW			0x026c
-#define EMIF_EXT_PHY_CTRL_15				0x0270
-#define EMIF_EXT_PHY_CTRL_15_SHDW			0x0274
-#define EMIF_EXT_PHY_CTRL_16				0x0278
-#define EMIF_EXT_PHY_CTRL_16_SHDW			0x027c
-#define EMIF_EXT_PHY_CTRL_17				0x0280
-#define EMIF_EXT_PHY_CTRL_17_SHDW			0x0284
-#define EMIF_EXT_PHY_CTRL_18				0x0288
-#define EMIF_EXT_PHY_CTRL_18_SHDW			0x028c
-#define EMIF_EXT_PHY_CTRL_19				0x0290
-#define EMIF_EXT_PHY_CTRL_19_SHDW			0x0294
-#define EMIF_EXT_PHY_CTRL_20				0x0298
-#define EMIF_EXT_PHY_CTRL_20_SHDW			0x029c
-#define EMIF_EXT_PHY_CTRL_21				0x02a0
-#define EMIF_EXT_PHY_CTRL_21_SHDW			0x02a4
-#define EMIF_EXT_PHY_CTRL_22				0x02a8
-#define EMIF_EXT_PHY_CTRL_22_SHDW			0x02ac
-#define EMIF_EXT_PHY_CTRL_23				0x02b0
-#define EMIF_EXT_PHY_CTRL_23_SHDW			0x02b4
-#define EMIF_EXT_PHY_CTRL_24				0x02b8
-#define EMIF_EXT_PHY_CTRL_24_SHDW			0x02bc
-#define EMIF_EXT_PHY_CTRL_25				0x02c0
-#define EMIF_EXT_PHY_CTRL_25_SHDW			0x02c4
-#define EMIF_EXT_PHY_CTRL_26				0x02c8
-#define EMIF_EXT_PHY_CTRL_26_SHDW			0x02cc
-#define EMIF_EXT_PHY_CTRL_27				0x02d0
-#define EMIF_EXT_PHY_CTRL_27_SHDW			0x02d4
-#define EMIF_EXT_PHY_CTRL_28				0x02d8
-#define EMIF_EXT_PHY_CTRL_28_SHDW			0x02dc
-#define EMIF_EXT_PHY_CTRL_29				0x02e0
-#define EMIF_EXT_PHY_CTRL_29_SHDW			0x02e4
-#define EMIF_EXT_PHY_CTRL_30				0x02e8
-#define EMIF_EXT_PHY_CTRL_30_SHDW			0x02ec
-
-/* Registers shifts and masks */
-
-/* EMIF_MODULE_ID_AND_REVISION */
-#define SCHEME_SHIFT					30
-#define SCHEME_MASK					(0x3 << 30)
-#define MODULE_ID_SHIFT					16
-#define MODULE_ID_MASK					(0xfff << 16)
-#define RTL_VERSION_SHIFT				11
-#define RTL_VERSION_MASK				(0x1f << 11)
-#define MAJOR_REVISION_SHIFT				8
-#define MAJOR_REVISION_MASK				(0x7 << 8)
-#define MINOR_REVISION_SHIFT				0
-#define MINOR_REVISION_MASK				(0x3f << 0)
-
-/* STATUS */
-#define BE_SHIFT					31
-#define BE_MASK						(1 << 31)
-#define DUAL_CLK_MODE_SHIFT				30
-#define DUAL_CLK_MODE_MASK				(1 << 30)
-#define FAST_INIT_SHIFT					29
-#define FAST_INIT_MASK					(1 << 29)
-#define RDLVLGATETO_SHIFT				6
-#define RDLVLGATETO_MASK				(1 << 6)
-#define RDLVLTO_SHIFT					5
-#define RDLVLTO_MASK					(1 << 5)
-#define WRLVLTO_SHIFT					4
-#define WRLVLTO_MASK					(1 << 4)
-#define PHY_DLL_READY_SHIFT				2
-#define PHY_DLL_READY_MASK				(1 << 2)
-
-/* SDRAM_CONFIG */
-#define SDRAM_TYPE_SHIFT				29
-#define SDRAM_TYPE_MASK					(0x7 << 29)
-#define IBANK_POS_SHIFT					27
-#define IBANK_POS_MASK					(0x3 << 27)
-#define DDR_TERM_SHIFT					24
-#define DDR_TERM_MASK					(0x7 << 24)
-#define DDR2_DDQS_SHIFT					23
-#define DDR2_DDQS_MASK					(1 << 23)
-#define DYN_ODT_SHIFT					21
-#define DYN_ODT_MASK					(0x3 << 21)
-#define DDR_DISABLE_DLL_SHIFT				20
-#define DDR_DISABLE_DLL_MASK				(1 << 20)
-#define SDRAM_DRIVE_SHIFT				18
-#define SDRAM_DRIVE_MASK				(0x3 << 18)
-#define CWL_SHIFT					16
-#define CWL_MASK					(0x3 << 16)
-#define NARROW_MODE_SHIFT				14
-#define NARROW_MODE_MASK				(0x3 << 14)
-#define CL_SHIFT					10
-#define CL_MASK						(0xf << 10)
-#define ROWSIZE_SHIFT					7
-#define ROWSIZE_MASK					(0x7 << 7)
-#define IBANK_SHIFT					4
-#define IBANK_MASK					(0x7 << 4)
-#define EBANK_SHIFT					3
-#define EBANK_MASK					(1 << 3)
-#define PAGESIZE_SHIFT					0
-#define PAGESIZE_MASK					(0x7 << 0)
-
-/* SDRAM_CONFIG_2 */
-#define CS1NVMEN_SHIFT					30
-#define CS1NVMEN_MASK					(1 << 30)
-#define EBANK_POS_SHIFT					27
-#define EBANK_POS_MASK					(1 << 27)
-#define RDBNUM_SHIFT					4
-#define RDBNUM_MASK					(0x3 << 4)
-#define RDBSIZE_SHIFT					0
-#define RDBSIZE_MASK					(0x7 << 0)
-
-/* SDRAM_REFRESH_CONTROL */
-#define INITREF_DIS_SHIFT				31
-#define INITREF_DIS_MASK				(1 << 31)
-#define SRT_SHIFT					29
-#define SRT_MASK					(1 << 29)
-#define ASR_SHIFT					28
-#define ASR_MASK					(1 << 28)
-#define PASR_SHIFT					24
-#define PASR_MASK					(0x7 << 24)
-#define REFRESH_RATE_SHIFT				0
-#define REFRESH_RATE_MASK				(0xffff << 0)
-
-/* SDRAM_TIMING_1 */
-#define T_RTW_SHIFT					29
-#define T_RTW_MASK					(0x7 << 29)
-#define T_RP_SHIFT					25
-#define T_RP_MASK					(0xf << 25)
-#define T_RCD_SHIFT					21
-#define T_RCD_MASK					(0xf << 21)
-#define T_WR_SHIFT					17
-#define T_WR_MASK					(0xf << 17)
-#define T_RAS_SHIFT					12
-#define T_RAS_MASK					(0x1f << 12)
-#define T_RC_SHIFT					6
-#define T_RC_MASK					(0x3f << 6)
-#define T_RRD_SHIFT					3
-#define T_RRD_MASK					(0x7 << 3)
-#define T_WTR_SHIFT					0
-#define T_WTR_MASK					(0x7 << 0)
-
-/* SDRAM_TIMING_2 */
-#define T_XP_SHIFT					28
-#define T_XP_MASK					(0x7 << 28)
-#define T_ODT_SHIFT					25
-#define T_ODT_MASK					(0x7 << 25)
-#define T_XSNR_SHIFT					16
-#define T_XSNR_MASK					(0x1ff << 16)
-#define T_XSRD_SHIFT					6
-#define T_XSRD_MASK					(0x3ff << 6)
-#define T_RTP_SHIFT					3
-#define T_RTP_MASK					(0x7 << 3)
-#define T_CKE_SHIFT					0
-#define T_CKE_MASK					(0x7 << 0)
-
-/* SDRAM_TIMING_3 */
-#define T_PDLL_UL_SHIFT					28
-#define T_PDLL_UL_MASK					(0xf << 28)
-#define T_CSTA_SHIFT					24
-#define T_CSTA_MASK					(0xf << 24)
-#define T_CKESR_SHIFT					21
-#define T_CKESR_MASK					(0x7 << 21)
-#define ZQ_ZQCS_SHIFT					15
-#define ZQ_ZQCS_MASK					(0x3f << 15)
-#define T_TDQSCKMAX_SHIFT				13
-#define T_TDQSCKMAX_MASK				(0x3 << 13)
-#define T_RFC_SHIFT					4
-#define T_RFC_MASK					(0x1ff << 4)
-#define T_RAS_MAX_SHIFT					0
-#define T_RAS_MAX_MASK					(0xf << 0)
-
-/* POWER_MANAGEMENT_CONTROL */
-#define PD_TIM_SHIFT					12
-#define PD_TIM_MASK					(0xf << 12)
-#define DPD_EN_SHIFT					11
-#define DPD_EN_MASK					(1 << 11)
-#define LP_MODE_SHIFT					8
-#define LP_MODE_MASK					(0x7 << 8)
-#define SR_TIM_SHIFT					4
-#define SR_TIM_MASK					(0xf << 4)
-#define CS_TIM_SHIFT					0
-#define CS_TIM_MASK					(0xf << 0)
-
-/* LPDDR2_MODE_REG_DATA */
-#define VALUE_0_SHIFT					0
-#define VALUE_0_MASK					(0x7f << 0)
-
-/* LPDDR2_MODE_REG_CONFIG */
-#define CS_SHIFT					31
-#define CS_MASK						(1 << 31)
-#define REFRESH_EN_SHIFT				30
-#define REFRESH_EN_MASK					(1 << 30)
-#define ADDRESS_SHIFT					0
-#define ADDRESS_MASK					(0xff << 0)
-
-/* OCP_CONFIG */
-#define SYS_THRESH_MAX_SHIFT				24
-#define SYS_THRESH_MAX_MASK				(0xf << 24)
-#define MPU_THRESH_MAX_SHIFT				20
-#define MPU_THRESH_MAX_MASK				(0xf << 20)
-#define LL_THRESH_MAX_SHIFT				16
-#define LL_THRESH_MAX_MASK				(0xf << 16)
-
-/* PERFORMANCE_COUNTER_1 */
-#define COUNTER1_SHIFT					0
-#define COUNTER1_MASK					(0xffffffff << 0)
-
-/* PERFORMANCE_COUNTER_2 */
-#define COUNTER2_SHIFT					0
-#define COUNTER2_MASK					(0xffffffff << 0)
-
-/* PERFORMANCE_COUNTER_CONFIG */
-#define CNTR2_MCONNID_EN_SHIFT				31
-#define CNTR2_MCONNID_EN_MASK				(1 << 31)
-#define CNTR2_REGION_EN_SHIFT				30
-#define CNTR2_REGION_EN_MASK				(1 << 30)
-#define CNTR2_CFG_SHIFT					16
-#define CNTR2_CFG_MASK					(0xf << 16)
-#define CNTR1_MCONNID_EN_SHIFT				15
-#define CNTR1_MCONNID_EN_MASK				(1 << 15)
-#define CNTR1_REGION_EN_SHIFT				14
-#define CNTR1_REGION_EN_MASK				(1 << 14)
-#define CNTR1_CFG_SHIFT					0
-#define CNTR1_CFG_MASK					(0xf << 0)
-
-/* PERFORMANCE_COUNTER_MASTER_REGION_SELECT */
-#define MCONNID2_SHIFT					24
-#define MCONNID2_MASK					(0xff << 24)
-#define REGION_SEL2_SHIFT				16
-#define REGION_SEL2_MASK				(0x3 << 16)
-#define MCONNID1_SHIFT					8
-#define MCONNID1_MASK					(0xff << 8)
-#define REGION_SEL1_SHIFT				0
-#define REGION_SEL1_MASK				(0x3 << 0)
-
-/* PERFORMANCE_COUNTER_TIME */
-#define TOTAL_TIME_SHIFT				0
-#define TOTAL_TIME_MASK					(0xffffffff << 0)
-
-/* DLL_CALIB_CTRL */
-#define ACK_WAIT_SHIFT					16
-#define ACK_WAIT_MASK					(0xf << 16)
-#define DLL_CALIB_INTERVAL_SHIFT			0
-#define DLL_CALIB_INTERVAL_MASK				(0x1ff << 0)
-
-/* END_OF_INTERRUPT */
-#define EOI_SHIFT					0
-#define EOI_MASK					(1 << 0)
-
-/* SYSTEM_OCP_INTERRUPT_RAW_STATUS */
-#define DNV_SYS_SHIFT					2
-#define DNV_SYS_MASK					(1 << 2)
-#define TA_SYS_SHIFT					1
-#define TA_SYS_MASK					(1 << 1)
-#define ERR_SYS_SHIFT					0
-#define ERR_SYS_MASK					(1 << 0)
-
-/* LOW_LATENCY_OCP_INTERRUPT_RAW_STATUS */
-#define DNV_LL_SHIFT					2
-#define DNV_LL_MASK					(1 << 2)
-#define TA_LL_SHIFT					1
-#define TA_LL_MASK					(1 << 1)
-#define ERR_LL_SHIFT					0
-#define ERR_LL_MASK					(1 << 0)
-
-/* SYSTEM_OCP_INTERRUPT_ENABLE_SET */
-#define EN_DNV_SYS_SHIFT				2
-#define EN_DNV_SYS_MASK					(1 << 2)
-#define EN_TA_SYS_SHIFT					1
-#define EN_TA_SYS_MASK					(1 << 1)
-#define EN_ERR_SYS_SHIFT					0
-#define EN_ERR_SYS_MASK					(1 << 0)
-
-/* LOW_LATENCY_OCP_INTERRUPT_ENABLE_SET */
-#define EN_DNV_LL_SHIFT					2
-#define EN_DNV_LL_MASK					(1 << 2)
-#define EN_TA_LL_SHIFT					1
-#define EN_TA_LL_MASK					(1 << 1)
-#define EN_ERR_LL_SHIFT					0
-#define EN_ERR_LL_MASK					(1 << 0)
-
-/* SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG */
-#define ZQ_CS1EN_SHIFT					31
-#define ZQ_CS1EN_MASK					(1 << 31)
-#define ZQ_CS0EN_SHIFT					30
-#define ZQ_CS0EN_MASK					(1 << 30)
-#define ZQ_DUALCALEN_SHIFT				29
-#define ZQ_DUALCALEN_MASK				(1 << 29)
-#define ZQ_SFEXITEN_SHIFT				28
-#define ZQ_SFEXITEN_MASK				(1 << 28)
-#define ZQ_ZQINIT_MULT_SHIFT				18
-#define ZQ_ZQINIT_MULT_MASK				(0x3 << 18)
-#define ZQ_ZQCL_MULT_SHIFT				16
-#define ZQ_ZQCL_MULT_MASK				(0x3 << 16)
-#define ZQ_REFINTERVAL_SHIFT				0
-#define ZQ_REFINTERVAL_MASK				(0xffff << 0)
-
-/* TEMPERATURE_ALERT_CONFIG */
-#define TA_CS1EN_SHIFT					31
-#define TA_CS1EN_MASK					(1 << 31)
-#define TA_CS0EN_SHIFT					30
-#define TA_CS0EN_MASK					(1 << 30)
-#define TA_SFEXITEN_SHIFT				28
-#define TA_SFEXITEN_MASK				(1 << 28)
-#define TA_DEVWDT_SHIFT					26
-#define TA_DEVWDT_MASK					(0x3 << 26)
-#define TA_DEVCNT_SHIFT					24
-#define TA_DEVCNT_MASK					(0x3 << 24)
-#define TA_REFINTERVAL_SHIFT				0
-#define TA_REFINTERVAL_MASK				(0x3fffff << 0)
-
-/* OCP_ERROR_LOG */
-#define MADDRSPACE_SHIFT				14
-#define MADDRSPACE_MASK					(0x3 << 14)
-#define MBURSTSEQ_SHIFT					11
-#define MBURSTSEQ_MASK					(0x7 << 11)
-#define MCMD_SHIFT					8
-#define MCMD_MASK					(0x7 << 8)
-#define MCONNID_SHIFT					0
-#define MCONNID_MASK					(0xff << 0)
-
-/* DDR_PHY_CTRL_1 - EMIF4D */
-#define DLL_SLAVE_DLY_CTRL_SHIFT_4D			4
-#define DLL_SLAVE_DLY_CTRL_MASK_4D			(0xFF << 4)
-#define READ_LATENCY_SHIFT_4D				0
-#define READ_LATENCY_MASK_4D				(0xf << 0)
-
-/* DDR_PHY_CTRL_1 - EMIF4D5 */
-#define DLL_HALF_DELAY_SHIFT_4D5			21
-#define DLL_HALF_DELAY_MASK_4D5				(1 << 21)
-#define READ_LATENCY_SHIFT_4D5				0
-#define READ_LATENCY_MASK_4D5				(0x1f << 0)
-
-/* DDR_PHY_CTRL_1_SHDW */
-#define DDR_PHY_CTRL_1_SHDW_SHIFT			5
-#define DDR_PHY_CTRL_1_SHDW_MASK			(0x7ffffff << 5)
-#define READ_LATENCY_SHDW_SHIFT				0
-#define READ_LATENCY_SHDW_MASK				(0x1f << 0)
-
-#ifndef __ASSEMBLY__
-/*
- * Structure containing shadow of important registers in EMIF
- * The calculation function fills in this structure to be later used for
- * initialisation and DVFS
- */
-struct emif_regs {
-	u32 freq;
-	u32 ref_ctrl_shdw;
-	u32 ref_ctrl_shdw_derated;
-	u32 sdram_tim1_shdw;
-	u32 sdram_tim1_shdw_derated;
-	u32 sdram_tim2_shdw;
-	u32 sdram_tim3_shdw;
-	u32 sdram_tim3_shdw_derated;
-	u32 pwr_mgmt_ctrl_shdw;
-	union {
-		u32 read_idle_ctrl_shdw_normal;
-		u32 dll_calib_ctrl_shdw_normal;
-	};
-	union {
-		u32 read_idle_ctrl_shdw_volt_ramp;
-		u32 dll_calib_ctrl_shdw_volt_ramp;
-	};
-
-	u32 phy_ctrl_1_shdw;
-	u32 ext_phy_ctrl_2_shdw;
-	u32 ext_phy_ctrl_3_shdw;
-	u32 ext_phy_ctrl_4_shdw;
-};
-#endif /* __ASSEMBLY__ */
-#endif /* __EMIF_H */
diff --git a/include/linux/ti_emif.h b/include/linux/ti_emif.h
new file mode 100644
index 0000000..bfe08ba
--- /dev/null
+++ b/include/linux/ti_emif.h
@@ -0,0 +1,589 @@
+/*
+ * Defines for the EMIF driver
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * Benoit Cousson (b-cousson@ti.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __EMIF_H
+#define __EMIF_H
+
+/*
+ * Maximum number of different frequencies supported by EMIF driver
+ * Determines the number of entries in the pointer array for register
+ * cache
+ */
+#define EMIF_MAX_NUM_FREQUENCIES			6
+
+/* State of the core voltage */
+#define DDR_VOLTAGE_STABLE				0
+#define DDR_VOLTAGE_RAMPING				1
+
+/* Defines for timing De-rating */
+#define EMIF_NORMAL_TIMINGS				0
+#define EMIF_DERATED_TIMINGS				1
+
+/* Length of the forced read idle period in terms of cycles */
+#define EMIF_READ_IDLE_LEN_VAL				5
+
+/*
+ * forced read idle interval to be used when voltage
+ * is changed as part of DVFS/DPS - 1ms
+ */
+#define READ_IDLE_INTERVAL_DVFS				(1*1000000)
+
+/*
+ * Forced read idle interval to be used when voltage is stable
+ * 50us - or maximum value will do
+ */
+#define READ_IDLE_INTERVAL_NORMAL			(50*1000000)
+
+/* DLL calibration interval when voltage is NOT stable - 1us */
+#define DLL_CALIB_INTERVAL_DVFS				(1*1000000)
+
+#define DLL_CALIB_ACK_WAIT_VAL				5
+
+/* Interval between ZQCS commands - hw team recommended value */
+#define EMIF_ZQCS_INTERVAL_US				(50*1000)
+/* Enable ZQ Calibration on exiting Self-refresh */
+#define ZQ_SFEXITEN_ENABLE				1
+/*
+ * ZQ Calibration simultaneously on both chip-selects:
+ * Needs one calibration resistor per CS
+ */
+#define	ZQ_DUALCALEN_DISABLE				0
+#define	ZQ_DUALCALEN_ENABLE				1
+
+#define T_ZQCS_DEFAULT_NS				90
+#define T_ZQCL_DEFAULT_NS				360
+#define T_ZQINIT_DEFAULT_NS				1000
+
+/* DPD_EN */
+#define DPD_DISABLE					0
+#define DPD_ENABLE					1
+
+/*
+ * Default values for the low-power entry to be used if not provided by user.
+ * OMAP4/5 has a hw bug(i735) due to which this value can not be less than 512
+ * Timeout values are in DDR clock 'cycles' and frequency threshold in Hz
+ */
+#define EMIF_LP_MODE_TIMEOUT_PERFORMANCE		2048
+#define EMIF_LP_MODE_TIMEOUT_POWER			512
+#define EMIF_LP_MODE_FREQ_THRESHOLD			400000000
+
+/* DDR_PHY_CTRL_1 values for EMIF4D - ATTILA PHY combination */
+#define EMIF_DDR_PHY_CTRL_1_BASE_VAL_ATTILAPHY		0x049FF000
+#define EMIF_DLL_SLAVE_DLY_CTRL_400_MHZ_ATTILAPHY	0x41
+#define EMIF_DLL_SLAVE_DLY_CTRL_200_MHZ_ATTILAPHY	0x80
+#define EMIF_DLL_SLAVE_DLY_CTRL_100_MHZ_AND_LESS_ATTILAPHY 0xFF
+
+/* DDR_PHY_CTRL_1 values for EMIF4D5 INTELLIPHY combination */
+#define EMIF_DDR_PHY_CTRL_1_BASE_VAL_INTELLIPHY		0x0E084200
+#define EMIF_PHY_TOTAL_READ_LATENCY_INTELLIPHY_PS	10000
+
+/* TEMP_ALERT_CONFIG - corresponding to temp gradient 5 C/s */
+#define TEMP_ALERT_POLL_INTERVAL_DEFAULT_MS		360
+
+#define EMIF_T_CSTA					3
+#define EMIF_T_PDLL_UL					128
+
+/* External PHY control registers magic values */
+#define EMIF_EXT_PHY_CTRL_1_VAL				0x04020080
+#define EMIF_EXT_PHY_CTRL_5_VAL				0x04010040
+#define EMIF_EXT_PHY_CTRL_6_VAL				0x01004010
+#define EMIF_EXT_PHY_CTRL_7_VAL				0x00001004
+#define EMIF_EXT_PHY_CTRL_8_VAL				0x04010040
+#define EMIF_EXT_PHY_CTRL_9_VAL				0x01004010
+#define EMIF_EXT_PHY_CTRL_10_VAL			0x00001004
+#define EMIF_EXT_PHY_CTRL_11_VAL			0x00000000
+#define EMIF_EXT_PHY_CTRL_12_VAL			0x00000000
+#define EMIF_EXT_PHY_CTRL_13_VAL			0x00000000
+#define EMIF_EXT_PHY_CTRL_14_VAL			0x80080080
+#define EMIF_EXT_PHY_CTRL_15_VAL			0x00800800
+#define EMIF_EXT_PHY_CTRL_16_VAL			0x08102040
+#define EMIF_EXT_PHY_CTRL_17_VAL			0x00000001
+#define EMIF_EXT_PHY_CTRL_18_VAL			0x540A8150
+#define EMIF_EXT_PHY_CTRL_19_VAL			0xA81502A0
+#define EMIF_EXT_PHY_CTRL_20_VAL			0x002A0540
+#define EMIF_EXT_PHY_CTRL_21_VAL			0x00000000
+#define EMIF_EXT_PHY_CTRL_22_VAL			0x00000000
+#define EMIF_EXT_PHY_CTRL_23_VAL			0x00000000
+#define EMIF_EXT_PHY_CTRL_24_VAL			0x00000077
+
+#define EMIF_INTELLI_PHY_DQS_GATE_OPENING_DELAY_PS	1200
+
+/* Registers offset */
+#define EMIF_MODULE_ID_AND_REVISION			0x0000
+#define EMIF_STATUS					0x0004
+#define EMIF_SDRAM_CONFIG				0x0008
+#define EMIF_SDRAM_CONFIG_2				0x000c
+#define EMIF_SDRAM_REFRESH_CONTROL			0x0010
+#define EMIF_SDRAM_REFRESH_CTRL_SHDW			0x0014
+#define EMIF_SDRAM_TIMING_1				0x0018
+#define EMIF_SDRAM_TIMING_1_SHDW			0x001c
+#define EMIF_SDRAM_TIMING_2				0x0020
+#define EMIF_SDRAM_TIMING_2_SHDW			0x0024
+#define EMIF_SDRAM_TIMING_3				0x0028
+#define EMIF_SDRAM_TIMING_3_SHDW			0x002c
+#define EMIF_LPDDR2_NVM_TIMING				0x0030
+#define EMIF_LPDDR2_NVM_TIMING_SHDW			0x0034
+#define EMIF_POWER_MANAGEMENT_CONTROL			0x0038
+#define EMIF_POWER_MANAGEMENT_CTRL_SHDW			0x003c
+#define EMIF_LPDDR2_MODE_REG_DATA			0x0040
+#define EMIF_LPDDR2_MODE_REG_CONFIG			0x0050
+#define EMIF_OCP_CONFIG					0x0054
+#define EMIF_OCP_CONFIG_VALUE_1				0x0058
+#define EMIF_OCP_CONFIG_VALUE_2				0x005c
+#define EMIF_IODFT_TEST_LOGIC_GLOBAL_CONTROL		0x0060
+#define EMIF_IODFT_TEST_LOGIC_CTRL_MISR_RESULT		0x0064
+#define EMIF_IODFT_TEST_LOGIC_ADDRESS_MISR_RESULT	0x0068
+#define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_1	0x006c
+#define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_2	0x0070
+#define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_3	0x0074
+#define EMIF_PERFORMANCE_COUNTER_1			0x0080
+#define EMIF_PERFORMANCE_COUNTER_2			0x0084
+#define EMIF_PERFORMANCE_COUNTER_CONFIG			0x0088
+#define EMIF_PERFORMANCE_COUNTER_MASTER_REGION_SELECT	0x008c
+#define EMIF_PERFORMANCE_COUNTER_TIME			0x0090
+#define EMIF_MISC_REG					0x0094
+#define EMIF_DLL_CALIB_CTRL				0x0098
+#define EMIF_DLL_CALIB_CTRL_SHDW			0x009c
+#define EMIF_END_OF_INTERRUPT				0x00a0
+#define EMIF_SYSTEM_OCP_INTERRUPT_RAW_STATUS		0x00a4
+#define EMIF_LL_OCP_INTERRUPT_RAW_STATUS		0x00a8
+#define EMIF_SYSTEM_OCP_INTERRUPT_STATUS		0x00ac
+#define EMIF_LL_OCP_INTERRUPT_STATUS			0x00b0
+#define EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_SET		0x00b4
+#define EMIF_LL_OCP_INTERRUPT_ENABLE_SET		0x00b8
+#define EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_CLEAR		0x00bc
+#define EMIF_LL_OCP_INTERRUPT_ENABLE_CLEAR		0x00c0
+#define EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG	0x00c8
+#define EMIF_TEMPERATURE_ALERT_CONFIG			0x00cc
+#define EMIF_OCP_ERROR_LOG				0x00d0
+#define EMIF_READ_WRITE_LEVELING_RAMP_WINDOW		0x00d4
+#define EMIF_READ_WRITE_LEVELING_RAMP_CONTROL		0x00d8
+#define EMIF_READ_WRITE_LEVELING_CONTROL		0x00dc
+#define EMIF_DDR_PHY_CTRL_1				0x00e4
+#define EMIF_DDR_PHY_CTRL_1_SHDW			0x00e8
+#define EMIF_DDR_PHY_CTRL_2				0x00ec
+#define EMIF_PRIORITY_TO_CLASS_OF_SERVICE_MAPPING	0x0100
+#define EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_1_MAPPING 0x0104
+#define EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_2_MAPPING 0x0108
+#define EMIF_READ_WRITE_EXECUTION_THRESHOLD		0x0120
+#define EMIF_COS_CONFIG					0x0124
+#define EMIF_PHY_STATUS_1				0x0140
+#define EMIF_PHY_STATUS_2				0x0144
+#define EMIF_PHY_STATUS_3				0x0148
+#define EMIF_PHY_STATUS_4				0x014c
+#define EMIF_PHY_STATUS_5				0x0150
+#define EMIF_PHY_STATUS_6				0x0154
+#define EMIF_PHY_STATUS_7				0x0158
+#define EMIF_PHY_STATUS_8				0x015c
+#define EMIF_PHY_STATUS_9				0x0160
+#define EMIF_PHY_STATUS_10				0x0164
+#define EMIF_PHY_STATUS_11				0x0168
+#define EMIF_PHY_STATUS_12				0x016c
+#define EMIF_PHY_STATUS_13				0x0170
+#define EMIF_PHY_STATUS_14				0x0174
+#define EMIF_PHY_STATUS_15				0x0178
+#define EMIF_PHY_STATUS_16				0x017c
+#define EMIF_PHY_STATUS_17				0x0180
+#define EMIF_PHY_STATUS_18				0x0184
+#define EMIF_PHY_STATUS_19				0x0188
+#define EMIF_PHY_STATUS_20				0x018c
+#define EMIF_PHY_STATUS_21				0x0190
+#define EMIF_EXT_PHY_CTRL_1				0x0200
+#define EMIF_EXT_PHY_CTRL_1_SHDW			0x0204
+#define EMIF_EXT_PHY_CTRL_2				0x0208
+#define EMIF_EXT_PHY_CTRL_2_SHDW			0x020c
+#define EMIF_EXT_PHY_CTRL_3				0x0210
+#define EMIF_EXT_PHY_CTRL_3_SHDW			0x0214
+#define EMIF_EXT_PHY_CTRL_4				0x0218
+#define EMIF_EXT_PHY_CTRL_4_SHDW			0x021c
+#define EMIF_EXT_PHY_CTRL_5				0x0220
+#define EMIF_EXT_PHY_CTRL_5_SHDW			0x0224
+#define EMIF_EXT_PHY_CTRL_6				0x0228
+#define EMIF_EXT_PHY_CTRL_6_SHDW			0x022c
+#define EMIF_EXT_PHY_CTRL_7				0x0230
+#define EMIF_EXT_PHY_CTRL_7_SHDW			0x0234
+#define EMIF_EXT_PHY_CTRL_8				0x0238
+#define EMIF_EXT_PHY_CTRL_8_SHDW			0x023c
+#define EMIF_EXT_PHY_CTRL_9				0x0240
+#define EMIF_EXT_PHY_CTRL_9_SHDW			0x0244
+#define EMIF_EXT_PHY_CTRL_10				0x0248
+#define EMIF_EXT_PHY_CTRL_10_SHDW			0x024c
+#define EMIF_EXT_PHY_CTRL_11				0x0250
+#define EMIF_EXT_PHY_CTRL_11_SHDW			0x0254
+#define EMIF_EXT_PHY_CTRL_12				0x0258
+#define EMIF_EXT_PHY_CTRL_12_SHDW			0x025c
+#define EMIF_EXT_PHY_CTRL_13				0x0260
+#define EMIF_EXT_PHY_CTRL_13_SHDW			0x0264
+#define EMIF_EXT_PHY_CTRL_14				0x0268
+#define EMIF_EXT_PHY_CTRL_14_SHDW			0x026c
+#define EMIF_EXT_PHY_CTRL_15				0x0270
+#define EMIF_EXT_PHY_CTRL_15_SHDW			0x0274
+#define EMIF_EXT_PHY_CTRL_16				0x0278
+#define EMIF_EXT_PHY_CTRL_16_SHDW			0x027c
+#define EMIF_EXT_PHY_CTRL_17				0x0280
+#define EMIF_EXT_PHY_CTRL_17_SHDW			0x0284
+#define EMIF_EXT_PHY_CTRL_18				0x0288
+#define EMIF_EXT_PHY_CTRL_18_SHDW			0x028c
+#define EMIF_EXT_PHY_CTRL_19				0x0290
+#define EMIF_EXT_PHY_CTRL_19_SHDW			0x0294
+#define EMIF_EXT_PHY_CTRL_20				0x0298
+#define EMIF_EXT_PHY_CTRL_20_SHDW			0x029c
+#define EMIF_EXT_PHY_CTRL_21				0x02a0
+#define EMIF_EXT_PHY_CTRL_21_SHDW			0x02a4
+#define EMIF_EXT_PHY_CTRL_22				0x02a8
+#define EMIF_EXT_PHY_CTRL_22_SHDW			0x02ac
+#define EMIF_EXT_PHY_CTRL_23				0x02b0
+#define EMIF_EXT_PHY_CTRL_23_SHDW			0x02b4
+#define EMIF_EXT_PHY_CTRL_24				0x02b8
+#define EMIF_EXT_PHY_CTRL_24_SHDW			0x02bc
+#define EMIF_EXT_PHY_CTRL_25				0x02c0
+#define EMIF_EXT_PHY_CTRL_25_SHDW			0x02c4
+#define EMIF_EXT_PHY_CTRL_26				0x02c8
+#define EMIF_EXT_PHY_CTRL_26_SHDW			0x02cc
+#define EMIF_EXT_PHY_CTRL_27				0x02d0
+#define EMIF_EXT_PHY_CTRL_27_SHDW			0x02d4
+#define EMIF_EXT_PHY_CTRL_28				0x02d8
+#define EMIF_EXT_PHY_CTRL_28_SHDW			0x02dc
+#define EMIF_EXT_PHY_CTRL_29				0x02e0
+#define EMIF_EXT_PHY_CTRL_29_SHDW			0x02e4
+#define EMIF_EXT_PHY_CTRL_30				0x02e8
+#define EMIF_EXT_PHY_CTRL_30_SHDW			0x02ec
+
+/* Registers shifts and masks */
+
+/* EMIF_MODULE_ID_AND_REVISION */
+#define SCHEME_SHIFT					30
+#define SCHEME_MASK					(0x3 << 30)
+#define MODULE_ID_SHIFT					16
+#define MODULE_ID_MASK					(0xfff << 16)
+#define RTL_VERSION_SHIFT				11
+#define RTL_VERSION_MASK				(0x1f << 11)
+#define MAJOR_REVISION_SHIFT				8
+#define MAJOR_REVISION_MASK				(0x7 << 8)
+#define MINOR_REVISION_SHIFT				0
+#define MINOR_REVISION_MASK				(0x3f << 0)
+
+/* STATUS */
+#define BE_SHIFT					31
+#define BE_MASK						(1 << 31)
+#define DUAL_CLK_MODE_SHIFT				30
+#define DUAL_CLK_MODE_MASK				(1 << 30)
+#define FAST_INIT_SHIFT					29
+#define FAST_INIT_MASK					(1 << 29)
+#define RDLVLGATETO_SHIFT				6
+#define RDLVLGATETO_MASK				(1 << 6)
+#define RDLVLTO_SHIFT					5
+#define RDLVLTO_MASK					(1 << 5)
+#define WRLVLTO_SHIFT					4
+#define WRLVLTO_MASK					(1 << 4)
+#define PHY_DLL_READY_SHIFT				2
+#define PHY_DLL_READY_MASK				(1 << 2)
+
+/* SDRAM_CONFIG */
+#define SDRAM_TYPE_SHIFT				29
+#define SDRAM_TYPE_MASK					(0x7 << 29)
+#define IBANK_POS_SHIFT					27
+#define IBANK_POS_MASK					(0x3 << 27)
+#define DDR_TERM_SHIFT					24
+#define DDR_TERM_MASK					(0x7 << 24)
+#define DDR2_DDQS_SHIFT					23
+#define DDR2_DDQS_MASK					(1 << 23)
+#define DYN_ODT_SHIFT					21
+#define DYN_ODT_MASK					(0x3 << 21)
+#define DDR_DISABLE_DLL_SHIFT				20
+#define DDR_DISABLE_DLL_MASK				(1 << 20)
+#define SDRAM_DRIVE_SHIFT				18
+#define SDRAM_DRIVE_MASK				(0x3 << 18)
+#define CWL_SHIFT					16
+#define CWL_MASK					(0x3 << 16)
+#define NARROW_MODE_SHIFT				14
+#define NARROW_MODE_MASK				(0x3 << 14)
+#define CL_SHIFT					10
+#define CL_MASK						(0xf << 10)
+#define ROWSIZE_SHIFT					7
+#define ROWSIZE_MASK					(0x7 << 7)
+#define IBANK_SHIFT					4
+#define IBANK_MASK					(0x7 << 4)
+#define EBANK_SHIFT					3
+#define EBANK_MASK					(1 << 3)
+#define PAGESIZE_SHIFT					0
+#define PAGESIZE_MASK					(0x7 << 0)
+
+/* SDRAM_CONFIG_2 */
+#define CS1NVMEN_SHIFT					30
+#define CS1NVMEN_MASK					(1 << 30)
+#define EBANK_POS_SHIFT					27
+#define EBANK_POS_MASK					(1 << 27)
+#define RDBNUM_SHIFT					4
+#define RDBNUM_MASK					(0x3 << 4)
+#define RDBSIZE_SHIFT					0
+#define RDBSIZE_MASK					(0x7 << 0)
+
+/* SDRAM_REFRESH_CONTROL */
+#define INITREF_DIS_SHIFT				31
+#define INITREF_DIS_MASK				(1 << 31)
+#define SRT_SHIFT					29
+#define SRT_MASK					(1 << 29)
+#define ASR_SHIFT					28
+#define ASR_MASK					(1 << 28)
+#define PASR_SHIFT					24
+#define PASR_MASK					(0x7 << 24)
+#define REFRESH_RATE_SHIFT				0
+#define REFRESH_RATE_MASK				(0xffff << 0)
+
+/* SDRAM_TIMING_1 */
+#define T_RTW_SHIFT					29
+#define T_RTW_MASK					(0x7 << 29)
+#define T_RP_SHIFT					25
+#define T_RP_MASK					(0xf << 25)
+#define T_RCD_SHIFT					21
+#define T_RCD_MASK					(0xf << 21)
+#define T_WR_SHIFT					17
+#define T_WR_MASK					(0xf << 17)
+#define T_RAS_SHIFT					12
+#define T_RAS_MASK					(0x1f << 12)
+#define T_RC_SHIFT					6
+#define T_RC_MASK					(0x3f << 6)
+#define T_RRD_SHIFT					3
+#define T_RRD_MASK					(0x7 << 3)
+#define T_WTR_SHIFT					0
+#define T_WTR_MASK					(0x7 << 0)
+
+/* SDRAM_TIMING_2 */
+#define T_XP_SHIFT					28
+#define T_XP_MASK					(0x7 << 28)
+#define T_ODT_SHIFT					25
+#define T_ODT_MASK					(0x7 << 25)
+#define T_XSNR_SHIFT					16
+#define T_XSNR_MASK					(0x1ff << 16)
+#define T_XSRD_SHIFT					6
+#define T_XSRD_MASK					(0x3ff << 6)
+#define T_RTP_SHIFT					3
+#define T_RTP_MASK					(0x7 << 3)
+#define T_CKE_SHIFT					0
+#define T_CKE_MASK					(0x7 << 0)
+
+/* SDRAM_TIMING_3 */
+#define T_PDLL_UL_SHIFT					28
+#define T_PDLL_UL_MASK					(0xf << 28)
+#define T_CSTA_SHIFT					24
+#define T_CSTA_MASK					(0xf << 24)
+#define T_CKESR_SHIFT					21
+#define T_CKESR_MASK					(0x7 << 21)
+#define ZQ_ZQCS_SHIFT					15
+#define ZQ_ZQCS_MASK					(0x3f << 15)
+#define T_TDQSCKMAX_SHIFT				13
+#define T_TDQSCKMAX_MASK				(0x3 << 13)
+#define T_RFC_SHIFT					4
+#define T_RFC_MASK					(0x1ff << 4)
+#define T_RAS_MAX_SHIFT					0
+#define T_RAS_MAX_MASK					(0xf << 0)
+
+/* POWER_MANAGEMENT_CONTROL */
+#define PD_TIM_SHIFT					12
+#define PD_TIM_MASK					(0xf << 12)
+#define DPD_EN_SHIFT					11
+#define DPD_EN_MASK					(1 << 11)
+#define LP_MODE_SHIFT					8
+#define LP_MODE_MASK					(0x7 << 8)
+#define SR_TIM_SHIFT					4
+#define SR_TIM_MASK					(0xf << 4)
+#define CS_TIM_SHIFT					0
+#define CS_TIM_MASK					(0xf << 0)
+
+/* LPDDR2_MODE_REG_DATA */
+#define VALUE_0_SHIFT					0
+#define VALUE_0_MASK					(0x7f << 0)
+
+/* LPDDR2_MODE_REG_CONFIG */
+#define CS_SHIFT					31
+#define CS_MASK						(1 << 31)
+#define REFRESH_EN_SHIFT				30
+#define REFRESH_EN_MASK					(1 << 30)
+#define ADDRESS_SHIFT					0
+#define ADDRESS_MASK					(0xff << 0)
+
+/* OCP_CONFIG */
+#define SYS_THRESH_MAX_SHIFT				24
+#define SYS_THRESH_MAX_MASK				(0xf << 24)
+#define MPU_THRESH_MAX_SHIFT				20
+#define MPU_THRESH_MAX_MASK				(0xf << 20)
+#define LL_THRESH_MAX_SHIFT				16
+#define LL_THRESH_MAX_MASK				(0xf << 16)
+
+/* PERFORMANCE_COUNTER_1 */
+#define COUNTER1_SHIFT					0
+#define COUNTER1_MASK					(0xffffffff << 0)
+
+/* PERFORMANCE_COUNTER_2 */
+#define COUNTER2_SHIFT					0
+#define COUNTER2_MASK					(0xffffffff << 0)
+
+/* PERFORMANCE_COUNTER_CONFIG */
+#define CNTR2_MCONNID_EN_SHIFT				31
+#define CNTR2_MCONNID_EN_MASK				(1 << 31)
+#define CNTR2_REGION_EN_SHIFT				30
+#define CNTR2_REGION_EN_MASK				(1 << 30)
+#define CNTR2_CFG_SHIFT					16
+#define CNTR2_CFG_MASK					(0xf << 16)
+#define CNTR1_MCONNID_EN_SHIFT				15
+#define CNTR1_MCONNID_EN_MASK				(1 << 15)
+#define CNTR1_REGION_EN_SHIFT				14
+#define CNTR1_REGION_EN_MASK				(1 << 14)
+#define CNTR1_CFG_SHIFT					0
+#define CNTR1_CFG_MASK					(0xf << 0)
+
+/* PERFORMANCE_COUNTER_MASTER_REGION_SELECT */
+#define MCONNID2_SHIFT					24
+#define MCONNID2_MASK					(0xff << 24)
+#define REGION_SEL2_SHIFT				16
+#define REGION_SEL2_MASK				(0x3 << 16)
+#define MCONNID1_SHIFT					8
+#define MCONNID1_MASK					(0xff << 8)
+#define REGION_SEL1_SHIFT				0
+#define REGION_SEL1_MASK				(0x3 << 0)
+
+/* PERFORMANCE_COUNTER_TIME */
+#define TOTAL_TIME_SHIFT				0
+#define TOTAL_TIME_MASK					(0xffffffff << 0)
+
+/* DLL_CALIB_CTRL */
+#define ACK_WAIT_SHIFT					16
+#define ACK_WAIT_MASK					(0xf << 16)
+#define DLL_CALIB_INTERVAL_SHIFT			0
+#define DLL_CALIB_INTERVAL_MASK				(0x1ff << 0)
+
+/* END_OF_INTERRUPT */
+#define EOI_SHIFT					0
+#define EOI_MASK					(1 << 0)
+
+/* SYSTEM_OCP_INTERRUPT_RAW_STATUS */
+#define DNV_SYS_SHIFT					2
+#define DNV_SYS_MASK					(1 << 2)
+#define TA_SYS_SHIFT					1
+#define TA_SYS_MASK					(1 << 1)
+#define ERR_SYS_SHIFT					0
+#define ERR_SYS_MASK					(1 << 0)
+
+/* LOW_LATENCY_OCP_INTERRUPT_RAW_STATUS */
+#define DNV_LL_SHIFT					2
+#define DNV_LL_MASK					(1 << 2)
+#define TA_LL_SHIFT					1
+#define TA_LL_MASK					(1 << 1)
+#define ERR_LL_SHIFT					0
+#define ERR_LL_MASK					(1 << 0)
+
+/* SYSTEM_OCP_INTERRUPT_ENABLE_SET */
+#define EN_DNV_SYS_SHIFT				2
+#define EN_DNV_SYS_MASK					(1 << 2)
+#define EN_TA_SYS_SHIFT					1
+#define EN_TA_SYS_MASK					(1 << 1)
+#define EN_ERR_SYS_SHIFT					0
+#define EN_ERR_SYS_MASK					(1 << 0)
+
+/* LOW_LATENCY_OCP_INTERRUPT_ENABLE_SET */
+#define EN_DNV_LL_SHIFT					2
+#define EN_DNV_LL_MASK					(1 << 2)
+#define EN_TA_LL_SHIFT					1
+#define EN_TA_LL_MASK					(1 << 1)
+#define EN_ERR_LL_SHIFT					0
+#define EN_ERR_LL_MASK					(1 << 0)
+
+/* SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG */
+#define ZQ_CS1EN_SHIFT					31
+#define ZQ_CS1EN_MASK					(1 << 31)
+#define ZQ_CS0EN_SHIFT					30
+#define ZQ_CS0EN_MASK					(1 << 30)
+#define ZQ_DUALCALEN_SHIFT				29
+#define ZQ_DUALCALEN_MASK				(1 << 29)
+#define ZQ_SFEXITEN_SHIFT				28
+#define ZQ_SFEXITEN_MASK				(1 << 28)
+#define ZQ_ZQINIT_MULT_SHIFT				18
+#define ZQ_ZQINIT_MULT_MASK				(0x3 << 18)
+#define ZQ_ZQCL_MULT_SHIFT				16
+#define ZQ_ZQCL_MULT_MASK				(0x3 << 16)
+#define ZQ_REFINTERVAL_SHIFT				0
+#define ZQ_REFINTERVAL_MASK				(0xffff << 0)
+
+/* TEMPERATURE_ALERT_CONFIG */
+#define TA_CS1EN_SHIFT					31
+#define TA_CS1EN_MASK					(1 << 31)
+#define TA_CS0EN_SHIFT					30
+#define TA_CS0EN_MASK					(1 << 30)
+#define TA_SFEXITEN_SHIFT				28
+#define TA_SFEXITEN_MASK				(1 << 28)
+#define TA_DEVWDT_SHIFT					26
+#define TA_DEVWDT_MASK					(0x3 << 26)
+#define TA_DEVCNT_SHIFT					24
+#define TA_DEVCNT_MASK					(0x3 << 24)
+#define TA_REFINTERVAL_SHIFT				0
+#define TA_REFINTERVAL_MASK				(0x3fffff << 0)
+
+/* OCP_ERROR_LOG */
+#define MADDRSPACE_SHIFT				14
+#define MADDRSPACE_MASK					(0x3 << 14)
+#define MBURSTSEQ_SHIFT					11
+#define MBURSTSEQ_MASK					(0x7 << 11)
+#define MCMD_SHIFT					8
+#define MCMD_MASK					(0x7 << 8)
+#define MCONNID_SHIFT					0
+#define MCONNID_MASK					(0xff << 0)
+
+/* DDR_PHY_CTRL_1 - EMIF4D */
+#define DLL_SLAVE_DLY_CTRL_SHIFT_4D			4
+#define DLL_SLAVE_DLY_CTRL_MASK_4D			(0xFF << 4)
+#define READ_LATENCY_SHIFT_4D				0
+#define READ_LATENCY_MASK_4D				(0xf << 0)
+
+/* DDR_PHY_CTRL_1 - EMIF4D5 */
+#define DLL_HALF_DELAY_SHIFT_4D5			21
+#define DLL_HALF_DELAY_MASK_4D5				(1 << 21)
+#define READ_LATENCY_SHIFT_4D5				0
+#define READ_LATENCY_MASK_4D5				(0x1f << 0)
+
+/* DDR_PHY_CTRL_1_SHDW */
+#define DDR_PHY_CTRL_1_SHDW_SHIFT			5
+#define DDR_PHY_CTRL_1_SHDW_MASK			(0x7ffffff << 5)
+#define READ_LATENCY_SHDW_SHIFT				0
+#define READ_LATENCY_SHDW_MASK				(0x1f << 0)
+
+#ifndef __ASSEMBLY__
+/*
+ * Structure containing shadow of important registers in EMIF
+ * The calculation function fills in this structure to be later used for
+ * initialisation and DVFS
+ */
+struct emif_regs {
+	u32 freq;
+	u32 ref_ctrl_shdw;
+	u32 ref_ctrl_shdw_derated;
+	u32 sdram_tim1_shdw;
+	u32 sdram_tim1_shdw_derated;
+	u32 sdram_tim2_shdw;
+	u32 sdram_tim3_shdw;
+	u32 sdram_tim3_shdw_derated;
+	u32 pwr_mgmt_ctrl_shdw;
+	union {
+		u32 read_idle_ctrl_shdw_normal;
+		u32 dll_calib_ctrl_shdw_normal;
+	};
+	union {
+		u32 read_idle_ctrl_shdw_volt_ramp;
+		u32 dll_calib_ctrl_shdw_volt_ramp;
+	};
+
+	u32 phy_ctrl_1_shdw;
+	u32 ext_phy_ctrl_2_shdw;
+	u32 ext_phy_ctrl_3_shdw;
+	u32 ext_phy_ctrl_4_shdw;
+};
+#endif /* __ASSEMBLY__ */
+#endif /* __EMIF_H */
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 03/18] memory: emif: Move EMIF related header file to include/linux/
@ 2012-12-31 13:06   ` Vaibhav Bedia
  0 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:06 UTC (permalink / raw)
  To: linux-arm-kernel

OMAP4 and AM33XX share the same EMIF controller IP. Although there
are significant differences in the IP integration due to which
AM33XX can't reuse the EMIF driver DVFS similar to OMAP4,
it can definitely benefit by reusing the EMIF related macros
defined in drivers/memory/emif.h.

In the current OMAP PM framework the PM code resides under
arch/arm/mach-omap2/. To enable reuse of the register defines move
the emif header file to include/linux so that both the EMIF driver
and the AM33XX PM code can benefit.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Aneesh V <aneesh@ti.com>
---
v1->v2:
	This is a new patch in the series to enable code reuse
	between the EMIF driver and AM33XX PM code

 drivers/memory/emif.c   |    2 +-
 drivers/memory/emif.h   |  589 -----------------------------------------------
 include/linux/ti_emif.h |  589 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 590 insertions(+), 590 deletions(-)
 delete mode 100644 drivers/memory/emif.h
 create mode 100644 include/linux/ti_emif.h

diff --git a/drivers/memory/emif.c b/drivers/memory/emif.c
index 06d31c9..a3d893d 100644
--- a/drivers/memory/emif.c
+++ b/drivers/memory/emif.c
@@ -24,8 +24,8 @@
 #include <linux/module.h>
 #include <linux/list.h>
 #include <linux/spinlock.h>
+#include <linux/ti_emif.h>
 #include <memory/jedec_ddr.h>
-#include "emif.h"
 #include "of_memory.h"
 
 /**
diff --git a/drivers/memory/emif.h b/drivers/memory/emif.h
deleted file mode 100644
index bfe08ba..0000000
--- a/drivers/memory/emif.h
+++ /dev/null
@@ -1,589 +0,0 @@
-/*
- * Defines for the EMIF driver
- *
- * Copyright (C) 2012 Texas Instruments, Inc.
- *
- * Benoit Cousson (b-cousson at ti.com)
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __EMIF_H
-#define __EMIF_H
-
-/*
- * Maximum number of different frequencies supported by EMIF driver
- * Determines the number of entries in the pointer array for register
- * cache
- */
-#define EMIF_MAX_NUM_FREQUENCIES			6
-
-/* State of the core voltage */
-#define DDR_VOLTAGE_STABLE				0
-#define DDR_VOLTAGE_RAMPING				1
-
-/* Defines for timing De-rating */
-#define EMIF_NORMAL_TIMINGS				0
-#define EMIF_DERATED_TIMINGS				1
-
-/* Length of the forced read idle period in terms of cycles */
-#define EMIF_READ_IDLE_LEN_VAL				5
-
-/*
- * forced read idle interval to be used when voltage
- * is changed as part of DVFS/DPS - 1ms
- */
-#define READ_IDLE_INTERVAL_DVFS				(1*1000000)
-
-/*
- * Forced read idle interval to be used when voltage is stable
- * 50us - or maximum value will do
- */
-#define READ_IDLE_INTERVAL_NORMAL			(50*1000000)
-
-/* DLL calibration interval when voltage is NOT stable - 1us */
-#define DLL_CALIB_INTERVAL_DVFS				(1*1000000)
-
-#define DLL_CALIB_ACK_WAIT_VAL				5
-
-/* Interval between ZQCS commands - hw team recommended value */
-#define EMIF_ZQCS_INTERVAL_US				(50*1000)
-/* Enable ZQ Calibration on exiting Self-refresh */
-#define ZQ_SFEXITEN_ENABLE				1
-/*
- * ZQ Calibration simultaneously on both chip-selects:
- * Needs one calibration resistor per CS
- */
-#define	ZQ_DUALCALEN_DISABLE				0
-#define	ZQ_DUALCALEN_ENABLE				1
-
-#define T_ZQCS_DEFAULT_NS				90
-#define T_ZQCL_DEFAULT_NS				360
-#define T_ZQINIT_DEFAULT_NS				1000
-
-/* DPD_EN */
-#define DPD_DISABLE					0
-#define DPD_ENABLE					1
-
-/*
- * Default values for the low-power entry to be used if not provided by user.
- * OMAP4/5 has a hw bug(i735) due to which this value can not be less than 512
- * Timeout values are in DDR clock 'cycles' and frequency threshold in Hz
- */
-#define EMIF_LP_MODE_TIMEOUT_PERFORMANCE		2048
-#define EMIF_LP_MODE_TIMEOUT_POWER			512
-#define EMIF_LP_MODE_FREQ_THRESHOLD			400000000
-
-/* DDR_PHY_CTRL_1 values for EMIF4D - ATTILA PHY combination */
-#define EMIF_DDR_PHY_CTRL_1_BASE_VAL_ATTILAPHY		0x049FF000
-#define EMIF_DLL_SLAVE_DLY_CTRL_400_MHZ_ATTILAPHY	0x41
-#define EMIF_DLL_SLAVE_DLY_CTRL_200_MHZ_ATTILAPHY	0x80
-#define EMIF_DLL_SLAVE_DLY_CTRL_100_MHZ_AND_LESS_ATTILAPHY 0xFF
-
-/* DDR_PHY_CTRL_1 values for EMIF4D5 INTELLIPHY combination */
-#define EMIF_DDR_PHY_CTRL_1_BASE_VAL_INTELLIPHY		0x0E084200
-#define EMIF_PHY_TOTAL_READ_LATENCY_INTELLIPHY_PS	10000
-
-/* TEMP_ALERT_CONFIG - corresponding to temp gradient 5 C/s */
-#define TEMP_ALERT_POLL_INTERVAL_DEFAULT_MS		360
-
-#define EMIF_T_CSTA					3
-#define EMIF_T_PDLL_UL					128
-
-/* External PHY control registers magic values */
-#define EMIF_EXT_PHY_CTRL_1_VAL				0x04020080
-#define EMIF_EXT_PHY_CTRL_5_VAL				0x04010040
-#define EMIF_EXT_PHY_CTRL_6_VAL				0x01004010
-#define EMIF_EXT_PHY_CTRL_7_VAL				0x00001004
-#define EMIF_EXT_PHY_CTRL_8_VAL				0x04010040
-#define EMIF_EXT_PHY_CTRL_9_VAL				0x01004010
-#define EMIF_EXT_PHY_CTRL_10_VAL			0x00001004
-#define EMIF_EXT_PHY_CTRL_11_VAL			0x00000000
-#define EMIF_EXT_PHY_CTRL_12_VAL			0x00000000
-#define EMIF_EXT_PHY_CTRL_13_VAL			0x00000000
-#define EMIF_EXT_PHY_CTRL_14_VAL			0x80080080
-#define EMIF_EXT_PHY_CTRL_15_VAL			0x00800800
-#define EMIF_EXT_PHY_CTRL_16_VAL			0x08102040
-#define EMIF_EXT_PHY_CTRL_17_VAL			0x00000001
-#define EMIF_EXT_PHY_CTRL_18_VAL			0x540A8150
-#define EMIF_EXT_PHY_CTRL_19_VAL			0xA81502A0
-#define EMIF_EXT_PHY_CTRL_20_VAL			0x002A0540
-#define EMIF_EXT_PHY_CTRL_21_VAL			0x00000000
-#define EMIF_EXT_PHY_CTRL_22_VAL			0x00000000
-#define EMIF_EXT_PHY_CTRL_23_VAL			0x00000000
-#define EMIF_EXT_PHY_CTRL_24_VAL			0x00000077
-
-#define EMIF_INTELLI_PHY_DQS_GATE_OPENING_DELAY_PS	1200
-
-/* Registers offset */
-#define EMIF_MODULE_ID_AND_REVISION			0x0000
-#define EMIF_STATUS					0x0004
-#define EMIF_SDRAM_CONFIG				0x0008
-#define EMIF_SDRAM_CONFIG_2				0x000c
-#define EMIF_SDRAM_REFRESH_CONTROL			0x0010
-#define EMIF_SDRAM_REFRESH_CTRL_SHDW			0x0014
-#define EMIF_SDRAM_TIMING_1				0x0018
-#define EMIF_SDRAM_TIMING_1_SHDW			0x001c
-#define EMIF_SDRAM_TIMING_2				0x0020
-#define EMIF_SDRAM_TIMING_2_SHDW			0x0024
-#define EMIF_SDRAM_TIMING_3				0x0028
-#define EMIF_SDRAM_TIMING_3_SHDW			0x002c
-#define EMIF_LPDDR2_NVM_TIMING				0x0030
-#define EMIF_LPDDR2_NVM_TIMING_SHDW			0x0034
-#define EMIF_POWER_MANAGEMENT_CONTROL			0x0038
-#define EMIF_POWER_MANAGEMENT_CTRL_SHDW			0x003c
-#define EMIF_LPDDR2_MODE_REG_DATA			0x0040
-#define EMIF_LPDDR2_MODE_REG_CONFIG			0x0050
-#define EMIF_OCP_CONFIG					0x0054
-#define EMIF_OCP_CONFIG_VALUE_1				0x0058
-#define EMIF_OCP_CONFIG_VALUE_2				0x005c
-#define EMIF_IODFT_TEST_LOGIC_GLOBAL_CONTROL		0x0060
-#define EMIF_IODFT_TEST_LOGIC_CTRL_MISR_RESULT		0x0064
-#define EMIF_IODFT_TEST_LOGIC_ADDRESS_MISR_RESULT	0x0068
-#define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_1	0x006c
-#define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_2	0x0070
-#define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_3	0x0074
-#define EMIF_PERFORMANCE_COUNTER_1			0x0080
-#define EMIF_PERFORMANCE_COUNTER_2			0x0084
-#define EMIF_PERFORMANCE_COUNTER_CONFIG			0x0088
-#define EMIF_PERFORMANCE_COUNTER_MASTER_REGION_SELECT	0x008c
-#define EMIF_PERFORMANCE_COUNTER_TIME			0x0090
-#define EMIF_MISC_REG					0x0094
-#define EMIF_DLL_CALIB_CTRL				0x0098
-#define EMIF_DLL_CALIB_CTRL_SHDW			0x009c
-#define EMIF_END_OF_INTERRUPT				0x00a0
-#define EMIF_SYSTEM_OCP_INTERRUPT_RAW_STATUS		0x00a4
-#define EMIF_LL_OCP_INTERRUPT_RAW_STATUS		0x00a8
-#define EMIF_SYSTEM_OCP_INTERRUPT_STATUS		0x00ac
-#define EMIF_LL_OCP_INTERRUPT_STATUS			0x00b0
-#define EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_SET		0x00b4
-#define EMIF_LL_OCP_INTERRUPT_ENABLE_SET		0x00b8
-#define EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_CLEAR		0x00bc
-#define EMIF_LL_OCP_INTERRUPT_ENABLE_CLEAR		0x00c0
-#define EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG	0x00c8
-#define EMIF_TEMPERATURE_ALERT_CONFIG			0x00cc
-#define EMIF_OCP_ERROR_LOG				0x00d0
-#define EMIF_READ_WRITE_LEVELING_RAMP_WINDOW		0x00d4
-#define EMIF_READ_WRITE_LEVELING_RAMP_CONTROL		0x00d8
-#define EMIF_READ_WRITE_LEVELING_CONTROL		0x00dc
-#define EMIF_DDR_PHY_CTRL_1				0x00e4
-#define EMIF_DDR_PHY_CTRL_1_SHDW			0x00e8
-#define EMIF_DDR_PHY_CTRL_2				0x00ec
-#define EMIF_PRIORITY_TO_CLASS_OF_SERVICE_MAPPING	0x0100
-#define EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_1_MAPPING 0x0104
-#define EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_2_MAPPING 0x0108
-#define EMIF_READ_WRITE_EXECUTION_THRESHOLD		0x0120
-#define EMIF_COS_CONFIG					0x0124
-#define EMIF_PHY_STATUS_1				0x0140
-#define EMIF_PHY_STATUS_2				0x0144
-#define EMIF_PHY_STATUS_3				0x0148
-#define EMIF_PHY_STATUS_4				0x014c
-#define EMIF_PHY_STATUS_5				0x0150
-#define EMIF_PHY_STATUS_6				0x0154
-#define EMIF_PHY_STATUS_7				0x0158
-#define EMIF_PHY_STATUS_8				0x015c
-#define EMIF_PHY_STATUS_9				0x0160
-#define EMIF_PHY_STATUS_10				0x0164
-#define EMIF_PHY_STATUS_11				0x0168
-#define EMIF_PHY_STATUS_12				0x016c
-#define EMIF_PHY_STATUS_13				0x0170
-#define EMIF_PHY_STATUS_14				0x0174
-#define EMIF_PHY_STATUS_15				0x0178
-#define EMIF_PHY_STATUS_16				0x017c
-#define EMIF_PHY_STATUS_17				0x0180
-#define EMIF_PHY_STATUS_18				0x0184
-#define EMIF_PHY_STATUS_19				0x0188
-#define EMIF_PHY_STATUS_20				0x018c
-#define EMIF_PHY_STATUS_21				0x0190
-#define EMIF_EXT_PHY_CTRL_1				0x0200
-#define EMIF_EXT_PHY_CTRL_1_SHDW			0x0204
-#define EMIF_EXT_PHY_CTRL_2				0x0208
-#define EMIF_EXT_PHY_CTRL_2_SHDW			0x020c
-#define EMIF_EXT_PHY_CTRL_3				0x0210
-#define EMIF_EXT_PHY_CTRL_3_SHDW			0x0214
-#define EMIF_EXT_PHY_CTRL_4				0x0218
-#define EMIF_EXT_PHY_CTRL_4_SHDW			0x021c
-#define EMIF_EXT_PHY_CTRL_5				0x0220
-#define EMIF_EXT_PHY_CTRL_5_SHDW			0x0224
-#define EMIF_EXT_PHY_CTRL_6				0x0228
-#define EMIF_EXT_PHY_CTRL_6_SHDW			0x022c
-#define EMIF_EXT_PHY_CTRL_7				0x0230
-#define EMIF_EXT_PHY_CTRL_7_SHDW			0x0234
-#define EMIF_EXT_PHY_CTRL_8				0x0238
-#define EMIF_EXT_PHY_CTRL_8_SHDW			0x023c
-#define EMIF_EXT_PHY_CTRL_9				0x0240
-#define EMIF_EXT_PHY_CTRL_9_SHDW			0x0244
-#define EMIF_EXT_PHY_CTRL_10				0x0248
-#define EMIF_EXT_PHY_CTRL_10_SHDW			0x024c
-#define EMIF_EXT_PHY_CTRL_11				0x0250
-#define EMIF_EXT_PHY_CTRL_11_SHDW			0x0254
-#define EMIF_EXT_PHY_CTRL_12				0x0258
-#define EMIF_EXT_PHY_CTRL_12_SHDW			0x025c
-#define EMIF_EXT_PHY_CTRL_13				0x0260
-#define EMIF_EXT_PHY_CTRL_13_SHDW			0x0264
-#define EMIF_EXT_PHY_CTRL_14				0x0268
-#define EMIF_EXT_PHY_CTRL_14_SHDW			0x026c
-#define EMIF_EXT_PHY_CTRL_15				0x0270
-#define EMIF_EXT_PHY_CTRL_15_SHDW			0x0274
-#define EMIF_EXT_PHY_CTRL_16				0x0278
-#define EMIF_EXT_PHY_CTRL_16_SHDW			0x027c
-#define EMIF_EXT_PHY_CTRL_17				0x0280
-#define EMIF_EXT_PHY_CTRL_17_SHDW			0x0284
-#define EMIF_EXT_PHY_CTRL_18				0x0288
-#define EMIF_EXT_PHY_CTRL_18_SHDW			0x028c
-#define EMIF_EXT_PHY_CTRL_19				0x0290
-#define EMIF_EXT_PHY_CTRL_19_SHDW			0x0294
-#define EMIF_EXT_PHY_CTRL_20				0x0298
-#define EMIF_EXT_PHY_CTRL_20_SHDW			0x029c
-#define EMIF_EXT_PHY_CTRL_21				0x02a0
-#define EMIF_EXT_PHY_CTRL_21_SHDW			0x02a4
-#define EMIF_EXT_PHY_CTRL_22				0x02a8
-#define EMIF_EXT_PHY_CTRL_22_SHDW			0x02ac
-#define EMIF_EXT_PHY_CTRL_23				0x02b0
-#define EMIF_EXT_PHY_CTRL_23_SHDW			0x02b4
-#define EMIF_EXT_PHY_CTRL_24				0x02b8
-#define EMIF_EXT_PHY_CTRL_24_SHDW			0x02bc
-#define EMIF_EXT_PHY_CTRL_25				0x02c0
-#define EMIF_EXT_PHY_CTRL_25_SHDW			0x02c4
-#define EMIF_EXT_PHY_CTRL_26				0x02c8
-#define EMIF_EXT_PHY_CTRL_26_SHDW			0x02cc
-#define EMIF_EXT_PHY_CTRL_27				0x02d0
-#define EMIF_EXT_PHY_CTRL_27_SHDW			0x02d4
-#define EMIF_EXT_PHY_CTRL_28				0x02d8
-#define EMIF_EXT_PHY_CTRL_28_SHDW			0x02dc
-#define EMIF_EXT_PHY_CTRL_29				0x02e0
-#define EMIF_EXT_PHY_CTRL_29_SHDW			0x02e4
-#define EMIF_EXT_PHY_CTRL_30				0x02e8
-#define EMIF_EXT_PHY_CTRL_30_SHDW			0x02ec
-
-/* Registers shifts and masks */
-
-/* EMIF_MODULE_ID_AND_REVISION */
-#define SCHEME_SHIFT					30
-#define SCHEME_MASK					(0x3 << 30)
-#define MODULE_ID_SHIFT					16
-#define MODULE_ID_MASK					(0xfff << 16)
-#define RTL_VERSION_SHIFT				11
-#define RTL_VERSION_MASK				(0x1f << 11)
-#define MAJOR_REVISION_SHIFT				8
-#define MAJOR_REVISION_MASK				(0x7 << 8)
-#define MINOR_REVISION_SHIFT				0
-#define MINOR_REVISION_MASK				(0x3f << 0)
-
-/* STATUS */
-#define BE_SHIFT					31
-#define BE_MASK						(1 << 31)
-#define DUAL_CLK_MODE_SHIFT				30
-#define DUAL_CLK_MODE_MASK				(1 << 30)
-#define FAST_INIT_SHIFT					29
-#define FAST_INIT_MASK					(1 << 29)
-#define RDLVLGATETO_SHIFT				6
-#define RDLVLGATETO_MASK				(1 << 6)
-#define RDLVLTO_SHIFT					5
-#define RDLVLTO_MASK					(1 << 5)
-#define WRLVLTO_SHIFT					4
-#define WRLVLTO_MASK					(1 << 4)
-#define PHY_DLL_READY_SHIFT				2
-#define PHY_DLL_READY_MASK				(1 << 2)
-
-/* SDRAM_CONFIG */
-#define SDRAM_TYPE_SHIFT				29
-#define SDRAM_TYPE_MASK					(0x7 << 29)
-#define IBANK_POS_SHIFT					27
-#define IBANK_POS_MASK					(0x3 << 27)
-#define DDR_TERM_SHIFT					24
-#define DDR_TERM_MASK					(0x7 << 24)
-#define DDR2_DDQS_SHIFT					23
-#define DDR2_DDQS_MASK					(1 << 23)
-#define DYN_ODT_SHIFT					21
-#define DYN_ODT_MASK					(0x3 << 21)
-#define DDR_DISABLE_DLL_SHIFT				20
-#define DDR_DISABLE_DLL_MASK				(1 << 20)
-#define SDRAM_DRIVE_SHIFT				18
-#define SDRAM_DRIVE_MASK				(0x3 << 18)
-#define CWL_SHIFT					16
-#define CWL_MASK					(0x3 << 16)
-#define NARROW_MODE_SHIFT				14
-#define NARROW_MODE_MASK				(0x3 << 14)
-#define CL_SHIFT					10
-#define CL_MASK						(0xf << 10)
-#define ROWSIZE_SHIFT					7
-#define ROWSIZE_MASK					(0x7 << 7)
-#define IBANK_SHIFT					4
-#define IBANK_MASK					(0x7 << 4)
-#define EBANK_SHIFT					3
-#define EBANK_MASK					(1 << 3)
-#define PAGESIZE_SHIFT					0
-#define PAGESIZE_MASK					(0x7 << 0)
-
-/* SDRAM_CONFIG_2 */
-#define CS1NVMEN_SHIFT					30
-#define CS1NVMEN_MASK					(1 << 30)
-#define EBANK_POS_SHIFT					27
-#define EBANK_POS_MASK					(1 << 27)
-#define RDBNUM_SHIFT					4
-#define RDBNUM_MASK					(0x3 << 4)
-#define RDBSIZE_SHIFT					0
-#define RDBSIZE_MASK					(0x7 << 0)
-
-/* SDRAM_REFRESH_CONTROL */
-#define INITREF_DIS_SHIFT				31
-#define INITREF_DIS_MASK				(1 << 31)
-#define SRT_SHIFT					29
-#define SRT_MASK					(1 << 29)
-#define ASR_SHIFT					28
-#define ASR_MASK					(1 << 28)
-#define PASR_SHIFT					24
-#define PASR_MASK					(0x7 << 24)
-#define REFRESH_RATE_SHIFT				0
-#define REFRESH_RATE_MASK				(0xffff << 0)
-
-/* SDRAM_TIMING_1 */
-#define T_RTW_SHIFT					29
-#define T_RTW_MASK					(0x7 << 29)
-#define T_RP_SHIFT					25
-#define T_RP_MASK					(0xf << 25)
-#define T_RCD_SHIFT					21
-#define T_RCD_MASK					(0xf << 21)
-#define T_WR_SHIFT					17
-#define T_WR_MASK					(0xf << 17)
-#define T_RAS_SHIFT					12
-#define T_RAS_MASK					(0x1f << 12)
-#define T_RC_SHIFT					6
-#define T_RC_MASK					(0x3f << 6)
-#define T_RRD_SHIFT					3
-#define T_RRD_MASK					(0x7 << 3)
-#define T_WTR_SHIFT					0
-#define T_WTR_MASK					(0x7 << 0)
-
-/* SDRAM_TIMING_2 */
-#define T_XP_SHIFT					28
-#define T_XP_MASK					(0x7 << 28)
-#define T_ODT_SHIFT					25
-#define T_ODT_MASK					(0x7 << 25)
-#define T_XSNR_SHIFT					16
-#define T_XSNR_MASK					(0x1ff << 16)
-#define T_XSRD_SHIFT					6
-#define T_XSRD_MASK					(0x3ff << 6)
-#define T_RTP_SHIFT					3
-#define T_RTP_MASK					(0x7 << 3)
-#define T_CKE_SHIFT					0
-#define T_CKE_MASK					(0x7 << 0)
-
-/* SDRAM_TIMING_3 */
-#define T_PDLL_UL_SHIFT					28
-#define T_PDLL_UL_MASK					(0xf << 28)
-#define T_CSTA_SHIFT					24
-#define T_CSTA_MASK					(0xf << 24)
-#define T_CKESR_SHIFT					21
-#define T_CKESR_MASK					(0x7 << 21)
-#define ZQ_ZQCS_SHIFT					15
-#define ZQ_ZQCS_MASK					(0x3f << 15)
-#define T_TDQSCKMAX_SHIFT				13
-#define T_TDQSCKMAX_MASK				(0x3 << 13)
-#define T_RFC_SHIFT					4
-#define T_RFC_MASK					(0x1ff << 4)
-#define T_RAS_MAX_SHIFT					0
-#define T_RAS_MAX_MASK					(0xf << 0)
-
-/* POWER_MANAGEMENT_CONTROL */
-#define PD_TIM_SHIFT					12
-#define PD_TIM_MASK					(0xf << 12)
-#define DPD_EN_SHIFT					11
-#define DPD_EN_MASK					(1 << 11)
-#define LP_MODE_SHIFT					8
-#define LP_MODE_MASK					(0x7 << 8)
-#define SR_TIM_SHIFT					4
-#define SR_TIM_MASK					(0xf << 4)
-#define CS_TIM_SHIFT					0
-#define CS_TIM_MASK					(0xf << 0)
-
-/* LPDDR2_MODE_REG_DATA */
-#define VALUE_0_SHIFT					0
-#define VALUE_0_MASK					(0x7f << 0)
-
-/* LPDDR2_MODE_REG_CONFIG */
-#define CS_SHIFT					31
-#define CS_MASK						(1 << 31)
-#define REFRESH_EN_SHIFT				30
-#define REFRESH_EN_MASK					(1 << 30)
-#define ADDRESS_SHIFT					0
-#define ADDRESS_MASK					(0xff << 0)
-
-/* OCP_CONFIG */
-#define SYS_THRESH_MAX_SHIFT				24
-#define SYS_THRESH_MAX_MASK				(0xf << 24)
-#define MPU_THRESH_MAX_SHIFT				20
-#define MPU_THRESH_MAX_MASK				(0xf << 20)
-#define LL_THRESH_MAX_SHIFT				16
-#define LL_THRESH_MAX_MASK				(0xf << 16)
-
-/* PERFORMANCE_COUNTER_1 */
-#define COUNTER1_SHIFT					0
-#define COUNTER1_MASK					(0xffffffff << 0)
-
-/* PERFORMANCE_COUNTER_2 */
-#define COUNTER2_SHIFT					0
-#define COUNTER2_MASK					(0xffffffff << 0)
-
-/* PERFORMANCE_COUNTER_CONFIG */
-#define CNTR2_MCONNID_EN_SHIFT				31
-#define CNTR2_MCONNID_EN_MASK				(1 << 31)
-#define CNTR2_REGION_EN_SHIFT				30
-#define CNTR2_REGION_EN_MASK				(1 << 30)
-#define CNTR2_CFG_SHIFT					16
-#define CNTR2_CFG_MASK					(0xf << 16)
-#define CNTR1_MCONNID_EN_SHIFT				15
-#define CNTR1_MCONNID_EN_MASK				(1 << 15)
-#define CNTR1_REGION_EN_SHIFT				14
-#define CNTR1_REGION_EN_MASK				(1 << 14)
-#define CNTR1_CFG_SHIFT					0
-#define CNTR1_CFG_MASK					(0xf << 0)
-
-/* PERFORMANCE_COUNTER_MASTER_REGION_SELECT */
-#define MCONNID2_SHIFT					24
-#define MCONNID2_MASK					(0xff << 24)
-#define REGION_SEL2_SHIFT				16
-#define REGION_SEL2_MASK				(0x3 << 16)
-#define MCONNID1_SHIFT					8
-#define MCONNID1_MASK					(0xff << 8)
-#define REGION_SEL1_SHIFT				0
-#define REGION_SEL1_MASK				(0x3 << 0)
-
-/* PERFORMANCE_COUNTER_TIME */
-#define TOTAL_TIME_SHIFT				0
-#define TOTAL_TIME_MASK					(0xffffffff << 0)
-
-/* DLL_CALIB_CTRL */
-#define ACK_WAIT_SHIFT					16
-#define ACK_WAIT_MASK					(0xf << 16)
-#define DLL_CALIB_INTERVAL_SHIFT			0
-#define DLL_CALIB_INTERVAL_MASK				(0x1ff << 0)
-
-/* END_OF_INTERRUPT */
-#define EOI_SHIFT					0
-#define EOI_MASK					(1 << 0)
-
-/* SYSTEM_OCP_INTERRUPT_RAW_STATUS */
-#define DNV_SYS_SHIFT					2
-#define DNV_SYS_MASK					(1 << 2)
-#define TA_SYS_SHIFT					1
-#define TA_SYS_MASK					(1 << 1)
-#define ERR_SYS_SHIFT					0
-#define ERR_SYS_MASK					(1 << 0)
-
-/* LOW_LATENCY_OCP_INTERRUPT_RAW_STATUS */
-#define DNV_LL_SHIFT					2
-#define DNV_LL_MASK					(1 << 2)
-#define TA_LL_SHIFT					1
-#define TA_LL_MASK					(1 << 1)
-#define ERR_LL_SHIFT					0
-#define ERR_LL_MASK					(1 << 0)
-
-/* SYSTEM_OCP_INTERRUPT_ENABLE_SET */
-#define EN_DNV_SYS_SHIFT				2
-#define EN_DNV_SYS_MASK					(1 << 2)
-#define EN_TA_SYS_SHIFT					1
-#define EN_TA_SYS_MASK					(1 << 1)
-#define EN_ERR_SYS_SHIFT					0
-#define EN_ERR_SYS_MASK					(1 << 0)
-
-/* LOW_LATENCY_OCP_INTERRUPT_ENABLE_SET */
-#define EN_DNV_LL_SHIFT					2
-#define EN_DNV_LL_MASK					(1 << 2)
-#define EN_TA_LL_SHIFT					1
-#define EN_TA_LL_MASK					(1 << 1)
-#define EN_ERR_LL_SHIFT					0
-#define EN_ERR_LL_MASK					(1 << 0)
-
-/* SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG */
-#define ZQ_CS1EN_SHIFT					31
-#define ZQ_CS1EN_MASK					(1 << 31)
-#define ZQ_CS0EN_SHIFT					30
-#define ZQ_CS0EN_MASK					(1 << 30)
-#define ZQ_DUALCALEN_SHIFT				29
-#define ZQ_DUALCALEN_MASK				(1 << 29)
-#define ZQ_SFEXITEN_SHIFT				28
-#define ZQ_SFEXITEN_MASK				(1 << 28)
-#define ZQ_ZQINIT_MULT_SHIFT				18
-#define ZQ_ZQINIT_MULT_MASK				(0x3 << 18)
-#define ZQ_ZQCL_MULT_SHIFT				16
-#define ZQ_ZQCL_MULT_MASK				(0x3 << 16)
-#define ZQ_REFINTERVAL_SHIFT				0
-#define ZQ_REFINTERVAL_MASK				(0xffff << 0)
-
-/* TEMPERATURE_ALERT_CONFIG */
-#define TA_CS1EN_SHIFT					31
-#define TA_CS1EN_MASK					(1 << 31)
-#define TA_CS0EN_SHIFT					30
-#define TA_CS0EN_MASK					(1 << 30)
-#define TA_SFEXITEN_SHIFT				28
-#define TA_SFEXITEN_MASK				(1 << 28)
-#define TA_DEVWDT_SHIFT					26
-#define TA_DEVWDT_MASK					(0x3 << 26)
-#define TA_DEVCNT_SHIFT					24
-#define TA_DEVCNT_MASK					(0x3 << 24)
-#define TA_REFINTERVAL_SHIFT				0
-#define TA_REFINTERVAL_MASK				(0x3fffff << 0)
-
-/* OCP_ERROR_LOG */
-#define MADDRSPACE_SHIFT				14
-#define MADDRSPACE_MASK					(0x3 << 14)
-#define MBURSTSEQ_SHIFT					11
-#define MBURSTSEQ_MASK					(0x7 << 11)
-#define MCMD_SHIFT					8
-#define MCMD_MASK					(0x7 << 8)
-#define MCONNID_SHIFT					0
-#define MCONNID_MASK					(0xff << 0)
-
-/* DDR_PHY_CTRL_1 - EMIF4D */
-#define DLL_SLAVE_DLY_CTRL_SHIFT_4D			4
-#define DLL_SLAVE_DLY_CTRL_MASK_4D			(0xFF << 4)
-#define READ_LATENCY_SHIFT_4D				0
-#define READ_LATENCY_MASK_4D				(0xf << 0)
-
-/* DDR_PHY_CTRL_1 - EMIF4D5 */
-#define DLL_HALF_DELAY_SHIFT_4D5			21
-#define DLL_HALF_DELAY_MASK_4D5				(1 << 21)
-#define READ_LATENCY_SHIFT_4D5				0
-#define READ_LATENCY_MASK_4D5				(0x1f << 0)
-
-/* DDR_PHY_CTRL_1_SHDW */
-#define DDR_PHY_CTRL_1_SHDW_SHIFT			5
-#define DDR_PHY_CTRL_1_SHDW_MASK			(0x7ffffff << 5)
-#define READ_LATENCY_SHDW_SHIFT				0
-#define READ_LATENCY_SHDW_MASK				(0x1f << 0)
-
-#ifndef __ASSEMBLY__
-/*
- * Structure containing shadow of important registers in EMIF
- * The calculation function fills in this structure to be later used for
- * initialisation and DVFS
- */
-struct emif_regs {
-	u32 freq;
-	u32 ref_ctrl_shdw;
-	u32 ref_ctrl_shdw_derated;
-	u32 sdram_tim1_shdw;
-	u32 sdram_tim1_shdw_derated;
-	u32 sdram_tim2_shdw;
-	u32 sdram_tim3_shdw;
-	u32 sdram_tim3_shdw_derated;
-	u32 pwr_mgmt_ctrl_shdw;
-	union {
-		u32 read_idle_ctrl_shdw_normal;
-		u32 dll_calib_ctrl_shdw_normal;
-	};
-	union {
-		u32 read_idle_ctrl_shdw_volt_ramp;
-		u32 dll_calib_ctrl_shdw_volt_ramp;
-	};
-
-	u32 phy_ctrl_1_shdw;
-	u32 ext_phy_ctrl_2_shdw;
-	u32 ext_phy_ctrl_3_shdw;
-	u32 ext_phy_ctrl_4_shdw;
-};
-#endif /* __ASSEMBLY__ */
-#endif /* __EMIF_H */
diff --git a/include/linux/ti_emif.h b/include/linux/ti_emif.h
new file mode 100644
index 0000000..bfe08ba
--- /dev/null
+++ b/include/linux/ti_emif.h
@@ -0,0 +1,589 @@
+/*
+ * Defines for the EMIF driver
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * Benoit Cousson (b-cousson at ti.com)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __EMIF_H
+#define __EMIF_H
+
+/*
+ * Maximum number of different frequencies supported by EMIF driver
+ * Determines the number of entries in the pointer array for register
+ * cache
+ */
+#define EMIF_MAX_NUM_FREQUENCIES			6
+
+/* State of the core voltage */
+#define DDR_VOLTAGE_STABLE				0
+#define DDR_VOLTAGE_RAMPING				1
+
+/* Defines for timing De-rating */
+#define EMIF_NORMAL_TIMINGS				0
+#define EMIF_DERATED_TIMINGS				1
+
+/* Length of the forced read idle period in terms of cycles */
+#define EMIF_READ_IDLE_LEN_VAL				5
+
+/*
+ * forced read idle interval to be used when voltage
+ * is changed as part of DVFS/DPS - 1ms
+ */
+#define READ_IDLE_INTERVAL_DVFS				(1*1000000)
+
+/*
+ * Forced read idle interval to be used when voltage is stable
+ * 50us - or maximum value will do
+ */
+#define READ_IDLE_INTERVAL_NORMAL			(50*1000000)
+
+/* DLL calibration interval when voltage is NOT stable - 1us */
+#define DLL_CALIB_INTERVAL_DVFS				(1*1000000)
+
+#define DLL_CALIB_ACK_WAIT_VAL				5
+
+/* Interval between ZQCS commands - hw team recommended value */
+#define EMIF_ZQCS_INTERVAL_US				(50*1000)
+/* Enable ZQ Calibration on exiting Self-refresh */
+#define ZQ_SFEXITEN_ENABLE				1
+/*
+ * ZQ Calibration simultaneously on both chip-selects:
+ * Needs one calibration resistor per CS
+ */
+#define	ZQ_DUALCALEN_DISABLE				0
+#define	ZQ_DUALCALEN_ENABLE				1
+
+#define T_ZQCS_DEFAULT_NS				90
+#define T_ZQCL_DEFAULT_NS				360
+#define T_ZQINIT_DEFAULT_NS				1000
+
+/* DPD_EN */
+#define DPD_DISABLE					0
+#define DPD_ENABLE					1
+
+/*
+ * Default values for the low-power entry to be used if not provided by user.
+ * OMAP4/5 has a hw bug(i735) due to which this value can not be less than 512
+ * Timeout values are in DDR clock 'cycles' and frequency threshold in Hz
+ */
+#define EMIF_LP_MODE_TIMEOUT_PERFORMANCE		2048
+#define EMIF_LP_MODE_TIMEOUT_POWER			512
+#define EMIF_LP_MODE_FREQ_THRESHOLD			400000000
+
+/* DDR_PHY_CTRL_1 values for EMIF4D - ATTILA PHY combination */
+#define EMIF_DDR_PHY_CTRL_1_BASE_VAL_ATTILAPHY		0x049FF000
+#define EMIF_DLL_SLAVE_DLY_CTRL_400_MHZ_ATTILAPHY	0x41
+#define EMIF_DLL_SLAVE_DLY_CTRL_200_MHZ_ATTILAPHY	0x80
+#define EMIF_DLL_SLAVE_DLY_CTRL_100_MHZ_AND_LESS_ATTILAPHY 0xFF
+
+/* DDR_PHY_CTRL_1 values for EMIF4D5 INTELLIPHY combination */
+#define EMIF_DDR_PHY_CTRL_1_BASE_VAL_INTELLIPHY		0x0E084200
+#define EMIF_PHY_TOTAL_READ_LATENCY_INTELLIPHY_PS	10000
+
+/* TEMP_ALERT_CONFIG - corresponding to temp gradient 5 C/s */
+#define TEMP_ALERT_POLL_INTERVAL_DEFAULT_MS		360
+
+#define EMIF_T_CSTA					3
+#define EMIF_T_PDLL_UL					128
+
+/* External PHY control registers magic values */
+#define EMIF_EXT_PHY_CTRL_1_VAL				0x04020080
+#define EMIF_EXT_PHY_CTRL_5_VAL				0x04010040
+#define EMIF_EXT_PHY_CTRL_6_VAL				0x01004010
+#define EMIF_EXT_PHY_CTRL_7_VAL				0x00001004
+#define EMIF_EXT_PHY_CTRL_8_VAL				0x04010040
+#define EMIF_EXT_PHY_CTRL_9_VAL				0x01004010
+#define EMIF_EXT_PHY_CTRL_10_VAL			0x00001004
+#define EMIF_EXT_PHY_CTRL_11_VAL			0x00000000
+#define EMIF_EXT_PHY_CTRL_12_VAL			0x00000000
+#define EMIF_EXT_PHY_CTRL_13_VAL			0x00000000
+#define EMIF_EXT_PHY_CTRL_14_VAL			0x80080080
+#define EMIF_EXT_PHY_CTRL_15_VAL			0x00800800
+#define EMIF_EXT_PHY_CTRL_16_VAL			0x08102040
+#define EMIF_EXT_PHY_CTRL_17_VAL			0x00000001
+#define EMIF_EXT_PHY_CTRL_18_VAL			0x540A8150
+#define EMIF_EXT_PHY_CTRL_19_VAL			0xA81502A0
+#define EMIF_EXT_PHY_CTRL_20_VAL			0x002A0540
+#define EMIF_EXT_PHY_CTRL_21_VAL			0x00000000
+#define EMIF_EXT_PHY_CTRL_22_VAL			0x00000000
+#define EMIF_EXT_PHY_CTRL_23_VAL			0x00000000
+#define EMIF_EXT_PHY_CTRL_24_VAL			0x00000077
+
+#define EMIF_INTELLI_PHY_DQS_GATE_OPENING_DELAY_PS	1200
+
+/* Registers offset */
+#define EMIF_MODULE_ID_AND_REVISION			0x0000
+#define EMIF_STATUS					0x0004
+#define EMIF_SDRAM_CONFIG				0x0008
+#define EMIF_SDRAM_CONFIG_2				0x000c
+#define EMIF_SDRAM_REFRESH_CONTROL			0x0010
+#define EMIF_SDRAM_REFRESH_CTRL_SHDW			0x0014
+#define EMIF_SDRAM_TIMING_1				0x0018
+#define EMIF_SDRAM_TIMING_1_SHDW			0x001c
+#define EMIF_SDRAM_TIMING_2				0x0020
+#define EMIF_SDRAM_TIMING_2_SHDW			0x0024
+#define EMIF_SDRAM_TIMING_3				0x0028
+#define EMIF_SDRAM_TIMING_3_SHDW			0x002c
+#define EMIF_LPDDR2_NVM_TIMING				0x0030
+#define EMIF_LPDDR2_NVM_TIMING_SHDW			0x0034
+#define EMIF_POWER_MANAGEMENT_CONTROL			0x0038
+#define EMIF_POWER_MANAGEMENT_CTRL_SHDW			0x003c
+#define EMIF_LPDDR2_MODE_REG_DATA			0x0040
+#define EMIF_LPDDR2_MODE_REG_CONFIG			0x0050
+#define EMIF_OCP_CONFIG					0x0054
+#define EMIF_OCP_CONFIG_VALUE_1				0x0058
+#define EMIF_OCP_CONFIG_VALUE_2				0x005c
+#define EMIF_IODFT_TEST_LOGIC_GLOBAL_CONTROL		0x0060
+#define EMIF_IODFT_TEST_LOGIC_CTRL_MISR_RESULT		0x0064
+#define EMIF_IODFT_TEST_LOGIC_ADDRESS_MISR_RESULT	0x0068
+#define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_1	0x006c
+#define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_2	0x0070
+#define EMIF_IODFT_TEST_LOGIC_DATA_MISR_RESULT_3	0x0074
+#define EMIF_PERFORMANCE_COUNTER_1			0x0080
+#define EMIF_PERFORMANCE_COUNTER_2			0x0084
+#define EMIF_PERFORMANCE_COUNTER_CONFIG			0x0088
+#define EMIF_PERFORMANCE_COUNTER_MASTER_REGION_SELECT	0x008c
+#define EMIF_PERFORMANCE_COUNTER_TIME			0x0090
+#define EMIF_MISC_REG					0x0094
+#define EMIF_DLL_CALIB_CTRL				0x0098
+#define EMIF_DLL_CALIB_CTRL_SHDW			0x009c
+#define EMIF_END_OF_INTERRUPT				0x00a0
+#define EMIF_SYSTEM_OCP_INTERRUPT_RAW_STATUS		0x00a4
+#define EMIF_LL_OCP_INTERRUPT_RAW_STATUS		0x00a8
+#define EMIF_SYSTEM_OCP_INTERRUPT_STATUS		0x00ac
+#define EMIF_LL_OCP_INTERRUPT_STATUS			0x00b0
+#define EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_SET		0x00b4
+#define EMIF_LL_OCP_INTERRUPT_ENABLE_SET		0x00b8
+#define EMIF_SYSTEM_OCP_INTERRUPT_ENABLE_CLEAR		0x00bc
+#define EMIF_LL_OCP_INTERRUPT_ENABLE_CLEAR		0x00c0
+#define EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG	0x00c8
+#define EMIF_TEMPERATURE_ALERT_CONFIG			0x00cc
+#define EMIF_OCP_ERROR_LOG				0x00d0
+#define EMIF_READ_WRITE_LEVELING_RAMP_WINDOW		0x00d4
+#define EMIF_READ_WRITE_LEVELING_RAMP_CONTROL		0x00d8
+#define EMIF_READ_WRITE_LEVELING_CONTROL		0x00dc
+#define EMIF_DDR_PHY_CTRL_1				0x00e4
+#define EMIF_DDR_PHY_CTRL_1_SHDW			0x00e8
+#define EMIF_DDR_PHY_CTRL_2				0x00ec
+#define EMIF_PRIORITY_TO_CLASS_OF_SERVICE_MAPPING	0x0100
+#define EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_1_MAPPING 0x0104
+#define EMIF_CONNECTION_ID_TO_CLASS_OF_SERVICE_2_MAPPING 0x0108
+#define EMIF_READ_WRITE_EXECUTION_THRESHOLD		0x0120
+#define EMIF_COS_CONFIG					0x0124
+#define EMIF_PHY_STATUS_1				0x0140
+#define EMIF_PHY_STATUS_2				0x0144
+#define EMIF_PHY_STATUS_3				0x0148
+#define EMIF_PHY_STATUS_4				0x014c
+#define EMIF_PHY_STATUS_5				0x0150
+#define EMIF_PHY_STATUS_6				0x0154
+#define EMIF_PHY_STATUS_7				0x0158
+#define EMIF_PHY_STATUS_8				0x015c
+#define EMIF_PHY_STATUS_9				0x0160
+#define EMIF_PHY_STATUS_10				0x0164
+#define EMIF_PHY_STATUS_11				0x0168
+#define EMIF_PHY_STATUS_12				0x016c
+#define EMIF_PHY_STATUS_13				0x0170
+#define EMIF_PHY_STATUS_14				0x0174
+#define EMIF_PHY_STATUS_15				0x0178
+#define EMIF_PHY_STATUS_16				0x017c
+#define EMIF_PHY_STATUS_17				0x0180
+#define EMIF_PHY_STATUS_18				0x0184
+#define EMIF_PHY_STATUS_19				0x0188
+#define EMIF_PHY_STATUS_20				0x018c
+#define EMIF_PHY_STATUS_21				0x0190
+#define EMIF_EXT_PHY_CTRL_1				0x0200
+#define EMIF_EXT_PHY_CTRL_1_SHDW			0x0204
+#define EMIF_EXT_PHY_CTRL_2				0x0208
+#define EMIF_EXT_PHY_CTRL_2_SHDW			0x020c
+#define EMIF_EXT_PHY_CTRL_3				0x0210
+#define EMIF_EXT_PHY_CTRL_3_SHDW			0x0214
+#define EMIF_EXT_PHY_CTRL_4				0x0218
+#define EMIF_EXT_PHY_CTRL_4_SHDW			0x021c
+#define EMIF_EXT_PHY_CTRL_5				0x0220
+#define EMIF_EXT_PHY_CTRL_5_SHDW			0x0224
+#define EMIF_EXT_PHY_CTRL_6				0x0228
+#define EMIF_EXT_PHY_CTRL_6_SHDW			0x022c
+#define EMIF_EXT_PHY_CTRL_7				0x0230
+#define EMIF_EXT_PHY_CTRL_7_SHDW			0x0234
+#define EMIF_EXT_PHY_CTRL_8				0x0238
+#define EMIF_EXT_PHY_CTRL_8_SHDW			0x023c
+#define EMIF_EXT_PHY_CTRL_9				0x0240
+#define EMIF_EXT_PHY_CTRL_9_SHDW			0x0244
+#define EMIF_EXT_PHY_CTRL_10				0x0248
+#define EMIF_EXT_PHY_CTRL_10_SHDW			0x024c
+#define EMIF_EXT_PHY_CTRL_11				0x0250
+#define EMIF_EXT_PHY_CTRL_11_SHDW			0x0254
+#define EMIF_EXT_PHY_CTRL_12				0x0258
+#define EMIF_EXT_PHY_CTRL_12_SHDW			0x025c
+#define EMIF_EXT_PHY_CTRL_13				0x0260
+#define EMIF_EXT_PHY_CTRL_13_SHDW			0x0264
+#define EMIF_EXT_PHY_CTRL_14				0x0268
+#define EMIF_EXT_PHY_CTRL_14_SHDW			0x026c
+#define EMIF_EXT_PHY_CTRL_15				0x0270
+#define EMIF_EXT_PHY_CTRL_15_SHDW			0x0274
+#define EMIF_EXT_PHY_CTRL_16				0x0278
+#define EMIF_EXT_PHY_CTRL_16_SHDW			0x027c
+#define EMIF_EXT_PHY_CTRL_17				0x0280
+#define EMIF_EXT_PHY_CTRL_17_SHDW			0x0284
+#define EMIF_EXT_PHY_CTRL_18				0x0288
+#define EMIF_EXT_PHY_CTRL_18_SHDW			0x028c
+#define EMIF_EXT_PHY_CTRL_19				0x0290
+#define EMIF_EXT_PHY_CTRL_19_SHDW			0x0294
+#define EMIF_EXT_PHY_CTRL_20				0x0298
+#define EMIF_EXT_PHY_CTRL_20_SHDW			0x029c
+#define EMIF_EXT_PHY_CTRL_21				0x02a0
+#define EMIF_EXT_PHY_CTRL_21_SHDW			0x02a4
+#define EMIF_EXT_PHY_CTRL_22				0x02a8
+#define EMIF_EXT_PHY_CTRL_22_SHDW			0x02ac
+#define EMIF_EXT_PHY_CTRL_23				0x02b0
+#define EMIF_EXT_PHY_CTRL_23_SHDW			0x02b4
+#define EMIF_EXT_PHY_CTRL_24				0x02b8
+#define EMIF_EXT_PHY_CTRL_24_SHDW			0x02bc
+#define EMIF_EXT_PHY_CTRL_25				0x02c0
+#define EMIF_EXT_PHY_CTRL_25_SHDW			0x02c4
+#define EMIF_EXT_PHY_CTRL_26				0x02c8
+#define EMIF_EXT_PHY_CTRL_26_SHDW			0x02cc
+#define EMIF_EXT_PHY_CTRL_27				0x02d0
+#define EMIF_EXT_PHY_CTRL_27_SHDW			0x02d4
+#define EMIF_EXT_PHY_CTRL_28				0x02d8
+#define EMIF_EXT_PHY_CTRL_28_SHDW			0x02dc
+#define EMIF_EXT_PHY_CTRL_29				0x02e0
+#define EMIF_EXT_PHY_CTRL_29_SHDW			0x02e4
+#define EMIF_EXT_PHY_CTRL_30				0x02e8
+#define EMIF_EXT_PHY_CTRL_30_SHDW			0x02ec
+
+/* Registers shifts and masks */
+
+/* EMIF_MODULE_ID_AND_REVISION */
+#define SCHEME_SHIFT					30
+#define SCHEME_MASK					(0x3 << 30)
+#define MODULE_ID_SHIFT					16
+#define MODULE_ID_MASK					(0xfff << 16)
+#define RTL_VERSION_SHIFT				11
+#define RTL_VERSION_MASK				(0x1f << 11)
+#define MAJOR_REVISION_SHIFT				8
+#define MAJOR_REVISION_MASK				(0x7 << 8)
+#define MINOR_REVISION_SHIFT				0
+#define MINOR_REVISION_MASK				(0x3f << 0)
+
+/* STATUS */
+#define BE_SHIFT					31
+#define BE_MASK						(1 << 31)
+#define DUAL_CLK_MODE_SHIFT				30
+#define DUAL_CLK_MODE_MASK				(1 << 30)
+#define FAST_INIT_SHIFT					29
+#define FAST_INIT_MASK					(1 << 29)
+#define RDLVLGATETO_SHIFT				6
+#define RDLVLGATETO_MASK				(1 << 6)
+#define RDLVLTO_SHIFT					5
+#define RDLVLTO_MASK					(1 << 5)
+#define WRLVLTO_SHIFT					4
+#define WRLVLTO_MASK					(1 << 4)
+#define PHY_DLL_READY_SHIFT				2
+#define PHY_DLL_READY_MASK				(1 << 2)
+
+/* SDRAM_CONFIG */
+#define SDRAM_TYPE_SHIFT				29
+#define SDRAM_TYPE_MASK					(0x7 << 29)
+#define IBANK_POS_SHIFT					27
+#define IBANK_POS_MASK					(0x3 << 27)
+#define DDR_TERM_SHIFT					24
+#define DDR_TERM_MASK					(0x7 << 24)
+#define DDR2_DDQS_SHIFT					23
+#define DDR2_DDQS_MASK					(1 << 23)
+#define DYN_ODT_SHIFT					21
+#define DYN_ODT_MASK					(0x3 << 21)
+#define DDR_DISABLE_DLL_SHIFT				20
+#define DDR_DISABLE_DLL_MASK				(1 << 20)
+#define SDRAM_DRIVE_SHIFT				18
+#define SDRAM_DRIVE_MASK				(0x3 << 18)
+#define CWL_SHIFT					16
+#define CWL_MASK					(0x3 << 16)
+#define NARROW_MODE_SHIFT				14
+#define NARROW_MODE_MASK				(0x3 << 14)
+#define CL_SHIFT					10
+#define CL_MASK						(0xf << 10)
+#define ROWSIZE_SHIFT					7
+#define ROWSIZE_MASK					(0x7 << 7)
+#define IBANK_SHIFT					4
+#define IBANK_MASK					(0x7 << 4)
+#define EBANK_SHIFT					3
+#define EBANK_MASK					(1 << 3)
+#define PAGESIZE_SHIFT					0
+#define PAGESIZE_MASK					(0x7 << 0)
+
+/* SDRAM_CONFIG_2 */
+#define CS1NVMEN_SHIFT					30
+#define CS1NVMEN_MASK					(1 << 30)
+#define EBANK_POS_SHIFT					27
+#define EBANK_POS_MASK					(1 << 27)
+#define RDBNUM_SHIFT					4
+#define RDBNUM_MASK					(0x3 << 4)
+#define RDBSIZE_SHIFT					0
+#define RDBSIZE_MASK					(0x7 << 0)
+
+/* SDRAM_REFRESH_CONTROL */
+#define INITREF_DIS_SHIFT				31
+#define INITREF_DIS_MASK				(1 << 31)
+#define SRT_SHIFT					29
+#define SRT_MASK					(1 << 29)
+#define ASR_SHIFT					28
+#define ASR_MASK					(1 << 28)
+#define PASR_SHIFT					24
+#define PASR_MASK					(0x7 << 24)
+#define REFRESH_RATE_SHIFT				0
+#define REFRESH_RATE_MASK				(0xffff << 0)
+
+/* SDRAM_TIMING_1 */
+#define T_RTW_SHIFT					29
+#define T_RTW_MASK					(0x7 << 29)
+#define T_RP_SHIFT					25
+#define T_RP_MASK					(0xf << 25)
+#define T_RCD_SHIFT					21
+#define T_RCD_MASK					(0xf << 21)
+#define T_WR_SHIFT					17
+#define T_WR_MASK					(0xf << 17)
+#define T_RAS_SHIFT					12
+#define T_RAS_MASK					(0x1f << 12)
+#define T_RC_SHIFT					6
+#define T_RC_MASK					(0x3f << 6)
+#define T_RRD_SHIFT					3
+#define T_RRD_MASK					(0x7 << 3)
+#define T_WTR_SHIFT					0
+#define T_WTR_MASK					(0x7 << 0)
+
+/* SDRAM_TIMING_2 */
+#define T_XP_SHIFT					28
+#define T_XP_MASK					(0x7 << 28)
+#define T_ODT_SHIFT					25
+#define T_ODT_MASK					(0x7 << 25)
+#define T_XSNR_SHIFT					16
+#define T_XSNR_MASK					(0x1ff << 16)
+#define T_XSRD_SHIFT					6
+#define T_XSRD_MASK					(0x3ff << 6)
+#define T_RTP_SHIFT					3
+#define T_RTP_MASK					(0x7 << 3)
+#define T_CKE_SHIFT					0
+#define T_CKE_MASK					(0x7 << 0)
+
+/* SDRAM_TIMING_3 */
+#define T_PDLL_UL_SHIFT					28
+#define T_PDLL_UL_MASK					(0xf << 28)
+#define T_CSTA_SHIFT					24
+#define T_CSTA_MASK					(0xf << 24)
+#define T_CKESR_SHIFT					21
+#define T_CKESR_MASK					(0x7 << 21)
+#define ZQ_ZQCS_SHIFT					15
+#define ZQ_ZQCS_MASK					(0x3f << 15)
+#define T_TDQSCKMAX_SHIFT				13
+#define T_TDQSCKMAX_MASK				(0x3 << 13)
+#define T_RFC_SHIFT					4
+#define T_RFC_MASK					(0x1ff << 4)
+#define T_RAS_MAX_SHIFT					0
+#define T_RAS_MAX_MASK					(0xf << 0)
+
+/* POWER_MANAGEMENT_CONTROL */
+#define PD_TIM_SHIFT					12
+#define PD_TIM_MASK					(0xf << 12)
+#define DPD_EN_SHIFT					11
+#define DPD_EN_MASK					(1 << 11)
+#define LP_MODE_SHIFT					8
+#define LP_MODE_MASK					(0x7 << 8)
+#define SR_TIM_SHIFT					4
+#define SR_TIM_MASK					(0xf << 4)
+#define CS_TIM_SHIFT					0
+#define CS_TIM_MASK					(0xf << 0)
+
+/* LPDDR2_MODE_REG_DATA */
+#define VALUE_0_SHIFT					0
+#define VALUE_0_MASK					(0x7f << 0)
+
+/* LPDDR2_MODE_REG_CONFIG */
+#define CS_SHIFT					31
+#define CS_MASK						(1 << 31)
+#define REFRESH_EN_SHIFT				30
+#define REFRESH_EN_MASK					(1 << 30)
+#define ADDRESS_SHIFT					0
+#define ADDRESS_MASK					(0xff << 0)
+
+/* OCP_CONFIG */
+#define SYS_THRESH_MAX_SHIFT				24
+#define SYS_THRESH_MAX_MASK				(0xf << 24)
+#define MPU_THRESH_MAX_SHIFT				20
+#define MPU_THRESH_MAX_MASK				(0xf << 20)
+#define LL_THRESH_MAX_SHIFT				16
+#define LL_THRESH_MAX_MASK				(0xf << 16)
+
+/* PERFORMANCE_COUNTER_1 */
+#define COUNTER1_SHIFT					0
+#define COUNTER1_MASK					(0xffffffff << 0)
+
+/* PERFORMANCE_COUNTER_2 */
+#define COUNTER2_SHIFT					0
+#define COUNTER2_MASK					(0xffffffff << 0)
+
+/* PERFORMANCE_COUNTER_CONFIG */
+#define CNTR2_MCONNID_EN_SHIFT				31
+#define CNTR2_MCONNID_EN_MASK				(1 << 31)
+#define CNTR2_REGION_EN_SHIFT				30
+#define CNTR2_REGION_EN_MASK				(1 << 30)
+#define CNTR2_CFG_SHIFT					16
+#define CNTR2_CFG_MASK					(0xf << 16)
+#define CNTR1_MCONNID_EN_SHIFT				15
+#define CNTR1_MCONNID_EN_MASK				(1 << 15)
+#define CNTR1_REGION_EN_SHIFT				14
+#define CNTR1_REGION_EN_MASK				(1 << 14)
+#define CNTR1_CFG_SHIFT					0
+#define CNTR1_CFG_MASK					(0xf << 0)
+
+/* PERFORMANCE_COUNTER_MASTER_REGION_SELECT */
+#define MCONNID2_SHIFT					24
+#define MCONNID2_MASK					(0xff << 24)
+#define REGION_SEL2_SHIFT				16
+#define REGION_SEL2_MASK				(0x3 << 16)
+#define MCONNID1_SHIFT					8
+#define MCONNID1_MASK					(0xff << 8)
+#define REGION_SEL1_SHIFT				0
+#define REGION_SEL1_MASK				(0x3 << 0)
+
+/* PERFORMANCE_COUNTER_TIME */
+#define TOTAL_TIME_SHIFT				0
+#define TOTAL_TIME_MASK					(0xffffffff << 0)
+
+/* DLL_CALIB_CTRL */
+#define ACK_WAIT_SHIFT					16
+#define ACK_WAIT_MASK					(0xf << 16)
+#define DLL_CALIB_INTERVAL_SHIFT			0
+#define DLL_CALIB_INTERVAL_MASK				(0x1ff << 0)
+
+/* END_OF_INTERRUPT */
+#define EOI_SHIFT					0
+#define EOI_MASK					(1 << 0)
+
+/* SYSTEM_OCP_INTERRUPT_RAW_STATUS */
+#define DNV_SYS_SHIFT					2
+#define DNV_SYS_MASK					(1 << 2)
+#define TA_SYS_SHIFT					1
+#define TA_SYS_MASK					(1 << 1)
+#define ERR_SYS_SHIFT					0
+#define ERR_SYS_MASK					(1 << 0)
+
+/* LOW_LATENCY_OCP_INTERRUPT_RAW_STATUS */
+#define DNV_LL_SHIFT					2
+#define DNV_LL_MASK					(1 << 2)
+#define TA_LL_SHIFT					1
+#define TA_LL_MASK					(1 << 1)
+#define ERR_LL_SHIFT					0
+#define ERR_LL_MASK					(1 << 0)
+
+/* SYSTEM_OCP_INTERRUPT_ENABLE_SET */
+#define EN_DNV_SYS_SHIFT				2
+#define EN_DNV_SYS_MASK					(1 << 2)
+#define EN_TA_SYS_SHIFT					1
+#define EN_TA_SYS_MASK					(1 << 1)
+#define EN_ERR_SYS_SHIFT					0
+#define EN_ERR_SYS_MASK					(1 << 0)
+
+/* LOW_LATENCY_OCP_INTERRUPT_ENABLE_SET */
+#define EN_DNV_LL_SHIFT					2
+#define EN_DNV_LL_MASK					(1 << 2)
+#define EN_TA_LL_SHIFT					1
+#define EN_TA_LL_MASK					(1 << 1)
+#define EN_ERR_LL_SHIFT					0
+#define EN_ERR_LL_MASK					(1 << 0)
+
+/* SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG */
+#define ZQ_CS1EN_SHIFT					31
+#define ZQ_CS1EN_MASK					(1 << 31)
+#define ZQ_CS0EN_SHIFT					30
+#define ZQ_CS0EN_MASK					(1 << 30)
+#define ZQ_DUALCALEN_SHIFT				29
+#define ZQ_DUALCALEN_MASK				(1 << 29)
+#define ZQ_SFEXITEN_SHIFT				28
+#define ZQ_SFEXITEN_MASK				(1 << 28)
+#define ZQ_ZQINIT_MULT_SHIFT				18
+#define ZQ_ZQINIT_MULT_MASK				(0x3 << 18)
+#define ZQ_ZQCL_MULT_SHIFT				16
+#define ZQ_ZQCL_MULT_MASK				(0x3 << 16)
+#define ZQ_REFINTERVAL_SHIFT				0
+#define ZQ_REFINTERVAL_MASK				(0xffff << 0)
+
+/* TEMPERATURE_ALERT_CONFIG */
+#define TA_CS1EN_SHIFT					31
+#define TA_CS1EN_MASK					(1 << 31)
+#define TA_CS0EN_SHIFT					30
+#define TA_CS0EN_MASK					(1 << 30)
+#define TA_SFEXITEN_SHIFT				28
+#define TA_SFEXITEN_MASK				(1 << 28)
+#define TA_DEVWDT_SHIFT					26
+#define TA_DEVWDT_MASK					(0x3 << 26)
+#define TA_DEVCNT_SHIFT					24
+#define TA_DEVCNT_MASK					(0x3 << 24)
+#define TA_REFINTERVAL_SHIFT				0
+#define TA_REFINTERVAL_MASK				(0x3fffff << 0)
+
+/* OCP_ERROR_LOG */
+#define MADDRSPACE_SHIFT				14
+#define MADDRSPACE_MASK					(0x3 << 14)
+#define MBURSTSEQ_SHIFT					11
+#define MBURSTSEQ_MASK					(0x7 << 11)
+#define MCMD_SHIFT					8
+#define MCMD_MASK					(0x7 << 8)
+#define MCONNID_SHIFT					0
+#define MCONNID_MASK					(0xff << 0)
+
+/* DDR_PHY_CTRL_1 - EMIF4D */
+#define DLL_SLAVE_DLY_CTRL_SHIFT_4D			4
+#define DLL_SLAVE_DLY_CTRL_MASK_4D			(0xFF << 4)
+#define READ_LATENCY_SHIFT_4D				0
+#define READ_LATENCY_MASK_4D				(0xf << 0)
+
+/* DDR_PHY_CTRL_1 - EMIF4D5 */
+#define DLL_HALF_DELAY_SHIFT_4D5			21
+#define DLL_HALF_DELAY_MASK_4D5				(1 << 21)
+#define READ_LATENCY_SHIFT_4D5				0
+#define READ_LATENCY_MASK_4D5				(0x1f << 0)
+
+/* DDR_PHY_CTRL_1_SHDW */
+#define DDR_PHY_CTRL_1_SHDW_SHIFT			5
+#define DDR_PHY_CTRL_1_SHDW_MASK			(0x7ffffff << 5)
+#define READ_LATENCY_SHDW_SHIFT				0
+#define READ_LATENCY_SHDW_MASK				(0x1f << 0)
+
+#ifndef __ASSEMBLY__
+/*
+ * Structure containing shadow of important registers in EMIF
+ * The calculation function fills in this structure to be later used for
+ * initialisation and DVFS
+ */
+struct emif_regs {
+	u32 freq;
+	u32 ref_ctrl_shdw;
+	u32 ref_ctrl_shdw_derated;
+	u32 sdram_tim1_shdw;
+	u32 sdram_tim1_shdw_derated;
+	u32 sdram_tim2_shdw;
+	u32 sdram_tim3_shdw;
+	u32 sdram_tim3_shdw_derated;
+	u32 pwr_mgmt_ctrl_shdw;
+	union {
+		u32 read_idle_ctrl_shdw_normal;
+		u32 dll_calib_ctrl_shdw_normal;
+	};
+	union {
+		u32 read_idle_ctrl_shdw_volt_ramp;
+		u32 dll_calib_ctrl_shdw_volt_ramp;
+	};
+
+	u32 phy_ctrl_1_shdw;
+	u32 ext_phy_ctrl_2_shdw;
+	u32 ext_phy_ctrl_3_shdw;
+	u32 ext_phy_ctrl_4_shdw;
+};
+#endif /* __ASSEMBLY__ */
+#endif /* __EMIF_H */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 04/18] ARM: OMAP2+: AM33XX: CM: Get rid of unncessary header inclusions
  2012-12-31 13:06 ` Vaibhav Bedia
@ 2012-12-31 13:06   ` Vaibhav Bedia
  -1 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:06 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, tony, khilman
  Cc: Vaibhav Bedia, Santosh Shilimkar, Benoit Cousson, Paul Walmsley,
	Vaibhav Hiremath

Some of the included header files are not needed so
remove them.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
---
v1->v2:
	This is a new patch in the series based on
	Santosh's feedback on splitting the changes

 arch/arm/mach-omap2/cm33xx.h |    7 +------
 1 files changed, 1 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-omap2/cm33xx.h b/arch/arm/mach-omap2/cm33xx.h
index 5fa0b62..8009e13 100644
--- a/arch/arm/mach-omap2/cm33xx.h
+++ b/arch/arm/mach-omap2/cm33xx.h
@@ -17,16 +17,11 @@
 #ifndef __ARCH_ARM_MACH_OMAP2_CM_33XX_H
 #define __ARCH_ARM_MACH_OMAP2_CM_33XX_H
 
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
 #include "common.h"
 
 #include "cm.h"
 #include "cm-regbits-33xx.h"
-#include "cm33xx.h"
+#include "iomap.h"
 
 /* CM base address */
 #define AM33XX_CM_BASE		0x44e00000
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 04/18] ARM: OMAP2+: AM33XX: CM: Get rid of unncessary header inclusions
@ 2012-12-31 13:06   ` Vaibhav Bedia
  0 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:06 UTC (permalink / raw)
  To: linux-arm-kernel

Some of the included header files are not needed so
remove them.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
---
v1->v2:
	This is a new patch in the series based on
	Santosh's feedback on splitting the changes

 arch/arm/mach-omap2/cm33xx.h |    7 +------
 1 files changed, 1 insertions(+), 6 deletions(-)

diff --git a/arch/arm/mach-omap2/cm33xx.h b/arch/arm/mach-omap2/cm33xx.h
index 5fa0b62..8009e13 100644
--- a/arch/arm/mach-omap2/cm33xx.h
+++ b/arch/arm/mach-omap2/cm33xx.h
@@ -17,16 +17,11 @@
 #ifndef __ARCH_ARM_MACH_OMAP2_CM_33XX_H
 #define __ARCH_ARM_MACH_OMAP2_CM_33XX_H
 
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/io.h>
-
 #include "common.h"
 
 #include "cm.h"
 #include "cm-regbits-33xx.h"
-#include "cm33xx.h"
+#include "iomap.h"
 
 /* CM base address */
 #define AM33XX_CM_BASE		0x44e00000
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 05/18] ARM: OMAP2+: AM33XX: CM/PRM: Use __ASSEMBLER__ macros in header files
  2012-12-31 13:06 ` Vaibhav Bedia
@ 2012-12-31 13:06   ` Vaibhav Bedia
  -1 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:06 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, tony, khilman
  Cc: Vaibhav Bedia, Santosh Shilimkar, Paul Walmsley, Benoit Cousson,
	Vaibhav Hiremath

This is necessary to ensure that macros declared here can
be reused from assembly files.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
---
v1->v2:
	Split out the header file changes in a separate patch
	based on the feedback from Santosh

 arch/arm/mach-omap2/cm33xx.h  |    3 +++
 arch/arm/mach-omap2/prm33xx.h |    3 +++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/cm33xx.h b/arch/arm/mach-omap2/cm33xx.h
index 8009e13..2f215cd 100644
--- a/arch/arm/mach-omap2/cm33xx.h
+++ b/arch/arm/mach-omap2/cm33xx.h
@@ -376,6 +376,7 @@
 #define AM33XX_CM_CEFUSE_CEFUSE_CLKCTRL			AM33XX_CM_REGADDR(AM33XX_CM_CEFUSE_MOD, 0x0020)
 
 
+#ifndef __ASSEMBLER__
 extern bool am33xx_cm_is_clkdm_in_hwsup(s16 inst, u16 cdoffs);
 extern void am33xx_cm_clkdm_enable_hwsup(s16 inst, u16 cdoffs);
 extern void am33xx_cm_clkdm_disable_hwsup(s16 inst, u16 cdoffs);
@@ -412,4 +413,6 @@ static inline int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs,
 }
 #endif
 
+#endif /* ASSEMBLER */
+
 #endif
diff --git a/arch/arm/mach-omap2/prm33xx.h b/arch/arm/mach-omap2/prm33xx.h
index 3f25c56..2f2eaa0 100644
--- a/arch/arm/mach-omap2/prm33xx.h
+++ b/arch/arm/mach-omap2/prm33xx.h
@@ -117,6 +117,7 @@
 #define AM33XX_PM_CEFUSE_PWRSTST_OFFSET		0x0004
 #define AM33XX_PM_CEFUSE_PWRSTST		AM33XX_PRM_REGADDR(AM33XX_PRM_CEFUSE_MOD, 0x0004)
 
+#ifndef __ASSEMBLER__
 extern u32 am33xx_prm_read_reg(s16 inst, u16 idx);
 extern void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx);
 extern u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
@@ -126,4 +127,6 @@ extern int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst,
 extern int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs);
 extern int am33xx_prm_deassert_hardreset(u8 shift, s16 inst,
 		u16 rstctrl_offs, u16 rstst_offs);
+#endif /* ASSEMBLER */
+
 #endif
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 05/18] ARM: OMAP2+: AM33XX: CM/PRM: Use __ASSEMBLER__ macros in header files
@ 2012-12-31 13:06   ` Vaibhav Bedia
  0 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:06 UTC (permalink / raw)
  To: linux-arm-kernel

This is necessary to ensure that macros declared here can
be reused from assembly files.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
---
v1->v2:
	Split out the header file changes in a separate patch
	based on the feedback from Santosh

 arch/arm/mach-omap2/cm33xx.h  |    3 +++
 arch/arm/mach-omap2/prm33xx.h |    3 +++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/cm33xx.h b/arch/arm/mach-omap2/cm33xx.h
index 8009e13..2f215cd 100644
--- a/arch/arm/mach-omap2/cm33xx.h
+++ b/arch/arm/mach-omap2/cm33xx.h
@@ -376,6 +376,7 @@
 #define AM33XX_CM_CEFUSE_CEFUSE_CLKCTRL			AM33XX_CM_REGADDR(AM33XX_CM_CEFUSE_MOD, 0x0020)
 
 
+#ifndef __ASSEMBLER__
 extern bool am33xx_cm_is_clkdm_in_hwsup(s16 inst, u16 cdoffs);
 extern void am33xx_cm_clkdm_enable_hwsup(s16 inst, u16 cdoffs);
 extern void am33xx_cm_clkdm_disable_hwsup(s16 inst, u16 cdoffs);
@@ -412,4 +413,6 @@ static inline int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs,
 }
 #endif
 
+#endif /* ASSEMBLER */
+
 #endif
diff --git a/arch/arm/mach-omap2/prm33xx.h b/arch/arm/mach-omap2/prm33xx.h
index 3f25c56..2f2eaa0 100644
--- a/arch/arm/mach-omap2/prm33xx.h
+++ b/arch/arm/mach-omap2/prm33xx.h
@@ -117,6 +117,7 @@
 #define AM33XX_PM_CEFUSE_PWRSTST_OFFSET		0x0004
 #define AM33XX_PM_CEFUSE_PWRSTST		AM33XX_PRM_REGADDR(AM33XX_PRM_CEFUSE_MOD, 0x0004)
 
+#ifndef __ASSEMBLER__
 extern u32 am33xx_prm_read_reg(s16 inst, u16 idx);
 extern void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx);
 extern u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
@@ -126,4 +127,6 @@ extern int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst,
 extern int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs);
 extern int am33xx_prm_deassert_hardreset(u8 shift, s16 inst,
 		u16 rstctrl_offs, u16 rstst_offs);
+#endif /* ASSEMBLER */
+
 #endif
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 06/18] ARM: OMAP2+: AM33XX: hwmod: Register OCMC RAM hwmod
  2012-12-31 13:06 ` Vaibhav Bedia
@ 2012-12-31 13:06   ` Vaibhav Bedia
  -1 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:06 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, tony, khilman
  Cc: Vaibhav Bedia, Santosh Shilimkar, Benoit Cousson, Paul Walmsley,
	Vaibhav Hiremath

OCMC RAM lies in the PER power domain and this memory
support retention.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
---
v1->v2:
	Move out the OCMC hwmod code from #if 0 block
	based on Vaibhav Hiremath's comment

 arch/arm/mach-omap2/omap_hwmod_33xx_data.c |   47 ++++++++++++++++------------
 1 files changed, 27 insertions(+), 20 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
index 081c71e..5e50e68 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
@@ -414,7 +414,6 @@ static struct omap_hwmod am33xx_adc_tsc_hwmod = {
  *    - cEFUSE (doesn't fall under any ocp_if)
  *    - clkdiv32k
  *    - debugss
- *    - ocmc ram
  *    - ocp watch point
  *    - aes0
  *    - sha0
@@ -481,25 +480,6 @@ static struct omap_hwmod am33xx_debugss_hwmod = {
 	},
 };
 
-/* ocmcram */
-static struct omap_hwmod_class am33xx_ocmcram_hwmod_class = {
-	.name = "ocmcram",
-};
-
-static struct omap_hwmod am33xx_ocmcram_hwmod = {
-	.name		= "ocmcram",
-	.class		= &am33xx_ocmcram_hwmod_class,
-	.clkdm_name	= "l3_clkdm",
-	.flags		= (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
-	.main_clk	= "l3_gclk",
-	.prcm		= {
-		.omap4	= {
-			.clkctrl_offs	= AM33XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET,
-			.modulemode	= MODULEMODE_SWCTRL,
-		},
-	},
-};
-
 /* ocpwp */
 static struct omap_hwmod_class am33xx_ocpwp_hwmod_class = {
 	.name		= "ocpwp",
@@ -570,6 +550,25 @@ static struct omap_hwmod am33xx_sha0_hwmod = {
 
 #endif
 
+/* ocmcram */
+static struct omap_hwmod_class am33xx_ocmcram_hwmod_class = {
+	.name = "ocmcram",
+};
+
+static struct omap_hwmod am33xx_ocmcram_hwmod = {
+	.name		= "ocmcram",
+	.class		= &am33xx_ocmcram_hwmod_class,
+	.clkdm_name	= "l3_clkdm",
+	.flags		= (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
+	.main_clk	= "l3_gclk",
+	.prcm		= {
+		.omap4	= {
+			.clkctrl_offs	= AM33XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET,
+			.modulemode	= MODULEMODE_SWCTRL,
+		},
+	},
+};
+
 /* 'smartreflex' class */
 static struct omap_hwmod_class am33xx_smartreflex_hwmod_class = {
 	.name		= "smartreflex",
@@ -3328,6 +3327,13 @@ static struct omap_hwmod_ocp_if am33xx_l3_s__usbss = {
 	.flags		= OCPIF_SWSUP_IDLE,
 };
 
+/* l3 main -> ocmc */
+static struct omap_hwmod_ocp_if am33xx_l3_main__ocmc = {
+	.master		= &am33xx_l3_main_hwmod,
+	.slave		= &am33xx_ocmcram_hwmod,
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
 static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = {
 	&am33xx_l4_fw__emif_fw,
 	&am33xx_l3_main__emif,
@@ -3398,6 +3404,7 @@ static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = {
 	&am33xx_l3_main__tptc0,
 	&am33xx_l3_main__tptc1,
 	&am33xx_l3_main__tptc2,
+	&am33xx_l3_main__ocmc,
 	&am33xx_l3_s__usbss,
 	&am33xx_l4_hs__cpgmac0,
 	&am33xx_cpgmac0__mdio,
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 06/18] ARM: OMAP2+: AM33XX: hwmod: Register OCMC RAM hwmod
@ 2012-12-31 13:06   ` Vaibhav Bedia
  0 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:06 UTC (permalink / raw)
  To: linux-arm-kernel

OCMC RAM lies in the PER power domain and this memory
support retention.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
---
v1->v2:
	Move out the OCMC hwmod code from #if 0 block
	based on Vaibhav Hiremath's comment

 arch/arm/mach-omap2/omap_hwmod_33xx_data.c |   47 ++++++++++++++++------------
 1 files changed, 27 insertions(+), 20 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
index 081c71e..5e50e68 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
@@ -414,7 +414,6 @@ static struct omap_hwmod am33xx_adc_tsc_hwmod = {
  *    - cEFUSE (doesn't fall under any ocp_if)
  *    - clkdiv32k
  *    - debugss
- *    - ocmc ram
  *    - ocp watch point
  *    - aes0
  *    - sha0
@@ -481,25 +480,6 @@ static struct omap_hwmod am33xx_debugss_hwmod = {
 	},
 };
 
-/* ocmcram */
-static struct omap_hwmod_class am33xx_ocmcram_hwmod_class = {
-	.name = "ocmcram",
-};
-
-static struct omap_hwmod am33xx_ocmcram_hwmod = {
-	.name		= "ocmcram",
-	.class		= &am33xx_ocmcram_hwmod_class,
-	.clkdm_name	= "l3_clkdm",
-	.flags		= (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
-	.main_clk	= "l3_gclk",
-	.prcm		= {
-		.omap4	= {
-			.clkctrl_offs	= AM33XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET,
-			.modulemode	= MODULEMODE_SWCTRL,
-		},
-	},
-};
-
 /* ocpwp */
 static struct omap_hwmod_class am33xx_ocpwp_hwmod_class = {
 	.name		= "ocpwp",
@@ -570,6 +550,25 @@ static struct omap_hwmod am33xx_sha0_hwmod = {
 
 #endif
 
+/* ocmcram */
+static struct omap_hwmod_class am33xx_ocmcram_hwmod_class = {
+	.name = "ocmcram",
+};
+
+static struct omap_hwmod am33xx_ocmcram_hwmod = {
+	.name		= "ocmcram",
+	.class		= &am33xx_ocmcram_hwmod_class,
+	.clkdm_name	= "l3_clkdm",
+	.flags		= (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET),
+	.main_clk	= "l3_gclk",
+	.prcm		= {
+		.omap4	= {
+			.clkctrl_offs	= AM33XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET,
+			.modulemode	= MODULEMODE_SWCTRL,
+		},
+	},
+};
+
 /* 'smartreflex' class */
 static struct omap_hwmod_class am33xx_smartreflex_hwmod_class = {
 	.name		= "smartreflex",
@@ -3328,6 +3327,13 @@ static struct omap_hwmod_ocp_if am33xx_l3_s__usbss = {
 	.flags		= OCPIF_SWSUP_IDLE,
 };
 
+/* l3 main -> ocmc */
+static struct omap_hwmod_ocp_if am33xx_l3_main__ocmc = {
+	.master		= &am33xx_l3_main_hwmod,
+	.slave		= &am33xx_ocmcram_hwmod,
+	.user		= OCP_USER_MPU | OCP_USER_SDMA,
+};
+
 static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = {
 	&am33xx_l4_fw__emif_fw,
 	&am33xx_l3_main__emif,
@@ -3398,6 +3404,7 @@ static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = {
 	&am33xx_l3_main__tptc0,
 	&am33xx_l3_main__tptc1,
 	&am33xx_l3_main__tptc2,
+	&am33xx_l3_main__ocmc,
 	&am33xx_l3_s__usbss,
 	&am33xx_l4_hs__cpgmac0,
 	&am33xx_cpgmac0__mdio,
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 07/18] ARM: OMAP2+: AM33XX: hwmod: Update TPTC0 hwmod with the right flags
  2012-12-31 13:06 ` Vaibhav Bedia
@ 2012-12-31 13:07   ` Vaibhav Bedia
  -1 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, tony, khilman
  Cc: Vaibhav Bedia, Santosh Shilimkar, Benoit Cousson, Paul Walmsley,
	Vaibhav Hiremath

TPTC0 needs to be idled and put to standby under SW control.
Add the appropriate flags in the TPTC0 hwmod entry.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
---
v1->v2:
	No change

 arch/arm/mach-omap2/omap_hwmod_33xx_data.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
index 5e50e68..5c34d4b 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
@@ -1823,6 +1823,7 @@ static struct omap_hwmod am33xx_tptc0_hwmod = {
 	.class		= &am33xx_tptc_hwmod_class,
 	.clkdm_name	= "l3_clkdm",
 	.mpu_irqs	= am33xx_tptc0_irqs,
+	.flags		= (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY),
 	.main_clk	= "l3_gclk",
 	.prcm		= {
 		.omap4	= {
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 07/18] ARM: OMAP2+: AM33XX: hwmod: Update TPTC0 hwmod with the right flags
@ 2012-12-31 13:07   ` Vaibhav Bedia
  0 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

TPTC0 needs to be idled and put to standby under SW control.
Add the appropriate flags in the TPTC0 hwmod entry.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
---
v1->v2:
	No change

 arch/arm/mach-omap2/omap_hwmod_33xx_data.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
index 5e50e68..5c34d4b 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
@@ -1823,6 +1823,7 @@ static struct omap_hwmod am33xx_tptc0_hwmod = {
 	.class		= &am33xx_tptc_hwmod_class,
 	.clkdm_name	= "l3_clkdm",
 	.mpu_irqs	= am33xx_tptc0_irqs,
+	.flags		= (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY),
 	.main_clk	= "l3_gclk",
 	.prcm		= {
 		.omap4	= {
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 08/18] ARM: OMAP2+: AM33XX: hwmod: Fixup cpgmac0 hwmod entry
  2012-12-31 13:06 ` Vaibhav Bedia
@ 2012-12-31 13:07   ` Vaibhav Bedia
  -1 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, tony, khilman
  Cc: Vaibhav Bedia, Santosh Shilimkar, Benoit Cousson, Paul Walmsley,
	Vaibhav Hiremath

The current HWMOD code expects the memory region with
the IP's SYSCONFIG register to be marked with ADDR_TYPE_RT
flag.

CPGMAC0 hwmod entry specifies two memory regions and marks
both with the flag ADDR_TYPE_RT although only the 2nd region
has the SYSCONFIG register. This leads to the HWMOD code
accessing the wrong memory address for idle and standby
operations. Fix this by removing the ADDR_TYPE_RT flag from
the 1st memory region in CPGMAC0 hwmod entry.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
---
v1->v2:
	Address review comments from Santosh and
	Vaibhav Hiremath. Previous discussion on the change
	is @ http://lists.infradead.org/pipermail/linux-arm-kernel/2012-November/129512.html

 arch/arm/mach-omap2/omap_hwmod_33xx_data.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
index 5c34d4b..863ce08 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
@@ -2496,7 +2496,6 @@ static struct omap_hwmod_addr_space am33xx_cpgmac0_addr_space[] = {
 	{
 		.pa_start	= 0x4a100000,
 		.pa_end		= 0x4a100000 + SZ_2K - 1,
-		.flags		= ADDR_TYPE_RT,
 	},
 	/* cpsw wr */
 	{
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 08/18] ARM: OMAP2+: AM33XX: hwmod: Fixup cpgmac0 hwmod entry
@ 2012-12-31 13:07   ` Vaibhav Bedia
  0 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

The current HWMOD code expects the memory region with
the IP's SYSCONFIG register to be marked with ADDR_TYPE_RT
flag.

CPGMAC0 hwmod entry specifies two memory regions and marks
both with the flag ADDR_TYPE_RT although only the 2nd region
has the SYSCONFIG register. This leads to the HWMOD code
accessing the wrong memory address for idle and standby
operations. Fix this by removing the ADDR_TYPE_RT flag from
the 1st memory region in CPGMAC0 hwmod entry.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
---
v1->v2:
	Address review comments from Santosh and
	Vaibhav Hiremath. Previous discussion on the change
	is @ http://lists.infradead.org/pipermail/linux-arm-kernel/2012-November/129512.html

 arch/arm/mach-omap2/omap_hwmod_33xx_data.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
index 5c34d4b..863ce08 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
@@ -2496,7 +2496,6 @@ static struct omap_hwmod_addr_space am33xx_cpgmac0_addr_space[] = {
 	{
 		.pa_start	= 0x4a100000,
 		.pa_end		= 0x4a100000 + SZ_2K - 1,
-		.flags		= ADDR_TYPE_RT,
 	},
 	/* cpsw wr */
 	{
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 09/18] ARM: OMAP2+: AM33XX: hwmod: Update the WKUP-M3 hwmod with reset status bit
  2012-12-31 13:06 ` Vaibhav Bedia
@ 2012-12-31 13:07   ` Vaibhav Bedia
  -1 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, tony, khilman
  Cc: Vaibhav Bedia, Santosh Shilimkar, Benoit Cousson, Paul Walmsley,
	Vaibhav Hiremath

WKUP-M3 has a reset status bit (RM_WKUP_STST.WKUP_M3_LRST)
Update the WKUP-M3 hwmod data to reflect the same.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
---
v1->v2:
	Change the patch order to keep git bisect happy

 arch/arm/mach-omap2/omap_hwmod_33xx_data.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
index 863ce08..bd4b171 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
@@ -269,6 +269,7 @@ static struct omap_hwmod am33xx_wkup_m3_hwmod = {
 		.omap4	= {
 			.clkctrl_offs	= AM33XX_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET,
 			.rstctrl_offs	= AM33XX_RM_WKUP_RSTCTRL_OFFSET,
+			.rstst_offs	= AM33XX_RM_WKUP_RSTST_OFFSET,
 			.modulemode	= MODULEMODE_SWCTRL,
 		},
 	},
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 09/18] ARM: OMAP2+: AM33XX: hwmod: Update the WKUP-M3 hwmod with reset status bit
@ 2012-12-31 13:07   ` Vaibhav Bedia
  0 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

WKUP-M3 has a reset status bit (RM_WKUP_STST.WKUP_M3_LRST)
Update the WKUP-M3 hwmod data to reflect the same.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
---
v1->v2:
	Change the patch order to keep git bisect happy

 arch/arm/mach-omap2/omap_hwmod_33xx_data.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
index 863ce08..bd4b171 100644
--- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
@@ -269,6 +269,7 @@ static struct omap_hwmod am33xx_wkup_m3_hwmod = {
 		.omap4	= {
 			.clkctrl_offs	= AM33XX_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET,
 			.rstctrl_offs	= AM33XX_RM_WKUP_RSTCTRL_OFFSET,
+			.rstst_offs	= AM33XX_RM_WKUP_RSTST_OFFSET,
 			.modulemode	= MODULEMODE_SWCTRL,
 		},
 	},
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 10/18] ARM: OMAP2+: AM33XX: Update the hardreset API
  2012-12-31 13:06 ` Vaibhav Bedia
@ 2012-12-31 13:07   ` Vaibhav Bedia
  -1 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, tony, khilman
  Cc: Vaibhav Bedia, Santosh Shilimkar, Benoit Cousson, Paul Walmsley,
	Vaibhav Hiremath

WKUP-M3 has a reset status bit (RM_WKUP_STST.WKUP_M3_LRST)
Update the hardreset API to ensure that the reset line properly
deasserted.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
---
v1->v2:
	Address comments from Vaibhav Hiremath and
	change the patch order as pointed out by
	Santosh Shilimkar

 arch/arm/mach-omap2/omap_hwmod.c |    5 +----
 arch/arm/mach-omap2/prm33xx.c    |   11 +++++++----
 arch/arm/mach-omap2/prm33xx.h    |    2 +-
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 4653efb..6549439 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -3041,11 +3041,8 @@ static int _am33xx_assert_hardreset(struct omap_hwmod *oh,
 static int _am33xx_deassert_hardreset(struct omap_hwmod *oh,
 				     struct omap_hwmod_rst_info *ohri)
 {
-	if (ohri->st_shift)
-		pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n",
-		       oh->name, ohri->name);
-
 	return am33xx_prm_deassert_hardreset(ohri->rst_shift,
+				ohri->st_shift,
 				oh->clkdm->pwrdm.ptr->prcm_offs,
 				oh->prcm.omap4.rstctrl_offs,
 				oh->prcm.omap4.rstst_offs);
diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c
index 1ac7388..44c0d72 100644
--- a/arch/arm/mach-omap2/prm33xx.c
+++ b/arch/arm/mach-omap2/prm33xx.c
@@ -110,11 +110,11 @@ int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs)
  * -EINVAL upon an argument error, -EEXIST if the submodule was already out
  * of reset, or -EBUSY if the submodule did not exit reset promptly.
  */
-int am33xx_prm_deassert_hardreset(u8 shift, s16 inst,
+int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, s16 inst,
 		u16 rstctrl_offs, u16 rstst_offs)
 {
 	int c;
-	u32 mask = 1 << shift;
+	u32 mask = 1 << st_shift;
 
 	/* Check the current status to avoid  de-asserting the line twice */
 	if (am33xx_prm_is_hardreset_asserted(shift, inst, rstctrl_offs) == 0)
@@ -122,11 +122,14 @@ int am33xx_prm_deassert_hardreset(u8 shift, s16 inst,
 
 	/* Clear the reset status by writing 1 to the status bit */
 	am33xx_prm_rmw_reg_bits(0xffffffff, mask, inst, rstst_offs);
+
 	/* de-assert the reset control line */
+	mask = 1 << shift;
+
 	am33xx_prm_rmw_reg_bits(mask, 0, inst, rstctrl_offs);
-	/* wait the status to be set */
 
-	omap_test_timeout(am33xx_prm_is_hardreset_asserted(shift, inst,
+	/* wait the status to be set */
+	omap_test_timeout(am33xx_prm_is_hardreset_asserted(st_shift, inst,
 							   rstst_offs),
 			  MAX_MODULE_HARDRESET_WAIT, c);
 
diff --git a/arch/arm/mach-omap2/prm33xx.h b/arch/arm/mach-omap2/prm33xx.h
index 2f2eaa0..aefde49 100644
--- a/arch/arm/mach-omap2/prm33xx.h
+++ b/arch/arm/mach-omap2/prm33xx.h
@@ -125,7 +125,7 @@ extern void am33xx_prm_global_warm_sw_reset(void);
 extern int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst,
 		u16 rstctrl_offs);
 extern int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs);
-extern int am33xx_prm_deassert_hardreset(u8 shift, s16 inst,
+extern int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, s16 inst,
 		u16 rstctrl_offs, u16 rstst_offs);
 #endif /* ASSEMBLER */
 
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 10/18] ARM: OMAP2+: AM33XX: Update the hardreset API
@ 2012-12-31 13:07   ` Vaibhav Bedia
  0 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

WKUP-M3 has a reset status bit (RM_WKUP_STST.WKUP_M3_LRST)
Update the hardreset API to ensure that the reset line properly
deasserted.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
---
v1->v2:
	Address comments from Vaibhav Hiremath and
	change the patch order as pointed out by
	Santosh Shilimkar

 arch/arm/mach-omap2/omap_hwmod.c |    5 +----
 arch/arm/mach-omap2/prm33xx.c    |   11 +++++++----
 arch/arm/mach-omap2/prm33xx.h    |    2 +-
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 4653efb..6549439 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -3041,11 +3041,8 @@ static int _am33xx_assert_hardreset(struct omap_hwmod *oh,
 static int _am33xx_deassert_hardreset(struct omap_hwmod *oh,
 				     struct omap_hwmod_rst_info *ohri)
 {
-	if (ohri->st_shift)
-		pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n",
-		       oh->name, ohri->name);
-
 	return am33xx_prm_deassert_hardreset(ohri->rst_shift,
+				ohri->st_shift,
 				oh->clkdm->pwrdm.ptr->prcm_offs,
 				oh->prcm.omap4.rstctrl_offs,
 				oh->prcm.omap4.rstst_offs);
diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c
index 1ac7388..44c0d72 100644
--- a/arch/arm/mach-omap2/prm33xx.c
+++ b/arch/arm/mach-omap2/prm33xx.c
@@ -110,11 +110,11 @@ int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs)
  * -EINVAL upon an argument error, -EEXIST if the submodule was already out
  * of reset, or -EBUSY if the submodule did not exit reset promptly.
  */
-int am33xx_prm_deassert_hardreset(u8 shift, s16 inst,
+int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, s16 inst,
 		u16 rstctrl_offs, u16 rstst_offs)
 {
 	int c;
-	u32 mask = 1 << shift;
+	u32 mask = 1 << st_shift;
 
 	/* Check the current status to avoid  de-asserting the line twice */
 	if (am33xx_prm_is_hardreset_asserted(shift, inst, rstctrl_offs) == 0)
@@ -122,11 +122,14 @@ int am33xx_prm_deassert_hardreset(u8 shift, s16 inst,
 
 	/* Clear the reset status by writing 1 to the status bit */
 	am33xx_prm_rmw_reg_bits(0xffffffff, mask, inst, rstst_offs);
+
 	/* de-assert the reset control line */
+	mask = 1 << shift;
+
 	am33xx_prm_rmw_reg_bits(mask, 0, inst, rstctrl_offs);
-	/* wait the status to be set */
 
-	omap_test_timeout(am33xx_prm_is_hardreset_asserted(shift, inst,
+	/* wait the status to be set */
+	omap_test_timeout(am33xx_prm_is_hardreset_asserted(st_shift, inst,
 							   rstst_offs),
 			  MAX_MODULE_HARDRESET_WAIT, c);
 
diff --git a/arch/arm/mach-omap2/prm33xx.h b/arch/arm/mach-omap2/prm33xx.h
index 2f2eaa0..aefde49 100644
--- a/arch/arm/mach-omap2/prm33xx.h
+++ b/arch/arm/mach-omap2/prm33xx.h
@@ -125,7 +125,7 @@ extern void am33xx_prm_global_warm_sw_reset(void);
 extern int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst,
 		u16 rstctrl_offs);
 extern int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs);
-extern int am33xx_prm_deassert_hardreset(u8 shift, s16 inst,
+extern int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, s16 inst,
 		u16 rstctrl_offs, u16 rstst_offs);
 #endif /* ASSEMBLER */
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 11/18] ARM: DTS: AM33XX: Add nodes for OCMC RAM and WKUP-M3
  2012-12-31 13:06 ` Vaibhav Bedia
@ 2012-12-31 13:07   ` Vaibhav Bedia
  -1 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, tony, khilman
  Cc: Vaibhav Bedia, Santosh Shilimkar, Benoit Cousson, Paul Walmsley,
	Vaibhav Hiremath

Since AM33XX supports only DT-boot, this is needed
for the appropriate device nodes to be created.

Note: OCMC RAM is part of the PER power domain and supports
retention. The assembly code for low power entry/exit will
run from OCMC RAM. To ensure that the OMAP PM code does not
attempt to disable the clock to OCMC RAM as part of the
suspend process add the no_idle_on_suspend flag.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Tony Lindgren <tony@atomide.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
---
v1->v2:
	Add a proper changelog

 arch/arm/boot/dts/am33xx.dtsi |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index c2f14e8..4731748 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -385,5 +385,16 @@
 				mac-address = [ 00 00 00 00 00 00 ];
 			};
 		};
+
+		ocmcram: ocmcram@40300000 {
+			compatible = "ti,ocmcram";
+			ti,hwmods = "ocmcram";
+			ti,no_idle_on_suspend;
+		};
+
+		wkup_m3: wkup_m3@44d00000 {
+			compatible = "ti,wkup_m3";
+			ti,hwmods = "wkup_m3";
+		};
 	};
 };
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 11/18] ARM: DTS: AM33XX: Add nodes for OCMC RAM and WKUP-M3
@ 2012-12-31 13:07   ` Vaibhav Bedia
  0 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

Since AM33XX supports only DT-boot, this is needed
for the appropriate device nodes to be created.

Note: OCMC RAM is part of the PER power domain and supports
retention. The assembly code for low power entry/exit will
run from OCMC RAM. To ensure that the OMAP PM code does not
attempt to disable the clock to OCMC RAM as part of the
suspend process add the no_idle_on_suspend flag.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Tony Lindgren <tony@atomide.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
---
v1->v2:
	Add a proper changelog

 arch/arm/boot/dts/am33xx.dtsi |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index c2f14e8..4731748 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -385,5 +385,16 @@
 				mac-address = [ 00 00 00 00 00 00 ];
 			};
 		};
+
+		ocmcram: ocmcram at 40300000 {
+			compatible = "ti,ocmcram";
+			ti,hwmods = "ocmcram";
+			ti,no_idle_on_suspend;
+		};
+
+		wkup_m3: wkup_m3 at 44d00000 {
+			compatible = "ti,wkup_m3";
+			ti,hwmods = "wkup_m3";
+		};
 	};
 };
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 12/18] ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent device
  2012-12-31 13:06 ` Vaibhav Bedia
@ 2012-12-31 13:07   ` Vaibhav Bedia
  -1 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, tony, khilman
  Cc: Vaibhav Bedia, Santosh Shilimkar, Benoit Cousson, Paul Walmsley,
	Vaibhav Hiremath, Jon Hunter

The current OMAP timer code registers two timers -
one as clocksource and one as clockevent.
AM33XX has only one usable timer in the WKUP domain
so one of the timers needs suspend-resume support
to restore the configuration to pre-suspend state.

commit adc78e6 (timekeeping: Add suspend and resume
of clock event devices) introduced .suspend and .resume
callbacks for clock event devices. Leverages these
callbacks to have AM33XX clockevent timer which is
in not in WKUP domain to behave properly across system
suspend.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
Cc: Jon Hunter <jon-hunter@ti.com>
---
v1->v2:
	Get rid of harcoded timer id.
	Note: since a platform device is not created for these timer
	instances and because there's very minimal change needed for
	restarting the timer a full blown context save and restore
	has been skipped.

 arch/arm/mach-omap2/timer.c |   33 +++++++++++++++++++++++++++++++++
 1 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 691aa67..38f9cbc 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -128,6 +128,36 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
 	}
 }
 
+static void omap_clkevt_suspend(struct clock_event_device *unused)
+{
+	char name[10];
+	struct omap_hwmod *oh;
+
+	sprintf(name, "timer%d", clkev.id);
+	oh = omap_hwmod_lookup(name);
+	if (!oh)
+		return;
+
+	__omap_dm_timer_stop(&clkev, 1, clkev.rate);
+	omap_hwmod_idle(oh);
+}
+
+static void omap_clkevt_resume(struct clock_event_device *unused)
+{
+	char name[10];
+	struct omap_hwmod *oh;
+
+	sprintf(name, "timer%d", clkev.id);
+	oh = omap_hwmod_lookup(name);
+	if (!oh)
+		return;
+
+	omap_hwmod_enable(oh);
+	__omap_dm_timer_load_start(&clkev,
+			OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
+	__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
+}
+
 static struct clock_event_device clockevent_gpt = {
 	.name		= "gp_timer",
 	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
@@ -135,6 +165,8 @@ static struct clock_event_device clockevent_gpt = {
 	.rating		= 300,
 	.set_next_event	= omap2_gp_timer_set_next_event,
 	.set_mode	= omap2_gp_timer_set_mode,
+	.suspend	= omap_clkevt_suspend,
+	.resume		= omap_clkevt_resume,
 };
 
 static struct property device_disabled = {
@@ -323,6 +355,7 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
 	int res;
 
 	clkev.errata = omap_dm_timer_get_errata();
+	clkev.id = gptimer_id;
 
 	/*
 	 * For clock-event timers we never read the timer counter and
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 12/18] ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent device
@ 2012-12-31 13:07   ` Vaibhav Bedia
  0 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

The current OMAP timer code registers two timers -
one as clocksource and one as clockevent.
AM33XX has only one usable timer in the WKUP domain
so one of the timers needs suspend-resume support
to restore the configuration to pre-suspend state.

commit adc78e6 (timekeeping: Add suspend and resume
of clock event devices) introduced .suspend and .resume
callbacks for clock event devices. Leverages these
callbacks to have AM33XX clockevent timer which is
in not in WKUP domain to behave properly across system
suspend.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
Cc: Jon Hunter <jon-hunter@ti.com>
---
v1->v2:
	Get rid of harcoded timer id.
	Note: since a platform device is not created for these timer
	instances and because there's very minimal change needed for
	restarting the timer a full blown context save and restore
	has been skipped.

 arch/arm/mach-omap2/timer.c |   33 +++++++++++++++++++++++++++++++++
 1 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 691aa67..38f9cbc 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -128,6 +128,36 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
 	}
 }
 
+static void omap_clkevt_suspend(struct clock_event_device *unused)
+{
+	char name[10];
+	struct omap_hwmod *oh;
+
+	sprintf(name, "timer%d", clkev.id);
+	oh = omap_hwmod_lookup(name);
+	if (!oh)
+		return;
+
+	__omap_dm_timer_stop(&clkev, 1, clkev.rate);
+	omap_hwmod_idle(oh);
+}
+
+static void omap_clkevt_resume(struct clock_event_device *unused)
+{
+	char name[10];
+	struct omap_hwmod *oh;
+
+	sprintf(name, "timer%d", clkev.id);
+	oh = omap_hwmod_lookup(name);
+	if (!oh)
+		return;
+
+	omap_hwmod_enable(oh);
+	__omap_dm_timer_load_start(&clkev,
+			OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
+	__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
+}
+
 static struct clock_event_device clockevent_gpt = {
 	.name		= "gp_timer",
 	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
@@ -135,6 +165,8 @@ static struct clock_event_device clockevent_gpt = {
 	.rating		= 300,
 	.set_next_event	= omap2_gp_timer_set_next_event,
 	.set_mode	= omap2_gp_timer_set_mode,
+	.suspend	= omap_clkevt_suspend,
+	.resume		= omap_clkevt_resume,
 };
 
 static struct property device_disabled = {
@@ -323,6 +355,7 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
 	int res;
 
 	clkev.errata = omap_dm_timer_get_errata();
+	clkev.id = gptimer_id;
 
 	/*
 	 * For clock-event timers we never read the timer counter and
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 13/18] ARM: OMAP2+: AM33XX: timer: Interchance clkevt and clksrc timers
  2012-12-31 13:06 ` Vaibhav Bedia
@ 2012-12-31 13:07   ` Vaibhav Bedia
  -1 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, tony, khilman
  Cc: Vaibhav Bedia, Vaibhav Hiremath, Santosh Shilimkar,
	Benoit Cousson, Paul Walmsley, Jon Hunter

AM33XX has two timers (DTIMER0/1) in the WKUP domain.
On GP devices the source of DMTIMER0 is fixed to an
inaccurate internal 32k RC oscillator and this makes
the DMTIMER0 practically either as a clocksource or
as clockevent.

Currently the timer instance in WKUP domain is used
as the clockevent and the timer in non-WKUP domain
as the clocksource. DMTIMER1 in WKUP domain can keep
running in suspend from a 32K clock fed from external
OSC and can serve as the persistent clock for the kernel.
To enable this, interchange the timers used as clocksource
and clockevent for AM33XX.

For now a new DT property has been added to allow the timer code
to select the timer with the right property.

It has been pointed out by Santosh Shilimkar and Kevin Hilman
that such a change will result in soc-idle never being achieved
on AM33XX. There are other reasons why soc-idle does not look
feasible on AM33XX so for now we go ahead with the interchange
of the the timers. If at a later point of time we do come up
with an approach which makes soc-idle possible on AM33XX, this
can be revisited.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
Cc: Tony Lingren <tony@atomide.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Jon Hunter <jon-hunter@ti.com>

---
v1->v2:
	Use DT properties for changing the timers

 .../devicetree/bindings/arm/omap/timer.txt         |    2 ++
 arch/arm/boot/dts/am33xx.dtsi                      |    1 +
 arch/arm/mach-omap2/timer.c                        |    6 +++---
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/omap/timer.txt b/Documentation/devicetree/bindings/arm/omap/timer.txt
index 8732d4d..62d4f2c 100644
--- a/Documentation/devicetree/bindings/arm/omap/timer.txt
+++ b/Documentation/devicetree/bindings/arm/omap/timer.txt
@@ -18,6 +18,8 @@ Optional properties:
 - ti,timer-pwm: 	Indicates the timer can generate a PWM output.
 - ti,timer-secure: 	Indicates the timer is reserved on a secure OMAP device
 			and therefore cannot be used by the kernel.
+- ti,timer-non-wkup	Indicates the timer is in non-wkup power domain and hence
+			will lose register context when the power domain transitions
 
 Example:
 
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index 4731748..b4e8bf7 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -251,6 +251,7 @@
 			reg = <0x48040000 0x400>;
 			interrupts = <68>;
 			ti,hwmods = "timer2";
+			ti,timer-non-wkup;
 		};
 
 		timer3: timer@48042000 {
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 38f9cbc..cfb3413 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -264,7 +264,7 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
 	int r = 0;
 
 	if (of_have_populated_dt()) {
-		np = omap_get_timer_dt(omap_timer_match, NULL);
+		np = omap_get_timer_dt(omap_timer_match, property);
 		if (!np)
 			return -ENODEV;
 
@@ -633,8 +633,8 @@ OMAP_SYS_TIMER(3_gp, gptimer);
 #endif /* CONFIG_ARCH_OMAP3 */
 
 #ifdef CONFIG_SOC_AM33XX
-OMAP_SYS_GP_TIMER_INIT(3_am33xx, 1, OMAP4_MPU_SOURCE, "ti,timer-alwon",
-		       2, OMAP4_MPU_SOURCE);
+OMAP_SYS_GP_TIMER_INIT(3_am33xx, 2, OMAP4_MPU_SOURCE, "ti,timer-non-wkup",
+		       1, OMAP4_MPU_SOURCE);
 OMAP_SYS_TIMER(3_am33xx, gptimer);
 #endif /* CONFIG_SOC_AM33XX */
 
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 13/18] ARM: OMAP2+: AM33XX: timer: Interchance clkevt and clksrc timers
@ 2012-12-31 13:07   ` Vaibhav Bedia
  0 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

AM33XX has two timers (DTIMER0/1) in the WKUP domain.
On GP devices the source of DMTIMER0 is fixed to an
inaccurate internal 32k RC oscillator and this makes
the DMTIMER0 practically either as a clocksource or
as clockevent.

Currently the timer instance in WKUP domain is used
as the clockevent and the timer in non-WKUP domain
as the clocksource. DMTIMER1 in WKUP domain can keep
running in suspend from a 32K clock fed from external
OSC and can serve as the persistent clock for the kernel.
To enable this, interchange the timers used as clocksource
and clockevent for AM33XX.

For now a new DT property has been added to allow the timer code
to select the timer with the right property.

It has been pointed out by Santosh Shilimkar and Kevin Hilman
that such a change will result in soc-idle never being achieved
on AM33XX. There are other reasons why soc-idle does not look
feasible on AM33XX so for now we go ahead with the interchange
of the the timers. If at a later point of time we do come up
with an approach which makes soc-idle possible on AM33XX, this
can be revisited.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
Cc: Tony Lingren <tony@atomide.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Jon Hunter <jon-hunter@ti.com>

---
v1->v2:
	Use DT properties for changing the timers

 .../devicetree/bindings/arm/omap/timer.txt         |    2 ++
 arch/arm/boot/dts/am33xx.dtsi                      |    1 +
 arch/arm/mach-omap2/timer.c                        |    6 +++---
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/arm/omap/timer.txt b/Documentation/devicetree/bindings/arm/omap/timer.txt
index 8732d4d..62d4f2c 100644
--- a/Documentation/devicetree/bindings/arm/omap/timer.txt
+++ b/Documentation/devicetree/bindings/arm/omap/timer.txt
@@ -18,6 +18,8 @@ Optional properties:
 - ti,timer-pwm: 	Indicates the timer can generate a PWM output.
 - ti,timer-secure: 	Indicates the timer is reserved on a secure OMAP device
 			and therefore cannot be used by the kernel.
+- ti,timer-non-wkup	Indicates the timer is in non-wkup power domain and hence
+			will lose register context when the power domain transitions
 
 Example:
 
diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
index 4731748..b4e8bf7 100644
--- a/arch/arm/boot/dts/am33xx.dtsi
+++ b/arch/arm/boot/dts/am33xx.dtsi
@@ -251,6 +251,7 @@
 			reg = <0x48040000 0x400>;
 			interrupts = <68>;
 			ti,hwmods = "timer2";
+			ti,timer-non-wkup;
 		};
 
 		timer3: timer at 48042000 {
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 38f9cbc..cfb3413 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -264,7 +264,7 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
 	int r = 0;
 
 	if (of_have_populated_dt()) {
-		np = omap_get_timer_dt(omap_timer_match, NULL);
+		np = omap_get_timer_dt(omap_timer_match, property);
 		if (!np)
 			return -ENODEV;
 
@@ -633,8 +633,8 @@ OMAP_SYS_TIMER(3_gp, gptimer);
 #endif /* CONFIG_ARCH_OMAP3 */
 
 #ifdef CONFIG_SOC_AM33XX
-OMAP_SYS_GP_TIMER_INIT(3_am33xx, 1, OMAP4_MPU_SOURCE, "ti,timer-alwon",
-		       2, OMAP4_MPU_SOURCE);
+OMAP_SYS_GP_TIMER_INIT(3_am33xx, 2, OMAP4_MPU_SOURCE, "ti,timer-non-wkup",
+		       1, OMAP4_MPU_SOURCE);
 OMAP_SYS_TIMER(3_am33xx, gptimer);
 #endif /* CONFIG_SOC_AM33XX */
 
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 14/18] ARM: OMAP2+: AM33XX: control: Add some control module registers and APIs
  2012-12-31 13:06 ` Vaibhav Bedia
@ 2012-12-31 13:07   ` Vaibhav Bedia
  -1 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, tony, khilman
  Cc: Vaibhav Bedia, Santosh Shilimkar, Benoit Cousson, Paul Walmsley,
	Vaibhav Hiremath

Add minimal APIs for writing to the IPC and the M3_TXEV registers
in the Control module. These will be used in a subsequent patch which
adds suspend-resume support for AM33XX.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Tony Lingren <tony@atomide.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
---
v1->v2:
	This a new patch in the series to isolate
	the control module accesses as pointed out
	by Kevin Hilman.

 arch/arm/mach-omap2/control.c |   20 ++++++++++++++++++++
 arch/arm/mach-omap2/control.h |   41 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index 2adb268..c5d54ae 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -604,3 +604,23 @@ int omap3_ctrl_save_padconf(void)
 }
 
 #endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */
+
+#if defined(CONFIG_SOC_AM33XX) && defined(CONFIG_PM)
+void am33xx_txev_eoi(void)
+{
+	omap_ctrl_writel(AM33XX_M3_TXEV_ACK, AM33XX_CONTROL_M3_TXEV_EOI);
+}
+
+void am33xx_txev_enable(void)
+{
+	omap_ctrl_writel(AM33XX_M3_TXEV_ENABLE, AM33XX_CONTROL_M3_TXEV_EOI);
+}
+
+void am33xx_wkup_m3_ipc_cmd(struct am33xx_ipc_data *data)
+{
+	omap_ctrl_writel(data->resume_addr, AM33XX_CONTROL_IPC_MSG_REG0);
+	omap_ctrl_writel(data->sleep_mode, AM33XX_CONTROL_IPC_MSG_REG1);
+	omap_ctrl_writel(data->param1, AM33XX_CONTROL_IPC_MSG_REG2);
+	omap_ctrl_writel(data->param2, AM33XX_CONTROL_IPC_MSG_REG3);
+}
+#endif /* CONFIG_SOC_AM33XX && CONFIG_PM */
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
index 3d944d3..4b05eb9 100644
--- a/arch/arm/mach-omap2/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -358,6 +358,37 @@
 #define AM33XX_CONTROL_STATUS_SYSBOOT1_WIDTH		0x2
 #define AM33XX_CONTROL_STATUS_SYSBOOT1_MASK		(0x3 << 22)
 
+#define AM33XX_DDR_IO_CTRL		0x0E04
+#define AM33XX_VTP0_CTRL_REG		0x0E0C
+
+/* AM33XX VTP0_CTRL_REG bits */
+#define AM33XX_VTP_CTRL_START_EN	(1 << 0)
+#define AM33XX_VTP_CTRL_LOCK_EN		(1 << 4)
+#define AM33XX_VTP_CTRL_READY		(1 << 5)
+#define AM33XX_VTP_CTRL_ENABLE		(1 << 6)
+
+/* AM33XX M3_TXEV_EOI register */
+#define AM33XX_CONTROL_M3_TXEV_EOI	0x1324
+
+#define AM33XX_M3_TXEV_ACK		(0x1 << 0)
+#define AM33XX_M3_TXEV_ENABLE		(0x0 << 0)
+
+/* AM33XX IPC message registers */
+#define AM33XX_CONTROL_IPC_MSG_REG0	0x1328
+#define AM33XX_CONTROL_IPC_MSG_REG1	0x132C
+#define AM33XX_CONTROL_IPC_MSG_REG2	0x1330
+#define AM33XX_CONTROL_IPC_MSG_REG3	0x1334
+#define AM33XX_CONTROL_IPC_MSG_REG4	0x1338
+#define AM33XX_CONTROL_IPC_MSG_REG5	0x133C
+#define AM33XX_CONTROL_IPC_MSG_REG6	0x1340
+#define AM33XX_CONTROL_IPC_MSG_REG7	0x1344
+
+#define AM33XX_DDR_CMD0_IOCTRL		0x1404
+#define AM33XX_DDR_CMD1_IOCTRL		0x1408
+#define AM33XX_DDR_CMD2_IOCTRL		0x140C
+#define AM33XX_DDR_DATA0_IOCTRL		0x1440
+#define AM33XX_DDR_DATA1_IOCTRL		0x1444
+
 /* CONTROL OMAP STATUS register to identify OMAP3 features */
 #define OMAP3_CONTROL_OMAP_STATUS	0x044c
 
@@ -417,6 +448,16 @@ extern void omap3630_ctrl_disable_rta(void);
 extern int omap3_ctrl_save_padconf(void);
 extern void omap2_set_globals_control(void __iomem *ctrl,
 				      void __iomem *ctrl_pad);
+struct am33xx_ipc_data {
+	u32 resume_addr;
+	u32 param1;
+	u32 param2;
+	u32 sleep_mode;
+};
+extern void am33xx_wkup_m3_ipc_cmd(struct am33xx_ipc_data *data);
+extern void am33xx_txev_eoi(void);
+extern void am33xx_txev_enable(void);
+
 #else
 #define omap_ctrl_base_get()		0
 #define omap_ctrl_readb(x)		0
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 14/18] ARM: OMAP2+: AM33XX: control: Add some control module registers and APIs
@ 2012-12-31 13:07   ` Vaibhav Bedia
  0 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

Add minimal APIs for writing to the IPC and the M3_TXEV registers
in the Control module. These will be used in a subsequent patch which
adds suspend-resume support for AM33XX.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Tony Lingren <tony@atomide.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Vaibhav Hiremath <hvaibhav@ti.com>
---
v1->v2:
	This a new patch in the series to isolate
	the control module accesses as pointed out
	by Kevin Hilman.

 arch/arm/mach-omap2/control.c |   20 ++++++++++++++++++++
 arch/arm/mach-omap2/control.h |   41 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c
index 2adb268..c5d54ae 100644
--- a/arch/arm/mach-omap2/control.c
+++ b/arch/arm/mach-omap2/control.c
@@ -604,3 +604,23 @@ int omap3_ctrl_save_padconf(void)
 }
 
 #endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */
+
+#if defined(CONFIG_SOC_AM33XX) && defined(CONFIG_PM)
+void am33xx_txev_eoi(void)
+{
+	omap_ctrl_writel(AM33XX_M3_TXEV_ACK, AM33XX_CONTROL_M3_TXEV_EOI);
+}
+
+void am33xx_txev_enable(void)
+{
+	omap_ctrl_writel(AM33XX_M3_TXEV_ENABLE, AM33XX_CONTROL_M3_TXEV_EOI);
+}
+
+void am33xx_wkup_m3_ipc_cmd(struct am33xx_ipc_data *data)
+{
+	omap_ctrl_writel(data->resume_addr, AM33XX_CONTROL_IPC_MSG_REG0);
+	omap_ctrl_writel(data->sleep_mode, AM33XX_CONTROL_IPC_MSG_REG1);
+	omap_ctrl_writel(data->param1, AM33XX_CONTROL_IPC_MSG_REG2);
+	omap_ctrl_writel(data->param2, AM33XX_CONTROL_IPC_MSG_REG3);
+}
+#endif /* CONFIG_SOC_AM33XX && CONFIG_PM */
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
index 3d944d3..4b05eb9 100644
--- a/arch/arm/mach-omap2/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -358,6 +358,37 @@
 #define AM33XX_CONTROL_STATUS_SYSBOOT1_WIDTH		0x2
 #define AM33XX_CONTROL_STATUS_SYSBOOT1_MASK		(0x3 << 22)
 
+#define AM33XX_DDR_IO_CTRL		0x0E04
+#define AM33XX_VTP0_CTRL_REG		0x0E0C
+
+/* AM33XX VTP0_CTRL_REG bits */
+#define AM33XX_VTP_CTRL_START_EN	(1 << 0)
+#define AM33XX_VTP_CTRL_LOCK_EN		(1 << 4)
+#define AM33XX_VTP_CTRL_READY		(1 << 5)
+#define AM33XX_VTP_CTRL_ENABLE		(1 << 6)
+
+/* AM33XX M3_TXEV_EOI register */
+#define AM33XX_CONTROL_M3_TXEV_EOI	0x1324
+
+#define AM33XX_M3_TXEV_ACK		(0x1 << 0)
+#define AM33XX_M3_TXEV_ENABLE		(0x0 << 0)
+
+/* AM33XX IPC message registers */
+#define AM33XX_CONTROL_IPC_MSG_REG0	0x1328
+#define AM33XX_CONTROL_IPC_MSG_REG1	0x132C
+#define AM33XX_CONTROL_IPC_MSG_REG2	0x1330
+#define AM33XX_CONTROL_IPC_MSG_REG3	0x1334
+#define AM33XX_CONTROL_IPC_MSG_REG4	0x1338
+#define AM33XX_CONTROL_IPC_MSG_REG5	0x133C
+#define AM33XX_CONTROL_IPC_MSG_REG6	0x1340
+#define AM33XX_CONTROL_IPC_MSG_REG7	0x1344
+
+#define AM33XX_DDR_CMD0_IOCTRL		0x1404
+#define AM33XX_DDR_CMD1_IOCTRL		0x1408
+#define AM33XX_DDR_CMD2_IOCTRL		0x140C
+#define AM33XX_DDR_DATA0_IOCTRL		0x1440
+#define AM33XX_DDR_DATA1_IOCTRL		0x1444
+
 /* CONTROL OMAP STATUS register to identify OMAP3 features */
 #define OMAP3_CONTROL_OMAP_STATUS	0x044c
 
@@ -417,6 +448,16 @@ extern void omap3630_ctrl_disable_rta(void);
 extern int omap3_ctrl_save_padconf(void);
 extern void omap2_set_globals_control(void __iomem *ctrl,
 				      void __iomem *ctrl_pad);
+struct am33xx_ipc_data {
+	u32 resume_addr;
+	u32 param1;
+	u32 param2;
+	u32 sleep_mode;
+};
+extern void am33xx_wkup_m3_ipc_cmd(struct am33xx_ipc_data *data);
+extern void am33xx_txev_eoi(void);
+extern void am33xx_txev_enable(void);
+
 #else
 #define omap_ctrl_base_get()		0
 #define omap_ctrl_readb(x)		0
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 15/18] ARM: OMAP2+: AM33XX: Add assembly code for PM operations
  2012-12-31 13:06 ` Vaibhav Bedia
@ 2012-12-31 13:07   ` Vaibhav Bedia
  -1 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, tony, khilman
  Cc: Vaibhav Bedia, Santosh Shilimkar

In preparation for suspend-resume support for AM33XX, add
the assembly file with the code which is copied to internal
memory (OCMC RAM) during bootup and runs from there.

As part of the low power entry (DeepSleep0 mode in AM33XX TRM),
the code running from OCMC RAM does the following
1. Stores the EMIF configuration
2. Puts external memory in self-refresh
3. Disables EMIF clock
4. Puts the PLLs in bypass
5. Executes WFI after writing to MPU_CLKCTRL register.

If no interrupts have come, WFI execution on MPU gets registered
as an interrupt with the WKUP-M3. WKUP-M3 takes care of disabling
some clocks which MPU should not (L3, L4, OCMC RAM etc) and takes
care of clockdomain and powerdomain transitions as part of the
DeepSleep0 mode entry.

In case a late interrupt comes in, WFI ends up as a NOP and MPU
continues execution from internal memory. The 'abort path' code
undoes whatever was done as part of the low power entry and indicates
a suspend failure by passing a non-zero value to the cpu_resume routine.

The 'resume path' code is similar to the 'abort path' with the key
difference of MMU being enabled in the 'abort path' but being
disabled in the 'resume path' due to MPU getting powered off.

In addition to the top level steps outlined above, there are some
additional register writes related to external memory controller
which help in lowering the overall power consumption in the suspended
state. These include changing the state of the IOs to LVCMOS mode
and enabling pull downs on the IOs to reduce leakage in low power state.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
---
v1->v2:
	This is a new patch in the series to keep the
	assembly code additionl separate as mentioned
	by Kevin Hilman

 arch/arm/mach-omap2/sleep33xx.S |  584 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 584 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-omap2/sleep33xx.S

diff --git a/arch/arm/mach-omap2/sleep33xx.S b/arch/arm/mach-omap2/sleep33xx.S
new file mode 100644
index 0000000..98fa76c
--- /dev/null
+++ b/arch/arm/mach-omap2/sleep33xx.S
@@ -0,0 +1,584 @@
+/*
+ * Low level suspend code for AM33XX SoCs
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ * Vaibhav Bedia <vaibhav.bedia@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/linkage.h>
+#include <linux/ti_emif.h>
+#include <asm/memory.h>
+#include <asm/assembler.h>
+
+#include "cm33xx.h"
+#include "pm33xx.h"
+#include "prm33xx.h"
+#include "control.h"
+
+	.text
+	.align 3
+
+	.macro	pll_bypass, name, clk_mode_addr, idlest_addr, pll_mode
+pll_bypass_\name:
+	ldr	r0, \clk_mode_addr
+	ldr	r1, [r0]
+	str	r1, clk_mode_\pll_mode
+	bic	r1, r1, #(7 << 0)
+	orr	r1, r1, #0x5
+	str	r1, [r0]
+	ldr	r0, \idlest_addr
+wait_pll_bypass_\name:
+	ldr	r1, [r0]
+	tst	r1, #0x0
+	bne	wait_pll_bypass_\name
+	.endm
+
+	.macro	pll_lock, name, clk_mode_addr, idlest_addr, pll_mode
+pll_lock_\name:
+	ldr	r0, \clk_mode_addr
+	ldr	r1, clk_mode_\pll_mode
+	str	r1, [r0]
+	and	r1, r1, #0x7
+	cmp	r1, #0x7
+	bne	pll_mode_restored_\name
+	ldr	r0, \idlest_addr
+wait_pll_lock_\name:
+	ldr	r1, [r0]
+	ands	r1, #0x1
+	beq	wait_pll_lock_\name
+pll_mode_restored_\name:
+	nop
+	.endm
+
+	.macro	ddr_self_refresh, num
+ddr_self_refresh_\num:
+	add	r1, r0, #EMIF_POWER_MANAGEMENT_CONTROL
+	ldr	r2, [r1]
+	orr	r2, r2, #0xa0		@ a reasonable delay for entering SR
+	str	r2, [r1, #0]
+	str	r2, [r1, #4]		@ write to shadow register also
+
+	ldr	r2, ddr_start		@ do a dummy access to DDR
+	ldr	r3, [r2, #0]
+	ldr	r3, [r1, #0]		@ now set the LP MODE to Self-Refresh
+	orr	r3, r3, #0x200
+	str	r3, [r1, #0]
+
+	mov	r1, #0x1000		@ Give some time for system to enter SR
+wait_sr_\num:
+	subs	r1, r1, #1
+	bne	wait_sr_\num
+	.endm
+
+	.macro	wait_sdram_config, num
+wait_sdram_config_\num:
+	mov	r0, #0x100
+wait_sc_\num:
+	subs	r0, r0 ,#1
+	bne	wait_sc_\num
+	.endm
+
+ENTRY(am33xx_do_wfi)
+	stmfd	sp!, {r4 - r11, lr}	@ save registers on stack
+	/* Get the EMIF virtual address */
+	ldr	r0, emif_addr_func
+	blx	r0
+	/* Save it for later use */
+	str	r0, emif_addr_virt
+
+	/* This ensures isb */
+	ldr	r0, dcache_flush
+	blx	r0
+
+	/* Same as v7_flush_icache_all - saving a branch */
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c5, 0	@ I+BTB cache invalidate
+
+	ldr	r0, emif_addr_virt
+	/* Save EMIF configuration */
+	ldr	r1, [r0, #EMIF_SDRAM_CONFIG]
+	str	r1, emif_sdcfg_val
+	ldr	r1, [r0, #EMIF_SDRAM_REFRESH_CONTROL]
+	str	r1, emif_ref_ctrl_val
+	ldr	r1, [r0, #EMIF_SDRAM_TIMING_1]
+	str	r1, emif_timing1_val
+	ldr	r1, [r0, #EMIF_SDRAM_TIMING_2]
+	str	r1, emif_timing2_val
+	ldr	r1, [r0, #EMIF_SDRAM_TIMING_3]
+	str	r1, emif_timing3_val
+	ldr	r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
+	str	r1, emif_pmcr_val
+	ldr	r1, [r0, #EMIF_POWER_MANAGEMENT_CTRL_SHDW]
+	str	r1, emif_pmcr_shdw_val
+	ldr	r1, [r0, #EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG]
+	str	r1, emif_zqcfg_val
+	ldr	r1, [r0, #EMIF_DDR_PHY_CTRL_1]
+	str	r1, emif_rd_lat_val
+
+	/* Ensure that all the writes to DDR leave the A8 */
+	dsb
+	dmb
+	isb
+
+	ddr_self_refresh	1
+
+	/* Disable EMIF at this point */
+	ldr	r1, virt_emif_clkctrl
+	ldr	r2, [r1]
+	bic	r2, r2, #(3 << 0)
+	str	r2, [r1]
+
+	ldr	r1, virt_emif_clkctrl
+wait_emif_disable:
+	ldr	r2, [r1]
+	ldr	r3, module_disabled_val
+	cmp	r2, r3
+	bne	wait_emif_disable
+
+	/*
+	 * For the MPU WFI to be registered as an interrupt
+	 * to WKUP_M3, MPU_CLKCTRL.MODULEMODE needs to be set
+	 * to DISABLED
+	 */
+	ldr	r1, virt_mpu_clkctrl
+	ldr	r2, [r1]
+	bic	r2, r2, #(3 << 0)
+	str	r2, [r1]
+
+	/* DDR3 reset override and mDDR mode selection */
+	ldr	r0, virt_ddr_io_ctrl
+	mov	r1, #(0x9 << 28)
+	str	r1, [r0]
+
+	/* Weak pull down for DQ, DM */
+	ldr	r1, virt_ddr_data0_ioctrl
+	ldr	r2, susp_io_pull_data
+	str	r2, [r1]
+
+	ldr	r1, virt_ddr_data1_ioctrl
+	ldr	r2, susp_io_pull_data
+	str	r2, [r1]
+
+	/* Disable VTP */
+	ldr	r1, virt_ddr_vtp_ctrl
+	ldr	r2, susp_vtp_ctrl_val
+	str	r2, [r1]
+
+	/* Enable SRAM LDO ret mode */
+	ldr	r0, virt_sram_ldo_addr
+	ldr	r1, [r0]
+	orr	r1, #1
+	str	r1, [r0]
+
+put_pll_bypass:
+	/* Put the PLLs in bypass mode */
+	pll_bypass	core, virt_core_clk_mode, virt_core_idlest, core_val
+	pll_bypass	ddr, virt_ddr_clk_mode, virt_ddr_idlest, ddr_val
+	pll_bypass	disp, virt_disp_clk_mode, virt_disp_idlest, disp_val
+	pll_bypass	per, virt_per_clk_mode, virt_per_idlest, per_val
+	pll_bypass	mpu, virt_mpu_clk_mode, virt_mpu_idlest, mpu_val
+
+	dsb
+	dmb
+	isb
+
+	wfi
+
+	/* NOPs to ensure the A8 pipeline is clean */
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	/* We come here in case of an abort due to a late interrupt */
+
+	/* Set MPU_CLKCTRL.MODULEMODE back to ENABLE */
+	ldr	r1, virt_mpu_clkctrl
+	mov	r2, #0x2
+	str	r2, [r1]
+
+	/* Relock the PLLs */
+	pll_lock	mpu_abt, virt_mpu_clk_mode, virt_mpu_idlest, mpu_val
+	pll_lock	per_abt, virt_per_clk_mode, virt_per_idlest, per_val
+	pll_lock	disp_abt, virt_disp_clk_mode, virt_disp_idlest, disp_val
+	pll_lock	ddr_abt, virt_ddr_clk_mode, virt_ddr_idlest, ddr_val
+	pll_lock	core_abt, virt_core_clk_mode, virt_core_idlest, core_val
+
+	/* Disable SRAM LDO ret mode */
+	ldr	r0, virt_sram_ldo_addr
+	ldr	r1, [r0]
+	bic	r1, #1
+	str	r1, [r0]
+
+	/* Restore the pull for DQ, DM */
+	ldr	r1, virt_ddr_data0_ioctrl
+	ldr	r2, resume_io_pull_data
+	str	r2, [r1]
+
+	ldr	r1, virt_ddr_data1_ioctrl
+	ldr	r2, resume_io_pull_data
+	str	r2, [r1]
+
+	/* Enable EMIF */
+	ldr	r1, virt_emif_clkctrl
+	mov	r2, #0x2
+	str	r2, [r1]
+wait_emif_enable:
+	ldr	r3, [r1]
+	cmp	r2, r3
+	bne	wait_emif_enable
+
+	/* Enable VTP */
+config_vtp_abt:
+	ldr	r0, virt_ddr_vtp_ctrl
+	ldr	r1, [r0]
+	mov	r2, #0x0	@ clear the register
+	str	r2, [r0]
+	mov	r2, #0x6	@ write the filter value
+	str	r2, [r0]
+
+	ldr	r1, [r0]
+	ldr	r2, vtp_enable	@ set the enable bit
+	orr	r2, r2, r1
+	str	r2, [r0]
+
+	ldr	r1, [r0]	@ toggle the CLRZ bit
+	bic	r1, #1
+	str	r1, [r0]
+
+	ldr	r1, [r0]
+	orr	r1, #1
+	str	r1, [r0]
+
+poll_vtp_ready_abt:
+	ldr	r1, [r0]	@ poll for VTP ready
+	tst	r1, #(AM33XX_VTP_CTRL_READY)
+	beq	poll_vtp_ready_abt
+
+	/* DDR3 reset override and mDDR mode clear */
+	ldr	r0, virt_ddr_io_ctrl
+	mov	r1, #0
+	str	r1, [r0]
+
+emif_self_refresh_dis:
+	/* Disable EMIF self-refresh */
+	ldr	r0, emif_addr_virt
+	add	r0, r0, #EMIF_POWER_MANAGEMENT_CONTROL
+	ldr	r1, [r0]
+	bic	r1, r1, #LP_MODE_MASK
+	str	r1, [r0]
+	str	r1, [r0, #4]
+
+	/*
+	 * A write to SDRAM CONFIG register triggers
+	 * an init sequence and hence it must be done
+	 * at the end
+	 */
+	ldr r0, emif_addr_virt
+	add r0, r0, #EMIF_SDRAM_CONFIG
+	ldr r4, emif_sdcfg_val
+	str r4, [r0]
+
+	mov r0, #0x1000
+wait_abt:
+	subs   r0, r0, #1
+	bne wait_abt
+
+	/* Let the suspend code know about the abort */
+	mov	r0, #1
+	ldmfd	sp!, {r4 - r11, pc}	@ restore regs and return
+ENDPROC(am33xx_do_wfi)
+
+	.align
+ENTRY(am33xx_resume_offset)
+	.word . - am33xx_do_wfi
+
+ENTRY(am33xx_resume_from_deep_sleep)
+	/* Take the PLLs out of LP_BYPASS */
+	pll_lock	mpu, phys_mpu_clk_mode, phys_mpu_idlest, mpu_val
+	pll_lock	per, phys_per_clk_mode, phys_per_idlest, per_val
+	pll_lock	disp, phys_disp_clk_mode, phys_disp_idlest, disp_val
+	pll_lock	ddr, phys_ddr_clk_mode, phys_ddr_idlest, ddr_val
+	pll_lock	core, phys_core_clk_mode, phys_core_idlest, core_val
+
+	/* Disable SRAM LDO ret mode */
+	ldr	r0, phys_sram_ldo_addr
+	ldr	r1, [r0]
+	bic	r1, #1
+	str	r1, [r0]
+
+	/* Restore the pull for DQ, DM */
+	ldr	r1, phys_ddr_data0_ioctrl
+	ldr	r2, resume_io_pull_data
+	str	r2, [r1]
+
+	ldr	r1, phys_ddr_data1_ioctrl
+	ldr	r2, resume_io_pull_data
+	str	r2, [r1]
+
+config_vtp:
+	ldr	r0, phys_ddr_vtp_ctrl
+	ldr	r1, [r0]
+	mov	r2, #0x0	@ clear the register
+	str	r2, [r0]
+	mov	r2, #0x6	@ write the filter value
+	str	r2, [r0]
+
+	ldr	r1, [r0]
+	ldr	r2, vtp_enable	@ set the enable bit
+	orr	r2, r2, r1
+	str	r2, [r0]
+
+	ldr	r1, [r0]	@ toggle the CLRZ bit
+	bic	r1, #1
+	str	r1, [r0]
+
+	ldr	r1, [r0]
+	orr	r1, #1
+	str	r1, [r0]
+
+poll_vtp_ready:
+	ldr	r1, [r0]	@ poll for VTP ready
+	tst	r1, #AM33XX_VTP_CTRL_READY
+	beq	poll_vtp_ready
+
+	/* DDR3 reset override and mDDR mode clear */
+	ldr	r0, phys_ddr_io_ctrl
+	mov	r1, #0
+	str	r1, [r0]
+
+	/* Enable EMIF */
+	ldr	r1, phys_emif_clkctrl
+	mov	r2, #0x2
+	str	r2, [r1]
+wait_emif_enable1:
+	ldr	r3, [r1]
+	cmp	r2, r3
+	bne	wait_emif_enable1
+
+config_emif_timings:
+	ldr	r3, emif_phys_addr
+	ldr	r4, emif_rd_lat_val
+	str	r4, [r3, #EMIF_DDR_PHY_CTRL_1]
+	str	r4, [r3, #EMIF_DDR_PHY_CTRL_1_SHDW]
+	ldr	r4, emif_timing1_val
+	str	r4, [r3, #EMIF_SDRAM_TIMING_1]
+	str	r4, [r3, #EMIF_SDRAM_TIMING_1_SHDW]
+	ldr	r4, emif_timing2_val
+	str	r4, [r3, #EMIF_SDRAM_TIMING_2]
+	str	r4, [r3, #EMIF_SDRAM_TIMING_2_SHDW]
+	ldr	r4, emif_timing3_val
+	str	r4, [r3, #EMIF_SDRAM_TIMING_3]
+	str	r4, [r3, #EMIF_SDRAM_TIMING_3_SHDW]
+	ldr	r4, emif_ref_ctrl_val
+	str	r4, [r3, #EMIF_SDRAM_REFRESH_CONTROL]
+	str	r4, [r3, #EMIF_SDRAM_REFRESH_CTRL_SHDW]
+	ldr	r4, emif_pmcr_val
+	str	r4, [r3, #EMIF_POWER_MANAGEMENT_CONTROL]
+	ldr	r4, emif_pmcr_shdw_val
+	str	r4, [r3, #EMIF_POWER_MANAGEMENT_CTRL_SHDW]
+
+	/*
+	 * A write to SDRAM CONFIG register triggers
+	 * an init sequence and hence it must be done
+	 * at the end
+	 */
+	ldr	r4, emif_sdcfg_val
+	str	r4, [r3, #EMIF_SDRAM_CONFIG]
+
+	/* Back from la-la-land. Kill some time for sanity to settle in */
+	mov	r0, #0x1000
+wait_resume:
+	subs	r0, r0, #1
+	bne	wait_resume
+
+	/* We are back. Branch to the common CPU resume routine */
+	mov	r0, #0
+	ldr	pc, resume_addr
+ENDPROC(am33xx_resume_from_deep_sleep)
+
+
+/*
+ * Local variables
+ */
+	.align
+resume_addr:
+	.word	cpu_resume - PAGE_OFFSET + 0x80000000
+dcache_flush:
+	.word   v7_flush_dcache_all
+emif_addr_func:
+	.word	am33xx_get_emif_base
+ddr_start:
+	.word	PAGE_OFFSET
+emif_phys_addr:
+	.word	AM33XX_EMIF_BASE
+virt_mpu_idlest:
+	.word	AM33XX_CM_IDLEST_DPLL_MPU
+virt_mpu_clk_mode:
+	.word	AM33XX_CM_CLKMODE_DPLL_MPU
+phys_mpu_clk_mode:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + \
+		AM33XX_CM_CLKMODE_DPLL_MPU_OFFSET)
+phys_mpu_idlest:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + \
+		AM33XX_CM_IDLEST_DPLL_MPU_OFFSET)
+virt_core_idlest:
+	.word	AM33XX_CM_IDLEST_DPLL_CORE
+virt_core_clk_mode:
+	.word	AM33XX_CM_CLKMODE_DPLL_CORE
+phys_core_clk_mode:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + \
+		AM33XX_CM_CLKMODE_DPLL_CORE_OFFSET)
+phys_core_idlest:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + \
+		AM33XX_CM_IDLEST_DPLL_CORE_OFFSET)
+virt_per_idlest:
+	.word	AM33XX_CM_IDLEST_DPLL_PER
+virt_per_clk_mode:
+	.word	AM33XX_CM_CLKMODE_DPLL_PER
+phys_per_clk_mode:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + \
+		AM33XX_CM_CLKMODE_DPLL_PER_OFFSET)
+phys_per_idlest:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + \
+		AM33XX_CM_IDLEST_DPLL_PER_OFFSET)
+virt_disp_idlest:
+	.word	AM33XX_CM_IDLEST_DPLL_DISP
+virt_disp_clk_mode:
+	.word	AM33XX_CM_CLKMODE_DPLL_DISP
+phys_disp_clk_mode:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + \
+		AM33XX_CM_CLKMODE_DPLL_DISP_OFFSET)
+phys_disp_idlest:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + \
+		AM33XX_CM_IDLEST_DPLL_DISP_OFFSET)
+virt_ddr_idlest:
+	.word	AM33XX_CM_IDLEST_DPLL_DDR
+virt_ddr_clk_mode:
+	.word	AM33XX_CM_CLKMODE_DPLL_DDR
+phys_ddr_clk_mode:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + \
+		AM33XX_CM_CLKMODE_DPLL_DDR_OFFSET)
+phys_ddr_idlest:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + \
+		AM33XX_CM_IDLEST_DPLL_DDR_OFFSET)
+virt_sram_ldo_addr:
+	.word	AM33XX_PRM_LDO_SRAM_MPU_CTRL
+phys_sram_ldo_addr:
+	.word	(AM33XX_PRM_BASE + AM33XX_PRM_DEVICE_MOD + \
+		AM33XX_PRM_LDO_SRAM_MPU_CTRL_OFFSET)
+virt_mpu_clkctrl:
+	.word	AM33XX_CM_MPU_MPU_CLKCTRL
+virt_emif_clkctrl:
+	.word	AM33XX_CM_PER_EMIF_CLKCTRL
+phys_emif_clkctrl:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_PER_MOD + \
+		AM33XX_CM_PER_EMIF_CLKCTRL_OFFSET)
+module_disabled_val:
+	.word	0x30000
+
+/* DDR related defines */
+virt_ddr_io_ctrl:
+	.word	AM33XX_CTRL_REGADDR(AM33XX_DDR_IO_CTRL)
+phys_ddr_io_ctrl:
+	.word	AM33XX_CTRL_BASE + AM33XX_DDR_IO_CTRL
+virt_ddr_vtp_ctrl:
+	.word	AM33XX_CTRL_REGADDR(AM33XX_VTP0_CTRL_REG)
+phys_ddr_vtp_ctrl:
+	.word	AM33XX_CTRL_BASE + AM33XX_VTP0_CTRL_REG
+virt_ddr_cmd0_ioctrl:
+	.word	AM33XX_CTRL_REGADDR(AM33XX_DDR_CMD0_IOCTRL)
+phys_ddr_cmd0_ioctrl:
+	.word	AM33XX_CTRL_BASE + AM33XX_DDR_CMD0_IOCTRL
+virt_ddr_cmd1_ioctrl:
+	.word	AM33XX_CTRL_REGADDR(AM33XX_DDR_CMD1_IOCTRL)
+phys_ddr_cmd1_ioctrl:
+	.word	AM33XX_CTRL_BASE + AM33XX_DDR_CMD1_IOCTRL
+virt_ddr_cmd2_ioctrl:
+	.word	AM33XX_CTRL_REGADDR(AM33XX_DDR_CMD2_IOCTRL)
+phys_ddr_cmd2_ioctrl:
+	.word	AM33XX_CTRL_BASE + AM33XX_DDR_CMD2_IOCTRL
+virt_ddr_data0_ioctrl:
+	.word	AM33XX_CTRL_REGADDR(AM33XX_DDR_DATA0_IOCTRL)
+phys_ddr_data0_ioctrl:
+	.word	AM33XX_CTRL_BASE + AM33XX_DDR_DATA0_IOCTRL
+virt_ddr_data1_ioctrl:
+	.word	AM33XX_CTRL_REGADDR(AM33XX_DDR_DATA1_IOCTRL)
+phys_ddr_data1_ioctrl:
+	.word	AM33XX_CTRL_BASE + AM33XX_DDR_DATA1_IOCTRL
+vtp_enable:
+	.word	AM33XX_VTP_CTRL_ENABLE
+
+/*
+ * Values recommended by the HW team. These change the pulls
+ * on certain IOs of DATA and CMD macros
+ */
+susp_io_pull_data:
+	.word	0x3FF00003
+susp_io_pull_cmd1:
+	.word   0xFFE0018B
+susp_io_pull_cmd2:
+	.word   0xFFA0098B
+resume_io_pull_data:
+	.word	0x18B
+resume_io_pull_cmd:
+	.word	0x18B
+susp_vtp_ctrl_val:
+	.word	0x10117
+
+/* Placeholder for storing EMIF configuration */
+emif_addr_virt:
+	.word	0xDEADBEEF
+emif_rd_lat_val:
+	.word	0xDEADBEEF
+emif_timing1_val:
+	.word	0xDEADBEEF
+emif_timing2_val:
+	.word	0xDEADBEEF
+emif_timing3_val:
+	.word	0xDEADBEEF
+emif_sdcfg_val:
+	.word	0xDEADBEEF
+emif_ref_ctrl_val:
+	.word	0xDEADBEEF
+emif_zqcfg_val:
+	.word	0xDEADBEEF
+emif_pmcr_val:
+	.word	0xDEADBEEF
+emif_pmcr_shdw_val:
+	.word	0xDEADBEEF
+
+/* Placeholder for storing PLL mode */
+clk_mode_mpu_val:
+	.word	0xDEADBEEF
+clk_mode_per_val:
+	.word	0xDEADBEEF
+clk_mode_disp_val:
+	.word	0xDEADBEEF
+clk_mode_ddr_val:
+	.word	0xDEADBEEF
+clk_mode_core_val:
+	.word	0xDEADBEEF
+
+	.align 3
+ENTRY(am33xx_do_wfi_sz)
+	.word	. - am33xx_do_wfi
+
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 15/18] ARM: OMAP2+: AM33XX: Add assembly code for PM operations
@ 2012-12-31 13:07   ` Vaibhav Bedia
  0 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

In preparation for suspend-resume support for AM33XX, add
the assembly file with the code which is copied to internal
memory (OCMC RAM) during bootup and runs from there.

As part of the low power entry (DeepSleep0 mode in AM33XX TRM),
the code running from OCMC RAM does the following
1. Stores the EMIF configuration
2. Puts external memory in self-refresh
3. Disables EMIF clock
4. Puts the PLLs in bypass
5. Executes WFI after writing to MPU_CLKCTRL register.

If no interrupts have come, WFI execution on MPU gets registered
as an interrupt with the WKUP-M3. WKUP-M3 takes care of disabling
some clocks which MPU should not (L3, L4, OCMC RAM etc) and takes
care of clockdomain and powerdomain transitions as part of the
DeepSleep0 mode entry.

In case a late interrupt comes in, WFI ends up as a NOP and MPU
continues execution from internal memory. The 'abort path' code
undoes whatever was done as part of the low power entry and indicates
a suspend failure by passing a non-zero value to the cpu_resume routine.

The 'resume path' code is similar to the 'abort path' with the key
difference of MMU being enabled in the 'abort path' but being
disabled in the 'resume path' due to MPU getting powered off.

In addition to the top level steps outlined above, there are some
additional register writes related to external memory controller
which help in lowering the overall power consumption in the suspended
state. These include changing the state of the IOs to LVCMOS mode
and enabling pull downs on the IOs to reduce leakage in low power state.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
---
v1->v2:
	This is a new patch in the series to keep the
	assembly code additionl separate as mentioned
	by Kevin Hilman

 arch/arm/mach-omap2/sleep33xx.S |  584 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 584 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-omap2/sleep33xx.S

diff --git a/arch/arm/mach-omap2/sleep33xx.S b/arch/arm/mach-omap2/sleep33xx.S
new file mode 100644
index 0000000..98fa76c
--- /dev/null
+++ b/arch/arm/mach-omap2/sleep33xx.S
@@ -0,0 +1,584 @@
+/*
+ * Low level suspend code for AM33XX SoCs
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ * Vaibhav Bedia <vaibhav.bedia@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/linkage.h>
+#include <linux/ti_emif.h>
+#include <asm/memory.h>
+#include <asm/assembler.h>
+
+#include "cm33xx.h"
+#include "pm33xx.h"
+#include "prm33xx.h"
+#include "control.h"
+
+	.text
+	.align 3
+
+	.macro	pll_bypass, name, clk_mode_addr, idlest_addr, pll_mode
+pll_bypass_\name:
+	ldr	r0, \clk_mode_addr
+	ldr	r1, [r0]
+	str	r1, clk_mode_\pll_mode
+	bic	r1, r1, #(7 << 0)
+	orr	r1, r1, #0x5
+	str	r1, [r0]
+	ldr	r0, \idlest_addr
+wait_pll_bypass_\name:
+	ldr	r1, [r0]
+	tst	r1, #0x0
+	bne	wait_pll_bypass_\name
+	.endm
+
+	.macro	pll_lock, name, clk_mode_addr, idlest_addr, pll_mode
+pll_lock_\name:
+	ldr	r0, \clk_mode_addr
+	ldr	r1, clk_mode_\pll_mode
+	str	r1, [r0]
+	and	r1, r1, #0x7
+	cmp	r1, #0x7
+	bne	pll_mode_restored_\name
+	ldr	r0, \idlest_addr
+wait_pll_lock_\name:
+	ldr	r1, [r0]
+	ands	r1, #0x1
+	beq	wait_pll_lock_\name
+pll_mode_restored_\name:
+	nop
+	.endm
+
+	.macro	ddr_self_refresh, num
+ddr_self_refresh_\num:
+	add	r1, r0, #EMIF_POWER_MANAGEMENT_CONTROL
+	ldr	r2, [r1]
+	orr	r2, r2, #0xa0		@ a reasonable delay for entering SR
+	str	r2, [r1, #0]
+	str	r2, [r1, #4]		@ write to shadow register also
+
+	ldr	r2, ddr_start		@ do a dummy access to DDR
+	ldr	r3, [r2, #0]
+	ldr	r3, [r1, #0]		@ now set the LP MODE to Self-Refresh
+	orr	r3, r3, #0x200
+	str	r3, [r1, #0]
+
+	mov	r1, #0x1000		@ Give some time for system to enter SR
+wait_sr_\num:
+	subs	r1, r1, #1
+	bne	wait_sr_\num
+	.endm
+
+	.macro	wait_sdram_config, num
+wait_sdram_config_\num:
+	mov	r0, #0x100
+wait_sc_\num:
+	subs	r0, r0 ,#1
+	bne	wait_sc_\num
+	.endm
+
+ENTRY(am33xx_do_wfi)
+	stmfd	sp!, {r4 - r11, lr}	@ save registers on stack
+	/* Get the EMIF virtual address */
+	ldr	r0, emif_addr_func
+	blx	r0
+	/* Save it for later use */
+	str	r0, emif_addr_virt
+
+	/* This ensures isb */
+	ldr	r0, dcache_flush
+	blx	r0
+
+	/* Same as v7_flush_icache_all - saving a branch */
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c5, 0	@ I+BTB cache invalidate
+
+	ldr	r0, emif_addr_virt
+	/* Save EMIF configuration */
+	ldr	r1, [r0, #EMIF_SDRAM_CONFIG]
+	str	r1, emif_sdcfg_val
+	ldr	r1, [r0, #EMIF_SDRAM_REFRESH_CONTROL]
+	str	r1, emif_ref_ctrl_val
+	ldr	r1, [r0, #EMIF_SDRAM_TIMING_1]
+	str	r1, emif_timing1_val
+	ldr	r1, [r0, #EMIF_SDRAM_TIMING_2]
+	str	r1, emif_timing2_val
+	ldr	r1, [r0, #EMIF_SDRAM_TIMING_3]
+	str	r1, emif_timing3_val
+	ldr	r1, [r0, #EMIF_POWER_MANAGEMENT_CONTROL]
+	str	r1, emif_pmcr_val
+	ldr	r1, [r0, #EMIF_POWER_MANAGEMENT_CTRL_SHDW]
+	str	r1, emif_pmcr_shdw_val
+	ldr	r1, [r0, #EMIF_SDRAM_OUTPUT_IMPEDANCE_CALIBRATION_CONFIG]
+	str	r1, emif_zqcfg_val
+	ldr	r1, [r0, #EMIF_DDR_PHY_CTRL_1]
+	str	r1, emif_rd_lat_val
+
+	/* Ensure that all the writes to DDR leave the A8 */
+	dsb
+	dmb
+	isb
+
+	ddr_self_refresh	1
+
+	/* Disable EMIF at this point */
+	ldr	r1, virt_emif_clkctrl
+	ldr	r2, [r1]
+	bic	r2, r2, #(3 << 0)
+	str	r2, [r1]
+
+	ldr	r1, virt_emif_clkctrl
+wait_emif_disable:
+	ldr	r2, [r1]
+	ldr	r3, module_disabled_val
+	cmp	r2, r3
+	bne	wait_emif_disable
+
+	/*
+	 * For the MPU WFI to be registered as an interrupt
+	 * to WKUP_M3, MPU_CLKCTRL.MODULEMODE needs to be set
+	 * to DISABLED
+	 */
+	ldr	r1, virt_mpu_clkctrl
+	ldr	r2, [r1]
+	bic	r2, r2, #(3 << 0)
+	str	r2, [r1]
+
+	/* DDR3 reset override and mDDR mode selection */
+	ldr	r0, virt_ddr_io_ctrl
+	mov	r1, #(0x9 << 28)
+	str	r1, [r0]
+
+	/* Weak pull down for DQ, DM */
+	ldr	r1, virt_ddr_data0_ioctrl
+	ldr	r2, susp_io_pull_data
+	str	r2, [r1]
+
+	ldr	r1, virt_ddr_data1_ioctrl
+	ldr	r2, susp_io_pull_data
+	str	r2, [r1]
+
+	/* Disable VTP */
+	ldr	r1, virt_ddr_vtp_ctrl
+	ldr	r2, susp_vtp_ctrl_val
+	str	r2, [r1]
+
+	/* Enable SRAM LDO ret mode */
+	ldr	r0, virt_sram_ldo_addr
+	ldr	r1, [r0]
+	orr	r1, #1
+	str	r1, [r0]
+
+put_pll_bypass:
+	/* Put the PLLs in bypass mode */
+	pll_bypass	core, virt_core_clk_mode, virt_core_idlest, core_val
+	pll_bypass	ddr, virt_ddr_clk_mode, virt_ddr_idlest, ddr_val
+	pll_bypass	disp, virt_disp_clk_mode, virt_disp_idlest, disp_val
+	pll_bypass	per, virt_per_clk_mode, virt_per_idlest, per_val
+	pll_bypass	mpu, virt_mpu_clk_mode, virt_mpu_idlest, mpu_val
+
+	dsb
+	dmb
+	isb
+
+	wfi
+
+	/* NOPs to ensure the A8 pipeline is clean */
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	/* We come here in case of an abort due to a late interrupt */
+
+	/* Set MPU_CLKCTRL.MODULEMODE back to ENABLE */
+	ldr	r1, virt_mpu_clkctrl
+	mov	r2, #0x2
+	str	r2, [r1]
+
+	/* Relock the PLLs */
+	pll_lock	mpu_abt, virt_mpu_clk_mode, virt_mpu_idlest, mpu_val
+	pll_lock	per_abt, virt_per_clk_mode, virt_per_idlest, per_val
+	pll_lock	disp_abt, virt_disp_clk_mode, virt_disp_idlest, disp_val
+	pll_lock	ddr_abt, virt_ddr_clk_mode, virt_ddr_idlest, ddr_val
+	pll_lock	core_abt, virt_core_clk_mode, virt_core_idlest, core_val
+
+	/* Disable SRAM LDO ret mode */
+	ldr	r0, virt_sram_ldo_addr
+	ldr	r1, [r0]
+	bic	r1, #1
+	str	r1, [r0]
+
+	/* Restore the pull for DQ, DM */
+	ldr	r1, virt_ddr_data0_ioctrl
+	ldr	r2, resume_io_pull_data
+	str	r2, [r1]
+
+	ldr	r1, virt_ddr_data1_ioctrl
+	ldr	r2, resume_io_pull_data
+	str	r2, [r1]
+
+	/* Enable EMIF */
+	ldr	r1, virt_emif_clkctrl
+	mov	r2, #0x2
+	str	r2, [r1]
+wait_emif_enable:
+	ldr	r3, [r1]
+	cmp	r2, r3
+	bne	wait_emif_enable
+
+	/* Enable VTP */
+config_vtp_abt:
+	ldr	r0, virt_ddr_vtp_ctrl
+	ldr	r1, [r0]
+	mov	r2, #0x0	@ clear the register
+	str	r2, [r0]
+	mov	r2, #0x6	@ write the filter value
+	str	r2, [r0]
+
+	ldr	r1, [r0]
+	ldr	r2, vtp_enable	@ set the enable bit
+	orr	r2, r2, r1
+	str	r2, [r0]
+
+	ldr	r1, [r0]	@ toggle the CLRZ bit
+	bic	r1, #1
+	str	r1, [r0]
+
+	ldr	r1, [r0]
+	orr	r1, #1
+	str	r1, [r0]
+
+poll_vtp_ready_abt:
+	ldr	r1, [r0]	@ poll for VTP ready
+	tst	r1, #(AM33XX_VTP_CTRL_READY)
+	beq	poll_vtp_ready_abt
+
+	/* DDR3 reset override and mDDR mode clear */
+	ldr	r0, virt_ddr_io_ctrl
+	mov	r1, #0
+	str	r1, [r0]
+
+emif_self_refresh_dis:
+	/* Disable EMIF self-refresh */
+	ldr	r0, emif_addr_virt
+	add	r0, r0, #EMIF_POWER_MANAGEMENT_CONTROL
+	ldr	r1, [r0]
+	bic	r1, r1, #LP_MODE_MASK
+	str	r1, [r0]
+	str	r1, [r0, #4]
+
+	/*
+	 * A write to SDRAM CONFIG register triggers
+	 * an init sequence and hence it must be done
+	 * at the end
+	 */
+	ldr r0, emif_addr_virt
+	add r0, r0, #EMIF_SDRAM_CONFIG
+	ldr r4, emif_sdcfg_val
+	str r4, [r0]
+
+	mov r0, #0x1000
+wait_abt:
+	subs   r0, r0, #1
+	bne wait_abt
+
+	/* Let the suspend code know about the abort */
+	mov	r0, #1
+	ldmfd	sp!, {r4 - r11, pc}	@ restore regs and return
+ENDPROC(am33xx_do_wfi)
+
+	.align
+ENTRY(am33xx_resume_offset)
+	.word . - am33xx_do_wfi
+
+ENTRY(am33xx_resume_from_deep_sleep)
+	/* Take the PLLs out of LP_BYPASS */
+	pll_lock	mpu, phys_mpu_clk_mode, phys_mpu_idlest, mpu_val
+	pll_lock	per, phys_per_clk_mode, phys_per_idlest, per_val
+	pll_lock	disp, phys_disp_clk_mode, phys_disp_idlest, disp_val
+	pll_lock	ddr, phys_ddr_clk_mode, phys_ddr_idlest, ddr_val
+	pll_lock	core, phys_core_clk_mode, phys_core_idlest, core_val
+
+	/* Disable SRAM LDO ret mode */
+	ldr	r0, phys_sram_ldo_addr
+	ldr	r1, [r0]
+	bic	r1, #1
+	str	r1, [r0]
+
+	/* Restore the pull for DQ, DM */
+	ldr	r1, phys_ddr_data0_ioctrl
+	ldr	r2, resume_io_pull_data
+	str	r2, [r1]
+
+	ldr	r1, phys_ddr_data1_ioctrl
+	ldr	r2, resume_io_pull_data
+	str	r2, [r1]
+
+config_vtp:
+	ldr	r0, phys_ddr_vtp_ctrl
+	ldr	r1, [r0]
+	mov	r2, #0x0	@ clear the register
+	str	r2, [r0]
+	mov	r2, #0x6	@ write the filter value
+	str	r2, [r0]
+
+	ldr	r1, [r0]
+	ldr	r2, vtp_enable	@ set the enable bit
+	orr	r2, r2, r1
+	str	r2, [r0]
+
+	ldr	r1, [r0]	@ toggle the CLRZ bit
+	bic	r1, #1
+	str	r1, [r0]
+
+	ldr	r1, [r0]
+	orr	r1, #1
+	str	r1, [r0]
+
+poll_vtp_ready:
+	ldr	r1, [r0]	@ poll for VTP ready
+	tst	r1, #AM33XX_VTP_CTRL_READY
+	beq	poll_vtp_ready
+
+	/* DDR3 reset override and mDDR mode clear */
+	ldr	r0, phys_ddr_io_ctrl
+	mov	r1, #0
+	str	r1, [r0]
+
+	/* Enable EMIF */
+	ldr	r1, phys_emif_clkctrl
+	mov	r2, #0x2
+	str	r2, [r1]
+wait_emif_enable1:
+	ldr	r3, [r1]
+	cmp	r2, r3
+	bne	wait_emif_enable1
+
+config_emif_timings:
+	ldr	r3, emif_phys_addr
+	ldr	r4, emif_rd_lat_val
+	str	r4, [r3, #EMIF_DDR_PHY_CTRL_1]
+	str	r4, [r3, #EMIF_DDR_PHY_CTRL_1_SHDW]
+	ldr	r4, emif_timing1_val
+	str	r4, [r3, #EMIF_SDRAM_TIMING_1]
+	str	r4, [r3, #EMIF_SDRAM_TIMING_1_SHDW]
+	ldr	r4, emif_timing2_val
+	str	r4, [r3, #EMIF_SDRAM_TIMING_2]
+	str	r4, [r3, #EMIF_SDRAM_TIMING_2_SHDW]
+	ldr	r4, emif_timing3_val
+	str	r4, [r3, #EMIF_SDRAM_TIMING_3]
+	str	r4, [r3, #EMIF_SDRAM_TIMING_3_SHDW]
+	ldr	r4, emif_ref_ctrl_val
+	str	r4, [r3, #EMIF_SDRAM_REFRESH_CONTROL]
+	str	r4, [r3, #EMIF_SDRAM_REFRESH_CTRL_SHDW]
+	ldr	r4, emif_pmcr_val
+	str	r4, [r3, #EMIF_POWER_MANAGEMENT_CONTROL]
+	ldr	r4, emif_pmcr_shdw_val
+	str	r4, [r3, #EMIF_POWER_MANAGEMENT_CTRL_SHDW]
+
+	/*
+	 * A write to SDRAM CONFIG register triggers
+	 * an init sequence and hence it must be done
+	 *@the end
+	 */
+	ldr	r4, emif_sdcfg_val
+	str	r4, [r3, #EMIF_SDRAM_CONFIG]
+
+	/* Back from la-la-land. Kill some time for sanity to settle in */
+	mov	r0, #0x1000
+wait_resume:
+	subs	r0, r0, #1
+	bne	wait_resume
+
+	/* We are back. Branch to the common CPU resume routine */
+	mov	r0, #0
+	ldr	pc, resume_addr
+ENDPROC(am33xx_resume_from_deep_sleep)
+
+
+/*
+ * Local variables
+ */
+	.align
+resume_addr:
+	.word	cpu_resume - PAGE_OFFSET + 0x80000000
+dcache_flush:
+	.word   v7_flush_dcache_all
+emif_addr_func:
+	.word	am33xx_get_emif_base
+ddr_start:
+	.word	PAGE_OFFSET
+emif_phys_addr:
+	.word	AM33XX_EMIF_BASE
+virt_mpu_idlest:
+	.word	AM33XX_CM_IDLEST_DPLL_MPU
+virt_mpu_clk_mode:
+	.word	AM33XX_CM_CLKMODE_DPLL_MPU
+phys_mpu_clk_mode:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + \
+		AM33XX_CM_CLKMODE_DPLL_MPU_OFFSET)
+phys_mpu_idlest:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + \
+		AM33XX_CM_IDLEST_DPLL_MPU_OFFSET)
+virt_core_idlest:
+	.word	AM33XX_CM_IDLEST_DPLL_CORE
+virt_core_clk_mode:
+	.word	AM33XX_CM_CLKMODE_DPLL_CORE
+phys_core_clk_mode:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + \
+		AM33XX_CM_CLKMODE_DPLL_CORE_OFFSET)
+phys_core_idlest:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + \
+		AM33XX_CM_IDLEST_DPLL_CORE_OFFSET)
+virt_per_idlest:
+	.word	AM33XX_CM_IDLEST_DPLL_PER
+virt_per_clk_mode:
+	.word	AM33XX_CM_CLKMODE_DPLL_PER
+phys_per_clk_mode:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + \
+		AM33XX_CM_CLKMODE_DPLL_PER_OFFSET)
+phys_per_idlest:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + \
+		AM33XX_CM_IDLEST_DPLL_PER_OFFSET)
+virt_disp_idlest:
+	.word	AM33XX_CM_IDLEST_DPLL_DISP
+virt_disp_clk_mode:
+	.word	AM33XX_CM_CLKMODE_DPLL_DISP
+phys_disp_clk_mode:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + \
+		AM33XX_CM_CLKMODE_DPLL_DISP_OFFSET)
+phys_disp_idlest:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + \
+		AM33XX_CM_IDLEST_DPLL_DISP_OFFSET)
+virt_ddr_idlest:
+	.word	AM33XX_CM_IDLEST_DPLL_DDR
+virt_ddr_clk_mode:
+	.word	AM33XX_CM_CLKMODE_DPLL_DDR
+phys_ddr_clk_mode:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + \
+		AM33XX_CM_CLKMODE_DPLL_DDR_OFFSET)
+phys_ddr_idlest:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + \
+		AM33XX_CM_IDLEST_DPLL_DDR_OFFSET)
+virt_sram_ldo_addr:
+	.word	AM33XX_PRM_LDO_SRAM_MPU_CTRL
+phys_sram_ldo_addr:
+	.word	(AM33XX_PRM_BASE + AM33XX_PRM_DEVICE_MOD + \
+		AM33XX_PRM_LDO_SRAM_MPU_CTRL_OFFSET)
+virt_mpu_clkctrl:
+	.word	AM33XX_CM_MPU_MPU_CLKCTRL
+virt_emif_clkctrl:
+	.word	AM33XX_CM_PER_EMIF_CLKCTRL
+phys_emif_clkctrl:
+	.word	(AM33XX_CM_BASE + AM33XX_CM_PER_MOD + \
+		AM33XX_CM_PER_EMIF_CLKCTRL_OFFSET)
+module_disabled_val:
+	.word	0x30000
+
+/* DDR related defines */
+virt_ddr_io_ctrl:
+	.word	AM33XX_CTRL_REGADDR(AM33XX_DDR_IO_CTRL)
+phys_ddr_io_ctrl:
+	.word	AM33XX_CTRL_BASE + AM33XX_DDR_IO_CTRL
+virt_ddr_vtp_ctrl:
+	.word	AM33XX_CTRL_REGADDR(AM33XX_VTP0_CTRL_REG)
+phys_ddr_vtp_ctrl:
+	.word	AM33XX_CTRL_BASE + AM33XX_VTP0_CTRL_REG
+virt_ddr_cmd0_ioctrl:
+	.word	AM33XX_CTRL_REGADDR(AM33XX_DDR_CMD0_IOCTRL)
+phys_ddr_cmd0_ioctrl:
+	.word	AM33XX_CTRL_BASE + AM33XX_DDR_CMD0_IOCTRL
+virt_ddr_cmd1_ioctrl:
+	.word	AM33XX_CTRL_REGADDR(AM33XX_DDR_CMD1_IOCTRL)
+phys_ddr_cmd1_ioctrl:
+	.word	AM33XX_CTRL_BASE + AM33XX_DDR_CMD1_IOCTRL
+virt_ddr_cmd2_ioctrl:
+	.word	AM33XX_CTRL_REGADDR(AM33XX_DDR_CMD2_IOCTRL)
+phys_ddr_cmd2_ioctrl:
+	.word	AM33XX_CTRL_BASE + AM33XX_DDR_CMD2_IOCTRL
+virt_ddr_data0_ioctrl:
+	.word	AM33XX_CTRL_REGADDR(AM33XX_DDR_DATA0_IOCTRL)
+phys_ddr_data0_ioctrl:
+	.word	AM33XX_CTRL_BASE + AM33XX_DDR_DATA0_IOCTRL
+virt_ddr_data1_ioctrl:
+	.word	AM33XX_CTRL_REGADDR(AM33XX_DDR_DATA1_IOCTRL)
+phys_ddr_data1_ioctrl:
+	.word	AM33XX_CTRL_BASE + AM33XX_DDR_DATA1_IOCTRL
+vtp_enable:
+	.word	AM33XX_VTP_CTRL_ENABLE
+
+/*
+ * Values recommended by the HW team. These change the pulls
+ * on certain IOs of DATA and CMD macros
+ */
+susp_io_pull_data:
+	.word	0x3FF00003
+susp_io_pull_cmd1:
+	.word   0xFFE0018B
+susp_io_pull_cmd2:
+	.word   0xFFA0098B
+resume_io_pull_data:
+	.word	0x18B
+resume_io_pull_cmd:
+	.word	0x18B
+susp_vtp_ctrl_val:
+	.word	0x10117
+
+/* Placeholder for storing EMIF configuration */
+emif_addr_virt:
+	.word	0xDEADBEEF
+emif_rd_lat_val:
+	.word	0xDEADBEEF
+emif_timing1_val:
+	.word	0xDEADBEEF
+emif_timing2_val:
+	.word	0xDEADBEEF
+emif_timing3_val:
+	.word	0xDEADBEEF
+emif_sdcfg_val:
+	.word	0xDEADBEEF
+emif_ref_ctrl_val:
+	.word	0xDEADBEEF
+emif_zqcfg_val:
+	.word	0xDEADBEEF
+emif_pmcr_val:
+	.word	0xDEADBEEF
+emif_pmcr_shdw_val:
+	.word	0xDEADBEEF
+
+/* Placeholder for storing PLL mode */
+clk_mode_mpu_val:
+	.word	0xDEADBEEF
+clk_mode_per_val:
+	.word	0xDEADBEEF
+clk_mode_disp_val:
+	.word	0xDEADBEEF
+clk_mode_ddr_val:
+	.word	0xDEADBEEF
+clk_mode_core_val:
+	.word	0xDEADBEEF
+
+	.align 3
+ENTRY(am33xx_do_wfi_sz)
+	.word	. - am33xx_do_wfi
+
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support
  2012-12-31 13:06 ` Vaibhav Bedia
@ 2012-12-31 13:07   ` Vaibhav Bedia
  -1 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, tony, khilman
  Cc: Vaibhav Bedia, Santosh Shilimkar, Benoit Cousson, Paul Walmsley

AM335x supports various low power modes as documented
in section 8.1.4.3 of the AM335x TRM which is available
@ http://www.ti.com/litv/pdf/spruh73f

DeepSleep0 mode offers the lowest power mode with limited
wakeup sources without a system reboot and is mapped as
the suspend state in the kernel. In this state, MPU and
PER domains are turned off with the internal RAM held in
retention to facilitate resume process. As part of the boot
process, the assembly code is copied over to OCMCRAM using
the OMAP SRAM code.

AM335x has a Cortex-M3 (WKUP_M3) which assists the MPU
in DeepSleep0 entry and exit. WKUP_M3 takes care of the
clockdomain and powerdomain transitions based on the
intended low power state. MPU needs to load the appropriate
WKUP_M3 binary onto the WKUP_M3 memory space before it can
leverage any of the PM features like DeepSleep.

The IPC mechanism between MPU and WKUP_M3 uses a mailbox
sub-module and 8 IPC registers in the Control module. MPU
uses the assigned Mailbox for issuing an interrupt to
WKUP_M3 which then goes and checks the IPC registers for
the payload. WKUP_M3 has the ability to trigger on interrupt
to MPU by executing the "sev" instruction.

In the current implementation when the suspend process
is initiated MPU interrupts the WKUP_M3 to let it know about
the intent of entering DeepSleep0 and waits for an ACK. When
the ACK is received MPU continues with its suspend process
to suspend all the drivers and then jumps to assembly in
OCMC RAM. The assembly code puts the PLLs in bypass, puts the
external RAM in self-refresh mode and then finally execute the
WFI instruction. Execution of the WFI instruction triggers another
interrupt to the WKUP_M3 which then continues wiht the power down
sequence wherein the clockdomain and powerdomain transition takes
place. As part of the sleep sequence, WKUP_M3 unmasks the interrupt
lines for the wakeup sources. WFI execution on WKUP_M3 causes the
hardware to disable the main oscillator of the SoC.

When a wakeup event occurs, WKUP_M3 starts the power-up
sequence by switching on the power domains and finally
enabling the clock to MPU. Since the MPU gets powered down
as part of the sleep sequence in the resume path ROM code
starts executing. The ROM code detects a wakeup from sleep
and then jumps to the resume location in OCMC which was
populated in one of the IPC registers as part of the suspend
sequence.

The low level code in OCMC relocks the PLLs, enables access
to external RAM and then jumps to the cpu_resume code of
the kernel to finish the resume process.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Tony Lingren <tony@atomide.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
---
v1->v2:
	Move assembly code addition, control module access
	and hookup in OMAP PM framework in separate patches.
	Address other comments from Kevin Hilman and Santosh
	Shilimkar on v1. The discussion on v1 is present @
	http://lists.infradead.org/pipermail/linux-arm-kernel/2012-November/129979.html
	Note: The mailbox change will need slight rework once
	the driver is finalized.

 arch/arm/mach-omap2/pm33xx.c |  469 ++++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/pm33xx.h |   56 +++++
 2 files changed, 525 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-omap2/pm33xx.c
 create mode 100644 arch/arm/mach-omap2/pm33xx.h

diff --git a/arch/arm/mach-omap2/pm33xx.c b/arch/arm/mach-omap2/pm33xx.c
new file mode 100644
index 0000000..aaa4daa
--- /dev/null
+++ b/arch/arm/mach-omap2/pm33xx.c
@@ -0,0 +1,469 @@
+/*
+ * AM33XX Power Management Routines
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ * Vaibhav Bedia <vaibhav.bedia@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/firmware.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/suspend.h>
+#include <linux/completion.h>
+#include <linux/module.h>
+#include <linux/mailbox.h>
+#include <linux/interrupt.h>
+
+#include <asm/suspend.h>
+#include <asm/proc-fns.h>
+#include <asm/sizes.h>
+#include <asm/fncpy.h>
+#include <asm/system_misc.h>
+
+#include "pm.h"
+#include "cm33xx.h"
+#include "pm33xx.h"
+#include "control.h"
+#include "clockdomain.h"
+#include "powerdomain.h"
+#include "omap_hwmod.h"
+#include "omap_device.h"
+#include "soc.h"
+#include "sram.h"
+
+void (*am33xx_do_wfi_sram)(void);
+
+static void __iomem *am33xx_emif_base;
+static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm, *per_pwrdm;
+static struct clockdomain *gfx_l4ls_clkdm;
+static struct omap_hwmod *usb_oh, *cpsw_oh, *tptc0_oh, *tptc1_oh, *tptc2_oh;
+static struct wkup_m3_context *wkup_m3;
+
+static DECLARE_COMPLETION(wkup_m3_sync);
+
+#ifdef CONFIG_SUSPEND
+static int am33xx_do_sram_idle(long unsigned int unused)
+{
+	am33xx_do_wfi_sram();
+	return 0;
+}
+
+static int am33xx_pm_suspend(void)
+{
+	int status, ret = 0;
+
+	/*
+	 * By default the following IPs do not have MSTANDBY asserted
+	 * which is necessary for PER domain transition. If the drivers
+	 * are not compiled into the kernel HWMOD code will not change the
+	 * state of the IPs if the IP was not never enabled. To ensure
+	 * that there no issues with or without the drivers being compiled
+	 * in the kernel, we forcefully put these IPs to idle.
+	 */
+	omap_hwmod_enable(usb_oh);
+	omap_hwmod_enable(tptc0_oh);
+	omap_hwmod_enable(tptc1_oh);
+	omap_hwmod_enable(tptc2_oh);
+	omap_hwmod_enable(cpsw_oh);
+
+	omap_hwmod_idle(usb_oh);
+	omap_hwmod_idle(tptc0_oh);
+	omap_hwmod_idle(tptc1_oh);
+	omap_hwmod_idle(tptc2_oh);
+	omap_hwmod_idle(cpsw_oh);
+
+	/* Try to put GFX to sleep */
+	pwrdm_set_next_fpwrst(gfx_pwrdm, PWRDM_FUNC_PWRST_OFF);
+
+	ret = cpu_suspend(0, am33xx_do_sram_idle);
+
+	status = pwrdm_read_fpwrst(gfx_pwrdm);
+	if (status != PWRDM_FUNC_PWRST_OFF)
+		pr_err("GFX domain did not transition\n");
+	else
+		pr_info("GFX domain entered low power state\n");
+
+	/*
+	 * GFX_L4LS clock domain needs to be woken up to
+	 * ensure thet L4LS clock domain does not get stuck in transition
+	 * If that happens L3 module does not get disabled, thereby leading
+	 * to PER power domain transition failing
+	 *
+	 * The clock framework should take care of ensuring
+	 * that the clock domain is in the right state when
+	 * GFX driver is active.
+	 */
+	clkdm_wakeup(gfx_l4ls_clkdm);
+	clkdm_sleep(gfx_l4ls_clkdm);
+
+	if (ret) {
+		pr_err("Kernel suspend failure\n");
+	} else {
+		status = omap_ctrl_readl(AM33XX_CONTROL_IPC_MSG_REG1);
+		status &= IPC_RESP_MASK;
+		status >>= __ffs(IPC_RESP_MASK);
+
+		switch (status) {
+		case 0:
+			pr_info("Successfully put all powerdomains to target state\n");
+			/*
+			 * XXX: Leads to loss of logic state in PER power domain
+			 * Use SOC specific ops for this?
+			 */
+			break;
+		case 1:
+			pr_err("Could not transition all powerdomains to target state\n");
+			ret = -1;
+			break;
+		default:
+			pr_err("Something went wrong :(\nStatus = %d\n",
+				status);
+			ret = -1;
+		}
+	}
+
+	return ret;
+}
+
+static int am33xx_pm_enter(suspend_state_t suspend_state)
+{
+	int ret = 0;
+
+	switch (suspend_state) {
+	case PM_SUSPEND_STANDBY:
+	case PM_SUSPEND_MEM:
+		ret = am33xx_pm_suspend();
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int am33xx_pm_begin(suspend_state_t state)
+{
+	int ret = 0;
+	struct mailbox_msg dummy_msg;
+
+	disable_hlt();
+
+	MAILBOX_FILL_HEADER_MSG(dummy_msg, 0xABCDABCD);
+
+	wkup_m3->ipc_data.sleep_mode = IPC_CMD_DS0;
+	wkup_m3->ipc_data.param1  = DS_IPC_DEFAULT;
+	wkup_m3->ipc_data.param2  = DS_IPC_DEFAULT;
+
+	am33xx_wkup_m3_ipc_cmd(&wkup_m3->ipc_data);
+
+	wkup_m3->state = M3_STATE_MSG_FOR_LP;
+
+	mailbox_enable_irq(wkup_m3->mbox, IRQ_RX);
+
+	ret = mailbox_msg_send(wkup_m3->mbox, &dummy_msg);
+	if (ret) {
+		pr_err("A8<->CM3 MSG for LP failed\n");
+		am33xx_m3_state_machine_reset();
+		ret = -1;
+	}
+
+	/* Give some time to M3 to respond. 500msec is a random value here */
+	if (!wait_for_completion_timeout(&wkup_m3_sync,
+					msecs_to_jiffies(500))) {
+		pr_err("A8<->CM3 sync failure\n");
+		am33xx_m3_state_machine_reset();
+		ret = -1;
+	} else {
+		pr_debug("Message sent for entering DeepSleep mode\n");
+		mailbox_disable_irq(wkup_m3->mbox, IRQ_RX);
+	}
+
+	return ret;
+}
+
+static void am33xx_pm_end(void)
+{
+	mailbox_enable_irq(wkup_m3->mbox, IRQ_RX);
+
+	am33xx_m3_state_machine_reset();
+
+	enable_hlt();
+
+	return;
+}
+
+static const struct platform_suspend_ops am33xx_pm_ops = {
+	.begin		= am33xx_pm_begin,
+	.end		= am33xx_pm_end,
+	.enter		= am33xx_pm_enter,
+	.valid		= suspend_valid_only_mem,
+};
+
+static void am33xx_m3_state_machine_reset(void)
+{
+	int ret = 0;
+	struct mailbox_msg dummy_msg;
+
+	MAILBOX_FILL_HEADER_MSG(dummy_msg, 0xABCDABCD);
+
+	wkup_m3->ipc_data.sleep_mode	= IPC_CMD_RESET;
+	wkup_m3->ipc_data.param1	= DS_IPC_DEFAULT;
+	wkup_m3->ipc_data.param2	= DS_IPC_DEFAULT;
+
+	am33xx_wkup_m3_ipc_cmd(&wkup_m3->ipc_data);
+
+	wkup_m3->state = M3_STATE_MSG_FOR_RESET;
+
+	ret = mailbox_msg_send(wkup_m3->mbox, &dummy_msg);
+	if (!ret) {
+		pr_debug("Message sent for resetting M3 state machine\n");
+		/* Give some to M3 to respond. 500msec is a random value here */
+		if (!wait_for_completion_timeout(&wkup_m3_sync,
+						msecs_to_jiffies(500)))
+			pr_err("A8<->CM3 sync failure\n");
+	} else {
+		pr_err("Could not reset M3 state machine!!!\n");
+		wkup_m3->state = M3_STATE_UNKNOWN;
+	}
+}
+#endif /* CONFIG_SUSPEND */
+
+/*
+ * Dummy notifier for the mailbox
+ * XXX: Get rid of this requirement once the MBX driver has been finalized
+ */
+static int wkup_mbox_msg(struct notifier_block *self, unsigned long len,
+		void *msg)
+{
+	return 0;
+}
+
+static struct notifier_block wkup_mbox_notifier = {
+	.notifier_call = wkup_mbox_msg,
+};
+
+static irqreturn_t wkup_m3_txev_handler(int irq, void *unused)
+{
+	am33xx_txev_eoi();
+
+	switch (wkup_m3->state) {
+	case M3_STATE_RESET:
+		wkup_m3->state = M3_STATE_INITED;
+		break;
+	case M3_STATE_MSG_FOR_RESET:
+		wkup_m3->state = M3_STATE_INITED;
+		mailbox_rx_flush(wkup_m3->mbox);
+		complete(&wkup_m3_sync);
+		break;
+	case M3_STATE_MSG_FOR_LP:
+		mailbox_rx_flush(wkup_m3->mbox);
+		complete(&wkup_m3_sync);
+		break;
+	case M3_STATE_UNKNOWN:
+		pr_err("IRQ %d with WKUP_M3 in unknown state\n", irq);
+		mailbox_rx_flush(wkup_m3->mbox);
+		return IRQ_NONE;
+	}
+
+	am33xx_txev_enable();
+	return IRQ_HANDLED;
+}
+
+static void am33xx_pm_firmware_cb(const struct firmware *fw, void *context)
+{
+	struct wkup_m3_context *wkup_m3_context = context;
+	struct platform_device *pdev = to_platform_device(wkup_m3_context->dev);
+	int ret = 0;
+
+	/* no firmware found */
+	if (!fw) {
+		dev_err(wkup_m3_context->dev, "request_firmware failed\n");
+		goto err;
+	}
+
+	memcpy((void *)wkup_m3_context->code, fw->data, fw->size);
+	pr_info("Copied the M3 firmware to UMEM\n");
+
+	wkup_m3->state = M3_STATE_RESET;
+
+	ret = omap_device_deassert_hardreset(pdev, "wkup_m3");
+	if (ret) {
+		pr_err("Could not deassert the reset for WKUP_M3\n");
+		goto err;
+	} else {
+#ifdef CONFIG_SUSPEND
+		suspend_set_ops(&am33xx_pm_ops);
+		/*
+		 * Physical resume address to be used by ROM code
+		 */
+		wkup_m3->ipc_data.resume_addr = (AM33XX_OCMC_END -
+				am33xx_do_wfi_sz + am33xx_resume_offset + 0x4);
+#endif
+		return;
+	}
+
+err:
+	mailbox_put(wkup_m3_context->mbox, &wkup_mbox_notifier);
+}
+
+static int wkup_m3_init(void)
+{
+	int irq, ret = 0;
+	struct resource *mem;
+	struct platform_device *pdev = to_platform_device(wkup_m3->dev);
+
+	omap_device_enable_hwmods(to_omap_device(pdev));
+
+	/* Reserve the MBOX for sending messages to M3 */
+	wkup_m3->mbox = mailbox_get("wkup_m3", &wkup_mbox_notifier);
+	if (IS_ERR(wkup_m3->mbox)) {
+		pr_err("Could not reserve mailbox for A8->M3 IPC\n");
+		ret = -ENODEV;
+		goto exit;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (!irq) {
+		dev_err(wkup_m3->dev, "no irq resource\n");
+		ret = -ENXIO;
+		goto err;
+	}
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem) {
+		dev_err(wkup_m3->dev, "no memory resource\n");
+		ret = -ENXIO;
+		goto err;
+	}
+
+	wkup_m3->code = devm_request_and_ioremap(wkup_m3->dev, mem);
+	if (!wkup_m3->code) {
+		dev_err(wkup_m3->dev, "could not ioremap\n");
+		ret = -EADDRNOTAVAIL;
+		goto err;
+	}
+
+	ret = devm_request_irq(wkup_m3->dev, irq, wkup_m3_txev_handler,
+		  IRQF_DISABLED, "wkup_m3_txev", NULL);
+	if (ret) {
+		dev_err(wkup_m3->dev, "request_irq failed\n");
+		goto err;
+	} else {
+		am33xx_txev_enable();
+	}
+
+	pr_info("Trying to load am335x-pm-firmware.bin");
+
+	/* We don't want to delay boot */
+	request_firmware_nowait(THIS_MODULE, 0, "am335x-pm-firmware.bin",
+				wkup_m3->dev, GFP_KERNEL, wkup_m3,
+				am33xx_pm_firmware_cb);
+	return 0;
+
+err:
+	mailbox_put(wkup_m3->mbox, &wkup_mbox_notifier);
+exit:
+	return ret;
+}
+
+/*
+ * Push the minimal suspend-resume code to SRAM
+ */
+void am33xx_push_sram_idle(void)
+{
+	am33xx_do_wfi_sram = (void *)omap_sram_push
+					(am33xx_do_wfi, am33xx_do_wfi_sz);
+}
+
+static int __init am33xx_map_emif(void)
+{
+	am33xx_emif_base = ioremap(AM33XX_EMIF_BASE, SZ_32K);
+
+	if (!am33xx_emif_base)
+		return -ENOMEM;
+
+	return 0;
+}
+
+void __iomem *am33xx_get_emif_base(void)
+{
+	return am33xx_emif_base;
+}
+
+int __init am33xx_pm_init(void)
+{
+	int ret;
+
+	if (!soc_is_am33xx())
+		return -ENODEV;
+
+	pr_info("Power Management for AM33XX family\n");
+
+	/*
+	 * By default the following IPs do not have MSTANDBY asserted
+	 * which is necessary for PER domain transition. If the drivers
+	 * are not compiled into the kernel HWMOD code will not change the
+	 * state of the IPs if the IP was not never enabled
+	 */
+	usb_oh		= omap_hwmod_lookup("usb_otg_hs");
+	tptc0_oh	= omap_hwmod_lookup("tptc0");
+	tptc1_oh	= omap_hwmod_lookup("tptc1");
+	tptc2_oh	= omap_hwmod_lookup("tptc2");
+	cpsw_oh		= omap_hwmod_lookup("cpgmac0");
+
+	gfx_pwrdm = pwrdm_lookup("gfx_pwrdm");
+	per_pwrdm = pwrdm_lookup("per_pwrdm");
+
+	gfx_l4ls_clkdm = clkdm_lookup("gfx_l4ls_gfx_clkdm");
+
+	if ((!usb_oh) || (!tptc0_oh) || (!tptc1_oh) || (!tptc2_oh) ||
+		(!cpsw_oh) || (!gfx_pwrdm) || (!per_pwrdm) ||
+		(!gfx_l4ls_clkdm)) {
+		ret = -ENODEV;
+		goto err;
+	}
+
+	wkup_m3 = kzalloc(sizeof(struct wkup_m3_context), GFP_KERNEL);
+	if (!wkup_m3) {
+		pr_err("Memory allocation failed\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	ret = am33xx_map_emif();
+	if (ret) {
+		pr_err("Could not ioremap EMIF\n");
+		goto err;
+	}
+
+	(void) clkdm_for_each(omap_pm_clkdms_setup, NULL);
+
+	/* CEFUSE domain can be turned off post bootup */
+	cefuse_pwrdm = pwrdm_lookup("cefuse_pwrdm");
+	if (cefuse_pwrdm)
+		pwrdm_set_next_fpwrst(cefuse_pwrdm, PWRDM_FUNC_PWRST_OFF);
+	else
+		pr_err("Failed to get cefuse_pwrdm\n");
+
+	wkup_m3->dev = omap_device_get_by_hwmod_name("wkup_m3");
+
+	ret = wkup_m3_init();
+	if (ret)
+		pr_err("Could not initialise firmware loading\n");
+
+err:
+	return ret;
+}
diff --git a/arch/arm/mach-omap2/pm33xx.h b/arch/arm/mach-omap2/pm33xx.h
new file mode 100644
index 0000000..13a2c85
--- /dev/null
+++ b/arch/arm/mach-omap2/pm33xx.h
@@ -0,0 +1,56 @@
+/*
+ * AM33XX Power Management Routines
+ *
+ * Copyright (C) 2012 Texas Instruments Inc.
+ * Vaibhav Bedia <vaibhav.bedia@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef __ARCH_ARM_MACH_OMAP2_PM33XX_H
+#define __ARCH_ARM_MACH_OMAP2_PM33XX_H
+
+#include "control.h"
+
+#ifndef __ASSEMBLER__
+struct wkup_m3_context {
+	struct am33xx_ipc_data	ipc_data;
+	struct device		*dev;
+	struct firmware		*firmware;
+	struct mailbox		*mbox;
+	void __iomem		*code;
+	u8			state;
+};
+
+#ifdef CONFIG_SUSPEND
+static void am33xx_m3_state_machine_reset(void);
+#else
+static inline void am33xx_m3_state_machine_reset(void) {}
+#endif /* CONFIG_SUSPEND */
+
+extern void __iomem *am33xx_get_emif_base(void);
+#endif
+
+#define	IPC_CMD_DS0			0x3
+#define IPC_CMD_RESET                   0xe
+#define DS_IPC_DEFAULT			0xffffffff
+
+#define IPC_RESP_SHIFT			16
+#define IPC_RESP_MASK			(0xffff << 16)
+
+#define M3_STATE_UNKNOWN		0
+#define M3_STATE_RESET			1
+#define M3_STATE_INITED			2
+#define M3_STATE_MSG_FOR_LP		3
+#define M3_STATE_MSG_FOR_RESET		4
+
+#define AM33XX_OCMC_END			0x40310000
+#define AM33XX_EMIF_BASE		0x4C000000
+
+#endif
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support
@ 2012-12-31 13:07   ` Vaibhav Bedia
  0 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

AM335x supports various low power modes as documented
in section 8.1.4.3 of the AM335x TRM which is available
@ http://www.ti.com/litv/pdf/spruh73f

DeepSleep0 mode offers the lowest power mode with limited
wakeup sources without a system reboot and is mapped as
the suspend state in the kernel. In this state, MPU and
PER domains are turned off with the internal RAM held in
retention to facilitate resume process. As part of the boot
process, the assembly code is copied over to OCMCRAM using
the OMAP SRAM code.

AM335x has a Cortex-M3 (WKUP_M3) which assists the MPU
in DeepSleep0 entry and exit. WKUP_M3 takes care of the
clockdomain and powerdomain transitions based on the
intended low power state. MPU needs to load the appropriate
WKUP_M3 binary onto the WKUP_M3 memory space before it can
leverage any of the PM features like DeepSleep.

The IPC mechanism between MPU and WKUP_M3 uses a mailbox
sub-module and 8 IPC registers in the Control module. MPU
uses the assigned Mailbox for issuing an interrupt to
WKUP_M3 which then goes and checks the IPC registers for
the payload. WKUP_M3 has the ability to trigger on interrupt
to MPU by executing the "sev" instruction.

In the current implementation when the suspend process
is initiated MPU interrupts the WKUP_M3 to let it know about
the intent of entering DeepSleep0 and waits for an ACK. When
the ACK is received MPU continues with its suspend process
to suspend all the drivers and then jumps to assembly in
OCMC RAM. The assembly code puts the PLLs in bypass, puts the
external RAM in self-refresh mode and then finally execute the
WFI instruction. Execution of the WFI instruction triggers another
interrupt to the WKUP_M3 which then continues wiht the power down
sequence wherein the clockdomain and powerdomain transition takes
place. As part of the sleep sequence, WKUP_M3 unmasks the interrupt
lines for the wakeup sources. WFI execution on WKUP_M3 causes the
hardware to disable the main oscillator of the SoC.

When a wakeup event occurs, WKUP_M3 starts the power-up
sequence by switching on the power domains and finally
enabling the clock to MPU. Since the MPU gets powered down
as part of the sleep sequence in the resume path ROM code
starts executing. The ROM code detects a wakeup from sleep
and then jumps to the resume location in OCMC which was
populated in one of the IPC registers as part of the suspend
sequence.

The low level code in OCMC relocks the PLLs, enables access
to external RAM and then jumps to the cpu_resume code of
the kernel to finish the resume process.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Tony Lingren <tony@atomide.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
---
v1->v2:
	Move assembly code addition, control module access
	and hookup in OMAP PM framework in separate patches.
	Address other comments from Kevin Hilman and Santosh
	Shilimkar on v1. The discussion on v1 is present @
	http://lists.infradead.org/pipermail/linux-arm-kernel/2012-November/129979.html
	Note: The mailbox change will need slight rework once
	the driver is finalized.

 arch/arm/mach-omap2/pm33xx.c |  469 ++++++++++++++++++++++++++++++++++++++++++
 arch/arm/mach-omap2/pm33xx.h |   56 +++++
 2 files changed, 525 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-omap2/pm33xx.c
 create mode 100644 arch/arm/mach-omap2/pm33xx.h

diff --git a/arch/arm/mach-omap2/pm33xx.c b/arch/arm/mach-omap2/pm33xx.c
new file mode 100644
index 0000000..aaa4daa
--- /dev/null
+++ b/arch/arm/mach-omap2/pm33xx.c
@@ -0,0 +1,469 @@
+/*
+ * AM33XX Power Management Routines
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ * Vaibhav Bedia <vaibhav.bedia@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/firmware.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/suspend.h>
+#include <linux/completion.h>
+#include <linux/module.h>
+#include <linux/mailbox.h>
+#include <linux/interrupt.h>
+
+#include <asm/suspend.h>
+#include <asm/proc-fns.h>
+#include <asm/sizes.h>
+#include <asm/fncpy.h>
+#include <asm/system_misc.h>
+
+#include "pm.h"
+#include "cm33xx.h"
+#include "pm33xx.h"
+#include "control.h"
+#include "clockdomain.h"
+#include "powerdomain.h"
+#include "omap_hwmod.h"
+#include "omap_device.h"
+#include "soc.h"
+#include "sram.h"
+
+void (*am33xx_do_wfi_sram)(void);
+
+static void __iomem *am33xx_emif_base;
+static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm, *per_pwrdm;
+static struct clockdomain *gfx_l4ls_clkdm;
+static struct omap_hwmod *usb_oh, *cpsw_oh, *tptc0_oh, *tptc1_oh, *tptc2_oh;
+static struct wkup_m3_context *wkup_m3;
+
+static DECLARE_COMPLETION(wkup_m3_sync);
+
+#ifdef CONFIG_SUSPEND
+static int am33xx_do_sram_idle(long unsigned int unused)
+{
+	am33xx_do_wfi_sram();
+	return 0;
+}
+
+static int am33xx_pm_suspend(void)
+{
+	int status, ret = 0;
+
+	/*
+	 * By default the following IPs do not have MSTANDBY asserted
+	 * which is necessary for PER domain transition. If the drivers
+	 * are not compiled into the kernel HWMOD code will not change the
+	 * state of the IPs if the IP was not never enabled. To ensure
+	 * that there no issues with or without the drivers being compiled
+	 * in the kernel, we forcefully put these IPs to idle.
+	 */
+	omap_hwmod_enable(usb_oh);
+	omap_hwmod_enable(tptc0_oh);
+	omap_hwmod_enable(tptc1_oh);
+	omap_hwmod_enable(tptc2_oh);
+	omap_hwmod_enable(cpsw_oh);
+
+	omap_hwmod_idle(usb_oh);
+	omap_hwmod_idle(tptc0_oh);
+	omap_hwmod_idle(tptc1_oh);
+	omap_hwmod_idle(tptc2_oh);
+	omap_hwmod_idle(cpsw_oh);
+
+	/* Try to put GFX to sleep */
+	pwrdm_set_next_fpwrst(gfx_pwrdm, PWRDM_FUNC_PWRST_OFF);
+
+	ret = cpu_suspend(0, am33xx_do_sram_idle);
+
+	status = pwrdm_read_fpwrst(gfx_pwrdm);
+	if (status != PWRDM_FUNC_PWRST_OFF)
+		pr_err("GFX domain did not transition\n");
+	else
+		pr_info("GFX domain entered low power state\n");
+
+	/*
+	 * GFX_L4LS clock domain needs to be woken up to
+	 * ensure thet L4LS clock domain does not get stuck in transition
+	 * If that happens L3 module does not get disabled, thereby leading
+	 * to PER power domain transition failing
+	 *
+	 * The clock framework should take care of ensuring
+	 * that the clock domain is in the right state when
+	 * GFX driver is active.
+	 */
+	clkdm_wakeup(gfx_l4ls_clkdm);
+	clkdm_sleep(gfx_l4ls_clkdm);
+
+	if (ret) {
+		pr_err("Kernel suspend failure\n");
+	} else {
+		status = omap_ctrl_readl(AM33XX_CONTROL_IPC_MSG_REG1);
+		status &= IPC_RESP_MASK;
+		status >>= __ffs(IPC_RESP_MASK);
+
+		switch (status) {
+		case 0:
+			pr_info("Successfully put all powerdomains to target state\n");
+			/*
+			 * XXX: Leads to loss of logic state in PER power domain
+			 * Use SOC specific ops for this?
+			 */
+			break;
+		case 1:
+			pr_err("Could not transition all powerdomains to target state\n");
+			ret = -1;
+			break;
+		default:
+			pr_err("Something went wrong :(\nStatus = %d\n",
+				status);
+			ret = -1;
+		}
+	}
+
+	return ret;
+}
+
+static int am33xx_pm_enter(suspend_state_t suspend_state)
+{
+	int ret = 0;
+
+	switch (suspend_state) {
+	case PM_SUSPEND_STANDBY:
+	case PM_SUSPEND_MEM:
+		ret = am33xx_pm_suspend();
+		break;
+	default:
+		ret = -EINVAL;
+	}
+
+	return ret;
+}
+
+static int am33xx_pm_begin(suspend_state_t state)
+{
+	int ret = 0;
+	struct mailbox_msg dummy_msg;
+
+	disable_hlt();
+
+	MAILBOX_FILL_HEADER_MSG(dummy_msg, 0xABCDABCD);
+
+	wkup_m3->ipc_data.sleep_mode = IPC_CMD_DS0;
+	wkup_m3->ipc_data.param1  = DS_IPC_DEFAULT;
+	wkup_m3->ipc_data.param2  = DS_IPC_DEFAULT;
+
+	am33xx_wkup_m3_ipc_cmd(&wkup_m3->ipc_data);
+
+	wkup_m3->state = M3_STATE_MSG_FOR_LP;
+
+	mailbox_enable_irq(wkup_m3->mbox, IRQ_RX);
+
+	ret = mailbox_msg_send(wkup_m3->mbox, &dummy_msg);
+	if (ret) {
+		pr_err("A8<->CM3 MSG for LP failed\n");
+		am33xx_m3_state_machine_reset();
+		ret = -1;
+	}
+
+	/* Give some time to M3 to respond. 500msec is a random value here */
+	if (!wait_for_completion_timeout(&wkup_m3_sync,
+					msecs_to_jiffies(500))) {
+		pr_err("A8<->CM3 sync failure\n");
+		am33xx_m3_state_machine_reset();
+		ret = -1;
+	} else {
+		pr_debug("Message sent for entering DeepSleep mode\n");
+		mailbox_disable_irq(wkup_m3->mbox, IRQ_RX);
+	}
+
+	return ret;
+}
+
+static void am33xx_pm_end(void)
+{
+	mailbox_enable_irq(wkup_m3->mbox, IRQ_RX);
+
+	am33xx_m3_state_machine_reset();
+
+	enable_hlt();
+
+	return;
+}
+
+static const struct platform_suspend_ops am33xx_pm_ops = {
+	.begin		= am33xx_pm_begin,
+	.end		= am33xx_pm_end,
+	.enter		= am33xx_pm_enter,
+	.valid		= suspend_valid_only_mem,
+};
+
+static void am33xx_m3_state_machine_reset(void)
+{
+	int ret = 0;
+	struct mailbox_msg dummy_msg;
+
+	MAILBOX_FILL_HEADER_MSG(dummy_msg, 0xABCDABCD);
+
+	wkup_m3->ipc_data.sleep_mode	= IPC_CMD_RESET;
+	wkup_m3->ipc_data.param1	= DS_IPC_DEFAULT;
+	wkup_m3->ipc_data.param2	= DS_IPC_DEFAULT;
+
+	am33xx_wkup_m3_ipc_cmd(&wkup_m3->ipc_data);
+
+	wkup_m3->state = M3_STATE_MSG_FOR_RESET;
+
+	ret = mailbox_msg_send(wkup_m3->mbox, &dummy_msg);
+	if (!ret) {
+		pr_debug("Message sent for resetting M3 state machine\n");
+		/* Give some to M3 to respond. 500msec is a random value here */
+		if (!wait_for_completion_timeout(&wkup_m3_sync,
+						msecs_to_jiffies(500)))
+			pr_err("A8<->CM3 sync failure\n");
+	} else {
+		pr_err("Could not reset M3 state machine!!!\n");
+		wkup_m3->state = M3_STATE_UNKNOWN;
+	}
+}
+#endif /* CONFIG_SUSPEND */
+
+/*
+ * Dummy notifier for the mailbox
+ * XXX: Get rid of this requirement once the MBX driver has been finalized
+ */
+static int wkup_mbox_msg(struct notifier_block *self, unsigned long len,
+		void *msg)
+{
+	return 0;
+}
+
+static struct notifier_block wkup_mbox_notifier = {
+	.notifier_call = wkup_mbox_msg,
+};
+
+static irqreturn_t wkup_m3_txev_handler(int irq, void *unused)
+{
+	am33xx_txev_eoi();
+
+	switch (wkup_m3->state) {
+	case M3_STATE_RESET:
+		wkup_m3->state = M3_STATE_INITED;
+		break;
+	case M3_STATE_MSG_FOR_RESET:
+		wkup_m3->state = M3_STATE_INITED;
+		mailbox_rx_flush(wkup_m3->mbox);
+		complete(&wkup_m3_sync);
+		break;
+	case M3_STATE_MSG_FOR_LP:
+		mailbox_rx_flush(wkup_m3->mbox);
+		complete(&wkup_m3_sync);
+		break;
+	case M3_STATE_UNKNOWN:
+		pr_err("IRQ %d with WKUP_M3 in unknown state\n", irq);
+		mailbox_rx_flush(wkup_m3->mbox);
+		return IRQ_NONE;
+	}
+
+	am33xx_txev_enable();
+	return IRQ_HANDLED;
+}
+
+static void am33xx_pm_firmware_cb(const struct firmware *fw, void *context)
+{
+	struct wkup_m3_context *wkup_m3_context = context;
+	struct platform_device *pdev = to_platform_device(wkup_m3_context->dev);
+	int ret = 0;
+
+	/* no firmware found */
+	if (!fw) {
+		dev_err(wkup_m3_context->dev, "request_firmware failed\n");
+		goto err;
+	}
+
+	memcpy((void *)wkup_m3_context->code, fw->data, fw->size);
+	pr_info("Copied the M3 firmware to UMEM\n");
+
+	wkup_m3->state = M3_STATE_RESET;
+
+	ret = omap_device_deassert_hardreset(pdev, "wkup_m3");
+	if (ret) {
+		pr_err("Could not deassert the reset for WKUP_M3\n");
+		goto err;
+	} else {
+#ifdef CONFIG_SUSPEND
+		suspend_set_ops(&am33xx_pm_ops);
+		/*
+		 * Physical resume address to be used by ROM code
+		 */
+		wkup_m3->ipc_data.resume_addr = (AM33XX_OCMC_END -
+				am33xx_do_wfi_sz + am33xx_resume_offset + 0x4);
+#endif
+		return;
+	}
+
+err:
+	mailbox_put(wkup_m3_context->mbox, &wkup_mbox_notifier);
+}
+
+static int wkup_m3_init(void)
+{
+	int irq, ret = 0;
+	struct resource *mem;
+	struct platform_device *pdev = to_platform_device(wkup_m3->dev);
+
+	omap_device_enable_hwmods(to_omap_device(pdev));
+
+	/* Reserve the MBOX for sending messages to M3 */
+	wkup_m3->mbox = mailbox_get("wkup_m3", &wkup_mbox_notifier);
+	if (IS_ERR(wkup_m3->mbox)) {
+		pr_err("Could not reserve mailbox for A8->M3 IPC\n");
+		ret = -ENODEV;
+		goto exit;
+	}
+
+	irq = platform_get_irq(pdev, 0);
+	if (!irq) {
+		dev_err(wkup_m3->dev, "no irq resource\n");
+		ret = -ENXIO;
+		goto err;
+	}
+
+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!mem) {
+		dev_err(wkup_m3->dev, "no memory resource\n");
+		ret = -ENXIO;
+		goto err;
+	}
+
+	wkup_m3->code = devm_request_and_ioremap(wkup_m3->dev, mem);
+	if (!wkup_m3->code) {
+		dev_err(wkup_m3->dev, "could not ioremap\n");
+		ret = -EADDRNOTAVAIL;
+		goto err;
+	}
+
+	ret = devm_request_irq(wkup_m3->dev, irq, wkup_m3_txev_handler,
+		  IRQF_DISABLED, "wkup_m3_txev", NULL);
+	if (ret) {
+		dev_err(wkup_m3->dev, "request_irq failed\n");
+		goto err;
+	} else {
+		am33xx_txev_enable();
+	}
+
+	pr_info("Trying to load am335x-pm-firmware.bin");
+
+	/* We don't want to delay boot */
+	request_firmware_nowait(THIS_MODULE, 0, "am335x-pm-firmware.bin",
+				wkup_m3->dev, GFP_KERNEL, wkup_m3,
+				am33xx_pm_firmware_cb);
+	return 0;
+
+err:
+	mailbox_put(wkup_m3->mbox, &wkup_mbox_notifier);
+exit:
+	return ret;
+}
+
+/*
+ * Push the minimal suspend-resume code to SRAM
+ */
+void am33xx_push_sram_idle(void)
+{
+	am33xx_do_wfi_sram = (void *)omap_sram_push
+					(am33xx_do_wfi, am33xx_do_wfi_sz);
+}
+
+static int __init am33xx_map_emif(void)
+{
+	am33xx_emif_base = ioremap(AM33XX_EMIF_BASE, SZ_32K);
+
+	if (!am33xx_emif_base)
+		return -ENOMEM;
+
+	return 0;
+}
+
+void __iomem *am33xx_get_emif_base(void)
+{
+	return am33xx_emif_base;
+}
+
+int __init am33xx_pm_init(void)
+{
+	int ret;
+
+	if (!soc_is_am33xx())
+		return -ENODEV;
+
+	pr_info("Power Management for AM33XX family\n");
+
+	/*
+	 * By default the following IPs do not have MSTANDBY asserted
+	 * which is necessary for PER domain transition. If the drivers
+	 * are not compiled into the kernel HWMOD code will not change the
+	 * state of the IPs if the IP was not never enabled
+	 */
+	usb_oh		= omap_hwmod_lookup("usb_otg_hs");
+	tptc0_oh	= omap_hwmod_lookup("tptc0");
+	tptc1_oh	= omap_hwmod_lookup("tptc1");
+	tptc2_oh	= omap_hwmod_lookup("tptc2");
+	cpsw_oh		= omap_hwmod_lookup("cpgmac0");
+
+	gfx_pwrdm = pwrdm_lookup("gfx_pwrdm");
+	per_pwrdm = pwrdm_lookup("per_pwrdm");
+
+	gfx_l4ls_clkdm = clkdm_lookup("gfx_l4ls_gfx_clkdm");
+
+	if ((!usb_oh) || (!tptc0_oh) || (!tptc1_oh) || (!tptc2_oh) ||
+		(!cpsw_oh) || (!gfx_pwrdm) || (!per_pwrdm) ||
+		(!gfx_l4ls_clkdm)) {
+		ret = -ENODEV;
+		goto err;
+	}
+
+	wkup_m3 = kzalloc(sizeof(struct wkup_m3_context), GFP_KERNEL);
+	if (!wkup_m3) {
+		pr_err("Memory allocation failed\n");
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	ret = am33xx_map_emif();
+	if (ret) {
+		pr_err("Could not ioremap EMIF\n");
+		goto err;
+	}
+
+	(void) clkdm_for_each(omap_pm_clkdms_setup, NULL);
+
+	/* CEFUSE domain can be turned off post bootup */
+	cefuse_pwrdm = pwrdm_lookup("cefuse_pwrdm");
+	if (cefuse_pwrdm)
+		pwrdm_set_next_fpwrst(cefuse_pwrdm, PWRDM_FUNC_PWRST_OFF);
+	else
+		pr_err("Failed to get cefuse_pwrdm\n");
+
+	wkup_m3->dev = omap_device_get_by_hwmod_name("wkup_m3");
+
+	ret = wkup_m3_init();
+	if (ret)
+		pr_err("Could not initialise firmware loading\n");
+
+err:
+	return ret;
+}
diff --git a/arch/arm/mach-omap2/pm33xx.h b/arch/arm/mach-omap2/pm33xx.h
new file mode 100644
index 0000000..13a2c85
--- /dev/null
+++ b/arch/arm/mach-omap2/pm33xx.h
@@ -0,0 +1,56 @@
+/*
+ * AM33XX Power Management Routines
+ *
+ * Copyright (C) 2012 Texas Instruments Inc.
+ * Vaibhav Bedia <vaibhav.bedia@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#ifndef __ARCH_ARM_MACH_OMAP2_PM33XX_H
+#define __ARCH_ARM_MACH_OMAP2_PM33XX_H
+
+#include "control.h"
+
+#ifndef __ASSEMBLER__
+struct wkup_m3_context {
+	struct am33xx_ipc_data	ipc_data;
+	struct device		*dev;
+	struct firmware		*firmware;
+	struct mailbox		*mbox;
+	void __iomem		*code;
+	u8			state;
+};
+
+#ifdef CONFIG_SUSPEND
+static void am33xx_m3_state_machine_reset(void);
+#else
+static inline void am33xx_m3_state_machine_reset(void) {}
+#endif /* CONFIG_SUSPEND */
+
+extern void __iomem *am33xx_get_emif_base(void);
+#endif
+
+#define	IPC_CMD_DS0			0x3
+#define IPC_CMD_RESET                   0xe
+#define DS_IPC_DEFAULT			0xffffffff
+
+#define IPC_RESP_SHIFT			16
+#define IPC_RESP_MASK			(0xffff << 16)
+
+#define M3_STATE_UNKNOWN		0
+#define M3_STATE_RESET			1
+#define M3_STATE_INITED			2
+#define M3_STATE_MSG_FOR_LP		3
+#define M3_STATE_MSG_FOR_RESET		4
+
+#define AM33XX_OCMC_END			0x40310000
+#define AM33XX_EMIF_BASE		0x4C000000
+
+#endif
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 17/18] ARM: OMAP2+: AM33XX: Select Mailbox when PM is enabled
  2012-12-31 13:06 ` Vaibhav Bedia
@ 2012-12-31 13:07   ` Vaibhav Bedia
  -1 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, tony, khilman
  Cc: Vaibhav Bedia, Santosh Shilimkar, Benoit Cousson, Paul Walmsley

PM services on AM33XX depend on mailbox for communication
with WKUP-M3 core so ensure that the right config options
are selected. Thanks to Kevin Hilman <khilman@deeprootsystems.com>
for the suggestion on updating the Kconfig and not just
the omap2plus_defconfig which was done in the previous version
of the AM33XX suspend-resume support.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Tony Lingren <tony@atomide.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
---
v1->v2:
	Update the Kconfig instead of the defconfig

 arch/arm/mach-omap2/Kconfig |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 41b581f..c026fbd 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -114,9 +114,11 @@ config SOC_AM33XX
 	bool "AM33XX support"
 	default y
 	select ARM_CPU_SUSPEND if PM
+	select COMMON_CLK
 	select CPU_V7
+	select MAILBOX if PM
 	select MULTI_IRQ_HANDLER
-	select COMMON_CLK
+	select OMAP2PLUS_MBOX if PM
 
 config OMAP_PACKAGE_ZAF
        bool
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 17/18] ARM: OMAP2+: AM33XX: Select Mailbox when PM is enabled
@ 2012-12-31 13:07   ` Vaibhav Bedia
  0 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

PM services on AM33XX depend on mailbox for communication
with WKUP-M3 core so ensure that the right config options
are selected. Thanks to Kevin Hilman <khilman@deeprootsystems.com>
for the suggestion on updating the Kconfig and not just
the omap2plus_defconfig which was done in the previous version
of the AM33XX suspend-resume support.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Tony Lingren <tony@atomide.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
---
v1->v2:
	Update the Kconfig instead of the defconfig

 arch/arm/mach-omap2/Kconfig |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 41b581f..c026fbd 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -114,9 +114,11 @@ config SOC_AM33XX
 	bool "AM33XX support"
 	default y
 	select ARM_CPU_SUSPEND if PM
+	select COMMON_CLK
 	select CPU_V7
+	select MAILBOX if PM
 	select MULTI_IRQ_HANDLER
-	select COMMON_CLK
+	select OMAP2PLUS_MBOX if PM
 
 config OMAP_PACKAGE_ZAF
        bool
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 18/18] ARM: OMAP2+: AM33XX: Hookup AM33XX PM code into OMAP builds
  2012-12-31 13:06 ` Vaibhav Bedia
@ 2012-12-31 13:07   ` Vaibhav Bedia
  -1 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-omap, linux-arm-kernel, tony, khilman
  Cc: Vaibhav Bedia, Santosh Shilimkar, Benoit Cousson, Paul Walmsley

With all the requisite changes in place we can now
enable basic PM support on AM33XX. This patch updates
the various OMAP files to enable suspend-resume on
AM33XX.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Tony Lingren <tony@atomide.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
---
v1->v2:
	This is a new patch in the series

 arch/arm/mach-omap2/Makefile        |    2 ++
 arch/arm/mach-omap2/board-generic.c |    1 +
 arch/arm/mach-omap2/common.h        |   10 ++++++++++
 arch/arm/mach-omap2/io.c            |    7 +++++++
 arch/arm/mach-omap2/pm.h            |    7 +++++++
 arch/arm/mach-omap2/sram.c          |   10 +++++++++-
 arch/arm/mach-omap2/sram.h          |    2 ++
 7 files changed, 38 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index e61867b..a5db55b 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -81,6 +81,7 @@ obj-$(CONFIG_ARCH_OMAP2)		+= sleep24xx.o
 obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o
 obj-$(CONFIG_ARCH_OMAP4)		+= pm44xx.o omap-mpuss-lowpower.o
 obj-$(CONFIG_SOC_OMAP5)			+= omap-mpuss-lowpower.o
+obj-$(CONFIG_SOC_AM33XX)		+= pm33xx.o sleep33xx.o
 obj-$(CONFIG_PM_DEBUG)			+= pm-debug.o
 
 obj-$(CONFIG_POWER_AVS_OMAP)		+= sr_device.o
@@ -88,6 +89,7 @@ obj-$(CONFIG_POWER_AVS_OMAP_CLASS3)    += smartreflex-class3.o
 
 AFLAGS_sleep24xx.o			:=-Wa,-march=armv6
 AFLAGS_sleep34xx.o			:=-Wa,-march=armv7-a$(plus_sec)
+AFLAGS_sleep33xx.o			:=-Wa,-march=armv7-a$(plus_sec)
 
 ifeq ($(CONFIG_PM_VERBOSE),y)
 CFLAGS_pm_bus.o				+= -DDEBUG
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 53cb380..1c9195d 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -136,6 +136,7 @@ DT_MACHINE_START(AM33XX_DT, "Generic AM33XX (Flattened Device Tree)")
 	.reserve	= omap_reserve,
 	.map_io		= am33xx_map_io,
 	.init_early	= am33xx_init_early,
+	.init_late	= am33xx_init_late,
 	.init_irq	= omap_intc_of_init,
 	.handle_irq	= omap3_intc_handle_irq,
 	.init_machine	= omap_generic_init,
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index 41d74fe..73cac5c 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -68,6 +68,15 @@ static inline int omap4_pm_init(void)
 }
 #endif
 
+#if defined(CONFIG_PM) && defined(CONFIG_SOC_AM33XX)
+int am33xx_pm_init(void);
+#else
+static inline int am33xx_pm_init(void)
+{
+	return 0;
+}
+#endif
+
 #ifdef CONFIG_OMAP_MUX
 int omap_mux_late_init(void);
 #else
@@ -106,6 +115,7 @@ void omap2430_init_late(void);
 void omap3430_init_late(void);
 void omap35xx_init_late(void);
 void omap3630_init_late(void);
+void am33xx_init_late(void);
 void am35xx_init_late(void);
 void ti81xx_init_late(void);
 void omap4430_init_late(void);
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 2c3fdd6..b5637c6 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -570,6 +570,13 @@ void __init am33xx_init_early(void)
 	omap_hwmod_init_postsetup();
 	am33xx_clk_init();
 }
+
+void __init am33xx_init_late(void)
+{
+	omap_mux_late_init();
+	omap2_common_pm_late_init();
+	am33xx_pm_init();
+}
 #endif
 
 #ifdef CONFIG_ARCH_OMAP4
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 531a4de..118ebde 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -76,6 +76,13 @@ extern unsigned int omap3_do_wfi_sz;
 /* ... and its pointer from SRAM after copy */
 extern void (*omap3_do_wfi_sram)(void);
 
+/* am33xx_do_wfi function pointer and size, for copy to SRAM */
+extern void am33xx_do_wfi(void);
+extern unsigned int am33xx_do_wfi_sz;
+extern unsigned int am33xx_resume_offset;
+/* ... and its pointer from SRAM after copy */
+extern void (*am33xx_do_wfi_sram)(void);
+
 /* save_secure_ram_context function pointer and size, for copy to SRAM */
 extern int save_secure_ram_context(u32 *addr);
 extern unsigned int save_secure_ram_context_sz;
diff --git a/arch/arm/mach-omap2/sram.c b/arch/arm/mach-omap2/sram.c
index 0ff0f06..7951e0d 100644
--- a/arch/arm/mach-omap2/sram.c
+++ b/arch/arm/mach-omap2/sram.c
@@ -151,7 +151,7 @@ static void __init omap2_map_sram(void)
 		omap_sram_size -= SZ_16K;
 	}
 #endif
-	if (cpu_is_omap34xx()) {
+	if (cpu_is_omap34xx() || soc_is_am33xx()) {
 		/*
 		 * SRAM must be marked as non-cached on OMAP3 since the
 		 * CORE DPLL M2 divider change code (in SRAM) runs with the
@@ -282,10 +282,18 @@ static inline int omap34xx_sram_init(void)
 }
 #endif /* CONFIG_ARCH_OMAP3 */
 
+#ifdef CONFIG_SOC_AM33XX
 static inline int am33xx_sram_init(void)
 {
+	am33xx_push_sram_idle();
 	return 0;
 }
+#else
+static inline int am33xx_sram_init(void)
+{
+	return 0;
+}
+#endif
 
 int __init omap_sram_init(void)
 {
diff --git a/arch/arm/mach-omap2/sram.h b/arch/arm/mach-omap2/sram.h
index ca7277c..24788b5 100644
--- a/arch/arm/mach-omap2/sram.h
+++ b/arch/arm/mach-omap2/sram.h
@@ -62,8 +62,10 @@ extern unsigned long omap3_sram_configure_core_dpll_sz;
 
 #ifdef CONFIG_PM
 extern void omap_push_sram_idle(void);
+extern void am33xx_push_sram_idle(void);
 #else
 static inline void omap_push_sram_idle(void) {}
+static inline void am33xx_push_sram_idle(void) {}
 #endif /* CONFIG_PM */
 
 #endif /* __ASSEMBLY__ */
-- 
1.7.0.4


^ permalink raw reply related	[flat|nested] 148+ messages in thread

* [RFC v2 18/18] ARM: OMAP2+: AM33XX: Hookup AM33XX PM code into OMAP builds
@ 2012-12-31 13:07   ` Vaibhav Bedia
  0 siblings, 0 replies; 148+ messages in thread
From: Vaibhav Bedia @ 2012-12-31 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

With all the requisite changes in place we can now
enable basic PM support on AM33XX. This patch updates
the various OMAP files to enable suspend-resume on
AM33XX.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
Cc: Tony Lingren <tony@atomide.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
---
v1->v2:
	This is a new patch in the series

 arch/arm/mach-omap2/Makefile        |    2 ++
 arch/arm/mach-omap2/board-generic.c |    1 +
 arch/arm/mach-omap2/common.h        |   10 ++++++++++
 arch/arm/mach-omap2/io.c            |    7 +++++++
 arch/arm/mach-omap2/pm.h            |    7 +++++++
 arch/arm/mach-omap2/sram.c          |   10 +++++++++-
 arch/arm/mach-omap2/sram.h          |    2 ++
 7 files changed, 38 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index e61867b..a5db55b 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -81,6 +81,7 @@ obj-$(CONFIG_ARCH_OMAP2)		+= sleep24xx.o
 obj-$(CONFIG_ARCH_OMAP3)		+= pm34xx.o sleep34xx.o
 obj-$(CONFIG_ARCH_OMAP4)		+= pm44xx.o omap-mpuss-lowpower.o
 obj-$(CONFIG_SOC_OMAP5)			+= omap-mpuss-lowpower.o
+obj-$(CONFIG_SOC_AM33XX)		+= pm33xx.o sleep33xx.o
 obj-$(CONFIG_PM_DEBUG)			+= pm-debug.o
 
 obj-$(CONFIG_POWER_AVS_OMAP)		+= sr_device.o
@@ -88,6 +89,7 @@ obj-$(CONFIG_POWER_AVS_OMAP_CLASS3)    += smartreflex-class3.o
 
 AFLAGS_sleep24xx.o			:=-Wa,-march=armv6
 AFLAGS_sleep34xx.o			:=-Wa,-march=armv7-a$(plus_sec)
+AFLAGS_sleep33xx.o			:=-Wa,-march=armv7-a$(plus_sec)
 
 ifeq ($(CONFIG_PM_VERBOSE),y)
 CFLAGS_pm_bus.o				+= -DDEBUG
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 53cb380..1c9195d 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -136,6 +136,7 @@ DT_MACHINE_START(AM33XX_DT, "Generic AM33XX (Flattened Device Tree)")
 	.reserve	= omap_reserve,
 	.map_io		= am33xx_map_io,
 	.init_early	= am33xx_init_early,
+	.init_late	= am33xx_init_late,
 	.init_irq	= omap_intc_of_init,
 	.handle_irq	= omap3_intc_handle_irq,
 	.init_machine	= omap_generic_init,
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index 41d74fe..73cac5c 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -68,6 +68,15 @@ static inline int omap4_pm_init(void)
 }
 #endif
 
+#if defined(CONFIG_PM) && defined(CONFIG_SOC_AM33XX)
+int am33xx_pm_init(void);
+#else
+static inline int am33xx_pm_init(void)
+{
+	return 0;
+}
+#endif
+
 #ifdef CONFIG_OMAP_MUX
 int omap_mux_late_init(void);
 #else
@@ -106,6 +115,7 @@ void omap2430_init_late(void);
 void omap3430_init_late(void);
 void omap35xx_init_late(void);
 void omap3630_init_late(void);
+void am33xx_init_late(void);
 void am35xx_init_late(void);
 void ti81xx_init_late(void);
 void omap4430_init_late(void);
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 2c3fdd6..b5637c6 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -570,6 +570,13 @@ void __init am33xx_init_early(void)
 	omap_hwmod_init_postsetup();
 	am33xx_clk_init();
 }
+
+void __init am33xx_init_late(void)
+{
+	omap_mux_late_init();
+	omap2_common_pm_late_init();
+	am33xx_pm_init();
+}
 #endif
 
 #ifdef CONFIG_ARCH_OMAP4
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 531a4de..118ebde 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -76,6 +76,13 @@ extern unsigned int omap3_do_wfi_sz;
 /* ... and its pointer from SRAM after copy */
 extern void (*omap3_do_wfi_sram)(void);
 
+/* am33xx_do_wfi function pointer and size, for copy to SRAM */
+extern void am33xx_do_wfi(void);
+extern unsigned int am33xx_do_wfi_sz;
+extern unsigned int am33xx_resume_offset;
+/* ... and its pointer from SRAM after copy */
+extern void (*am33xx_do_wfi_sram)(void);
+
 /* save_secure_ram_context function pointer and size, for copy to SRAM */
 extern int save_secure_ram_context(u32 *addr);
 extern unsigned int save_secure_ram_context_sz;
diff --git a/arch/arm/mach-omap2/sram.c b/arch/arm/mach-omap2/sram.c
index 0ff0f06..7951e0d 100644
--- a/arch/arm/mach-omap2/sram.c
+++ b/arch/arm/mach-omap2/sram.c
@@ -151,7 +151,7 @@ static void __init omap2_map_sram(void)
 		omap_sram_size -= SZ_16K;
 	}
 #endif
-	if (cpu_is_omap34xx()) {
+	if (cpu_is_omap34xx() || soc_is_am33xx()) {
 		/*
 		 * SRAM must be marked as non-cached on OMAP3 since the
 		 * CORE DPLL M2 divider change code (in SRAM) runs with the
@@ -282,10 +282,18 @@ static inline int omap34xx_sram_init(void)
 }
 #endif /* CONFIG_ARCH_OMAP3 */
 
+#ifdef CONFIG_SOC_AM33XX
 static inline int am33xx_sram_init(void)
 {
+	am33xx_push_sram_idle();
 	return 0;
 }
+#else
+static inline int am33xx_sram_init(void)
+{
+	return 0;
+}
+#endif
 
 int __init omap_sram_init(void)
 {
diff --git a/arch/arm/mach-omap2/sram.h b/arch/arm/mach-omap2/sram.h
index ca7277c..24788b5 100644
--- a/arch/arm/mach-omap2/sram.h
+++ b/arch/arm/mach-omap2/sram.h
@@ -62,8 +62,10 @@ extern unsigned long omap3_sram_configure_core_dpll_sz;
 
 #ifdef CONFIG_PM
 extern void omap_push_sram_idle(void);
+extern void am33xx_push_sram_idle(void);
 #else
 static inline void omap_push_sram_idle(void) {}
+static inline void am33xx_push_sram_idle(void) {}
 #endif /* CONFIG_PM */
 
 #endif /* __ASSEMBLY__ */
-- 
1.7.0.4

^ permalink raw reply related	[flat|nested] 148+ messages in thread

* Re: [RFC v2 01/18] mailbox: OMAP2+: Add support for AM33XX
  2012-12-31 13:06   ` Vaibhav Bedia
@ 2013-01-01 18:25     ` Tony Lindgren
  -1 siblings, 0 replies; 148+ messages in thread
From: Tony Lindgren @ 2013-01-01 18:25 UTC (permalink / raw)
  To: Vaibhav Bedia
  Cc: linux-omap, linux-arm-kernel, khilman, Russ Dill, Santosh Shilimkar

* Vaibhav Bedia <vaibhav.bedia@ti.com> [121231 05:10]:
> Mailbox IP on AM33XX is the same as that present in OMAP4.
> The single instance of Mailbox IP on AM33XX contains
> 8 sub-modules and facilitates communication between MPU,
> PRUs and WKUP_M3.
> 
> The first mailbox sub-module is assigned for communication
> between MPU and WKUP-M3.
> 
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Russ Dill <russ.dill@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
> v1->v2:
> 	Address the comment on operator usage from Russ Dill
> 
>  drivers/mailbox/mailbox-omap2.c |   35 ++++++++++++++++++++++++++++++++++-
>  1 files changed, 34 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/mailbox/mailbox-omap2.c b/drivers/mailbox/mailbox-omap2.c
> index 7c26bed..6d61159 100644
> --- a/drivers/mailbox/mailbox-omap2.c
> +++ b/drivers/mailbox/mailbox-omap2.c
> @@ -151,7 +151,7 @@ static void omap2_mbox_disable_irq(struct mailbox *mbox,
>  	struct omap_mbox2_priv *p = mbox->priv;
>  	u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
>  
> -	if (!cpu_is_omap44xx())
> +	if (!cpu_is_omap44xx() && !soc_is_am33xx())
>  		bit = mbox_read_reg(p->irqdisable) & ~bit;
>  
>  	mbox_write_reg(bit, p->irqdisable);

The cpu_is/soc_is macros are no longer available to drivers
with 8d91a42e (Merge tag 'omap-late-cleanups'...). So you'll
have to pass whatever flags the driver needs in platform_data
or as device tree properties.

> @@ -386,6 +412,13 @@ static int __devinit omap2_mbox_probe(struct platform_device *pdev)
>  		list[0]->irq = list[1]->irq = platform_get_irq(pdev, 0);
>  	}
>  #endif
> +#if defined(CONFIG_SOC_AM33XX)
> +	else if (soc_is_am33xx()) {
> +		list = am33xx_mboxes;
> +
> +		list[0]->irq = platform_get_irq(pdev, 0);
> +	}
> +#endif
>  	else {
>  		pr_err("%s: platform not supported\n", __func__);
>  		return -ENODEV;

Here too.

Tony

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 01/18] mailbox: OMAP2+: Add support for AM33XX
@ 2013-01-01 18:25     ` Tony Lindgren
  0 siblings, 0 replies; 148+ messages in thread
From: Tony Lindgren @ 2013-01-01 18:25 UTC (permalink / raw)
  To: linux-arm-kernel

* Vaibhav Bedia <vaibhav.bedia@ti.com> [121231 05:10]:
> Mailbox IP on AM33XX is the same as that present in OMAP4.
> The single instance of Mailbox IP on AM33XX contains
> 8 sub-modules and facilitates communication between MPU,
> PRUs and WKUP_M3.
> 
> The first mailbox sub-module is assigned for communication
> between MPU and WKUP-M3.
> 
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Russ Dill <russ.dill@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
> v1->v2:
> 	Address the comment on operator usage from Russ Dill
> 
>  drivers/mailbox/mailbox-omap2.c |   35 ++++++++++++++++++++++++++++++++++-
>  1 files changed, 34 insertions(+), 1 deletions(-)
> 
> diff --git a/drivers/mailbox/mailbox-omap2.c b/drivers/mailbox/mailbox-omap2.c
> index 7c26bed..6d61159 100644
> --- a/drivers/mailbox/mailbox-omap2.c
> +++ b/drivers/mailbox/mailbox-omap2.c
> @@ -151,7 +151,7 @@ static void omap2_mbox_disable_irq(struct mailbox *mbox,
>  	struct omap_mbox2_priv *p = mbox->priv;
>  	u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
>  
> -	if (!cpu_is_omap44xx())
> +	if (!cpu_is_omap44xx() && !soc_is_am33xx())
>  		bit = mbox_read_reg(p->irqdisable) & ~bit;
>  
>  	mbox_write_reg(bit, p->irqdisable);

The cpu_is/soc_is macros are no longer available to drivers
with 8d91a42e (Merge tag 'omap-late-cleanups'...). So you'll
have to pass whatever flags the driver needs in platform_data
or as device tree properties.

> @@ -386,6 +412,13 @@ static int __devinit omap2_mbox_probe(struct platform_device *pdev)
>  		list[0]->irq = list[1]->irq = platform_get_irq(pdev, 0);
>  	}
>  #endif
> +#if defined(CONFIG_SOC_AM33XX)
> +	else if (soc_is_am33xx()) {
> +		list = am33xx_mboxes;
> +
> +		list[0]->irq = platform_get_irq(pdev, 0);
> +	}
> +#endif
>  	else {
>  		pr_err("%s: platform not supported\n", __func__);
>  		return -ENODEV;

Here too.

Tony

^ permalink raw reply	[flat|nested] 148+ messages in thread

* RE: [RFC v2 01/18] mailbox: OMAP2+: Add support for AM33XX
  2013-01-01 18:25     ` Tony Lindgren
@ 2013-01-02 11:09       ` Bedia, Vaibhav
  -1 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-02 11:09 UTC (permalink / raw)
  To: Tony Lindgren
  Cc: linux-omap, linux-arm-kernel, khilman, Dill, Russ, Shilimkar, Santosh

Hi Tony,

On Tue, Jan 01, 2013 at 23:55:06, Tony Lindgren wrote:
[...]
> >  
> >  	mbox_write_reg(bit, p->irqdisable);
> 
> The cpu_is/soc_is macros are no longer available to drivers
> with 8d91a42e (Merge tag 'omap-late-cleanups'...). So you'll
> have to pass whatever flags the driver needs in platform_data
> or as device tree properties.
> 

Thanks for the heads-up. Will rework this patch once the mailbox driver
migration is finalized.

Regards,
Vaibhav 


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 01/18] mailbox: OMAP2+: Add support for AM33XX
@ 2013-01-02 11:09       ` Bedia, Vaibhav
  0 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-02 11:09 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Tony,

On Tue, Jan 01, 2013 at 23:55:06, Tony Lindgren wrote:
[...]
> >  
> >  	mbox_write_reg(bit, p->irqdisable);
> 
> The cpu_is/soc_is macros are no longer available to drivers
> with 8d91a42e (Merge tag 'omap-late-cleanups'...). So you'll
> have to pass whatever flags the driver needs in platform_data
> or as device tree properties.
> 

Thanks for the heads-up. Will rework this patch once the mailbox driver
migration is finalized.

Regards,
Vaibhav 

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 01/18] mailbox: OMAP2+: Add support for AM33XX
  2012-12-31 13:06   ` Vaibhav Bedia
@ 2013-01-08 13:53     ` Santosh Shilimkar
  -1 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 13:53 UTC (permalink / raw)
  To: Vaibhav Bedia; +Cc: linux-omap, linux-arm-kernel, tony, khilman, Russ Dill

On Monday 31 December 2012 06:36 PM, Vaibhav Bedia wrote:
> Mailbox IP on AM33XX is the same as that present in OMAP4.
> The single instance of Mailbox IP on AM33XX contains
> 8 sub-modules and facilitates communication between MPU,
> PRUs and WKUP_M3.
>
PRUS?

> The first mailbox sub-module is assigned for communication
> between MPU and WKUP-M3.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Russ Dill <russ.dill@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
> v1->v2:
> 	Address the comment on operator usage from Russ Dill
>
>   drivers/mailbox/mailbox-omap2.c |   35 ++++++++++++++++++++++++++++++++++-
>   1 files changed, 34 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/mailbox/mailbox-omap2.c b/drivers/mailbox/mailbox-omap2.c
> index 7c26bed..6d61159 100644
> --- a/drivers/mailbox/mailbox-omap2.c
> +++ b/drivers/mailbox/mailbox-omap2.c
> @@ -151,7 +151,7 @@ static void omap2_mbox_disable_irq(struct mailbox *mbox,
>   	struct omap_mbox2_priv *p = mbox->priv;
>   	u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
>
> -	if (!cpu_is_omap44xx())
> +	if (!cpu_is_omap44xx() && !soc_is_am33xx())
>   		bit = mbox_read_reg(p->irqdisable) & ~bit;
>
>   	mbox_write_reg(bit, p->irqdisable);
> @@ -352,6 +352,32 @@ struct mailbox mbox_2_info = {
>   struct mailbox *omap4_mboxes[] = { &mbox_1_info, &mbox_2_info, NULL };
>   #endif
>
> +#if defined(CONFIG_SOC_AM33XX)
> +static struct omap_mbox2_priv omap2_mbox_wkup_m3_priv = {
> +	.tx_fifo = {
> +		.msg		= MAILBOX_MESSAGE(0),
> +		.fifo_stat	= MAILBOX_FIFOSTATUS(0),
> +		.msg_stat	= MAILBOX_MSGSTATUS(0),
> +	},
> +	.rx_fifo = {
> +		.msg		= MAILBOX_MESSAGE(1),
> +		.msg_stat	= MAILBOX_MSGSTATUS(1),
> +	},
> +	.irqenable	= OMAP4_MAILBOX_IRQENABLE(3),
> +	.irqstatus	= OMAP4_MAILBOX_IRQSTATUS(3),
> +	.irqdisable	= OMAP4_MAILBOX_IRQENABLE_CLR(3),
> +	.notfull_bit	= MAILBOX_IRQ_NOTFULL(0),
> +	.newmsg_bit	= MAILBOX_IRQ_NEWMSG(0),
> +};
> +
> +struct mailbox mbox_wkup_m3_info = {
> +	.name	= "wkup_m3",
> +	.ops	= &omap2_mbox_ops,
> +	.priv	= &omap2_mbox_wkup_m3_priv,
> +};
> +struct mailbox *am33xx_mboxes[] = { &mbox_wkup_m3_info, NULL };
> +#endif
> +
>   static int __devinit omap2_mbox_probe(struct platform_device *pdev)
>   {
>   	struct resource *mem;
> @@ -386,6 +412,13 @@ static int __devinit omap2_mbox_probe(struct platform_device *pdev)
>   		list[0]->irq = list[1]->irq = platform_get_irq(pdev, 0);
>   	}
>   #endif
> +#if defined(CONFIG_SOC_AM33XX)
ifdef in middle of the code. I know you are just
following what is already there.
> +	else if (soc_is_am33xx()) {
> +		list = am33xx_mboxes;
> +
UN-necessary extra line here.
> +		list[0]->irq = platform_get_irq(pdev, 0);
> +	}
> +#endif

Hopefully mailbox clean-up will kill that #ifdeffery.
Apart from those comments, patch looks fine to me.

Regards
Santosh

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 01/18] mailbox: OMAP2+: Add support for AM33XX
@ 2013-01-08 13:53     ` Santosh Shilimkar
  0 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 13:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 31 December 2012 06:36 PM, Vaibhav Bedia wrote:
> Mailbox IP on AM33XX is the same as that present in OMAP4.
> The single instance of Mailbox IP on AM33XX contains
> 8 sub-modules and facilitates communication between MPU,
> PRUs and WKUP_M3.
>
PRUS?

> The first mailbox sub-module is assigned for communication
> between MPU and WKUP-M3.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Russ Dill <russ.dill@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
> v1->v2:
> 	Address the comment on operator usage from Russ Dill
>
>   drivers/mailbox/mailbox-omap2.c |   35 ++++++++++++++++++++++++++++++++++-
>   1 files changed, 34 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/mailbox/mailbox-omap2.c b/drivers/mailbox/mailbox-omap2.c
> index 7c26bed..6d61159 100644
> --- a/drivers/mailbox/mailbox-omap2.c
> +++ b/drivers/mailbox/mailbox-omap2.c
> @@ -151,7 +151,7 @@ static void omap2_mbox_disable_irq(struct mailbox *mbox,
>   	struct omap_mbox2_priv *p = mbox->priv;
>   	u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
>
> -	if (!cpu_is_omap44xx())
> +	if (!cpu_is_omap44xx() && !soc_is_am33xx())
>   		bit = mbox_read_reg(p->irqdisable) & ~bit;
>
>   	mbox_write_reg(bit, p->irqdisable);
> @@ -352,6 +352,32 @@ struct mailbox mbox_2_info = {
>   struct mailbox *omap4_mboxes[] = { &mbox_1_info, &mbox_2_info, NULL };
>   #endif
>
> +#if defined(CONFIG_SOC_AM33XX)
> +static struct omap_mbox2_priv omap2_mbox_wkup_m3_priv = {
> +	.tx_fifo = {
> +		.msg		= MAILBOX_MESSAGE(0),
> +		.fifo_stat	= MAILBOX_FIFOSTATUS(0),
> +		.msg_stat	= MAILBOX_MSGSTATUS(0),
> +	},
> +	.rx_fifo = {
> +		.msg		= MAILBOX_MESSAGE(1),
> +		.msg_stat	= MAILBOX_MSGSTATUS(1),
> +	},
> +	.irqenable	= OMAP4_MAILBOX_IRQENABLE(3),
> +	.irqstatus	= OMAP4_MAILBOX_IRQSTATUS(3),
> +	.irqdisable	= OMAP4_MAILBOX_IRQENABLE_CLR(3),
> +	.notfull_bit	= MAILBOX_IRQ_NOTFULL(0),
> +	.newmsg_bit	= MAILBOX_IRQ_NEWMSG(0),
> +};
> +
> +struct mailbox mbox_wkup_m3_info = {
> +	.name	= "wkup_m3",
> +	.ops	= &omap2_mbox_ops,
> +	.priv	= &omap2_mbox_wkup_m3_priv,
> +};
> +struct mailbox *am33xx_mboxes[] = { &mbox_wkup_m3_info, NULL };
> +#endif
> +
>   static int __devinit omap2_mbox_probe(struct platform_device *pdev)
>   {
>   	struct resource *mem;
> @@ -386,6 +412,13 @@ static int __devinit omap2_mbox_probe(struct platform_device *pdev)
>   		list[0]->irq = list[1]->irq = platform_get_irq(pdev, 0);
>   	}
>   #endif
> +#if defined(CONFIG_SOC_AM33XX)
ifdef in middle of the code. I know you are just
following what is already there.
> +	else if (soc_is_am33xx()) {
> +		list = am33xx_mboxes;
> +
UN-necessary extra line here.
> +		list[0]->irq = platform_get_irq(pdev, 0);
> +	}
> +#endif

Hopefully mailbox clean-up will kill that #ifdeffery.
Apart from those comments, patch looks fine to me.

Regards
Santosh

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 02/18] mailbox: Add an API for flushing the FIFO
  2012-12-31 13:06   ` Vaibhav Bedia
@ 2013-01-08 13:56     ` Santosh Shilimkar
  -1 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 13:56 UTC (permalink / raw)
  To: Vaibhav Bedia; +Cc: linux-omap, linux-arm-kernel, tony, khilman

On Monday 31 December 2012 06:36 PM, Vaibhav Bedia wrote:
> On AM33XX, the mailbox module between the MPU and the
> WKUP-M3 co-processor facilitates a one-way communication.
> MPU uses the assigned mailbox sub-module to issue the
> interrupt to the WKUP-M3 co-processor which then goes
> and reads the the IPC data from registers in the control
> module.
>
> WKUP-M3 is in the L4_WKUP and does not have any access to
> the mailbox module. Due to this limitation, the MPU is
> completely responsible for FIFO maintenance and interrupt
> generation. MPU needs to ensure that the FIFO does not
> overflow by reading back the assigned mailbox sub-module.
>
> This patch adds an API in the mailbox code which the MPU
> can use to empty the FIFO by issuing a readback command.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
> Note: This patch which will be slightly reworked once the mailbox
> driver changes are finalized.
>
Can you expand a bit please ?

>   drivers/mailbox/mailbox-omap2.c |   19 +++++++++++++++++++
>   drivers/mailbox/mailbox.c       |   36 ++++++++++++++++++++++++++++++++++++
>   drivers/mailbox/mailbox.h       |    3 +++
>   include/linux/mailbox.h         |    1 +
>   4 files changed, 59 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/mailbox/mailbox-omap2.c b/drivers/mailbox/mailbox-omap2.c
> index 6d61159..c732be1 100644
> --- a/drivers/mailbox/mailbox-omap2.c
> +++ b/drivers/mailbox/mailbox-omap2.c
> @@ -125,6 +125,23 @@ static int omap2_mbox_fifo_full(struct mailbox *mbox)
>   	return mbox_read_reg(fifo->fifo_stat);
>   }
>
> +static int omap2_mbox_fifo_needs_flush(struct mailbox *mbox)
> +{
> +	struct omap_mbox2_priv *p = mbox->priv;
> +	struct omap_mbox2_fifo *fifo = &p->tx_fifo;
> +
> +	return mbox_read_reg(fifo->msg_stat);
> +}
> +
> +static void omap2_mbox_fifo_readback(struct mailbox *mbox,
> +			struct mailbox_msg *msg)
> +{
> +	struct omap_mbox2_priv *p = mbox->priv;
> +	struct omap_mbox2_fifo *fifo = &p->tx_fifo;
> +
> +	msg->header = mbox_read_reg(fifo->msg);
> +}
> +
>   static int ompa2_mbox_poll_for_space(struct mailbox *mbox)
>   {
>   	if (omap2_mbox_fifo_full(mbox))
> @@ -221,6 +238,8 @@ static struct mailbox_ops omap2_mbox_ops = {
>   	.read           = omap2_mbox_fifo_read,
>   	.write          = omap2_mbox_fifo_write,
>   	.empty          = omap2_mbox_fifo_empty,
> +	.fifo_needs_flush	= omap2_mbox_fifo_needs_flush,
> +	.fifo_readback		= omap2_mbox_fifo_readback,
>   	.poll_for_space = ompa2_mbox_poll_for_space,
>   	.enable_irq     = omap2_mbox_enable_irq,
>   	.disable_irq    = omap2_mbox_disable_irq,
> diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
> index 2f50226..92c9f68 100644
> --- a/drivers/mailbox/mailbox.c
> +++ b/drivers/mailbox/mailbox.c
> @@ -57,6 +57,15 @@ static inline int mbox_empty(struct mailbox *mbox)
>   {
>   	return mbox->ops->empty(mbox);
>   }
> +static inline int mbox_fifo_needs_flush(struct mailbox *mbox)
> +{
> +	return mbox->ops->fifo_needs_flush(mbox);
> +}
> +static inline void mbox_fifo_readback(struct mailbox *mbox,
> +				struct mailbox_msg *msg)
> +{
> +	mbox->ops->fifo_readback(mbox, msg);
> +}
>
>   /* Mailbox IRQ handle functions */
>   static inline void ack_mbox_irq(struct mailbox *mbox, mailbox_irq_t irq)
> @@ -110,6 +119,33 @@ out:
>   }
>   EXPORT_SYMBOL(mailbox_msg_send);
>
> +/*
s/*/**
> + * Flush the Rx FIFO by reading back the messages
> + * Since the normal expectation is that the Rx will do the
> + * reading, add a debug message to indicate if we really flush
> + *
> + * Returns the no. of messages read back
> + */
Just look at the kernel doc style for above

Rest looks fine.

Regards
Santosh

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 02/18] mailbox: Add an API for flushing the FIFO
@ 2013-01-08 13:56     ` Santosh Shilimkar
  0 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 13:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 31 December 2012 06:36 PM, Vaibhav Bedia wrote:
> On AM33XX, the mailbox module between the MPU and the
> WKUP-M3 co-processor facilitates a one-way communication.
> MPU uses the assigned mailbox sub-module to issue the
> interrupt to the WKUP-M3 co-processor which then goes
> and reads the the IPC data from registers in the control
> module.
>
> WKUP-M3 is in the L4_WKUP and does not have any access to
> the mailbox module. Due to this limitation, the MPU is
> completely responsible for FIFO maintenance and interrupt
> generation. MPU needs to ensure that the FIFO does not
> overflow by reading back the assigned mailbox sub-module.
>
> This patch adds an API in the mailbox code which the MPU
> can use to empty the FIFO by issuing a readback command.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> ---
> Note: This patch which will be slightly reworked once the mailbox
> driver changes are finalized.
>
Can you expand a bit please ?

>   drivers/mailbox/mailbox-omap2.c |   19 +++++++++++++++++++
>   drivers/mailbox/mailbox.c       |   36 ++++++++++++++++++++++++++++++++++++
>   drivers/mailbox/mailbox.h       |    3 +++
>   include/linux/mailbox.h         |    1 +
>   4 files changed, 59 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/mailbox/mailbox-omap2.c b/drivers/mailbox/mailbox-omap2.c
> index 6d61159..c732be1 100644
> --- a/drivers/mailbox/mailbox-omap2.c
> +++ b/drivers/mailbox/mailbox-omap2.c
> @@ -125,6 +125,23 @@ static int omap2_mbox_fifo_full(struct mailbox *mbox)
>   	return mbox_read_reg(fifo->fifo_stat);
>   }
>
> +static int omap2_mbox_fifo_needs_flush(struct mailbox *mbox)
> +{
> +	struct omap_mbox2_priv *p = mbox->priv;
> +	struct omap_mbox2_fifo *fifo = &p->tx_fifo;
> +
> +	return mbox_read_reg(fifo->msg_stat);
> +}
> +
> +static void omap2_mbox_fifo_readback(struct mailbox *mbox,
> +			struct mailbox_msg *msg)
> +{
> +	struct omap_mbox2_priv *p = mbox->priv;
> +	struct omap_mbox2_fifo *fifo = &p->tx_fifo;
> +
> +	msg->header = mbox_read_reg(fifo->msg);
> +}
> +
>   static int ompa2_mbox_poll_for_space(struct mailbox *mbox)
>   {
>   	if (omap2_mbox_fifo_full(mbox))
> @@ -221,6 +238,8 @@ static struct mailbox_ops omap2_mbox_ops = {
>   	.read           = omap2_mbox_fifo_read,
>   	.write          = omap2_mbox_fifo_write,
>   	.empty          = omap2_mbox_fifo_empty,
> +	.fifo_needs_flush	= omap2_mbox_fifo_needs_flush,
> +	.fifo_readback		= omap2_mbox_fifo_readback,
>   	.poll_for_space = ompa2_mbox_poll_for_space,
>   	.enable_irq     = omap2_mbox_enable_irq,
>   	.disable_irq    = omap2_mbox_disable_irq,
> diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
> index 2f50226..92c9f68 100644
> --- a/drivers/mailbox/mailbox.c
> +++ b/drivers/mailbox/mailbox.c
> @@ -57,6 +57,15 @@ static inline int mbox_empty(struct mailbox *mbox)
>   {
>   	return mbox->ops->empty(mbox);
>   }
> +static inline int mbox_fifo_needs_flush(struct mailbox *mbox)
> +{
> +	return mbox->ops->fifo_needs_flush(mbox);
> +}
> +static inline void mbox_fifo_readback(struct mailbox *mbox,
> +				struct mailbox_msg *msg)
> +{
> +	mbox->ops->fifo_readback(mbox, msg);
> +}
>
>   /* Mailbox IRQ handle functions */
>   static inline void ack_mbox_irq(struct mailbox *mbox, mailbox_irq_t irq)
> @@ -110,6 +119,33 @@ out:
>   }
>   EXPORT_SYMBOL(mailbox_msg_send);
>
> +/*
s/*/**
> + * Flush the Rx FIFO by reading back the messages
> + * Since the normal expectation is that the Rx will do the
> + * reading, add a debug message to indicate if we really flush
> + *
> + * Returns the no. of messages read back
> + */
Just look at the kernel doc style for above

Rest looks fine.

Regards
Santosh

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 03/18] memory: emif: Move EMIF related header file to include/linux/
  2012-12-31 13:06   ` Vaibhav Bedia
@ 2013-01-08 14:04     ` Santosh Shilimkar
  -1 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 14:04 UTC (permalink / raw)
  To: Vaibhav Bedia
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Benoit Cousson, Aneesh V

On Monday 31 December 2012 06:36 PM, Vaibhav Bedia wrote:
> OMAP4 and AM33XX share the same EMIF controller IP. Although there
> are significant differences in the IP integration due to which
> AM33XX can't reuse the EMIF driver DVFS similar to OMAP4,
> it can definitely benefit by reusing the EMIF related macros
> defined in drivers/memory/emif.h.
>
> In the current OMAP PM framework the PM code resides under
> arch/arm/mach-omap2/. To enable reuse of the register defines move
> the emif header file to include/linux so that both the EMIF driver
> and the AM33XX PM code can benefit.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Aneesh V <aneesh@ti.com>
> ---
> v1->v2:
> 	This is a new patch in the series to enable code reuse
> 	between the EMIF driver and AM33XX PM code
>
>   drivers/memory/emif.c   |    2 +-
>   drivers/memory/emif.h   |  589 -----------------------------------------------
>   include/linux/ti_emif.h |  589 +++++++++++++++++++++++++++++++++++++++++++++++
You are just moving the file. So "git mv file1 flie2; and the git 
format-patch -C"
on committed patch should just generate few lines of patch.

> +/* DDR_PHY_CTRL_1 - EMIF4D5 */
> +#define DLL_HALF_DELAY_SHIFT_4D5			21
> +#define DLL_HALF_DELAY_MASK_4D5				(1 << 21)
> +#define READ_LATENCY_SHIFT_4D5				0
> +#define READ_LATENCY_MASK_4D5				(0x1f << 0)
> +
> +/* DDR_PHY_CTRL_1_SHDW */
> +#define DDR_PHY_CTRL_1_SHDW_SHIFT			5
> +#define DDR_PHY_CTRL_1_SHDW_MASK			(0x7ffffff << 5)
> +#define READ_LATENCY_SHDW_SHIFT				0
> +#define READ_LATENCY_SHDW_MASK				(0x1f << 0)
> +
> +#ifndef __ASSEMBLY__
> +/*
> + * Structure containing shadow of important registers in EMIF
> + * The calculation function fills in this structure to be later used for
> + * initialisation and DVFS
> + */
> +struct emif_regs {
Are you using above struct. If not we can leave it in same place and
just move the register defines.

Regards
santosh


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 03/18] memory: emif: Move EMIF related header file to include/linux/
@ 2013-01-08 14:04     ` Santosh Shilimkar
  0 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 14:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 31 December 2012 06:36 PM, Vaibhav Bedia wrote:
> OMAP4 and AM33XX share the same EMIF controller IP. Although there
> are significant differences in the IP integration due to which
> AM33XX can't reuse the EMIF driver DVFS similar to OMAP4,
> it can definitely benefit by reusing the EMIF related macros
> defined in drivers/memory/emif.h.
>
> In the current OMAP PM framework the PM code resides under
> arch/arm/mach-omap2/. To enable reuse of the register defines move
> the emif header file to include/linux so that both the EMIF driver
> and the AM33XX PM code can benefit.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Aneesh V <aneesh@ti.com>
> ---
> v1->v2:
> 	This is a new patch in the series to enable code reuse
> 	between the EMIF driver and AM33XX PM code
>
>   drivers/memory/emif.c   |    2 +-
>   drivers/memory/emif.h   |  589 -----------------------------------------------
>   include/linux/ti_emif.h |  589 +++++++++++++++++++++++++++++++++++++++++++++++
You are just moving the file. So "git mv file1 flie2; and the git 
format-patch -C"
on committed patch should just generate few lines of patch.

> +/* DDR_PHY_CTRL_1 - EMIF4D5 */
> +#define DLL_HALF_DELAY_SHIFT_4D5			21
> +#define DLL_HALF_DELAY_MASK_4D5				(1 << 21)
> +#define READ_LATENCY_SHIFT_4D5				0
> +#define READ_LATENCY_MASK_4D5				(0x1f << 0)
> +
> +/* DDR_PHY_CTRL_1_SHDW */
> +#define DDR_PHY_CTRL_1_SHDW_SHIFT			5
> +#define DDR_PHY_CTRL_1_SHDW_MASK			(0x7ffffff << 5)
> +#define READ_LATENCY_SHDW_SHIFT				0
> +#define READ_LATENCY_SHDW_MASK				(0x1f << 0)
> +
> +#ifndef __ASSEMBLY__
> +/*
> + * Structure containing shadow of important registers in EMIF
> + * The calculation function fills in this structure to be later used for
> + * initialisation and DVFS
> + */
> +struct emif_regs {
Are you using above struct. If not we can leave it in same place and
just move the register defines.

Regards
santosh

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 04/18] ARM: OMAP2+: AM33XX: CM: Get rid of unncessary header inclusions
  2012-12-31 13:06   ` Vaibhav Bedia
@ 2013-01-08 15:00     ` Santosh Shilimkar
  -1 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:00 UTC (permalink / raw)
  To: Vaibhav Bedia
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Benoit Cousson,
	Paul Walmsley, Vaibhav Hiremath

On Monday 31 December 2012 06:36 PM, Vaibhav Bedia wrote:
> Some of the included header files are not needed so
> remove them.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 04/18] ARM: OMAP2+: AM33XX: CM: Get rid of unncessary header inclusions
@ 2013-01-08 15:00     ` Santosh Shilimkar
  0 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 31 December 2012 06:36 PM, Vaibhav Bedia wrote:
> Some of the included header files are not needed so
> remove them.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 05/18] ARM: OMAP2+: AM33XX: CM/PRM: Use __ASSEMBLER__ macros in header files
  2012-12-31 13:06   ` Vaibhav Bedia
@ 2013-01-08 15:01     ` Santosh Shilimkar
  -1 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:01 UTC (permalink / raw)
  To: Vaibhav Bedia
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Paul Walmsley,
	Benoit Cousson, Vaibhav Hiremath

On Monday 31 December 2012 06:36 PM, Vaibhav Bedia wrote:
> This is necessary to ensure that macros declared here can
> be reused from assembly files.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
> v1->v2:
> 	Split out the header file changes in a separate patch
> 	based on the feedback from Santosh
>
>   arch/arm/mach-omap2/cm33xx.h  |    3 +++
>   arch/arm/mach-omap2/prm33xx.h |    3 +++
>   2 files changed, 6 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/cm33xx.h b/arch/arm/mach-omap2/cm33xx.h
> index 8009e13..2f215cd 100644
> --- a/arch/arm/mach-omap2/cm33xx.h
> +++ b/arch/arm/mach-omap2/cm33xx.h
> @@ -376,6 +376,7 @@
>   #define AM33XX_CM_CEFUSE_CEFUSE_CLKCTRL			AM33XX_CM_REGADDR(AM33XX_CM_CEFUSE_MOD, 0x0020)
>
>
> +#ifndef __ASSEMBLER__
>   extern bool am33xx_cm_is_clkdm_in_hwsup(s16 inst, u16 cdoffs);
>   extern void am33xx_cm_clkdm_enable_hwsup(s16 inst, u16 cdoffs);
>   extern void am33xx_cm_clkdm_disable_hwsup(s16 inst, u16 cdoffs);
> @@ -412,4 +413,6 @@ static inline int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs,
>   }
>   #endif
>
> +#endif /* ASSEMBLER */
> +
Drop that extra line.
>   #endif
> diff --git a/arch/arm/mach-omap2/prm33xx.h b/arch/arm/mach-omap2/prm33xx.h
> index 3f25c56..2f2eaa0 100644
> --- a/arch/arm/mach-omap2/prm33xx.h
> +++ b/arch/arm/mach-omap2/prm33xx.h
> @@ -117,6 +117,7 @@
>   #define AM33XX_PM_CEFUSE_PWRSTST_OFFSET		0x0004
>   #define AM33XX_PM_CEFUSE_PWRSTST		AM33XX_PRM_REGADDR(AM33XX_PRM_CEFUSE_MOD, 0x0004)
>
> +#ifndef __ASSEMBLER__
>   extern u32 am33xx_prm_read_reg(s16 inst, u16 idx);
>   extern void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx);
>   extern u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
> @@ -126,4 +127,6 @@ extern int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst,
>   extern int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs);
>   extern int am33xx_prm_deassert_hardreset(u8 shift, s16 inst,
>   		u16 rstctrl_offs, u16 rstst_offs);
> +#endif /* ASSEMBLER */
> +
ditto

Otherwise looks fine.
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 05/18] ARM: OMAP2+: AM33XX: CM/PRM: Use __ASSEMBLER__ macros in header files
@ 2013-01-08 15:01     ` Santosh Shilimkar
  0 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 31 December 2012 06:36 PM, Vaibhav Bedia wrote:
> This is necessary to ensure that macros declared here can
> be reused from assembly files.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
> v1->v2:
> 	Split out the header file changes in a separate patch
> 	based on the feedback from Santosh
>
>   arch/arm/mach-omap2/cm33xx.h  |    3 +++
>   arch/arm/mach-omap2/prm33xx.h |    3 +++
>   2 files changed, 6 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/cm33xx.h b/arch/arm/mach-omap2/cm33xx.h
> index 8009e13..2f215cd 100644
> --- a/arch/arm/mach-omap2/cm33xx.h
> +++ b/arch/arm/mach-omap2/cm33xx.h
> @@ -376,6 +376,7 @@
>   #define AM33XX_CM_CEFUSE_CEFUSE_CLKCTRL			AM33XX_CM_REGADDR(AM33XX_CM_CEFUSE_MOD, 0x0020)
>
>
> +#ifndef __ASSEMBLER__
>   extern bool am33xx_cm_is_clkdm_in_hwsup(s16 inst, u16 cdoffs);
>   extern void am33xx_cm_clkdm_enable_hwsup(s16 inst, u16 cdoffs);
>   extern void am33xx_cm_clkdm_disable_hwsup(s16 inst, u16 cdoffs);
> @@ -412,4 +413,6 @@ static inline int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs,
>   }
>   #endif
>
> +#endif /* ASSEMBLER */
> +
Drop that extra line.
>   #endif
> diff --git a/arch/arm/mach-omap2/prm33xx.h b/arch/arm/mach-omap2/prm33xx.h
> index 3f25c56..2f2eaa0 100644
> --- a/arch/arm/mach-omap2/prm33xx.h
> +++ b/arch/arm/mach-omap2/prm33xx.h
> @@ -117,6 +117,7 @@
>   #define AM33XX_PM_CEFUSE_PWRSTST_OFFSET		0x0004
>   #define AM33XX_PM_CEFUSE_PWRSTST		AM33XX_PRM_REGADDR(AM33XX_PRM_CEFUSE_MOD, 0x0004)
>
> +#ifndef __ASSEMBLER__
>   extern u32 am33xx_prm_read_reg(s16 inst, u16 idx);
>   extern void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx);
>   extern u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
> @@ -126,4 +127,6 @@ extern int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst,
>   extern int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs);
>   extern int am33xx_prm_deassert_hardreset(u8 shift, s16 inst,
>   		u16 rstctrl_offs, u16 rstst_offs);
> +#endif /* ASSEMBLER */
> +
ditto

Otherwise looks fine.
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 06/18] ARM: OMAP2+: AM33XX: hwmod: Register OCMC RAM hwmod
  2012-12-31 13:06   ` Vaibhav Bedia
@ 2013-01-08 15:04     ` Santosh Shilimkar
  -1 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:04 UTC (permalink / raw)
  To: Vaibhav Bedia
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Benoit Cousson,
	Paul Walmsley, Vaibhav Hiremath

On Monday 31 December 2012 06:36 PM, Vaibhav Bedia wrote:
> OCMC RAM lies in the PER power domain and this memory
> support retention.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
Looks fine to me.
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 06/18] ARM: OMAP2+: AM33XX: hwmod: Register OCMC RAM hwmod
@ 2013-01-08 15:04     ` Santosh Shilimkar
  0 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 31 December 2012 06:36 PM, Vaibhav Bedia wrote:
> OCMC RAM lies in the PER power domain and this memory
> support retention.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
Looks fine to me.
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 07/18] ARM: OMAP2+: AM33XX: hwmod: Update TPTC0 hwmod with the right flags
  2012-12-31 13:07   ` Vaibhav Bedia
@ 2013-01-08 15:05     ` Santosh Shilimkar
  -1 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:05 UTC (permalink / raw)
  To: Vaibhav Bedia
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Benoit Cousson,
	Paul Walmsley, Vaibhav Hiremath

On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> TPTC0 needs to be idled and put to standby under SW control.
> Add the appropriate flags in the TPTC0 hwmod entry.
>
Can you please expand TPTC0 in chane log.
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
Patch is fine otherwise.
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 07/18] ARM: OMAP2+: AM33XX: hwmod: Update TPTC0 hwmod with the right flags
@ 2013-01-08 15:05     ` Santosh Shilimkar
  0 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:05 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> TPTC0 needs to be idled and put to standby under SW control.
> Add the appropriate flags in the TPTC0 hwmod entry.
>
Can you please expand TPTC0 in chane log.
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
Patch is fine otherwise.
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 08/18] ARM: OMAP2+: AM33XX: hwmod: Fixup cpgmac0 hwmod entry
  2012-12-31 13:07   ` Vaibhav Bedia
@ 2013-01-08 15:08     ` Santosh Shilimkar
  -1 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:08 UTC (permalink / raw)
  To: Vaibhav Bedia
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Benoit Cousson,
	Paul Walmsley, Vaibhav Hiremath

On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> The current HWMOD code expects the memory region with
> the IP's SYSCONFIG register to be marked with ADDR_TYPE_RT
> flag.
>
> CPGMAC0 hwmod entry specifies two memory regions and marks
> both with the flag ADDR_TYPE_RT although only the 2nd region
> has the SYSCONFIG register. This leads to the HWMOD code
> accessing the wrong memory address for idle and standby
> operations. Fix this by removing the ADDR_TYPE_RT flag from
> the 1st memory region in CPGMAC0 hwmod entry.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
Seems correct to me though Benoit, Paul can
may have comment.

Regards
Santosh


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 08/18] ARM: OMAP2+: AM33XX: hwmod: Fixup cpgmac0 hwmod entry
@ 2013-01-08 15:08     ` Santosh Shilimkar
  0 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> The current HWMOD code expects the memory region with
> the IP's SYSCONFIG register to be marked with ADDR_TYPE_RT
> flag.
>
> CPGMAC0 hwmod entry specifies two memory regions and marks
> both with the flag ADDR_TYPE_RT although only the 2nd region
> has the SYSCONFIG register. This leads to the HWMOD code
> accessing the wrong memory address for idle and standby
> operations. Fix this by removing the ADDR_TYPE_RT flag from
> the 1st memory region in CPGMAC0 hwmod entry.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
Seems correct to me though Benoit, Paul can
may have comment.

Regards
Santosh

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 09/18] ARM: OMAP2+: AM33XX: hwmod: Update the WKUP-M3 hwmod with reset status bit
  2012-12-31 13:07   ` Vaibhav Bedia
@ 2013-01-08 15:09     ` Santosh Shilimkar
  -1 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:09 UTC (permalink / raw)
  To: Vaibhav Bedia
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Benoit Cousson,
	Paul Walmsley, Vaibhav Hiremath

Vaibhav,

On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> WKUP-M3 has a reset status bit (RM_WKUP_STST.WKUP_M3_LRST)
> Update the WKUP-M3 hwmod data to reflect the same.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
I think you should make a separate series for
the data file updates/fixes.

Regards
Santosh


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 09/18] ARM: OMAP2+: AM33XX: hwmod: Update the WKUP-M3 hwmod with reset status bit
@ 2013-01-08 15:09     ` Santosh Shilimkar
  0 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:09 UTC (permalink / raw)
  To: linux-arm-kernel

Vaibhav,

On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> WKUP-M3 has a reset status bit (RM_WKUP_STST.WKUP_M3_LRST)
> Update the WKUP-M3 hwmod data to reflect the same.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
I think you should make a separate series for
the data file updates/fixes.

Regards
Santosh

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 10/18] ARM: OMAP2+: AM33XX: Update the hardreset API
  2012-12-31 13:07   ` Vaibhav Bedia
@ 2013-01-08 15:10     ` Santosh Shilimkar
  -1 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:10 UTC (permalink / raw)
  To: Vaibhav Bedia
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Benoit Cousson,
	Paul Walmsley, Vaibhav Hiremath

On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> WKUP-M3 has a reset status bit (RM_WKUP_STST.WKUP_M3_LRST)
> Update the hardreset API to ensure that the reset line properly
> deasserted.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
Looks good.
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 10/18] ARM: OMAP2+: AM33XX: Update the hardreset API
@ 2013-01-08 15:10     ` Santosh Shilimkar
  0 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> WKUP-M3 has a reset status bit (RM_WKUP_STST.WKUP_M3_LRST)
> Update the hardreset API to ensure that the reset line properly
> deasserted.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
Looks good.
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 11/18] ARM: DTS: AM33XX: Add nodes for OCMC RAM and WKUP-M3
  2012-12-31 13:07   ` Vaibhav Bedia
@ 2013-01-08 15:12     ` Santosh Shilimkar
  -1 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:12 UTC (permalink / raw)
  To: Vaibhav Bedia
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Benoit Cousson,
	Paul Walmsley, Vaibhav Hiremath

On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> Since AM33XX supports only DT-boot, this is needed
> for the appropriate device nodes to be created.
>
> Note: OCMC RAM is part of the PER power domain and supports
> retention. The assembly code for low power entry/exit will
> run from OCMC RAM. To ensure that the OMAP PM code does not
> attempt to disable the clock to OCMC RAM as part of the
> suspend process add the no_idle_on_suspend flag.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Tony Lindgren <tony@atomide.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
Looks fine to me.
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 11/18] ARM: DTS: AM33XX: Add nodes for OCMC RAM and WKUP-M3
@ 2013-01-08 15:12     ` Santosh Shilimkar
  0 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:12 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> Since AM33XX supports only DT-boot, this is needed
> for the appropriate device nodes to be created.
>
> Note: OCMC RAM is part of the PER power domain and supports
> retention. The assembly code for low power entry/exit will
> run from OCMC RAM. To ensure that the OMAP PM code does not
> attempt to disable the clock to OCMC RAM as part of the
> suspend process add the no_idle_on_suspend flag.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Tony Lindgren <tony@atomide.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
Looks fine to me.
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 12/18] ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent device
  2012-12-31 13:07   ` Vaibhav Bedia
@ 2013-01-08 15:15     ` Santosh Shilimkar
  -1 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:15 UTC (permalink / raw)
  To: Vaibhav Bedia, Jon Hunter
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Benoit Cousson,
	Paul Walmsley, Vaibhav Hiremath

On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> The current OMAP timer code registers two timers -
> one as clocksource and one as clockevent.
> AM33XX has only one usable timer in the WKUP domain
> so one of the timers needs suspend-resume support
> to restore the configuration to pre-suspend state.
>
> commit adc78e6 (timekeeping: Add suspend and resume
> of clock event devices) introduced .suspend and .resume
> callbacks for clock event devices. Leverages these
> callbacks to have AM33XX clockevent timer which is
> in not in WKUP domain to behave properly across system
> suspend.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> Cc: Jon Hunter <jon-hunter@ti.com>
> ---
> v1->v2:
> 	Get rid of harcoded timer id.
> 	Note: since a platform device is not created for these timer
> 	instances and because there's very minimal change needed for
> 	restarting the timer a full blown context save and restore
> 	has been skipped.
>
>   arch/arm/mach-omap2/timer.c |   33 +++++++++++++++++++++++++++++++++
>   1 files changed, 33 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
> index 691aa67..38f9cbc 100644
> --- a/arch/arm/mach-omap2/timer.c
> +++ b/arch/arm/mach-omap2/timer.c
> @@ -128,6 +128,36 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
>   	}
>   }
>
> +static void omap_clkevt_suspend(struct clock_event_device *unused)
> +{
> +	char name[10];
> +	struct omap_hwmod *oh;
> +
> +	sprintf(name, "timer%d", clkev.id);
> +	oh = omap_hwmod_lookup(name);
> +	if (!oh)
> +		return;
> +
> +	__omap_dm_timer_stop(&clkev, 1, clkev.rate);
> +	omap_hwmod_idle(oh);
> +}
> +
> +static void omap_clkevt_resume(struct clock_event_device *unused)
> +{
> +	char name[10];
> +	struct omap_hwmod *oh;
> +
> +	sprintf(name, "timer%d", clkev.id);
> +	oh = omap_hwmod_lookup(name);
> +	if (!oh)
> +		return;
> +
> +	omap_hwmod_enable(oh);
> +	__omap_dm_timer_load_start(&clkev,
> +			OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
> +	__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
> +}
> +
Am still bit uncomfortable with direct hwmod usage in the suspend/resmue
hooks.

Jon, Any alternatives you can think of ?

Regards,
Santosh



^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 12/18] ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent device
@ 2013-01-08 15:15     ` Santosh Shilimkar
  0 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:15 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> The current OMAP timer code registers two timers -
> one as clocksource and one as clockevent.
> AM33XX has only one usable timer in the WKUP domain
> so one of the timers needs suspend-resume support
> to restore the configuration to pre-suspend state.
>
> commit adc78e6 (timekeeping: Add suspend and resume
> of clock event devices) introduced .suspend and .resume
> callbacks for clock event devices. Leverages these
> callbacks to have AM33XX clockevent timer which is
> in not in WKUP domain to behave properly across system
> suspend.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> Cc: Jon Hunter <jon-hunter@ti.com>
> ---
> v1->v2:
> 	Get rid of harcoded timer id.
> 	Note: since a platform device is not created for these timer
> 	instances and because there's very minimal change needed for
> 	restarting the timer a full blown context save and restore
> 	has been skipped.
>
>   arch/arm/mach-omap2/timer.c |   33 +++++++++++++++++++++++++++++++++
>   1 files changed, 33 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
> index 691aa67..38f9cbc 100644
> --- a/arch/arm/mach-omap2/timer.c
> +++ b/arch/arm/mach-omap2/timer.c
> @@ -128,6 +128,36 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
>   	}
>   }
>
> +static void omap_clkevt_suspend(struct clock_event_device *unused)
> +{
> +	char name[10];
> +	struct omap_hwmod *oh;
> +
> +	sprintf(name, "timer%d", clkev.id);
> +	oh = omap_hwmod_lookup(name);
> +	if (!oh)
> +		return;
> +
> +	__omap_dm_timer_stop(&clkev, 1, clkev.rate);
> +	omap_hwmod_idle(oh);
> +}
> +
> +static void omap_clkevt_resume(struct clock_event_device *unused)
> +{
> +	char name[10];
> +	struct omap_hwmod *oh;
> +
> +	sprintf(name, "timer%d", clkev.id);
> +	oh = omap_hwmod_lookup(name);
> +	if (!oh)
> +		return;
> +
> +	omap_hwmod_enable(oh);
> +	__omap_dm_timer_load_start(&clkev,
> +			OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
> +	__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
> +}
> +
Am still bit uncomfortable with direct hwmod usage in the suspend/resmue
hooks.

Jon, Any alternatives you can think of ?

Regards,
Santosh

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 13/18] ARM: OMAP2+: AM33XX: timer: Interchance clkevt and clksrc timers
  2012-12-31 13:07   ` Vaibhav Bedia
@ 2013-01-08 15:17     ` Santosh Shilimkar
  -1 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:17 UTC (permalink / raw)
  To: Vaibhav Bedia
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Vaibhav Hiremath,
	Benoit Cousson, Paul Walmsley, Jon Hunter

On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> AM33XX has two timers (DTIMER0/1) in the WKUP domain.
> On GP devices the source of DMTIMER0 is fixed to an
> inaccurate internal 32k RC oscillator and this makes
> the DMTIMER0 practically either as a clocksource or
> as clockevent.
>
> Currently the timer instance in WKUP domain is used
> as the clockevent and the timer in non-WKUP domain
> as the clocksource. DMTIMER1 in WKUP domain can keep
> running in suspend from a 32K clock fed from external
> OSC and can serve as the persistent clock for the kernel.
> To enable this, interchange the timers used as clocksource
> and clockevent for AM33XX.
>
> For now a new DT property has been added to allow the timer code
> to select the timer with the right property.
>
> It has been pointed out by Santosh Shilimkar and Kevin Hilman
> that such a change will result in soc-idle never being achieved
> on AM33XX. There are other reasons why soc-idle does not look
> feasible on AM33XX so for now we go ahead with the interchange
> of the the timers. If at a later point of time we do come up
> with an approach which makes soc-idle possible on AM33XX, this
> can be revisited.
>
Can you please explain other reasons as well for clarity ?

Regards
Santosh

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 13/18] ARM: OMAP2+: AM33XX: timer: Interchance clkevt and clksrc timers
@ 2013-01-08 15:17     ` Santosh Shilimkar
  0 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> AM33XX has two timers (DTIMER0/1) in the WKUP domain.
> On GP devices the source of DMTIMER0 is fixed to an
> inaccurate internal 32k RC oscillator and this makes
> the DMTIMER0 practically either as a clocksource or
> as clockevent.
>
> Currently the timer instance in WKUP domain is used
> as the clockevent and the timer in non-WKUP domain
> as the clocksource. DMTIMER1 in WKUP domain can keep
> running in suspend from a 32K clock fed from external
> OSC and can serve as the persistent clock for the kernel.
> To enable this, interchange the timers used as clocksource
> and clockevent for AM33XX.
>
> For now a new DT property has been added to allow the timer code
> to select the timer with the right property.
>
> It has been pointed out by Santosh Shilimkar and Kevin Hilman
> that such a change will result in soc-idle never being achieved
> on AM33XX. There are other reasons why soc-idle does not look
> feasible on AM33XX so for now we go ahead with the interchange
> of the the timers. If at a later point of time we do come up
> with an approach which makes soc-idle possible on AM33XX, this
> can be revisited.
>
Can you please explain other reasons as well for clarity ?

Regards
Santosh

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 14/18] ARM: OMAP2+: AM33XX: control: Add some control module registers and APIs
  2012-12-31 13:07   ` Vaibhav Bedia
@ 2013-01-08 15:21     ` Santosh Shilimkar
  -1 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:21 UTC (permalink / raw)
  To: Vaibhav Bedia
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Benoit Cousson,
	Paul Walmsley, Vaibhav Hiremath

On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> Add minimal APIs for writing to the IPC and the M3_TXEV registers
> in the Control module. These will be used in a subsequent patch which
> adds suspend-resume support for AM33XX.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Tony Lingren <tony@atomide.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
On Control module, we are trying to move driver/module
specific code to respective drivers. Can you not
add below code to ipc related driver component.

If not, then patch as such is fine with me.

Regards
Santosh

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 14/18] ARM: OMAP2+: AM33XX: control: Add some control module registers and APIs
@ 2013-01-08 15:21     ` Santosh Shilimkar
  0 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> Add minimal APIs for writing to the IPC and the M3_TXEV registers
> in the Control module. These will be used in a subsequent patch which
> adds suspend-resume support for AM33XX.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Tony Lingren <tony@atomide.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
On Control module, we are trying to move driver/module
specific code to respective drivers. Can you not
add below code to ipc related driver component.

If not, then patch as such is fine with me.

Regards
Santosh

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 17/18] ARM: OMAP2+: AM33XX: Select Mailbox when PM is enabled
  2012-12-31 13:07   ` Vaibhav Bedia
@ 2013-01-08 15:22     ` Santosh Shilimkar
  -1 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:22 UTC (permalink / raw)
  To: Vaibhav Bedia
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Benoit Cousson,
	Paul Walmsley

On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> PM services on AM33XX depend on mailbox for communication
> with WKUP-M3 core so ensure that the right config options
> are selected. Thanks to Kevin Hilman <khilman@deeprootsystems.com>
> for the suggestion on updating the Kconfig and not just
> the omap2plus_defconfig which was done in the previous version
> of the AM33XX suspend-resume support.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Tony Lingren <tony@atomide.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> ---
Unrelated to series. You can post this patch separately.

regards
Santosh


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 17/18] ARM: OMAP2+: AM33XX: Select Mailbox when PM is enabled
@ 2013-01-08 15:22     ` Santosh Shilimkar
  0 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> PM services on AM33XX depend on mailbox for communication
> with WKUP-M3 core so ensure that the right config options
> are selected. Thanks to Kevin Hilman <khilman@deeprootsystems.com>
> for the suggestion on updating the Kconfig and not just
> the omap2plus_defconfig which was done in the previous version
> of the AM33XX suspend-resume support.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Tony Lingren <tony@atomide.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> ---
Unrelated to series. You can post this patch separately.

regards
Santosh

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 00/18] ARM: OMAP2+: AM33XX: Add suspend-resume support
  2012-12-31 13:06 ` Vaibhav Bedia
@ 2013-01-08 15:31   ` Santosh Shilimkar
  -1 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:31 UTC (permalink / raw)
  To: Vaibhav Bedia; +Cc: linux-omap, linux-arm-kernel, tony, khilman

Vaibhav,

On Monday 31 December 2012 06:36 PM, Vaibhav Bedia wrote:
> Hi,
>
> This is the second version of the patch series for adding suspend-resume
> support for AM33XX. Based on the feedback received on the previous patch
> series [1] almost all the patches have undergone a bit a rework.
>
> The 1st two patches depend on the changes for mailbox code migration
> from arch/arm/*-omap*/ to drivers/mailbox/ [2].
>
> The patch series also depends on recent changes to the OMAP PM framework
> by Paul Walmsley.
>
> I found it easiest to apply the AM33XX suspend-resume patches on top of
> Paul's TEST_pwrdm_post_fpwrst_devel_a_3.9 branch + the patches @ [2].
>
> With these dependencies met, the PM code uses the firmware interface
> and expects the userspace to load the WKUP_M3 binary before the
> suspend-resume functionality is made available. The binary file (and
> the source-code for WKUP_M3) can be obtained from the 'next' branch at
> [3]. The WKUP_M3 binary can either be loaded post bootup via
> the sysfs entry './sys/devices/ocp.2/wkup_m3.4/firmware' or
> it can be included in the kernel image as part of the build process.
>
> DDR3 specific changes have been skipped for now since mainline U-Boot
> exhibited stability issues on all the DDR3 based AM335x boards that i could
> lay my hands on.
>
> I have done basic testing along with power measurments on the different
> power rails on the AM335x EVM. PER domain transition on the BeagleBone fails
> if the CPSW driver is included in the kernel and is yet to be root caused.
> Along with this issue more extensive testing on other OMAP platforms is also
> pending right now.
>
> For more details on the AM335x suspend-resume support please refer to the
> changelog in the different patches.
>
I still haven't reviewed patch 15, 16 and 18 which adds suspend support.
Will do that in coming days since they need a bit a closer look.

But as mentioned in some of the patches, you need to split this series
since except 15, 16 and 18 which adds suspend support, rest of the
patches are
- data file fixes
- timer suspend/resume update
- mailbox support, control module update.

Would be good to split the series to help the reviews.

Regards
Santosh



^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 00/18] ARM: OMAP2+: AM33XX: Add suspend-resume support
@ 2013-01-08 15:31   ` Santosh Shilimkar
  0 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-08 15:31 UTC (permalink / raw)
  To: linux-arm-kernel

Vaibhav,

On Monday 31 December 2012 06:36 PM, Vaibhav Bedia wrote:
> Hi,
>
> This is the second version of the patch series for adding suspend-resume
> support for AM33XX. Based on the feedback received on the previous patch
> series [1] almost all the patches have undergone a bit a rework.
>
> The 1st two patches depend on the changes for mailbox code migration
> from arch/arm/*-omap*/ to drivers/mailbox/ [2].
>
> The patch series also depends on recent changes to the OMAP PM framework
> by Paul Walmsley.
>
> I found it easiest to apply the AM33XX suspend-resume patches on top of
> Paul's TEST_pwrdm_post_fpwrst_devel_a_3.9 branch + the patches @ [2].
>
> With these dependencies met, the PM code uses the firmware interface
> and expects the userspace to load the WKUP_M3 binary before the
> suspend-resume functionality is made available. The binary file (and
> the source-code for WKUP_M3) can be obtained from the 'next' branch at
> [3]. The WKUP_M3 binary can either be loaded post bootup via
> the sysfs entry './sys/devices/ocp.2/wkup_m3.4/firmware' or
> it can be included in the kernel image as part of the build process.
>
> DDR3 specific changes have been skipped for now since mainline U-Boot
> exhibited stability issues on all the DDR3 based AM335x boards that i could
> lay my hands on.
>
> I have done basic testing along with power measurments on the different
> power rails on the AM335x EVM. PER domain transition on the BeagleBone fails
> if the CPSW driver is included in the kernel and is yet to be root caused.
> Along with this issue more extensive testing on other OMAP platforms is also
> pending right now.
>
> For more details on the AM335x suspend-resume support please refer to the
> changelog in the different patches.
>
I still haven't reviewed patch 15, 16 and 18 which adds suspend support.
Will do that in coming days since they need a bit a closer look.

But as mentioned in some of the patches, you need to split this series
since except 15, 16 and 18 which adds suspend support, rest of the
patches are
- data file fixes
- timer suspend/resume update
- mailbox support, control module update.

Would be good to split the series to help the reviews.

Regards
Santosh

^ permalink raw reply	[flat|nested] 148+ messages in thread

* RE: [RFC v2 01/18] mailbox: OMAP2+: Add support for AM33XX
  2013-01-08 13:53     ` Santosh Shilimkar
@ 2013-01-09  5:16       ` Bedia, Vaibhav
  -1 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-09  5:16 UTC (permalink / raw)
  To: Shilimkar, Santosh
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Dill, Russ

On Tue, Jan 08, 2013 at 19:23:44, Shilimkar, Santosh wrote:
> On Monday 31 December 2012 06:36 PM, Vaibhav Bedia wrote:
> > Mailbox IP on AM33XX is the same as that present in OMAP4.
> > The single instance of Mailbox IP on AM33XX contains
> > 8 sub-modules and facilitates communication between MPU,
> > PRUs and WKUP_M3.
> >
> PRUS?

Programmable Real Time Units. Will clarify in next version

> 
> > The first mailbox sub-module is assigned for communication
> > between MPU and WKUP-M3.
> >
> > Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> > Cc: Russ Dill <russ.dill@ti.com>
> > Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > ---
> > v1->v2:
> > 	Address the comment on operator usage from Russ Dill
> >
> >   drivers/mailbox/mailbox-omap2.c |   35 ++++++++++++++++++++++++++++++++++-
> >   1 files changed, 34 insertions(+), 1 deletions(-)
> >
> > diff --git a/drivers/mailbox/mailbox-omap2.c b/drivers/mailbox/mailbox-omap2.c
> > index 7c26bed..6d61159 100644
> > --- a/drivers/mailbox/mailbox-omap2.c
> > +++ b/drivers/mailbox/mailbox-omap2.c
> > @@ -151,7 +151,7 @@ static void omap2_mbox_disable_irq(struct mailbox *mbox,
> >   	struct omap_mbox2_priv *p = mbox->priv;
> >   	u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
> >
> > -	if (!cpu_is_omap44xx())
> > +	if (!cpu_is_omap44xx() && !soc_is_am33xx())
> >   		bit = mbox_read_reg(p->irqdisable) & ~bit;
> >
> >   	mbox_write_reg(bit, p->irqdisable);
> > @@ -352,6 +352,32 @@ struct mailbox mbox_2_info = {
> >   struct mailbox *omap4_mboxes[] = { &mbox_1_info, &mbox_2_info, NULL };
> >   #endif
> >
> > +#if defined(CONFIG_SOC_AM33XX)
> > +static struct omap_mbox2_priv omap2_mbox_wkup_m3_priv = {
> > +	.tx_fifo = {
> > +		.msg		= MAILBOX_MESSAGE(0),
> > +		.fifo_stat	= MAILBOX_FIFOSTATUS(0),
> > +		.msg_stat	= MAILBOX_MSGSTATUS(0),
> > +	},
> > +	.rx_fifo = {
> > +		.msg		= MAILBOX_MESSAGE(1),
> > +		.msg_stat	= MAILBOX_MSGSTATUS(1),
> > +	},
> > +	.irqenable	= OMAP4_MAILBOX_IRQENABLE(3),
> > +	.irqstatus	= OMAP4_MAILBOX_IRQSTATUS(3),
> > +	.irqdisable	= OMAP4_MAILBOX_IRQENABLE_CLR(3),
> > +	.notfull_bit	= MAILBOX_IRQ_NOTFULL(0),
> > +	.newmsg_bit	= MAILBOX_IRQ_NEWMSG(0),
> > +};
> > +
> > +struct mailbox mbox_wkup_m3_info = {
> > +	.name	= "wkup_m3",
> > +	.ops	= &omap2_mbox_ops,
> > +	.priv	= &omap2_mbox_wkup_m3_priv,
> > +};
> > +struct mailbox *am33xx_mboxes[] = { &mbox_wkup_m3_info, NULL };
> > +#endif
> > +
> >   static int __devinit omap2_mbox_probe(struct platform_device *pdev)
> >   {
> >   	struct resource *mem;
> > @@ -386,6 +412,13 @@ static int __devinit omap2_mbox_probe(struct platform_device *pdev)
> >   		list[0]->irq = list[1]->irq = platform_get_irq(pdev, 0);
> >   	}
> >   #endif
> > +#if defined(CONFIG_SOC_AM33XX)
> ifdef in middle of the code. I know you are just
> following what is already there.
> > +	else if (soc_is_am33xx()) {
> > +		list = am33xx_mboxes;
> > +
> UN-necessary extra line here.

Will remove

> > +		list[0]->irq = platform_get_irq(pdev, 0);
> > +	}
> > +#endif
> 
> Hopefully mailbox clean-up will kill that #ifdeffery.
> Apart from those comments, patch looks fine to me.
> 

Thanks,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* RE: [RFC v2 02/18] mailbox: Add an API for flushing the FIFO
  2013-01-08 13:56     ` Santosh Shilimkar
@ 2013-01-09  5:16       ` Bedia, Vaibhav
  -1 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-09  5:16 UTC (permalink / raw)
  To: Shilimkar, Santosh; +Cc: linux-omap, linux-arm-kernel, tony, khilman

On Tue, Jan 08, 2013 at 19:26:51, Shilimkar, Santosh wrote:
> On Monday 31 December 2012 06:36 PM, Vaibhav Bedia wrote:
> > On AM33XX, the mailbox module between the MPU and the
> > WKUP-M3 co-processor facilitates a one-way communication.
> > MPU uses the assigned mailbox sub-module to issue the
> > interrupt to the WKUP-M3 co-processor which then goes
> > and reads the the IPC data from registers in the control
> > module.
> >
> > WKUP-M3 is in the L4_WKUP and does not have any access to
> > the mailbox module. Due to this limitation, the MPU is
> > completely responsible for FIFO maintenance and interrupt
> > generation. MPU needs to ensure that the FIFO does not
> > overflow by reading back the assigned mailbox sub-module.
> >
> > This patch adds an API in the mailbox code which the MPU
> > can use to empty the FIFO by issuing a readback command.
> >
> > Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> > Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > ---
> > Note: This patch which will be slightly reworked once the mailbox
> > driver changes are finalized.
> >
> Can you expand a bit please ?

There could be some changes in the structure names.

> 
> >   drivers/mailbox/mailbox-omap2.c |   19 +++++++++++++++++++
> >   drivers/mailbox/mailbox.c       |   36 ++++++++++++++++++++++++++++++++++++
> >   drivers/mailbox/mailbox.h       |    3 +++
> >   include/linux/mailbox.h         |    1 +
> >   4 files changed, 59 insertions(+), 0 deletions(-)
> >
> > diff --git a/drivers/mailbox/mailbox-omap2.c b/drivers/mailbox/mailbox-omap2.c
> > index 6d61159..c732be1 100644
> > --- a/drivers/mailbox/mailbox-omap2.c
> > +++ b/drivers/mailbox/mailbox-omap2.c
> > @@ -125,6 +125,23 @@ static int omap2_mbox_fifo_full(struct mailbox *mbox)
> >   	return mbox_read_reg(fifo->fifo_stat);
> >   }
> >
> > +static int omap2_mbox_fifo_needs_flush(struct mailbox *mbox)
> > +{
> > +	struct omap_mbox2_priv *p = mbox->priv;
> > +	struct omap_mbox2_fifo *fifo = &p->tx_fifo;
> > +
> > +	return mbox_read_reg(fifo->msg_stat);
> > +}
> > +
> > +static void omap2_mbox_fifo_readback(struct mailbox *mbox,
> > +			struct mailbox_msg *msg)
> > +{
> > +	struct omap_mbox2_priv *p = mbox->priv;
> > +	struct omap_mbox2_fifo *fifo = &p->tx_fifo;
> > +
> > +	msg->header = mbox_read_reg(fifo->msg);
> > +}
> > +
> >   static int ompa2_mbox_poll_for_space(struct mailbox *mbox)
> >   {
> >   	if (omap2_mbox_fifo_full(mbox))
> > @@ -221,6 +238,8 @@ static struct mailbox_ops omap2_mbox_ops = {
> >   	.read           = omap2_mbox_fifo_read,
> >   	.write          = omap2_mbox_fifo_write,
> >   	.empty          = omap2_mbox_fifo_empty,
> > +	.fifo_needs_flush	= omap2_mbox_fifo_needs_flush,
> > +	.fifo_readback		= omap2_mbox_fifo_readback,
> >   	.poll_for_space = ompa2_mbox_poll_for_space,
> >   	.enable_irq     = omap2_mbox_enable_irq,
> >   	.disable_irq    = omap2_mbox_disable_irq,
> > diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
> > index 2f50226..92c9f68 100644
> > --- a/drivers/mailbox/mailbox.c
> > +++ b/drivers/mailbox/mailbox.c
> > @@ -57,6 +57,15 @@ static inline int mbox_empty(struct mailbox *mbox)
> >   {
> >   	return mbox->ops->empty(mbox);
> >   }
> > +static inline int mbox_fifo_needs_flush(struct mailbox *mbox)
> > +{
> > +	return mbox->ops->fifo_needs_flush(mbox);
> > +}
> > +static inline void mbox_fifo_readback(struct mailbox *mbox,
> > +				struct mailbox_msg *msg)
> > +{
> > +	mbox->ops->fifo_readback(mbox, msg);
> > +}
> >
> >   /* Mailbox IRQ handle functions */
> >   static inline void ack_mbox_irq(struct mailbox *mbox, mailbox_irq_t irq)
> > @@ -110,6 +119,33 @@ out:
> >   }
> >   EXPORT_SYMBOL(mailbox_msg_send);
> >
> > +/*
> s/*/**

Will do.

> > + * Flush the Rx FIFO by reading back the messages
> > + * Since the normal expectation is that the Rx will do the
> > + * reading, add a debug message to indicate if we really flush
> > + *
> > + * Returns the no. of messages read back
> > + */
> Just look at the kernel doc style for above
> 
> Rest looks fine.
> 

Ok.

Thanks,
Vaibhav 


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 01/18] mailbox: OMAP2+: Add support for AM33XX
@ 2013-01-09  5:16       ` Bedia, Vaibhav
  0 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-09  5:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jan 08, 2013 at 19:23:44, Shilimkar, Santosh wrote:
> On Monday 31 December 2012 06:36 PM, Vaibhav Bedia wrote:
> > Mailbox IP on AM33XX is the same as that present in OMAP4.
> > The single instance of Mailbox IP on AM33XX contains
> > 8 sub-modules and facilitates communication between MPU,
> > PRUs and WKUP_M3.
> >
> PRUS?

Programmable Real Time Units. Will clarify in next version

> 
> > The first mailbox sub-module is assigned for communication
> > between MPU and WKUP-M3.
> >
> > Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> > Cc: Russ Dill <russ.dill@ti.com>
> > Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > ---
> > v1->v2:
> > 	Address the comment on operator usage from Russ Dill
> >
> >   drivers/mailbox/mailbox-omap2.c |   35 ++++++++++++++++++++++++++++++++++-
> >   1 files changed, 34 insertions(+), 1 deletions(-)
> >
> > diff --git a/drivers/mailbox/mailbox-omap2.c b/drivers/mailbox/mailbox-omap2.c
> > index 7c26bed..6d61159 100644
> > --- a/drivers/mailbox/mailbox-omap2.c
> > +++ b/drivers/mailbox/mailbox-omap2.c
> > @@ -151,7 +151,7 @@ static void omap2_mbox_disable_irq(struct mailbox *mbox,
> >   	struct omap_mbox2_priv *p = mbox->priv;
> >   	u32 bit = (irq == IRQ_TX) ? p->notfull_bit : p->newmsg_bit;
> >
> > -	if (!cpu_is_omap44xx())
> > +	if (!cpu_is_omap44xx() && !soc_is_am33xx())
> >   		bit = mbox_read_reg(p->irqdisable) & ~bit;
> >
> >   	mbox_write_reg(bit, p->irqdisable);
> > @@ -352,6 +352,32 @@ struct mailbox mbox_2_info = {
> >   struct mailbox *omap4_mboxes[] = { &mbox_1_info, &mbox_2_info, NULL };
> >   #endif
> >
> > +#if defined(CONFIG_SOC_AM33XX)
> > +static struct omap_mbox2_priv omap2_mbox_wkup_m3_priv = {
> > +	.tx_fifo = {
> > +		.msg		= MAILBOX_MESSAGE(0),
> > +		.fifo_stat	= MAILBOX_FIFOSTATUS(0),
> > +		.msg_stat	= MAILBOX_MSGSTATUS(0),
> > +	},
> > +	.rx_fifo = {
> > +		.msg		= MAILBOX_MESSAGE(1),
> > +		.msg_stat	= MAILBOX_MSGSTATUS(1),
> > +	},
> > +	.irqenable	= OMAP4_MAILBOX_IRQENABLE(3),
> > +	.irqstatus	= OMAP4_MAILBOX_IRQSTATUS(3),
> > +	.irqdisable	= OMAP4_MAILBOX_IRQENABLE_CLR(3),
> > +	.notfull_bit	= MAILBOX_IRQ_NOTFULL(0),
> > +	.newmsg_bit	= MAILBOX_IRQ_NEWMSG(0),
> > +};
> > +
> > +struct mailbox mbox_wkup_m3_info = {
> > +	.name	= "wkup_m3",
> > +	.ops	= &omap2_mbox_ops,
> > +	.priv	= &omap2_mbox_wkup_m3_priv,
> > +};
> > +struct mailbox *am33xx_mboxes[] = { &mbox_wkup_m3_info, NULL };
> > +#endif
> > +
> >   static int __devinit omap2_mbox_probe(struct platform_device *pdev)
> >   {
> >   	struct resource *mem;
> > @@ -386,6 +412,13 @@ static int __devinit omap2_mbox_probe(struct platform_device *pdev)
> >   		list[0]->irq = list[1]->irq = platform_get_irq(pdev, 0);
> >   	}
> >   #endif
> > +#if defined(CONFIG_SOC_AM33XX)
> ifdef in middle of the code. I know you are just
> following what is already there.
> > +	else if (soc_is_am33xx()) {
> > +		list = am33xx_mboxes;
> > +
> UN-necessary extra line here.

Will remove

> > +		list[0]->irq = platform_get_irq(pdev, 0);
> > +	}
> > +#endif
> 
> Hopefully mailbox clean-up will kill that #ifdeffery.
> Apart from those comments, patch looks fine to me.
> 

Thanks,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 02/18] mailbox: Add an API for flushing the FIFO
@ 2013-01-09  5:16       ` Bedia, Vaibhav
  0 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-09  5:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jan 08, 2013 at 19:26:51, Shilimkar, Santosh wrote:
> On Monday 31 December 2012 06:36 PM, Vaibhav Bedia wrote:
> > On AM33XX, the mailbox module between the MPU and the
> > WKUP-M3 co-processor facilitates a one-way communication.
> > MPU uses the assigned mailbox sub-module to issue the
> > interrupt to the WKUP-M3 co-processor which then goes
> > and reads the the IPC data from registers in the control
> > module.
> >
> > WKUP-M3 is in the L4_WKUP and does not have any access to
> > the mailbox module. Due to this limitation, the MPU is
> > completely responsible for FIFO maintenance and interrupt
> > generation. MPU needs to ensure that the FIFO does not
> > overflow by reading back the assigned mailbox sub-module.
> >
> > This patch adds an API in the mailbox code which the MPU
> > can use to empty the FIFO by issuing a readback command.
> >
> > Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> > Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > ---
> > Note: This patch which will be slightly reworked once the mailbox
> > driver changes are finalized.
> >
> Can you expand a bit please ?

There could be some changes in the structure names.

> 
> >   drivers/mailbox/mailbox-omap2.c |   19 +++++++++++++++++++
> >   drivers/mailbox/mailbox.c       |   36 ++++++++++++++++++++++++++++++++++++
> >   drivers/mailbox/mailbox.h       |    3 +++
> >   include/linux/mailbox.h         |    1 +
> >   4 files changed, 59 insertions(+), 0 deletions(-)
> >
> > diff --git a/drivers/mailbox/mailbox-omap2.c b/drivers/mailbox/mailbox-omap2.c
> > index 6d61159..c732be1 100644
> > --- a/drivers/mailbox/mailbox-omap2.c
> > +++ b/drivers/mailbox/mailbox-omap2.c
> > @@ -125,6 +125,23 @@ static int omap2_mbox_fifo_full(struct mailbox *mbox)
> >   	return mbox_read_reg(fifo->fifo_stat);
> >   }
> >
> > +static int omap2_mbox_fifo_needs_flush(struct mailbox *mbox)
> > +{
> > +	struct omap_mbox2_priv *p = mbox->priv;
> > +	struct omap_mbox2_fifo *fifo = &p->tx_fifo;
> > +
> > +	return mbox_read_reg(fifo->msg_stat);
> > +}
> > +
> > +static void omap2_mbox_fifo_readback(struct mailbox *mbox,
> > +			struct mailbox_msg *msg)
> > +{
> > +	struct omap_mbox2_priv *p = mbox->priv;
> > +	struct omap_mbox2_fifo *fifo = &p->tx_fifo;
> > +
> > +	msg->header = mbox_read_reg(fifo->msg);
> > +}
> > +
> >   static int ompa2_mbox_poll_for_space(struct mailbox *mbox)
> >   {
> >   	if (omap2_mbox_fifo_full(mbox))
> > @@ -221,6 +238,8 @@ static struct mailbox_ops omap2_mbox_ops = {
> >   	.read           = omap2_mbox_fifo_read,
> >   	.write          = omap2_mbox_fifo_write,
> >   	.empty          = omap2_mbox_fifo_empty,
> > +	.fifo_needs_flush	= omap2_mbox_fifo_needs_flush,
> > +	.fifo_readback		= omap2_mbox_fifo_readback,
> >   	.poll_for_space = ompa2_mbox_poll_for_space,
> >   	.enable_irq     = omap2_mbox_enable_irq,
> >   	.disable_irq    = omap2_mbox_disable_irq,
> > diff --git a/drivers/mailbox/mailbox.c b/drivers/mailbox/mailbox.c
> > index 2f50226..92c9f68 100644
> > --- a/drivers/mailbox/mailbox.c
> > +++ b/drivers/mailbox/mailbox.c
> > @@ -57,6 +57,15 @@ static inline int mbox_empty(struct mailbox *mbox)
> >   {
> >   	return mbox->ops->empty(mbox);
> >   }
> > +static inline int mbox_fifo_needs_flush(struct mailbox *mbox)
> > +{
> > +	return mbox->ops->fifo_needs_flush(mbox);
> > +}
> > +static inline void mbox_fifo_readback(struct mailbox *mbox,
> > +				struct mailbox_msg *msg)
> > +{
> > +	mbox->ops->fifo_readback(mbox, msg);
> > +}
> >
> >   /* Mailbox IRQ handle functions */
> >   static inline void ack_mbox_irq(struct mailbox *mbox, mailbox_irq_t irq)
> > @@ -110,6 +119,33 @@ out:
> >   }
> >   EXPORT_SYMBOL(mailbox_msg_send);
> >
> > +/*
> s/*/**

Will do.

> > + * Flush the Rx FIFO by reading back the messages
> > + * Since the normal expectation is that the Rx will do the
> > + * reading, add a debug message to indicate if we really flush
> > + *
> > + * Returns the no. of messages read back
> > + */
> Just look at the kernel doc style for above
> 
> Rest looks fine.
> 

Ok.

Thanks,
Vaibhav 

^ permalink raw reply	[flat|nested] 148+ messages in thread

* RE: [RFC v2 03/18] memory: emif: Move EMIF related header file to include/linux/
  2013-01-08 14:04     ` Santosh Shilimkar
@ 2013-01-09  5:31       ` Bedia, Vaibhav
  -1 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-09  5:31 UTC (permalink / raw)
  To: Shilimkar, Santosh
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Cousson, Benoit, V, Aneesh

On Tue, Jan 08, 2013 at 19:34:41, Shilimkar, Santosh wrote:
[...]
> >
> >   drivers/memory/emif.c   |    2 +-
> >   drivers/memory/emif.h   |  589 -----------------------------------------------
> >   include/linux/ti_emif.h |  589 +++++++++++++++++++++++++++++++++++++++++++++++
> You are just moving the file. So "git mv file1 flie2; and the git 
> format-patch -C"
> on committed patch should just generate few lines of patch.
> 

Ok. Didn't know about this.

> > +/* DDR_PHY_CTRL_1 - EMIF4D5 */
> > +#define DLL_HALF_DELAY_SHIFT_4D5			21
> > +#define DLL_HALF_DELAY_MASK_4D5				(1 << 21)
> > +#define READ_LATENCY_SHIFT_4D5				0
> > +#define READ_LATENCY_MASK_4D5				(0x1f << 0)
> > +
> > +/* DDR_PHY_CTRL_1_SHDW */
> > +#define DDR_PHY_CTRL_1_SHDW_SHIFT			5
> > +#define DDR_PHY_CTRL_1_SHDW_MASK			(0x7ffffff << 5)
> > +#define READ_LATENCY_SHDW_SHIFT				0
> > +#define READ_LATENCY_SHDW_MASK				(0x1f << 0)
> > +
> > +#ifndef __ASSEMBLY__
> > +/*
> > + * Structure containing shadow of important registers in EMIF
> > + * The calculation function fills in this structure to be later used for
> > + * initialisation and DVFS
> > + */
> > +struct emif_regs {
> Are you using above struct. If not we can leave it in same place and
> just move the register defines.
> 

No, the struct is not used. I'll leave it here in the next version.

Regards,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* RE: [RFC v2 05/18] ARM: OMAP2+: AM33XX: CM/PRM: Use __ASSEMBLER__ macros in header files
  2013-01-08 15:01     ` Santosh Shilimkar
@ 2013-01-09  5:31       ` Bedia, Vaibhav
  -1 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-09  5:31 UTC (permalink / raw)
  To: Shilimkar, Santosh
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Paul Walmsley,
	Cousson, Benoit, Hiremath, Vaibhav

On Tue, Jan 08, 2013 at 20:31:44, Shilimkar, Santosh wrote:
[...]
> > +#endif /* ASSEMBLER */
> > +
> Drop that extra line.

Ok.

> >   #endif
> > diff --git a/arch/arm/mach-omap2/prm33xx.h b/arch/arm/mach-omap2/prm33xx.h
> > index 3f25c56..2f2eaa0 100644
> > --- a/arch/arm/mach-omap2/prm33xx.h
> > +++ b/arch/arm/mach-omap2/prm33xx.h
> > @@ -117,6 +117,7 @@
> >   #define AM33XX_PM_CEFUSE_PWRSTST_OFFSET		0x0004
> >   #define AM33XX_PM_CEFUSE_PWRSTST		AM33XX_PRM_REGADDR(AM33XX_PRM_CEFUSE_MOD, 0x0004)
> >
> > +#ifndef __ASSEMBLER__
> >   extern u32 am33xx_prm_read_reg(s16 inst, u16 idx);
> >   extern void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx);
> >   extern u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
> > @@ -126,4 +127,6 @@ extern int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst,
> >   extern int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs);
> >   extern int am33xx_prm_deassert_hardreset(u8 shift, s16 inst,
> >   		u16 rstctrl_offs, u16 rstst_offs);
> > +#endif /* ASSEMBLER */
> > +
> ditto
> 

Ok.
> Otherwise looks fine.
> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> 

Thanks,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* RE: [RFC v2 13/18] ARM: OMAP2+: AM33XX: timer: Interchance clkevt and clksrc timers
  2013-01-08 15:17     ` Santosh Shilimkar
@ 2013-01-09  5:31       ` Bedia, Vaibhav
  -1 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-09  5:31 UTC (permalink / raw)
  To: Shilimkar, Santosh
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Hiremath, Vaibhav,
	Cousson, Benoit, Paul Walmsley, Hunter, Jon

On Tue, Jan 08, 2013 at 20:47:28, Shilimkar, Santosh wrote:
> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> > AM33XX has two timers (DTIMER0/1) in the WKUP domain.
> > On GP devices the source of DMTIMER0 is fixed to an
> > inaccurate internal 32k RC oscillator and this makes
> > the DMTIMER0 practically either as a clocksource or
> > as clockevent.
> >
> > Currently the timer instance in WKUP domain is used
> > as the clockevent and the timer in non-WKUP domain
> > as the clocksource. DMTIMER1 in WKUP domain can keep
> > running in suspend from a 32K clock fed from external
> > OSC and can serve as the persistent clock for the kernel.
> > To enable this, interchange the timers used as clocksource
> > and clockevent for AM33XX.
> >
> > For now a new DT property has been added to allow the timer code
> > to select the timer with the right property.
> >
> > It has been pointed out by Santosh Shilimkar and Kevin Hilman
> > that such a change will result in soc-idle never being achieved
> > on AM33XX. There are other reasons why soc-idle does not look
> > feasible on AM33XX so for now we go ahead with the interchange
> > of the the timers. If at a later point of time we do come up
> > with an approach which makes soc-idle possible on AM33XX, this
> > can be revisited.
> >
> Can you please explain other reasons as well for clarity ?
> 

I guess from h/w perspective it boils down to lack of HW-AUTO and IO-Daisy
chaining on AM33xx [1]. 

Since there's no 32ksynctimer, do we also need to register DMTIMER1 as the persistent
clock on AM33xx? This can only be done from DMTIMER1 which is currently serving as
the clockevent.

Regards,
Vaibhav

[1] http://marc.info/?l=linux-arm-kernel&m=135238055717206&w=4

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 03/18] memory: emif: Move EMIF related header file to include/linux/
@ 2013-01-09  5:31       ` Bedia, Vaibhav
  0 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-09  5:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jan 08, 2013 at 19:34:41, Shilimkar, Santosh wrote:
[...]
> >
> >   drivers/memory/emif.c   |    2 +-
> >   drivers/memory/emif.h   |  589 -----------------------------------------------
> >   include/linux/ti_emif.h |  589 +++++++++++++++++++++++++++++++++++++++++++++++
> You are just moving the file. So "git mv file1 flie2; and the git 
> format-patch -C"
> on committed patch should just generate few lines of patch.
> 

Ok. Didn't know about this.

> > +/* DDR_PHY_CTRL_1 - EMIF4D5 */
> > +#define DLL_HALF_DELAY_SHIFT_4D5			21
> > +#define DLL_HALF_DELAY_MASK_4D5				(1 << 21)
> > +#define READ_LATENCY_SHIFT_4D5				0
> > +#define READ_LATENCY_MASK_4D5				(0x1f << 0)
> > +
> > +/* DDR_PHY_CTRL_1_SHDW */
> > +#define DDR_PHY_CTRL_1_SHDW_SHIFT			5
> > +#define DDR_PHY_CTRL_1_SHDW_MASK			(0x7ffffff << 5)
> > +#define READ_LATENCY_SHDW_SHIFT				0
> > +#define READ_LATENCY_SHDW_MASK				(0x1f << 0)
> > +
> > +#ifndef __ASSEMBLY__
> > +/*
> > + * Structure containing shadow of important registers in EMIF
> > + * The calculation function fills in this structure to be later used for
> > + * initialisation and DVFS
> > + */
> > +struct emif_regs {
> Are you using above struct. If not we can leave it in same place and
> just move the register defines.
> 

No, the struct is not used. I'll leave it here in the next version.

Regards,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 05/18] ARM: OMAP2+: AM33XX: CM/PRM: Use __ASSEMBLER__ macros in header files
@ 2013-01-09  5:31       ` Bedia, Vaibhav
  0 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-09  5:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jan 08, 2013 at 20:31:44, Shilimkar, Santosh wrote:
[...]
> > +#endif /* ASSEMBLER */
> > +
> Drop that extra line.

Ok.

> >   #endif
> > diff --git a/arch/arm/mach-omap2/prm33xx.h b/arch/arm/mach-omap2/prm33xx.h
> > index 3f25c56..2f2eaa0 100644
> > --- a/arch/arm/mach-omap2/prm33xx.h
> > +++ b/arch/arm/mach-omap2/prm33xx.h
> > @@ -117,6 +117,7 @@
> >   #define AM33XX_PM_CEFUSE_PWRSTST_OFFSET		0x0004
> >   #define AM33XX_PM_CEFUSE_PWRSTST		AM33XX_PRM_REGADDR(AM33XX_PRM_CEFUSE_MOD, 0x0004)
> >
> > +#ifndef __ASSEMBLER__
> >   extern u32 am33xx_prm_read_reg(s16 inst, u16 idx);
> >   extern void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx);
> >   extern u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx);
> > @@ -126,4 +127,6 @@ extern int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst,
> >   extern int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs);
> >   extern int am33xx_prm_deassert_hardreset(u8 shift, s16 inst,
> >   		u16 rstctrl_offs, u16 rstst_offs);
> > +#endif /* ASSEMBLER */
> > +
> ditto
> 

Ok.
> Otherwise looks fine.
> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> 

Thanks,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 13/18] ARM: OMAP2+: AM33XX: timer: Interchance clkevt and clksrc timers
@ 2013-01-09  5:31       ` Bedia, Vaibhav
  0 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-09  5:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jan 08, 2013 at 20:47:28, Shilimkar, Santosh wrote:
> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> > AM33XX has two timers (DTIMER0/1) in the WKUP domain.
> > On GP devices the source of DMTIMER0 is fixed to an
> > inaccurate internal 32k RC oscillator and this makes
> > the DMTIMER0 practically either as a clocksource or
> > as clockevent.
> >
> > Currently the timer instance in WKUP domain is used
> > as the clockevent and the timer in non-WKUP domain
> > as the clocksource. DMTIMER1 in WKUP domain can keep
> > running in suspend from a 32K clock fed from external
> > OSC and can serve as the persistent clock for the kernel.
> > To enable this, interchange the timers used as clocksource
> > and clockevent for AM33XX.
> >
> > For now a new DT property has been added to allow the timer code
> > to select the timer with the right property.
> >
> > It has been pointed out by Santosh Shilimkar and Kevin Hilman
> > that such a change will result in soc-idle never being achieved
> > on AM33XX. There are other reasons why soc-idle does not look
> > feasible on AM33XX so for now we go ahead with the interchange
> > of the the timers. If at a later point of time we do come up
> > with an approach which makes soc-idle possible on AM33XX, this
> > can be revisited.
> >
> Can you please explain other reasons as well for clarity ?
> 

I guess from h/w perspective it boils down to lack of HW-AUTO and IO-Daisy
chaining on AM33xx [1]. 

Since there's no 32ksynctimer, do we also need to register DMTIMER1 as the persistent
clock on AM33xx? This can only be done from DMTIMER1 which is currently serving as
the clockevent.

Regards,
Vaibhav

[1] http://marc.info/?l=linux-arm-kernel&m=135238055717206&w=4

^ permalink raw reply	[flat|nested] 148+ messages in thread

* RE: [RFC v2 14/18] ARM: OMAP2+: AM33XX: control: Add some control module registers and APIs
  2013-01-08 15:21     ` Santosh Shilimkar
@ 2013-01-09  5:38       ` Bedia, Vaibhav
  -1 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-09  5:38 UTC (permalink / raw)
  To: Shilimkar, Santosh
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Cousson, Benoit,
	Paul Walmsley, Hiremath, Vaibhav

On Tue, Jan 08, 2013 at 20:51:08, Shilimkar, Santosh wrote:
> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> > Add minimal APIs for writing to the IPC and the M3_TXEV registers
> > in the Control module. These will be used in a subsequent patch which
> > adds suspend-resume support for AM33XX.
> >
> > Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> > Cc: Tony Lingren <tony@atomide.com>
> > Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > Cc: Benoit Cousson <b-cousson@ti.com>
> > Cc: Paul Walmsley <paul@pwsan.com>
> > Cc: Kevin Hilman <khilman@deeprootsystems.com>
> > Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> > ---
> On Control module, we are trying to move driver/module
> specific code to respective drivers. Can you not
> add below code to ipc related driver component.
> 
> If not, then patch as such is fine with me.
> 

I had it in the pm33xx.c in the previous version. Kevin had asked me to
move it to control.c. Should I revert move it back there?

Regards,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 14/18] ARM: OMAP2+: AM33XX: control: Add some control module registers and APIs
@ 2013-01-09  5:38       ` Bedia, Vaibhav
  0 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-09  5:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jan 08, 2013 at 20:51:08, Shilimkar, Santosh wrote:
> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> > Add minimal APIs for writing to the IPC and the M3_TXEV registers
> > in the Control module. These will be used in a subsequent patch which
> > adds suspend-resume support for AM33XX.
> >
> > Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> > Cc: Tony Lingren <tony@atomide.com>
> > Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > Cc: Benoit Cousson <b-cousson@ti.com>
> > Cc: Paul Walmsley <paul@pwsan.com>
> > Cc: Kevin Hilman <khilman@deeprootsystems.com>
> > Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> > ---
> On Control module, we are trying to move driver/module
> specific code to respective drivers. Can you not
> add below code to ipc related driver component.
> 
> If not, then patch as such is fine with me.
> 

I had it in the pm33xx.c in the previous version. Kevin had asked me to
move it to control.c. Should I revert move it back there?

Regards,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* RE: [RFC v2 00/18] ARM: OMAP2+: AM33XX: Add suspend-resume support
  2013-01-08 15:31   ` Santosh Shilimkar
@ 2013-01-09  5:38     ` Bedia, Vaibhav
  -1 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-09  5:38 UTC (permalink / raw)
  To: Shilimkar, Santosh; +Cc: linux-omap, linux-arm-kernel, tony, khilman

Hi Santosh,

On Tue, Jan 08, 2013 at 21:01:51, Shilimkar, Santosh wrote:
> Vaibhav,
> 
> On Monday 31 December 2012 06:36 PM, Vaibhav Bedia wrote:
> > Hi,
> >
> > This is the second version of the patch series for adding suspend-resume
> > support for AM33XX. Based on the feedback received on the previous patch
> > series [1] almost all the patches have undergone a bit a rework.
> >
> > The 1st two patches depend on the changes for mailbox code migration
> > from arch/arm/*-omap*/ to drivers/mailbox/ [2].
> >
> > The patch series also depends on recent changes to the OMAP PM framework
> > by Paul Walmsley.
> >
> > I found it easiest to apply the AM33XX suspend-resume patches on top of
> > Paul's TEST_pwrdm_post_fpwrst_devel_a_3.9 branch + the patches @ [2].
> >
> > With these dependencies met, the PM code uses the firmware interface
> > and expects the userspace to load the WKUP_M3 binary before the
> > suspend-resume functionality is made available. The binary file (and
> > the source-code for WKUP_M3) can be obtained from the 'next' branch at
> > [3]. The WKUP_M3 binary can either be loaded post bootup via
> > the sysfs entry './sys/devices/ocp.2/wkup_m3.4/firmware' or
> > it can be included in the kernel image as part of the build process.
> >
> > DDR3 specific changes have been skipped for now since mainline U-Boot
> > exhibited stability issues on all the DDR3 based AM335x boards that i could
> > lay my hands on.
> >
> > I have done basic testing along with power measurments on the different
> > power rails on the AM335x EVM. PER domain transition on the BeagleBone fails
> > if the CPSW driver is included in the kernel and is yet to be root caused.
> > Along with this issue more extensive testing on other OMAP platforms is also
> > pending right now.
> >
> > For more details on the AM335x suspend-resume support please refer to the
> > changelog in the different patches.
> >
> I still haven't reviewed patch 15, 16 and 18 which adds suspend support.
> Will do that in coming days since they need a bit a closer look.
> 
> But as mentioned in some of the patches, you need to split this series
> since except 15, 16 and 18 which adds suspend support, rest of the
> patches are
> - data file fixes
> - timer suspend/resume update
> - mailbox support, control module update.
> 
> Would be good to split the series to help the reviews.
> 

Sure. I'll split it up like you mentioned. Since all these changes are needed for
a working suspend-resume I kept it in a single series to reduce dependencies and
also to help set an initial context for the AM33xx PM changes.

Regards,
Vaibhav


^ permalink raw reply	[flat|nested] 148+ messages in thread

* RE: [RFC v2 17/18] ARM: OMAP2+: AM33XX: Select Mailbox when PM is enabled
  2013-01-08 15:22     ` Santosh Shilimkar
@ 2013-01-09  5:38       ` Bedia, Vaibhav
  -1 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-09  5:38 UTC (permalink / raw)
  To: Shilimkar, Santosh
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Cousson, Benoit,
	Paul Walmsley

On Tue, Jan 08, 2013 at 20:52:37, Shilimkar, Santosh wrote:
> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> > PM services on AM33XX depend on mailbox for communication
> > with WKUP-M3 core so ensure that the right config options
> > are selected. Thanks to Kevin Hilman <khilman@deeprootsystems.com>
> > for the suggestion on updating the Kconfig and not just
> > the omap2plus_defconfig which was done in the previous version
> > of the AM33XX suspend-resume support.
> >
> > Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> > Cc: Tony Lingren <tony@atomide.com>
> > Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > Cc: Benoit Cousson <b-cousson@ti.com>
> > Cc: Paul Walmsley <paul@pwsan.com>
> > Cc: Kevin Hilman <khilman@deeprootsystems.com>
> > ---
> Unrelated to series. You can post this patch separately.
> 

Ok. I kept it in this series so that it does not look to be 
some random patch.

Regards,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 17/18] ARM: OMAP2+: AM33XX: Select Mailbox when PM is enabled
@ 2013-01-09  5:38       ` Bedia, Vaibhav
  0 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-09  5:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jan 08, 2013 at 20:52:37, Shilimkar, Santosh wrote:
> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> > PM services on AM33XX depend on mailbox for communication
> > with WKUP-M3 core so ensure that the right config options
> > are selected. Thanks to Kevin Hilman <khilman@deeprootsystems.com>
> > for the suggestion on updating the Kconfig and not just
> > the omap2plus_defconfig which was done in the previous version
> > of the AM33XX suspend-resume support.
> >
> > Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> > Cc: Tony Lingren <tony@atomide.com>
> > Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > Cc: Benoit Cousson <b-cousson@ti.com>
> > Cc: Paul Walmsley <paul@pwsan.com>
> > Cc: Kevin Hilman <khilman@deeprootsystems.com>
> > ---
> Unrelated to series. You can post this patch separately.
> 

Ok. I kept it in this series so that it does not look to be 
some random patch.

Regards,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 00/18] ARM: OMAP2+: AM33XX: Add suspend-resume support
@ 2013-01-09  5:38     ` Bedia, Vaibhav
  0 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-09  5:38 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Santosh,

On Tue, Jan 08, 2013 at 21:01:51, Shilimkar, Santosh wrote:
> Vaibhav,
> 
> On Monday 31 December 2012 06:36 PM, Vaibhav Bedia wrote:
> > Hi,
> >
> > This is the second version of the patch series for adding suspend-resume
> > support for AM33XX. Based on the feedback received on the previous patch
> > series [1] almost all the patches have undergone a bit a rework.
> >
> > The 1st two patches depend on the changes for mailbox code migration
> > from arch/arm/*-omap*/ to drivers/mailbox/ [2].
> >
> > The patch series also depends on recent changes to the OMAP PM framework
> > by Paul Walmsley.
> >
> > I found it easiest to apply the AM33XX suspend-resume patches on top of
> > Paul's TEST_pwrdm_post_fpwrst_devel_a_3.9 branch + the patches @ [2].
> >
> > With these dependencies met, the PM code uses the firmware interface
> > and expects the userspace to load the WKUP_M3 binary before the
> > suspend-resume functionality is made available. The binary file (and
> > the source-code for WKUP_M3) can be obtained from the 'next' branch at
> > [3]. The WKUP_M3 binary can either be loaded post bootup via
> > the sysfs entry './sys/devices/ocp.2/wkup_m3.4/firmware' or
> > it can be included in the kernel image as part of the build process.
> >
> > DDR3 specific changes have been skipped for now since mainline U-Boot
> > exhibited stability issues on all the DDR3 based AM335x boards that i could
> > lay my hands on.
> >
> > I have done basic testing along with power measurments on the different
> > power rails on the AM335x EVM. PER domain transition on the BeagleBone fails
> > if the CPSW driver is included in the kernel and is yet to be root caused.
> > Along with this issue more extensive testing on other OMAP platforms is also
> > pending right now.
> >
> > For more details on the AM335x suspend-resume support please refer to the
> > changelog in the different patches.
> >
> I still haven't reviewed patch 15, 16 and 18 which adds suspend support.
> Will do that in coming days since they need a bit a closer look.
> 
> But as mentioned in some of the patches, you need to split this series
> since except 15, 16 and 18 which adds suspend support, rest of the
> patches are
> - data file fixes
> - timer suspend/resume update
> - mailbox support, control module update.
> 
> Would be good to split the series to help the reviews.
> 

Sure. I'll split it up like you mentioned. Since all these changes are needed for
a working suspend-resume I kept it in a single series to reduce dependencies and
also to help set an initial context for the AM33xx PM changes.

Regards,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* RE: [RFC v2 07/18] ARM: OMAP2+: AM33XX: hwmod: Update TPTC0 hwmod with the right flags
  2013-01-08 15:05     ` Santosh Shilimkar
@ 2013-01-09  6:02       ` Bedia, Vaibhav
  -1 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-09  6:02 UTC (permalink / raw)
  To: Shilimkar, Santosh
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Cousson, Benoit,
	Paul Walmsley, Hiremath, Vaibhav

On Tue, Jan 08, 2013 at 20:35:39, Shilimkar, Santosh wrote:
> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> > TPTC0 needs to be idled and put to standby under SW control.
> > Add the appropriate flags in the TPTC0 hwmod entry.
> >
> Can you please expand TPTC0 in chane log.

Third Party Transfer Controller. It's part of the DMA IP.
Will add it in the changelog.

> > Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> > Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > Cc: Benoit Cousson <b-cousson@ti.com>
> > Cc: Paul Walmsley <paul@pwsan.com>
> > Cc: Kevin Hilman <khilman@deeprootsystems.com>
> > Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> > ---
> Patch is fine otherwise.
> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> 
> 


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 07/18] ARM: OMAP2+: AM33XX: hwmod: Update TPTC0 hwmod with the right flags
@ 2013-01-09  6:02       ` Bedia, Vaibhav
  0 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-09  6:02 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jan 08, 2013 at 20:35:39, Shilimkar, Santosh wrote:
> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> > TPTC0 needs to be idled and put to standby under SW control.
> > Add the appropriate flags in the TPTC0 hwmod entry.
> >
> Can you please expand TPTC0 in chane log.

Third Party Transfer Controller. It's part of the DMA IP.
Will add it in the changelog.

> > Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> > Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > Cc: Benoit Cousson <b-cousson@ti.com>
> > Cc: Paul Walmsley <paul@pwsan.com>
> > Cc: Kevin Hilman <khilman@deeprootsystems.com>
> > Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> > ---
> Patch is fine otherwise.
> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
> 
> 

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 14/18] ARM: OMAP2+: AM33XX: control: Add some control module registers and APIs
  2013-01-09  5:38       ` Bedia, Vaibhav
@ 2013-01-09  7:31         ` Santosh Shilimkar
  -1 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-09  7:31 UTC (permalink / raw)
  To: Bedia, Vaibhav
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Cousson, Benoit,
	Paul Walmsley, Hiremath, Vaibhav

On Wednesday 09 January 2013 11:08 AM, Bedia, Vaibhav wrote:
> On Tue, Jan 08, 2013 at 20:51:08, Shilimkar, Santosh wrote:
>> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
>>> Add minimal APIs for writing to the IPC and the M3_TXEV registers
>>> in the Control module. These will be used in a subsequent patch which
>>> adds suspend-resume support for AM33XX.
>>>
>>> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
>>> Cc: Tony Lingren <tony@atomide.com>
>>> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>> Cc: Benoit Cousson <b-cousson@ti.com>
>>> Cc: Paul Walmsley <paul@pwsan.com>
>>> Cc: Kevin Hilman <khilman@deeprootsystems.com>
>>> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
>>> ---
>> On Control module, we are trying to move driver/module
>> specific code to respective drivers. Can you not
>> add below code to ipc related driver component.
>>
>> If not, then patch as such is fine with me.
>>
>
> I had it in the pm33xx.c in the previous version. Kevin had asked me to
> move it to control.c. Should I revert move it back there?
>
pm33xx.c is not the right place. I was hoping to move to some driver.
If that is not possible then leave it in control module.

Regards
Santosh


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 14/18] ARM: OMAP2+: AM33XX: control: Add some control module registers and APIs
@ 2013-01-09  7:31         ` Santosh Shilimkar
  0 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-09  7:31 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 09 January 2013 11:08 AM, Bedia, Vaibhav wrote:
> On Tue, Jan 08, 2013 at 20:51:08, Shilimkar, Santosh wrote:
>> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
>>> Add minimal APIs for writing to the IPC and the M3_TXEV registers
>>> in the Control module. These will be used in a subsequent patch which
>>> adds suspend-resume support for AM33XX.
>>>
>>> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
>>> Cc: Tony Lingren <tony@atomide.com>
>>> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>> Cc: Benoit Cousson <b-cousson@ti.com>
>>> Cc: Paul Walmsley <paul@pwsan.com>
>>> Cc: Kevin Hilman <khilman@deeprootsystems.com>
>>> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
>>> ---
>> On Control module, we are trying to move driver/module
>> specific code to respective drivers. Can you not
>> add below code to ipc related driver component.
>>
>> If not, then patch as such is fine with me.
>>
>
> I had it in the pm33xx.c in the previous version. Kevin had asked me to
> move it to control.c. Should I revert move it back there?
>
pm33xx.c is not the right place. I was hoping to move to some driver.
If that is not possible then leave it in control module.

Regards
Santosh

^ permalink raw reply	[flat|nested] 148+ messages in thread

* RE: [RFC v2 14/18] ARM: OMAP2+: AM33XX: control: Add some control module registers and APIs
  2013-01-09  7:31         ` Santosh Shilimkar
@ 2013-01-09  9:37           ` Bedia, Vaibhav
  -1 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-09  9:37 UTC (permalink / raw)
  To: Shilimkar, Santosh
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Cousson, Benoit,
	Paul Walmsley, Hiremath, Vaibhav

On Wed, Jan 09, 2013 at 13:01:03, Shilimkar, Santosh wrote:
> On Wednesday 09 January 2013 11:08 AM, Bedia, Vaibhav wrote:
> > On Tue, Jan 08, 2013 at 20:51:08, Shilimkar, Santosh wrote:
> >> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> >>> Add minimal APIs for writing to the IPC and the M3_TXEV registers
> >>> in the Control module. These will be used in a subsequent patch which
> >>> adds suspend-resume support for AM33XX.
> >>>
> >>> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> >>> Cc: Tony Lingren <tony@atomide.com>
> >>> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> >>> Cc: Benoit Cousson <b-cousson@ti.com>
> >>> Cc: Paul Walmsley <paul@pwsan.com>
> >>> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> >>> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> >>> ---
> >> On Control module, we are trying to move driver/module
> >> specific code to respective drivers. Can you not
> >> add below code to ipc related driver component.
> >>
> >> If not, then patch as such is fine with me.
> >>
> >
> > I had it in the pm33xx.c in the previous version. Kevin had asked me to
> > move it to control.c. Should I revert move it back there?
> >
> pm33xx.c is not the right place. I was hoping to move to some driver.
> If that is not possible then leave it in control module.
> 

I think I'll leave it here for now. Could I have you ack in that case?

Thanks,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 14/18] ARM: OMAP2+: AM33XX: control: Add some control module registers and APIs
@ 2013-01-09  9:37           ` Bedia, Vaibhav
  0 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-09  9:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jan 09, 2013 at 13:01:03, Shilimkar, Santosh wrote:
> On Wednesday 09 January 2013 11:08 AM, Bedia, Vaibhav wrote:
> > On Tue, Jan 08, 2013 at 20:51:08, Shilimkar, Santosh wrote:
> >> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> >>> Add minimal APIs for writing to the IPC and the M3_TXEV registers
> >>> in the Control module. These will be used in a subsequent patch which
> >>> adds suspend-resume support for AM33XX.
> >>>
> >>> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> >>> Cc: Tony Lingren <tony@atomide.com>
> >>> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> >>> Cc: Benoit Cousson <b-cousson@ti.com>
> >>> Cc: Paul Walmsley <paul@pwsan.com>
> >>> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> >>> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> >>> ---
> >> On Control module, we are trying to move driver/module
> >> specific code to respective drivers. Can you not
> >> add below code to ipc related driver component.
> >>
> >> If not, then patch as such is fine with me.
> >>
> >
> > I had it in the pm33xx.c in the previous version. Kevin had asked me to
> > move it to control.c. Should I revert move it back there?
> >
> pm33xx.c is not the right place. I was hoping to move to some driver.
> If that is not possible then leave it in control module.
> 

I think I'll leave it here for now. Could I have you ack in that case?

Thanks,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 14/18] ARM: OMAP2+: AM33XX: control: Add some control module registers and APIs
  2013-01-09  9:37           ` Bedia, Vaibhav
@ 2013-01-09  9:53             ` Santosh Shilimkar
  -1 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-09  9:53 UTC (permalink / raw)
  To: Bedia, Vaibhav
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Cousson, Benoit,
	Paul Walmsley, Hiremath, Vaibhav

On Wednesday 09 January 2013 03:07 PM, Bedia, Vaibhav wrote:
> On Wed, Jan 09, 2013 at 13:01:03, Shilimkar, Santosh wrote:
>> On Wednesday 09 January 2013 11:08 AM, Bedia, Vaibhav wrote:
>>> On Tue, Jan 08, 2013 at 20:51:08, Shilimkar, Santosh wrote:
>>>> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
>>>>> Add minimal APIs for writing to the IPC and the M3_TXEV registers
>>>>> in the Control module. These will be used in a subsequent patch which
>>>>> adds suspend-resume support for AM33XX.
>>>>>
>>>>> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
>>>>> Cc: Tony Lingren <tony@atomide.com>
>>>>> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>>>> Cc: Benoit Cousson <b-cousson@ti.com>
>>>>> Cc: Paul Walmsley <paul@pwsan.com>
>>>>> Cc: Kevin Hilman <khilman@deeprootsystems.com>
>>>>> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
>>>>> ---
>>>> On Control module, we are trying to move driver/module
>>>> specific code to respective drivers. Can you not
>>>> add below code to ipc related driver component.
>>>>
>>>> If not, then patch as such is fine with me.
>>>>
>>>
>>> I had it in the pm33xx.c in the previous version. Kevin had asked me to
>>> move it to control.c. Should I revert move it back there?
>>>
>> pm33xx.c is not the right place. I was hoping to move to some driver.
>> If that is not possible then leave it in control module.
>>
>
> I think I'll leave it here for now. Could I have you ack in that case?
>
Yep.
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 14/18] ARM: OMAP2+: AM33XX: control: Add some control module registers and APIs
@ 2013-01-09  9:53             ` Santosh Shilimkar
  0 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-09  9:53 UTC (permalink / raw)
  To: linux-arm-kernel

On Wednesday 09 January 2013 03:07 PM, Bedia, Vaibhav wrote:
> On Wed, Jan 09, 2013 at 13:01:03, Shilimkar, Santosh wrote:
>> On Wednesday 09 January 2013 11:08 AM, Bedia, Vaibhav wrote:
>>> On Tue, Jan 08, 2013 at 20:51:08, Shilimkar, Santosh wrote:
>>>> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
>>>>> Add minimal APIs for writing to the IPC and the M3_TXEV registers
>>>>> in the Control module. These will be used in a subsequent patch which
>>>>> adds suspend-resume support for AM33XX.
>>>>>
>>>>> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
>>>>> Cc: Tony Lingren <tony@atomide.com>
>>>>> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>>>> Cc: Benoit Cousson <b-cousson@ti.com>
>>>>> Cc: Paul Walmsley <paul@pwsan.com>
>>>>> Cc: Kevin Hilman <khilman@deeprootsystems.com>
>>>>> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
>>>>> ---
>>>> On Control module, we are trying to move driver/module
>>>> specific code to respective drivers. Can you not
>>>> add below code to ipc related driver component.
>>>>
>>>> If not, then patch as such is fine with me.
>>>>
>>>
>>> I had it in the pm33xx.c in the previous version. Kevin had asked me to
>>> move it to control.c. Should I revert move it back there?
>>>
>> pm33xx.c is not the right place. I was hoping to move to some driver.
>> If that is not possible then leave it in control module.
>>
>
> I think I'll leave it here for now. Could I have you ack in that case?
>
Yep.
Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com>

^ permalink raw reply	[flat|nested] 148+ messages in thread

* RE: [RFC v2 12/18] ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent device
  2013-01-08 15:15     ` Santosh Shilimkar
@ 2013-01-11  4:37       ` Bedia, Vaibhav
  -1 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-11  4:37 UTC (permalink / raw)
  To: Shilimkar, Santosh, Hunter, Jon
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Cousson, Benoit,
	Paul Walmsley, Hiremath, Vaibhav

On Tue, Jan 08, 2013 at 20:45:10, Shilimkar, Santosh wrote:
> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> > The current OMAP timer code registers two timers -
> > one as clocksource and one as clockevent.
> > AM33XX has only one usable timer in the WKUP domain
> > so one of the timers needs suspend-resume support
> > to restore the configuration to pre-suspend state.
> >
> > commit adc78e6 (timekeeping: Add suspend and resume
> > of clock event devices) introduced .suspend and .resume
> > callbacks for clock event devices. Leverages these
> > callbacks to have AM33XX clockevent timer which is
> > in not in WKUP domain to behave properly across system
> > suspend.
> >
> > Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> > Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > Cc: Benoit Cousson <b-cousson@ti.com>
> > Cc: Paul Walmsley <paul@pwsan.com>
> > Cc: Kevin Hilman <khilman@deeprootsystems.com>
> > Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> > Cc: Jon Hunter <jon-hunter@ti.com>
> > ---
> > v1->v2:
> > 	Get rid of harcoded timer id.
> > 	Note: since a platform device is not created for these timer
> > 	instances and because there's very minimal change needed for
> > 	restarting the timer a full blown context save and restore
> > 	has been skipped.
> >
> >   arch/arm/mach-omap2/timer.c |   33 +++++++++++++++++++++++++++++++++
> >   1 files changed, 33 insertions(+), 0 deletions(-)
> >
> > diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
> > index 691aa67..38f9cbc 100644
> > --- a/arch/arm/mach-omap2/timer.c
> > +++ b/arch/arm/mach-omap2/timer.c
> > @@ -128,6 +128,36 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
> >   	}
> >   }
> >
> > +static void omap_clkevt_suspend(struct clock_event_device *unused)
> > +{
> > +	char name[10];
> > +	struct omap_hwmod *oh;
> > +
> > +	sprintf(name, "timer%d", clkev.id);
> > +	oh = omap_hwmod_lookup(name);
> > +	if (!oh)
> > +		return;
> > +
> > +	__omap_dm_timer_stop(&clkev, 1, clkev.rate);
> > +	omap_hwmod_idle(oh);
> > +}
> > +
> > +static void omap_clkevt_resume(struct clock_event_device *unused)
> > +{
> > +	char name[10];
> > +	struct omap_hwmod *oh;
> > +
> > +	sprintf(name, "timer%d", clkev.id);
> > +	oh = omap_hwmod_lookup(name);
> > +	if (!oh)
> > +		return;
> > +
> > +	omap_hwmod_enable(oh);
> > +	__omap_dm_timer_load_start(&clkev,
> > +			OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
> > +	__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
> > +}
> > +
> Am still bit uncomfortable with direct hwmod usage in the suspend/resmue
> hooks.
> 
> Jon, Any alternatives you can think of ?
> 

Jon,

Any suggestions here?

Regards,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 12/18] ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent device
@ 2013-01-11  4:37       ` Bedia, Vaibhav
  0 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-11  4:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jan 08, 2013 at 20:45:10, Shilimkar, Santosh wrote:
> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> > The current OMAP timer code registers two timers -
> > one as clocksource and one as clockevent.
> > AM33XX has only one usable timer in the WKUP domain
> > so one of the timers needs suspend-resume support
> > to restore the configuration to pre-suspend state.
> >
> > commit adc78e6 (timekeeping: Add suspend and resume
> > of clock event devices) introduced .suspend and .resume
> > callbacks for clock event devices. Leverages these
> > callbacks to have AM33XX clockevent timer which is
> > in not in WKUP domain to behave properly across system
> > suspend.
> >
> > Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> > Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > Cc: Benoit Cousson <b-cousson@ti.com>
> > Cc: Paul Walmsley <paul@pwsan.com>
> > Cc: Kevin Hilman <khilman@deeprootsystems.com>
> > Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> > Cc: Jon Hunter <jon-hunter@ti.com>
> > ---
> > v1->v2:
> > 	Get rid of harcoded timer id.
> > 	Note: since a platform device is not created for these timer
> > 	instances and because there's very minimal change needed for
> > 	restarting the timer a full blown context save and restore
> > 	has been skipped.
> >
> >   arch/arm/mach-omap2/timer.c |   33 +++++++++++++++++++++++++++++++++
> >   1 files changed, 33 insertions(+), 0 deletions(-)
> >
> > diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
> > index 691aa67..38f9cbc 100644
> > --- a/arch/arm/mach-omap2/timer.c
> > +++ b/arch/arm/mach-omap2/timer.c
> > @@ -128,6 +128,36 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
> >   	}
> >   }
> >
> > +static void omap_clkevt_suspend(struct clock_event_device *unused)
> > +{
> > +	char name[10];
> > +	struct omap_hwmod *oh;
> > +
> > +	sprintf(name, "timer%d", clkev.id);
> > +	oh = omap_hwmod_lookup(name);
> > +	if (!oh)
> > +		return;
> > +
> > +	__omap_dm_timer_stop(&clkev, 1, clkev.rate);
> > +	omap_hwmod_idle(oh);
> > +}
> > +
> > +static void omap_clkevt_resume(struct clock_event_device *unused)
> > +{
> > +	char name[10];
> > +	struct omap_hwmod *oh;
> > +
> > +	sprintf(name, "timer%d", clkev.id);
> > +	oh = omap_hwmod_lookup(name);
> > +	if (!oh)
> > +		return;
> > +
> > +	omap_hwmod_enable(oh);
> > +	__omap_dm_timer_load_start(&clkev,
> > +			OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
> > +	__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
> > +}
> > +
> Am still bit uncomfortable with direct hwmod usage in the suspend/resmue
> hooks.
> 
> Jon, Any alternatives you can think of ?
> 

Jon,

Any suggestions here?

Regards,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support
  2012-12-31 13:07   ` Vaibhav Bedia
@ 2013-01-17 14:27     ` Peter Korsgaard
  -1 siblings, 0 replies; 148+ messages in thread
From: Peter Korsgaard @ 2013-01-17 14:27 UTC (permalink / raw)
  To: Vaibhav Bedia
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Santosh Shilimkar,
	Benoit Cousson, Paul Walmsley

>>>>> "V" == Vaibhav Bedia <vaibhav.bedia@ti.com> writes:

Hi,

 V> +static void am33xx_pm_firmware_cb(const struct firmware *fw, void *context)
 V> +{
 V> +	struct wkup_m3_context *wkup_m3_context = context;
 V> +	struct platform_device *pdev = to_platform_device(wkup_m3_context->dev);
 V> +	int ret = 0;
 V> +
 V> +	/* no firmware found */
 V> +	if (!fw) {
 V> +		dev_err(wkup_m3_context->dev, "request_firmware failed\n");
 V> +		goto err;
 V> +	}
 V> +
 V> +	memcpy((void *)wkup_m3_context->code, fw->data, fw->size);

A size check would be good. I don't know much about the finer details
about the m3 and how it is connected, but don't you need to ensure data
is flushed before resetting the m3?



 V> +	pr_info("Copied the M3 firmware to UMEM\n");
 V> +
 V> +	wkup_m3->state = M3_STATE_RESET;
 V> +
 V> +	ret = omap_device_deassert_hardreset(pdev, "wkup_m3");
 V> +	if (ret) {
 V> +		pr_err("Could not deassert the reset for WKUP_M3\n");
 V> +		goto err;
 V> +	} else {
 V> +#ifdef CONFIG_SUSPEND
 V> +		suspend_set_ops(&am33xx_pm_ops);
 V> +		/*
 V> +		 * Physical resume address to be used by ROM code
 V> +		 */
 V> +		wkup_m3->ipc_data.resume_addr = (AM33XX_OCMC_END -
 V> +				am33xx_do_wfi_sz + am33xx_resume_offset + 0x4);
 V> +#endif
 V> +		return;
 V> +	}
 V> +
 V> +err:
 V> +	mailbox_put(wkup_m3_context->mbox, &wkup_mbox_notifier);
 V> +}

-- 
Bye, Peter Korsgaard

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support
@ 2013-01-17 14:27     ` Peter Korsgaard
  0 siblings, 0 replies; 148+ messages in thread
From: Peter Korsgaard @ 2013-01-17 14:27 UTC (permalink / raw)
  To: linux-arm-kernel

>>>>> "V" == Vaibhav Bedia <vaibhav.bedia@ti.com> writes:

Hi,

 V> +static void am33xx_pm_firmware_cb(const struct firmware *fw, void *context)
 V> +{
 V> +	struct wkup_m3_context *wkup_m3_context = context;
 V> +	struct platform_device *pdev = to_platform_device(wkup_m3_context->dev);
 V> +	int ret = 0;
 V> +
 V> +	/* no firmware found */
 V> +	if (!fw) {
 V> +		dev_err(wkup_m3_context->dev, "request_firmware failed\n");
 V> +		goto err;
 V> +	}
 V> +
 V> +	memcpy((void *)wkup_m3_context->code, fw->data, fw->size);

A size check would be good. I don't know much about the finer details
about the m3 and how it is connected, but don't you need to ensure data
is flushed before resetting the m3?



 V> +	pr_info("Copied the M3 firmware to UMEM\n");
 V> +
 V> +	wkup_m3->state = M3_STATE_RESET;
 V> +
 V> +	ret = omap_device_deassert_hardreset(pdev, "wkup_m3");
 V> +	if (ret) {
 V> +		pr_err("Could not deassert the reset for WKUP_M3\n");
 V> +		goto err;
 V> +	} else {
 V> +#ifdef CONFIG_SUSPEND
 V> +		suspend_set_ops(&am33xx_pm_ops);
 V> +		/*
 V> +		 * Physical resume address to be used by ROM code
 V> +		 */
 V> +		wkup_m3->ipc_data.resume_addr = (AM33XX_OCMC_END -
 V> +				am33xx_do_wfi_sz + am33xx_resume_offset + 0x4);
 V> +#endif
 V> +		return;
 V> +	}
 V> +
 V> +err:
 V> +	mailbox_put(wkup_m3_context->mbox, &wkup_mbox_notifier);
 V> +}

-- 
Bye, Peter Korsgaard

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 12/18] ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent device
  2012-12-31 13:07   ` Vaibhav Bedia
@ 2013-01-17 18:40     ` Jon Hunter
  -1 siblings, 0 replies; 148+ messages in thread
From: Jon Hunter @ 2013-01-17 18:40 UTC (permalink / raw)
  To: Vaibhav Bedia
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Paul Walmsley,
	Benoit Cousson, Vaibhav Hiremath, Santosh Shilimkar


On 12/31/2012 07:07 AM, Vaibhav Bedia wrote:
> The current OMAP timer code registers two timers -
> one as clocksource and one as clockevent.
> AM33XX has only one usable timer in the WKUP domain
> so one of the timers needs suspend-resume support
> to restore the configuration to pre-suspend state.
> 
> commit adc78e6 (timekeeping: Add suspend and resume
> of clock event devices) introduced .suspend and .resume
> callbacks for clock event devices. Leverages these
> callbacks to have AM33XX clockevent timer which is
> in not in WKUP domain to behave properly across system
> suspend.
> 
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> Cc: Jon Hunter <jon-hunter@ti.com>
> ---
> v1->v2:
> 	Get rid of harcoded timer id.
> 	Note: since a platform device is not created for these timer
> 	instances and because there's very minimal change needed for
> 	restarting the timer a full blown context save and restore
> 	has been skipped.
> 
>  arch/arm/mach-omap2/timer.c |   33 +++++++++++++++++++++++++++++++++
>  1 files changed, 33 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
> index 691aa67..38f9cbc 100644
> --- a/arch/arm/mach-omap2/timer.c
> +++ b/arch/arm/mach-omap2/timer.c
> @@ -128,6 +128,36 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
>  	}
>  }
>  
> +static void omap_clkevt_suspend(struct clock_event_device *unused)
> +{
> +	char name[10];
> +	struct omap_hwmod *oh;
> +
> +	sprintf(name, "timer%d", clkev.id);
> +	oh = omap_hwmod_lookup(name);
> +	if (!oh)
> +		return;
> +
> +	__omap_dm_timer_stop(&clkev, 1, clkev.rate);

I am not sure you need to call __omap_dm_timer_stop() here. This should
have already been called as timekeeping_suspend() will call
omap2_gp_timer_set_mode() to shutdown the timer.

> +	omap_hwmod_idle(oh);
> +}
> +
> +static void omap_clkevt_resume(struct clock_event_device *unused)
> +{
> +	char name[10];
> +	struct omap_hwmod *oh;
> +
> +	sprintf(name, "timer%d", clkev.id);
> +	oh = omap_hwmod_lookup(name);
> +	if (!oh)
> +		return;
> +
> +	omap_hwmod_enable(oh);
> +	__omap_dm_timer_load_start(&clkev,
> +			OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
> +	__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);

Similarly here, I am not sure these __omap_dm_timer_xxxx calls are needed.

> +}
> +
>  static struct clock_event_device clockevent_gpt = {
>  	.name		= "gp_timer",
>  	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
> @@ -135,6 +165,8 @@ static struct clock_event_device clockevent_gpt = {
>  	.rating		= 300,
>  	.set_next_event	= omap2_gp_timer_set_next_event,
>  	.set_mode	= omap2_gp_timer_set_mode,
> +	.suspend	= omap_clkevt_suspend,
> +	.resume		= omap_clkevt_resume,

AFAIK, this is only applicable for AM335x devices and so should not be
added for all.

>  };
>  
>  static struct property device_disabled = {
> @@ -323,6 +355,7 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
>  	int res;
>  
>  	clkev.errata = omap_dm_timer_get_errata();
> +	clkev.id = gptimer_id;

We should not use gptimer_id anymore. This will go away once the
migration to dev-tree is completed. You may be better off storing the
oh_name in the clock_event_device name field and passing to the
suspend/resume handlers.

Cheers
Jon

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 12/18] ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent device
@ 2013-01-17 18:40     ` Jon Hunter
  0 siblings, 0 replies; 148+ messages in thread
From: Jon Hunter @ 2013-01-17 18:40 UTC (permalink / raw)
  To: linux-arm-kernel


On 12/31/2012 07:07 AM, Vaibhav Bedia wrote:
> The current OMAP timer code registers two timers -
> one as clocksource and one as clockevent.
> AM33XX has only one usable timer in the WKUP domain
> so one of the timers needs suspend-resume support
> to restore the configuration to pre-suspend state.
> 
> commit adc78e6 (timekeeping: Add suspend and resume
> of clock event devices) introduced .suspend and .resume
> callbacks for clock event devices. Leverages these
> callbacks to have AM33XX clockevent timer which is
> in not in WKUP domain to behave properly across system
> suspend.
> 
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> Cc: Jon Hunter <jon-hunter@ti.com>
> ---
> v1->v2:
> 	Get rid of harcoded timer id.
> 	Note: since a platform device is not created for these timer
> 	instances and because there's very minimal change needed for
> 	restarting the timer a full blown context save and restore
> 	has been skipped.
> 
>  arch/arm/mach-omap2/timer.c |   33 +++++++++++++++++++++++++++++++++
>  1 files changed, 33 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
> index 691aa67..38f9cbc 100644
> --- a/arch/arm/mach-omap2/timer.c
> +++ b/arch/arm/mach-omap2/timer.c
> @@ -128,6 +128,36 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
>  	}
>  }
>  
> +static void omap_clkevt_suspend(struct clock_event_device *unused)
> +{
> +	char name[10];
> +	struct omap_hwmod *oh;
> +
> +	sprintf(name, "timer%d", clkev.id);
> +	oh = omap_hwmod_lookup(name);
> +	if (!oh)
> +		return;
> +
> +	__omap_dm_timer_stop(&clkev, 1, clkev.rate);

I am not sure you need to call __omap_dm_timer_stop() here. This should
have already been called as timekeeping_suspend() will call
omap2_gp_timer_set_mode() to shutdown the timer.

> +	omap_hwmod_idle(oh);
> +}
> +
> +static void omap_clkevt_resume(struct clock_event_device *unused)
> +{
> +	char name[10];
> +	struct omap_hwmod *oh;
> +
> +	sprintf(name, "timer%d", clkev.id);
> +	oh = omap_hwmod_lookup(name);
> +	if (!oh)
> +		return;
> +
> +	omap_hwmod_enable(oh);
> +	__omap_dm_timer_load_start(&clkev,
> +			OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
> +	__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);

Similarly here, I am not sure these __omap_dm_timer_xxxx calls are needed.

> +}
> +
>  static struct clock_event_device clockevent_gpt = {
>  	.name		= "gp_timer",
>  	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
> @@ -135,6 +165,8 @@ static struct clock_event_device clockevent_gpt = {
>  	.rating		= 300,
>  	.set_next_event	= omap2_gp_timer_set_next_event,
>  	.set_mode	= omap2_gp_timer_set_mode,
> +	.suspend	= omap_clkevt_suspend,
> +	.resume		= omap_clkevt_resume,

AFAIK, this is only applicable for AM335x devices and so should not be
added for all.

>  };
>  
>  static struct property device_disabled = {
> @@ -323,6 +355,7 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
>  	int res;
>  
>  	clkev.errata = omap_dm_timer_get_errata();
> +	clkev.id = gptimer_id;

We should not use gptimer_id anymore. This will go away once the
migration to dev-tree is completed. You may be better off storing the
oh_name in the clock_event_device name field and passing to the
suspend/resume handlers.

Cheers
Jon

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 12/18] ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent device
  2013-01-11  4:37       ` Bedia, Vaibhav
@ 2013-01-17 18:45         ` Jon Hunter
  -1 siblings, 0 replies; 148+ messages in thread
From: Jon Hunter @ 2013-01-17 18:45 UTC (permalink / raw)
  To: Bedia, Vaibhav
  Cc: Shilimkar, Santosh, linux-omap, linux-arm-kernel, tony, khilman,
	Cousson, Benoit, Paul Walmsley, Hiremath, Vaibhav


On 01/10/2013 10:37 PM, Bedia, Vaibhav wrote:
> On Tue, Jan 08, 2013 at 20:45:10, Shilimkar, Santosh wrote:
>> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
>>> The current OMAP timer code registers two timers -
>>> one as clocksource and one as clockevent.
>>> AM33XX has only one usable timer in the WKUP domain
>>> so one of the timers needs suspend-resume support
>>> to restore the configuration to pre-suspend state.
>>>
>>> commit adc78e6 (timekeeping: Add suspend and resume
>>> of clock event devices) introduced .suspend and .resume
>>> callbacks for clock event devices. Leverages these
>>> callbacks to have AM33XX clockevent timer which is
>>> in not in WKUP domain to behave properly across system
>>> suspend.
>>>
>>> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
>>> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>> Cc: Benoit Cousson <b-cousson@ti.com>
>>> Cc: Paul Walmsley <paul@pwsan.com>
>>> Cc: Kevin Hilman <khilman@deeprootsystems.com>
>>> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
>>> Cc: Jon Hunter <jon-hunter@ti.com>
>>> ---
>>> v1->v2:
>>> 	Get rid of harcoded timer id.
>>> 	Note: since a platform device is not created for these timer
>>> 	instances and because there's very minimal change needed for
>>> 	restarting the timer a full blown context save and restore
>>> 	has been skipped.
>>>
>>>   arch/arm/mach-omap2/timer.c |   33 +++++++++++++++++++++++++++++++++
>>>   1 files changed, 33 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
>>> index 691aa67..38f9cbc 100644
>>> --- a/arch/arm/mach-omap2/timer.c
>>> +++ b/arch/arm/mach-omap2/timer.c
>>> @@ -128,6 +128,36 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
>>>   	}
>>>   }
>>>
>>> +static void omap_clkevt_suspend(struct clock_event_device *unused)
>>> +{
>>> +	char name[10];
>>> +	struct omap_hwmod *oh;
>>> +
>>> +	sprintf(name, "timer%d", clkev.id);
>>> +	oh = omap_hwmod_lookup(name);
>>> +	if (!oh)
>>> +		return;
>>> +
>>> +	__omap_dm_timer_stop(&clkev, 1, clkev.rate);
>>> +	omap_hwmod_idle(oh);
>>> +}
>>> +
>>> +static void omap_clkevt_resume(struct clock_event_device *unused)
>>> +{
>>> +	char name[10];
>>> +	struct omap_hwmod *oh;
>>> +
>>> +	sprintf(name, "timer%d", clkev.id);
>>> +	oh = omap_hwmod_lookup(name);
>>> +	if (!oh)
>>> +		return;
>>> +
>>> +	omap_hwmod_enable(oh);
>>> +	__omap_dm_timer_load_start(&clkev,
>>> +			OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
>>> +	__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
>>> +}
>>> +
>> Am still bit uncomfortable with direct hwmod usage in the suspend/resmue
>> hooks.
>>
>> Jon, Any alternatives you can think of ?
>>
> 
> Jon,
> 
> Any suggestions here?

Sorry completed this missed this!

Unfortunately, I don't have any good suggestions here. However, I am
wondering if the suspend/resume handlers can just be calls to
omap_hwmod_idle/enable and we can remove these __omap_dm_timer_xxxx
calls (I don't think they are needed). Furthermore, my understanding is
this is only needed for AM335x (per the changelog), and so we should not
add suspend/resume handlers for all OMAP2+ based devices.

Cheers
Jon

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 12/18] ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent device
@ 2013-01-17 18:45         ` Jon Hunter
  0 siblings, 0 replies; 148+ messages in thread
From: Jon Hunter @ 2013-01-17 18:45 UTC (permalink / raw)
  To: linux-arm-kernel


On 01/10/2013 10:37 PM, Bedia, Vaibhav wrote:
> On Tue, Jan 08, 2013 at 20:45:10, Shilimkar, Santosh wrote:
>> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
>>> The current OMAP timer code registers two timers -
>>> one as clocksource and one as clockevent.
>>> AM33XX has only one usable timer in the WKUP domain
>>> so one of the timers needs suspend-resume support
>>> to restore the configuration to pre-suspend state.
>>>
>>> commit adc78e6 (timekeeping: Add suspend and resume
>>> of clock event devices) introduced .suspend and .resume
>>> callbacks for clock event devices. Leverages these
>>> callbacks to have AM33XX clockevent timer which is
>>> in not in WKUP domain to behave properly across system
>>> suspend.
>>>
>>> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
>>> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>> Cc: Benoit Cousson <b-cousson@ti.com>
>>> Cc: Paul Walmsley <paul@pwsan.com>
>>> Cc: Kevin Hilman <khilman@deeprootsystems.com>
>>> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
>>> Cc: Jon Hunter <jon-hunter@ti.com>
>>> ---
>>> v1->v2:
>>> 	Get rid of harcoded timer id.
>>> 	Note: since a platform device is not created for these timer
>>> 	instances and because there's very minimal change needed for
>>> 	restarting the timer a full blown context save and restore
>>> 	has been skipped.
>>>
>>>   arch/arm/mach-omap2/timer.c |   33 +++++++++++++++++++++++++++++++++
>>>   1 files changed, 33 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
>>> index 691aa67..38f9cbc 100644
>>> --- a/arch/arm/mach-omap2/timer.c
>>> +++ b/arch/arm/mach-omap2/timer.c
>>> @@ -128,6 +128,36 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
>>>   	}
>>>   }
>>>
>>> +static void omap_clkevt_suspend(struct clock_event_device *unused)
>>> +{
>>> +	char name[10];
>>> +	struct omap_hwmod *oh;
>>> +
>>> +	sprintf(name, "timer%d", clkev.id);
>>> +	oh = omap_hwmod_lookup(name);
>>> +	if (!oh)
>>> +		return;
>>> +
>>> +	__omap_dm_timer_stop(&clkev, 1, clkev.rate);
>>> +	omap_hwmod_idle(oh);
>>> +}
>>> +
>>> +static void omap_clkevt_resume(struct clock_event_device *unused)
>>> +{
>>> +	char name[10];
>>> +	struct omap_hwmod *oh;
>>> +
>>> +	sprintf(name, "timer%d", clkev.id);
>>> +	oh = omap_hwmod_lookup(name);
>>> +	if (!oh)
>>> +		return;
>>> +
>>> +	omap_hwmod_enable(oh);
>>> +	__omap_dm_timer_load_start(&clkev,
>>> +			OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
>>> +	__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
>>> +}
>>> +
>> Am still bit uncomfortable with direct hwmod usage in the suspend/resmue
>> hooks.
>>
>> Jon, Any alternatives you can think of ?
>>
> 
> Jon,
> 
> Any suggestions here?

Sorry completed this missed this!

Unfortunately, I don't have any good suggestions here. However, I am
wondering if the suspend/resume handlers can just be calls to
omap_hwmod_idle/enable and we can remove these __omap_dm_timer_xxxx
calls (I don't think they are needed). Furthermore, my understanding is
this is only needed for AM335x (per the changelog), and so we should not
add suspend/resume handlers for all OMAP2+ based devices.

Cheers
Jon

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 13/18] ARM: OMAP2+: AM33XX: timer: Interchance clkevt and clksrc timers
  2012-12-31 13:07   ` Vaibhav Bedia
@ 2013-01-17 19:09     ` Jon Hunter
  -1 siblings, 0 replies; 148+ messages in thread
From: Jon Hunter @ 2013-01-17 19:09 UTC (permalink / raw)
  To: Vaibhav Bedia
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Paul Walmsley,
	Benoit Cousson, Vaibhav Hiremath, Santosh Shilimkar


On 12/31/2012 07:07 AM, Vaibhav Bedia wrote:
> AM33XX has two timers (DTIMER0/1) in the WKUP domain.
> On GP devices the source of DMTIMER0 is fixed to an
> inaccurate internal 32k RC oscillator and this makes
> the DMTIMER0 practically either as a clocksource or
> as clockevent.
> 
> Currently the timer instance in WKUP domain is used
> as the clockevent and the timer in non-WKUP domain
> as the clocksource. DMTIMER1 in WKUP domain can keep
> running in suspend from a 32K clock fed from external
> OSC and can serve as the persistent clock for the kernel.
> To enable this, interchange the timers used as clocksource
> and clockevent for AM33XX.
> 
> For now a new DT property has been added to allow the timer code
> to select the timer with the right property.
> 
> It has been pointed out by Santosh Shilimkar and Kevin Hilman
> that such a change will result in soc-idle never being achieved
> on AM33XX. There are other reasons why soc-idle does not look
> feasible on AM33XX so for now we go ahead with the interchange
> of the the timers. If at a later point of time we do come up
> with an approach which makes soc-idle possible on AM33XX, this
> can be revisited.
> 
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
> Cc: Tony Lingren <tony@atomide.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Jon Hunter <jon-hunter@ti.com>
> 
> ---
> v1->v2:
> 	Use DT properties for changing the timers
> 
>  .../devicetree/bindings/arm/omap/timer.txt         |    2 ++
>  arch/arm/boot/dts/am33xx.dtsi                      |    1 +
>  arch/arm/mach-omap2/timer.c                        |    6 +++---
>  3 files changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/arm/omap/timer.txt b/Documentation/devicetree/bindings/arm/omap/timer.txt
> index 8732d4d..62d4f2c 100644
> --- a/Documentation/devicetree/bindings/arm/omap/timer.txt
> +++ b/Documentation/devicetree/bindings/arm/omap/timer.txt
> @@ -18,6 +18,8 @@ Optional properties:
>  - ti,timer-pwm: 	Indicates the timer can generate a PWM output.
>  - ti,timer-secure: 	Indicates the timer is reserved on a secure OMAP device
>  			and therefore cannot be used by the kernel.
> +- ti,timer-non-wkup	Indicates the timer is in non-wkup power domain and hence
> +			will lose register context when the power domain transitions

I was hoping that we could avoid adding another property, especially
given that his equivalent to a timer that does not have the
"ti,timer-alwon" property.

>  Example:
>  
> diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
> index 4731748..b4e8bf7 100644
> --- a/arch/arm/boot/dts/am33xx.dtsi
> +++ b/arch/arm/boot/dts/am33xx.dtsi
> @@ -251,6 +251,7 @@
>  			reg = <0x48040000 0x400>;
>  			interrupts = <68>;
>  			ti,hwmods = "timer2";
> +			ti,timer-non-wkup;

Is this is only one not in the wake-up domain?

>  		};
>  
>  		timer3: timer@48042000 {
> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
> index 38f9cbc..cfb3413 100644
> --- a/arch/arm/mach-omap2/timer.c
> +++ b/arch/arm/mach-omap2/timer.c
> @@ -264,7 +264,7 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
>  	int r = 0;
>  
>  	if (of_have_populated_dt()) {
> -		np = omap_get_timer_dt(omap_timer_match, NULL);
> +		np = omap_get_timer_dt(omap_timer_match, property);
>  		if (!np)
>  			return -ENODEV;
>  
> @@ -633,8 +633,8 @@ OMAP_SYS_TIMER(3_gp, gptimer);
>  #endif /* CONFIG_ARCH_OMAP3 */
>  
>  #ifdef CONFIG_SOC_AM33XX
> -OMAP_SYS_GP_TIMER_INIT(3_am33xx, 1, OMAP4_MPU_SOURCE, "ti,timer-alwon",
> -		       2, OMAP4_MPU_SOURCE);
> +OMAP_SYS_GP_TIMER_INIT(3_am33xx, 2, OMAP4_MPU_SOURCE, "ti,timer-non-wkup",
> +		       1, OMAP4_MPU_SOURCE);

It seems to me here that we should specify the property "ti,timer-alwon"
for the clocksource and then no property for the clockevent. Hence, may
be the code needs to be adjusted so that if clockevent or clocksource
can use any timer (ie. no property specified), we look for a timer that
has no "ti-timer-xxxx" properties. This will ensure that if we need a
particular timer for clocksource, which we look for after clockevent, it
will be available.

Cheers
Jon



^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 13/18] ARM: OMAP2+: AM33XX: timer: Interchance clkevt and clksrc timers
@ 2013-01-17 19:09     ` Jon Hunter
  0 siblings, 0 replies; 148+ messages in thread
From: Jon Hunter @ 2013-01-17 19:09 UTC (permalink / raw)
  To: linux-arm-kernel


On 12/31/2012 07:07 AM, Vaibhav Bedia wrote:
> AM33XX has two timers (DTIMER0/1) in the WKUP domain.
> On GP devices the source of DMTIMER0 is fixed to an
> inaccurate internal 32k RC oscillator and this makes
> the DMTIMER0 practically either as a clocksource or
> as clockevent.
> 
> Currently the timer instance in WKUP domain is used
> as the clockevent and the timer in non-WKUP domain
> as the clocksource. DMTIMER1 in WKUP domain can keep
> running in suspend from a 32K clock fed from external
> OSC and can serve as the persistent clock for the kernel.
> To enable this, interchange the timers used as clocksource
> and clockevent for AM33XX.
> 
> For now a new DT property has been added to allow the timer code
> to select the timer with the right property.
> 
> It has been pointed out by Santosh Shilimkar and Kevin Hilman
> that such a change will result in soc-idle never being achieved
> on AM33XX. There are other reasons why soc-idle does not look
> feasible on AM33XX so for now we go ahead with the interchange
> of the the timers. If at a later point of time we do come up
> with an approach which makes soc-idle possible on AM33XX, this
> can be revisited.
> 
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Signed-off-by: Vaibhav Hiremath <hvaibhav@ti.com>
> Cc: Tony Lingren <tony@atomide.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Jon Hunter <jon-hunter@ti.com>
> 
> ---
> v1->v2:
> 	Use DT properties for changing the timers
> 
>  .../devicetree/bindings/arm/omap/timer.txt         |    2 ++
>  arch/arm/boot/dts/am33xx.dtsi                      |    1 +
>  arch/arm/mach-omap2/timer.c                        |    6 +++---
>  3 files changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/Documentation/devicetree/bindings/arm/omap/timer.txt b/Documentation/devicetree/bindings/arm/omap/timer.txt
> index 8732d4d..62d4f2c 100644
> --- a/Documentation/devicetree/bindings/arm/omap/timer.txt
> +++ b/Documentation/devicetree/bindings/arm/omap/timer.txt
> @@ -18,6 +18,8 @@ Optional properties:
>  - ti,timer-pwm: 	Indicates the timer can generate a PWM output.
>  - ti,timer-secure: 	Indicates the timer is reserved on a secure OMAP device
>  			and therefore cannot be used by the kernel.
> +- ti,timer-non-wkup	Indicates the timer is in non-wkup power domain and hence
> +			will lose register context when the power domain transitions

I was hoping that we could avoid adding another property, especially
given that his equivalent to a timer that does not have the
"ti,timer-alwon" property.

>  Example:
>  
> diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi
> index 4731748..b4e8bf7 100644
> --- a/arch/arm/boot/dts/am33xx.dtsi
> +++ b/arch/arm/boot/dts/am33xx.dtsi
> @@ -251,6 +251,7 @@
>  			reg = <0x48040000 0x400>;
>  			interrupts = <68>;
>  			ti,hwmods = "timer2";
> +			ti,timer-non-wkup;

Is this is only one not in the wake-up domain?

>  		};
>  
>  		timer3: timer at 48042000 {
> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
> index 38f9cbc..cfb3413 100644
> --- a/arch/arm/mach-omap2/timer.c
> +++ b/arch/arm/mach-omap2/timer.c
> @@ -264,7 +264,7 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
>  	int r = 0;
>  
>  	if (of_have_populated_dt()) {
> -		np = omap_get_timer_dt(omap_timer_match, NULL);
> +		np = omap_get_timer_dt(omap_timer_match, property);
>  		if (!np)
>  			return -ENODEV;
>  
> @@ -633,8 +633,8 @@ OMAP_SYS_TIMER(3_gp, gptimer);
>  #endif /* CONFIG_ARCH_OMAP3 */
>  
>  #ifdef CONFIG_SOC_AM33XX
> -OMAP_SYS_GP_TIMER_INIT(3_am33xx, 1, OMAP4_MPU_SOURCE, "ti,timer-alwon",
> -		       2, OMAP4_MPU_SOURCE);
> +OMAP_SYS_GP_TIMER_INIT(3_am33xx, 2, OMAP4_MPU_SOURCE, "ti,timer-non-wkup",
> +		       1, OMAP4_MPU_SOURCE);

It seems to me here that we should specify the property "ti,timer-alwon"
for the clocksource and then no property for the clockevent. Hence, may
be the code needs to be adjusted so that if clockevent or clocksource
can use any timer (ie. no property specified), we look for a timer that
has no "ti-timer-xxxx" properties. This will ensure that if we need a
particular timer for clocksource, which we look for after clockevent, it
will be available.

Cheers
Jon

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 12/18] ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent device
  2013-01-17 18:45         ` Jon Hunter
@ 2013-01-18  5:25           ` Santosh Shilimkar
  -1 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-18  5:25 UTC (permalink / raw)
  To: Jon Hunter
  Cc: Bedia, Vaibhav, linux-omap, linux-arm-kernel, tony, khilman,
	Cousson, Benoit, Paul Walmsley, Hiremath, Vaibhav

On Friday 18 January 2013 12:15 AM, Jon Hunter wrote:
>
> On 01/10/2013 10:37 PM, Bedia, Vaibhav wrote:
>> On Tue, Jan 08, 2013 at 20:45:10, Shilimkar, Santosh wrote:
>>> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
>>>> The current OMAP timer code registers two timers -
>>>> one as clocksource and one as clockevent.
>>>> AM33XX has only one usable timer in the WKUP domain
>>>> so one of the timers needs suspend-resume support
>>>> to restore the configuration to pre-suspend state.
>>>>
>>>> commit adc78e6 (timekeeping: Add suspend and resume
>>>> of clock event devices) introduced .suspend and .resume
>>>> callbacks for clock event devices. Leverages these
>>>> callbacks to have AM33XX clockevent timer which is
>>>> in not in WKUP domain to behave properly across system
>>>> suspend.
>>>>
>>>> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
>>>> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>>> Cc: Benoit Cousson <b-cousson@ti.com>
>>>> Cc: Paul Walmsley <paul@pwsan.com>
>>>> Cc: Kevin Hilman <khilman@deeprootsystems.com>
>>>> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
>>>> Cc: Jon Hunter <jon-hunter@ti.com>
>>>> ---
>>>> v1->v2:
>>>> 	Get rid of harcoded timer id.
>>>> 	Note: since a platform device is not created for these timer
>>>> 	instances and because there's very minimal change needed for
>>>> 	restarting the timer a full blown context save and restore
>>>> 	has been skipped.
>>>>
>>>>    arch/arm/mach-omap2/timer.c |   33 +++++++++++++++++++++++++++++++++
>>>>    1 files changed, 33 insertions(+), 0 deletions(-)
>>>>
>>>> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
>>>> index 691aa67..38f9cbc 100644
>>>> --- a/arch/arm/mach-omap2/timer.c
>>>> +++ b/arch/arm/mach-omap2/timer.c
>>>> @@ -128,6 +128,36 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
>>>>    	}
>>>>    }
>>>>
>>>> +static void omap_clkevt_suspend(struct clock_event_device *unused)
>>>> +{
>>>> +	char name[10];
>>>> +	struct omap_hwmod *oh;
>>>> +
>>>> +	sprintf(name, "timer%d", clkev.id);
>>>> +	oh = omap_hwmod_lookup(name);
>>>> +	if (!oh)
>>>> +		return;
>>>> +
>>>> +	__omap_dm_timer_stop(&clkev, 1, clkev.rate);
>>>> +	omap_hwmod_idle(oh);
>>>> +}
>>>> +
>>>> +static void omap_clkevt_resume(struct clock_event_device *unused)
>>>> +{
>>>> +	char name[10];
>>>> +	struct omap_hwmod *oh;
>>>> +
>>>> +	sprintf(name, "timer%d", clkev.id);
>>>> +	oh = omap_hwmod_lookup(name);
>>>> +	if (!oh)
>>>> +		return;
>>>> +
>>>> +	omap_hwmod_enable(oh);
>>>> +	__omap_dm_timer_load_start(&clkev,
>>>> +			OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
>>>> +	__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
>>>> +}
>>>> +
>>> Am still bit uncomfortable with direct hwmod usage in the suspend/resmue
>>> hooks.
>>>
>>> Jon, Any alternatives you can think of ?
>>>
>>
>> Jon,
>>
>> Any suggestions here?
>
> Sorry completed this missed this!
>
> Unfortunately, I don't have any good suggestions here. However, I am
> wondering if the suspend/resume handlers can just be calls to
> omap_hwmod_idle/enable and we can remove these __omap_dm_timer_xxxx
> calls (I don't think they are needed). Furthermore, my understanding is
> this is only needed for AM335x (per the changelog), and so we should not
> add suspend/resume handlers for all OMAP2+ based devices.
>
I agree with the direction.

Regards,
Santosh


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 12/18] ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent device
@ 2013-01-18  5:25           ` Santosh Shilimkar
  0 siblings, 0 replies; 148+ messages in thread
From: Santosh Shilimkar @ 2013-01-18  5:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Friday 18 January 2013 12:15 AM, Jon Hunter wrote:
>
> On 01/10/2013 10:37 PM, Bedia, Vaibhav wrote:
>> On Tue, Jan 08, 2013 at 20:45:10, Shilimkar, Santosh wrote:
>>> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
>>>> The current OMAP timer code registers two timers -
>>>> one as clocksource and one as clockevent.
>>>> AM33XX has only one usable timer in the WKUP domain
>>>> so one of the timers needs suspend-resume support
>>>> to restore the configuration to pre-suspend state.
>>>>
>>>> commit adc78e6 (timekeeping: Add suspend and resume
>>>> of clock event devices) introduced .suspend and .resume
>>>> callbacks for clock event devices. Leverages these
>>>> callbacks to have AM33XX clockevent timer which is
>>>> in not in WKUP domain to behave properly across system
>>>> suspend.
>>>>
>>>> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
>>>> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>>> Cc: Benoit Cousson <b-cousson@ti.com>
>>>> Cc: Paul Walmsley <paul@pwsan.com>
>>>> Cc: Kevin Hilman <khilman@deeprootsystems.com>
>>>> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
>>>> Cc: Jon Hunter <jon-hunter@ti.com>
>>>> ---
>>>> v1->v2:
>>>> 	Get rid of harcoded timer id.
>>>> 	Note: since a platform device is not created for these timer
>>>> 	instances and because there's very minimal change needed for
>>>> 	restarting the timer a full blown context save and restore
>>>> 	has been skipped.
>>>>
>>>>    arch/arm/mach-omap2/timer.c |   33 +++++++++++++++++++++++++++++++++
>>>>    1 files changed, 33 insertions(+), 0 deletions(-)
>>>>
>>>> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
>>>> index 691aa67..38f9cbc 100644
>>>> --- a/arch/arm/mach-omap2/timer.c
>>>> +++ b/arch/arm/mach-omap2/timer.c
>>>> @@ -128,6 +128,36 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
>>>>    	}
>>>>    }
>>>>
>>>> +static void omap_clkevt_suspend(struct clock_event_device *unused)
>>>> +{
>>>> +	char name[10];
>>>> +	struct omap_hwmod *oh;
>>>> +
>>>> +	sprintf(name, "timer%d", clkev.id);
>>>> +	oh = omap_hwmod_lookup(name);
>>>> +	if (!oh)
>>>> +		return;
>>>> +
>>>> +	__omap_dm_timer_stop(&clkev, 1, clkev.rate);
>>>> +	omap_hwmod_idle(oh);
>>>> +}
>>>> +
>>>> +static void omap_clkevt_resume(struct clock_event_device *unused)
>>>> +{
>>>> +	char name[10];
>>>> +	struct omap_hwmod *oh;
>>>> +
>>>> +	sprintf(name, "timer%d", clkev.id);
>>>> +	oh = omap_hwmod_lookup(name);
>>>> +	if (!oh)
>>>> +		return;
>>>> +
>>>> +	omap_hwmod_enable(oh);
>>>> +	__omap_dm_timer_load_start(&clkev,
>>>> +			OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
>>>> +	__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
>>>> +}
>>>> +
>>> Am still bit uncomfortable with direct hwmod usage in the suspend/resmue
>>> hooks.
>>>
>>> Jon, Any alternatives you can think of ?
>>>
>>
>> Jon,
>>
>> Any suggestions here?
>
> Sorry completed this missed this!
>
> Unfortunately, I don't have any good suggestions here. However, I am
> wondering if the suspend/resume handlers can just be calls to
> omap_hwmod_idle/enable and we can remove these __omap_dm_timer_xxxx
> calls (I don't think they are needed). Furthermore, my understanding is
> this is only needed for AM335x (per the changelog), and so we should not
> add suspend/resume handlers for all OMAP2+ based devices.
>
I agree with the direction.

Regards,
Santosh

^ permalink raw reply	[flat|nested] 148+ messages in thread

* RE: [RFC v2 12/18] ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent device
  2013-01-17 18:40     ` Jon Hunter
@ 2013-01-21  7:22       ` Bedia, Vaibhav
  -1 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-21  7:22 UTC (permalink / raw)
  To: Hunter, Jon
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Paul Walmsley,
	Cousson, Benoit, Hiremath, Vaibhav, Shilimkar, Santosh

Hi Jon,

On Fri, Jan 18, 2013 at 00:10:40, Hunter, Jon wrote:
> 
> On 12/31/2012 07:07 AM, Vaibhav Bedia wrote:
> > The current OMAP timer code registers two timers -
> > one as clocksource and one as clockevent.
> > AM33XX has only one usable timer in the WKUP domain
> > so one of the timers needs suspend-resume support
> > to restore the configuration to pre-suspend state.
> > 
> > commit adc78e6 (timekeeping: Add suspend and resume
> > of clock event devices) introduced .suspend and .resume
> > callbacks for clock event devices. Leverages these
> > callbacks to have AM33XX clockevent timer which is
> > in not in WKUP domain to behave properly across system
> > suspend.
> > 
> > Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> > Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > Cc: Benoit Cousson <b-cousson@ti.com>
> > Cc: Paul Walmsley <paul@pwsan.com>
> > Cc: Kevin Hilman <khilman@deeprootsystems.com>
> > Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> > Cc: Jon Hunter <jon-hunter@ti.com>
> > ---
> > v1->v2:
> > 	Get rid of harcoded timer id.
> > 	Note: since a platform device is not created for these timer
> > 	instances and because there's very minimal change needed for
> > 	restarting the timer a full blown context save and restore
> > 	has been skipped.
> > 
> >  arch/arm/mach-omap2/timer.c |   33 +++++++++++++++++++++++++++++++++
> >  1 files changed, 33 insertions(+), 0 deletions(-)
> > 
> > diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
> > index 691aa67..38f9cbc 100644
> > --- a/arch/arm/mach-omap2/timer.c
> > +++ b/arch/arm/mach-omap2/timer.c
> > @@ -128,6 +128,36 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
> >  	}
> >  }
> >  
> > +static void omap_clkevt_suspend(struct clock_event_device *unused)
> > +{
> > +	char name[10];
> > +	struct omap_hwmod *oh;
> > +
> > +	sprintf(name, "timer%d", clkev.id);
> > +	oh = omap_hwmod_lookup(name);
> > +	if (!oh)
> > +		return;
> > +
> > +	__omap_dm_timer_stop(&clkev, 1, clkev.rate);
> 
> I am not sure you need to call __omap_dm_timer_stop() here. This should
> have already been called as timekeeping_suspend() will call
> omap2_gp_timer_set_mode() to shutdown the timer.

You are right, i can drop the call to __omap_dm_timer_stop().

> 
> > +	omap_hwmod_idle(oh);
> > +}
> > +
> > +static void omap_clkevt_resume(struct clock_event_device *unused)
> > +{
> > +	char name[10];
> > +	struct omap_hwmod *oh;
> > +
> > +	sprintf(name, "timer%d", clkev.id);
> > +	oh = omap_hwmod_lookup(name);
> > +	if (!oh)
> > +		return;
> > +
> > +	omap_hwmod_enable(oh);
> > +	__omap_dm_timer_load_start(&clkev,
> > +			OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
> > +	__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
> 
> Similarly here, I am not sure these __omap_dm_timer_xxxx calls are needed.

I went through the code again. __omap_dm_timer_load_start() is invoked
from omap2_gp_timer_set_mode() with the auto-reload flag when setting the
mode to CLOCK_EVT_MODE_PERIODIC and without the auto-reload flag in
omap2_gp_timer_set_next_event(). So looks like this call can be dropped.
But I do need the call to __omap_dm_timer_int_enable() to re-enable the
interrupts from the timer.

> 
> > +}
> > +
> >  static struct clock_event_device clockevent_gpt = {
> >  	.name		= "gp_timer",
> >  	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
> > @@ -135,6 +165,8 @@ static struct clock_event_device clockevent_gpt = {
> >  	.rating		= 300,
> >  	.set_next_event	= omap2_gp_timer_set_next_event,
> >  	.set_mode	= omap2_gp_timer_set_mode,
> > +	.suspend	= omap_clkevt_suspend,
> > +	.resume		= omap_clkevt_resume,
> 
> AFAIK, this is only applicable for AM335x devices and so should not be
> added for all.
> 

Agreed. Will address this in the next version.

> >  };
> >  
> >  static struct property device_disabled = {
> > @@ -323,6 +355,7 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
> >  	int res;
> >  
> >  	clkev.errata = omap_dm_timer_get_errata();
> > +	clkev.id = gptimer_id;
> 
> We should not use gptimer_id anymore. This will go away once the
> migration to dev-tree is completed. You may be better off storing the
> oh_name in the clock_event_device name field and passing to the
> suspend/resume handlers.
> 

Currently the name field in clock_event_device is set to "gp_timer". Should I set
the name in omap2_gp_clockevent_init() based on the gptimer_id?

Regards,
Vaibhav 


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 12/18] ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent device
@ 2013-01-21  7:22       ` Bedia, Vaibhav
  0 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-21  7:22 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Jon,

On Fri, Jan 18, 2013 at 00:10:40, Hunter, Jon wrote:
> 
> On 12/31/2012 07:07 AM, Vaibhav Bedia wrote:
> > The current OMAP timer code registers two timers -
> > one as clocksource and one as clockevent.
> > AM33XX has only one usable timer in the WKUP domain
> > so one of the timers needs suspend-resume support
> > to restore the configuration to pre-suspend state.
> > 
> > commit adc78e6 (timekeeping: Add suspend and resume
> > of clock event devices) introduced .suspend and .resume
> > callbacks for clock event devices. Leverages these
> > callbacks to have AM33XX clockevent timer which is
> > in not in WKUP domain to behave properly across system
> > suspend.
> > 
> > Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> > Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> > Cc: Benoit Cousson <b-cousson@ti.com>
> > Cc: Paul Walmsley <paul@pwsan.com>
> > Cc: Kevin Hilman <khilman@deeprootsystems.com>
> > Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> > Cc: Jon Hunter <jon-hunter@ti.com>
> > ---
> > v1->v2:
> > 	Get rid of harcoded timer id.
> > 	Note: since a platform device is not created for these timer
> > 	instances and because there's very minimal change needed for
> > 	restarting the timer a full blown context save and restore
> > 	has been skipped.
> > 
> >  arch/arm/mach-omap2/timer.c |   33 +++++++++++++++++++++++++++++++++
> >  1 files changed, 33 insertions(+), 0 deletions(-)
> > 
> > diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
> > index 691aa67..38f9cbc 100644
> > --- a/arch/arm/mach-omap2/timer.c
> > +++ b/arch/arm/mach-omap2/timer.c
> > @@ -128,6 +128,36 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
> >  	}
> >  }
> >  
> > +static void omap_clkevt_suspend(struct clock_event_device *unused)
> > +{
> > +	char name[10];
> > +	struct omap_hwmod *oh;
> > +
> > +	sprintf(name, "timer%d", clkev.id);
> > +	oh = omap_hwmod_lookup(name);
> > +	if (!oh)
> > +		return;
> > +
> > +	__omap_dm_timer_stop(&clkev, 1, clkev.rate);
> 
> I am not sure you need to call __omap_dm_timer_stop() here. This should
> have already been called as timekeeping_suspend() will call
> omap2_gp_timer_set_mode() to shutdown the timer.

You are right, i can drop the call to __omap_dm_timer_stop().

> 
> > +	omap_hwmod_idle(oh);
> > +}
> > +
> > +static void omap_clkevt_resume(struct clock_event_device *unused)
> > +{
> > +	char name[10];
> > +	struct omap_hwmod *oh;
> > +
> > +	sprintf(name, "timer%d", clkev.id);
> > +	oh = omap_hwmod_lookup(name);
> > +	if (!oh)
> > +		return;
> > +
> > +	omap_hwmod_enable(oh);
> > +	__omap_dm_timer_load_start(&clkev,
> > +			OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
> > +	__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
> 
> Similarly here, I am not sure these __omap_dm_timer_xxxx calls are needed.

I went through the code again. __omap_dm_timer_load_start() is invoked
from omap2_gp_timer_set_mode() with the auto-reload flag when setting the
mode to CLOCK_EVT_MODE_PERIODIC and without the auto-reload flag in
omap2_gp_timer_set_next_event(). So looks like this call can be dropped.
But I do need the call to __omap_dm_timer_int_enable() to re-enable the
interrupts from the timer.

> 
> > +}
> > +
> >  static struct clock_event_device clockevent_gpt = {
> >  	.name		= "gp_timer",
> >  	.features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
> > @@ -135,6 +165,8 @@ static struct clock_event_device clockevent_gpt = {
> >  	.rating		= 300,
> >  	.set_next_event	= omap2_gp_timer_set_next_event,
> >  	.set_mode	= omap2_gp_timer_set_mode,
> > +	.suspend	= omap_clkevt_suspend,
> > +	.resume		= omap_clkevt_resume,
> 
> AFAIK, this is only applicable for AM335x devices and so should not be
> added for all.
> 

Agreed. Will address this in the next version.

> >  };
> >  
> >  static struct property device_disabled = {
> > @@ -323,6 +355,7 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
> >  	int res;
> >  
> >  	clkev.errata = omap_dm_timer_get_errata();
> > +	clkev.id = gptimer_id;
> 
> We should not use gptimer_id anymore. This will go away once the
> migration to dev-tree is completed. You may be better off storing the
> oh_name in the clock_event_device name field and passing to the
> suspend/resume handlers.
> 

Currently the name field in clock_event_device is set to "gp_timer". Should I set
the name in omap2_gp_clockevent_init() based on the gptimer_id?

Regards,
Vaibhav 

^ permalink raw reply	[flat|nested] 148+ messages in thread

* RE: [RFC v2 12/18] ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent device
  2013-01-18  5:25           ` Santosh Shilimkar
@ 2013-01-21  7:22             ` Bedia, Vaibhav
  -1 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-21  7:22 UTC (permalink / raw)
  To: Shilimkar, Santosh, Hunter, Jon
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Cousson, Benoit,
	Paul Walmsley, Hiremath, Vaibhav

On Fri, Jan 18, 2013 at 10:55:43, Shilimkar, Santosh wrote:
> On Friday 18 January 2013 12:15 AM, Jon Hunter wrote:
> >
> > On 01/10/2013 10:37 PM, Bedia, Vaibhav wrote:
> >> On Tue, Jan 08, 2013 at 20:45:10, Shilimkar, Santosh wrote:
> >>> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> >>>> The current OMAP timer code registers two timers -
> >>>> one as clocksource and one as clockevent.
> >>>> AM33XX has only one usable timer in the WKUP domain
> >>>> so one of the timers needs suspend-resume support
> >>>> to restore the configuration to pre-suspend state.
> >>>>
> >>>> commit adc78e6 (timekeeping: Add suspend and resume
> >>>> of clock event devices) introduced .suspend and .resume
> >>>> callbacks for clock event devices. Leverages these
> >>>> callbacks to have AM33XX clockevent timer which is
> >>>> in not in WKUP domain to behave properly across system
> >>>> suspend.
> >>>>
> >>>> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> >>>> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> >>>> Cc: Benoit Cousson <b-cousson@ti.com>
> >>>> Cc: Paul Walmsley <paul@pwsan.com>
> >>>> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> >>>> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> >>>> Cc: Jon Hunter <jon-hunter@ti.com>
> >>>> ---
> >>>> v1->v2:
> >>>> 	Get rid of harcoded timer id.
> >>>> 	Note: since a platform device is not created for these timer
> >>>> 	instances and because there's very minimal change needed for
> >>>> 	restarting the timer a full blown context save and restore
> >>>> 	has been skipped.
> >>>>
> >>>>    arch/arm/mach-omap2/timer.c |   33 +++++++++++++++++++++++++++++++++
> >>>>    1 files changed, 33 insertions(+), 0 deletions(-)
> >>>>
> >>>> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
> >>>> index 691aa67..38f9cbc 100644
> >>>> --- a/arch/arm/mach-omap2/timer.c
> >>>> +++ b/arch/arm/mach-omap2/timer.c
> >>>> @@ -128,6 +128,36 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
> >>>>    	}
> >>>>    }
> >>>>
> >>>> +static void omap_clkevt_suspend(struct clock_event_device *unused)
> >>>> +{
> >>>> +	char name[10];
> >>>> +	struct omap_hwmod *oh;
> >>>> +
> >>>> +	sprintf(name, "timer%d", clkev.id);
> >>>> +	oh = omap_hwmod_lookup(name);
> >>>> +	if (!oh)
> >>>> +		return;
> >>>> +
> >>>> +	__omap_dm_timer_stop(&clkev, 1, clkev.rate);
> >>>> +	omap_hwmod_idle(oh);
> >>>> +}
> >>>> +
> >>>> +static void omap_clkevt_resume(struct clock_event_device *unused)
> >>>> +{
> >>>> +	char name[10];
> >>>> +	struct omap_hwmod *oh;
> >>>> +
> >>>> +	sprintf(name, "timer%d", clkev.id);
> >>>> +	oh = omap_hwmod_lookup(name);
> >>>> +	if (!oh)
> >>>> +		return;
> >>>> +
> >>>> +	omap_hwmod_enable(oh);
> >>>> +	__omap_dm_timer_load_start(&clkev,
> >>>> +			OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
> >>>> +	__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
> >>>> +}
> >>>> +
> >>> Am still bit uncomfortable with direct hwmod usage in the suspend/resmue
> >>> hooks.
> >>>
> >>> Jon, Any alternatives you can think of ?
> >>>
> >>
> >> Jon,
> >>
> >> Any suggestions here?
> >
> > Sorry completed this missed this!
> >
> > Unfortunately, I don't have any good suggestions here. However, I am
> > wondering if the suspend/resume handlers can just be calls to
> > omap_hwmod_idle/enable and we can remove these __omap_dm_timer_xxxx
> > calls (I don't think they are needed). Furthermore, my understanding is
> > this is only needed for AM335x (per the changelog), and so we should not
> > add suspend/resume handlers for all OMAP2+ based devices.
> >
> I agree with the direction.
> 

I need to retain the call to enable the interrupt but the others can be dropped.
Will take care of this and the comment on invoking the suspend/resume handlers
only for AM335x in the next version.

Regards,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 12/18] ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent device
@ 2013-01-21  7:22             ` Bedia, Vaibhav
  0 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-21  7:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jan 18, 2013 at 10:55:43, Shilimkar, Santosh wrote:
> On Friday 18 January 2013 12:15 AM, Jon Hunter wrote:
> >
> > On 01/10/2013 10:37 PM, Bedia, Vaibhav wrote:
> >> On Tue, Jan 08, 2013 at 20:45:10, Shilimkar, Santosh wrote:
> >>> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
> >>>> The current OMAP timer code registers two timers -
> >>>> one as clocksource and one as clockevent.
> >>>> AM33XX has only one usable timer in the WKUP domain
> >>>> so one of the timers needs suspend-resume support
> >>>> to restore the configuration to pre-suspend state.
> >>>>
> >>>> commit adc78e6 (timekeeping: Add suspend and resume
> >>>> of clock event devices) introduced .suspend and .resume
> >>>> callbacks for clock event devices. Leverages these
> >>>> callbacks to have AM33XX clockevent timer which is
> >>>> in not in WKUP domain to behave properly across system
> >>>> suspend.
> >>>>
> >>>> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> >>>> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> >>>> Cc: Benoit Cousson <b-cousson@ti.com>
> >>>> Cc: Paul Walmsley <paul@pwsan.com>
> >>>> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> >>>> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> >>>> Cc: Jon Hunter <jon-hunter@ti.com>
> >>>> ---
> >>>> v1->v2:
> >>>> 	Get rid of harcoded timer id.
> >>>> 	Note: since a platform device is not created for these timer
> >>>> 	instances and because there's very minimal change needed for
> >>>> 	restarting the timer a full blown context save and restore
> >>>> 	has been skipped.
> >>>>
> >>>>    arch/arm/mach-omap2/timer.c |   33 +++++++++++++++++++++++++++++++++
> >>>>    1 files changed, 33 insertions(+), 0 deletions(-)
> >>>>
> >>>> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
> >>>> index 691aa67..38f9cbc 100644
> >>>> --- a/arch/arm/mach-omap2/timer.c
> >>>> +++ b/arch/arm/mach-omap2/timer.c
> >>>> @@ -128,6 +128,36 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
> >>>>    	}
> >>>>    }
> >>>>
> >>>> +static void omap_clkevt_suspend(struct clock_event_device *unused)
> >>>> +{
> >>>> +	char name[10];
> >>>> +	struct omap_hwmod *oh;
> >>>> +
> >>>> +	sprintf(name, "timer%d", clkev.id);
> >>>> +	oh = omap_hwmod_lookup(name);
> >>>> +	if (!oh)
> >>>> +		return;
> >>>> +
> >>>> +	__omap_dm_timer_stop(&clkev, 1, clkev.rate);
> >>>> +	omap_hwmod_idle(oh);
> >>>> +}
> >>>> +
> >>>> +static void omap_clkevt_resume(struct clock_event_device *unused)
> >>>> +{
> >>>> +	char name[10];
> >>>> +	struct omap_hwmod *oh;
> >>>> +
> >>>> +	sprintf(name, "timer%d", clkev.id);
> >>>> +	oh = omap_hwmod_lookup(name);
> >>>> +	if (!oh)
> >>>> +		return;
> >>>> +
> >>>> +	omap_hwmod_enable(oh);
> >>>> +	__omap_dm_timer_load_start(&clkev,
> >>>> +			OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
> >>>> +	__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
> >>>> +}
> >>>> +
> >>> Am still bit uncomfortable with direct hwmod usage in the suspend/resmue
> >>> hooks.
> >>>
> >>> Jon, Any alternatives you can think of ?
> >>>
> >>
> >> Jon,
> >>
> >> Any suggestions here?
> >
> > Sorry completed this missed this!
> >
> > Unfortunately, I don't have any good suggestions here. However, I am
> > wondering if the suspend/resume handlers can just be calls to
> > omap_hwmod_idle/enable and we can remove these __omap_dm_timer_xxxx
> > calls (I don't think they are needed). Furthermore, my understanding is
> > this is only needed for AM335x (per the changelog), and so we should not
> > add suspend/resume handlers for all OMAP2+ based devices.
> >
> I agree with the direction.
> 

I need to retain the call to enable the interrupt but the others can be dropped.
Will take care of this and the comment on invoking the suspend/resume handlers
only for AM335x in the next version.

Regards,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* RE: [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support
  2013-01-17 14:27     ` Peter Korsgaard
@ 2013-01-21 10:37       ` Bedia, Vaibhav
  -1 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-21 10:37 UTC (permalink / raw)
  To: Peter Korsgaard
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Shilimkar, Santosh,
	Cousson, Benoit, Paul Walmsley

Hi Peter,

On Thu, Jan 17, 2013 at 19:57:20, Peter Korsgaard wrote:
> >>>>> "V" == Vaibhav Bedia <vaibhav.bedia@ti.com> writes:
> 
> Hi,
> 
>  V> +static void am33xx_pm_firmware_cb(const struct firmware *fw, void *context)
>  V> +{
>  V> +	struct wkup_m3_context *wkup_m3_context = context;
>  V> +	struct platform_device *pdev = to_platform_device(wkup_m3_context->dev);
>  V> +	int ret = 0;
>  V> +
>  V> +	/* no firmware found */
>  V> +	if (!fw) {
>  V> +		dev_err(wkup_m3_context->dev, "request_firmware failed\n");
>  V> +		goto err;
>  V> +	}
>  V> +
>  V> +	memcpy((void *)wkup_m3_context->code, fw->data, fw->size);
> 
> A size check would be good. I don't know much about the finer details
> about the m3 and how it is connected, but don't you need to ensure data
> is flushed before resetting the m3?
> 

Will add the reg property in the next version. The wkup-m3 memory is coming via
ioremap() so AFAIK it should be ok. I realized that I do need to replace the memcpy()
with memcpy_toio() here.

Thanks,
Vaibhav


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support
@ 2013-01-21 10:37       ` Bedia, Vaibhav
  0 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-21 10:37 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Peter,

On Thu, Jan 17, 2013 at 19:57:20, Peter Korsgaard wrote:
> >>>>> "V" == Vaibhav Bedia <vaibhav.bedia@ti.com> writes:
> 
> Hi,
> 
>  V> +static void am33xx_pm_firmware_cb(const struct firmware *fw, void *context)
>  V> +{
>  V> +	struct wkup_m3_context *wkup_m3_context = context;
>  V> +	struct platform_device *pdev = to_platform_device(wkup_m3_context->dev);
>  V> +	int ret = 0;
>  V> +
>  V> +	/* no firmware found */
>  V> +	if (!fw) {
>  V> +		dev_err(wkup_m3_context->dev, "request_firmware failed\n");
>  V> +		goto err;
>  V> +	}
>  V> +
>  V> +	memcpy((void *)wkup_m3_context->code, fw->data, fw->size);
> 
> A size check would be good. I don't know much about the finer details
> about the m3 and how it is connected, but don't you need to ensure data
> is flushed before resetting the m3?
> 

Will add the reg property in the next version. The wkup-m3 memory is coming via
ioremap() so AFAIK it should be ok. I realized that I do need to replace the memcpy()
with memcpy_toio() here.

Thanks,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support
  2013-01-21 10:37       ` Bedia, Vaibhav
@ 2013-01-22 12:50         ` Peter Korsgaard
  -1 siblings, 0 replies; 148+ messages in thread
From: Peter Korsgaard @ 2013-01-22 12:50 UTC (permalink / raw)
  To: Bedia, Vaibhav
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Shilimkar, Santosh,
	Cousson, Benoit, Paul Walmsley

>>>>> "V" == Bedia, Vaibhav <vaibhav.bedia@ti.com> writes:

Hi,

 V> +	memcpy((void *)wkup_m3_context->code, fw->data, fw->size);
 >> 
 >> A size check would be good. I don't know much about the finer details
 >> about the m3 and how it is connected, but don't you need to ensure data
 >> is flushed before resetting the m3?
 >> 

 V> Will add the reg property in the next version. The wkup-m3 memory is
 V> coming via ioremap() so AFAIK it should be ok. I realized that I do
 V> need to replace the memcpy() with memcpy_toio() here.

Ok, thanks.

-- 
Bye, Peter Korsgaard

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support
@ 2013-01-22 12:50         ` Peter Korsgaard
  0 siblings, 0 replies; 148+ messages in thread
From: Peter Korsgaard @ 2013-01-22 12:50 UTC (permalink / raw)
  To: linux-arm-kernel

>>>>> "V" == Bedia, Vaibhav <vaibhav.bedia@ti.com> writes:

Hi,

 V> +	memcpy((void *)wkup_m3_context->code, fw->data, fw->size);
 >> 
 >> A size check would be good. I don't know much about the finer details
 >> about the m3 and how it is connected, but don't you need to ensure data
 >> is flushed before resetting the m3?
 >> 

 V> Will add the reg property in the next version. The wkup-m3 memory is
 V> coming via ioremap() so AFAIK it should be ok. I realized that I do
 V> need to replace the memcpy() with memcpy_toio() here.

Ok, thanks.

-- 
Bye, Peter Korsgaard

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 13/18] ARM: OMAP2+: AM33XX: timer: Interchance clkevt and clksrc timers
  2012-12-31 13:07   ` Vaibhav Bedia
@ 2013-01-24 22:30     ` Jon Hunter
  -1 siblings, 0 replies; 148+ messages in thread
From: Jon Hunter @ 2013-01-24 22:30 UTC (permalink / raw)
  To: Vaibhav Bedia
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Paul Walmsley,
	Benoit Cousson, Vaibhav Hiremath, Santosh Shilimkar

Hi Vaibhav,

On 12/31/2012 07:07 AM, Vaibhav Bedia wrote:
> AM33XX has two timers (DTIMER0/1) in the WKUP domain.
> On GP devices the source of DMTIMER0 is fixed to an
> inaccurate internal 32k RC oscillator and this makes
> the DMTIMER0 practically either as a clocksource or
> as clockevent.
> 
> Currently the timer instance in WKUP domain is used
> as the clockevent and the timer in non-WKUP domain
> as the clocksource. DMTIMER1 in WKUP domain can keep
> running in suspend from a 32K clock fed from external
> OSC and can serve as the persistent clock for the kernel.
> To enable this, interchange the timers used as clocksource
> and clockevent for AM33XX.

I have been thinking about this some more. In the case where we are
using gptimers for both clock-events and clock-source (on both AM33xx
and OMAP) and I am wondering if it makes sense to switch the timers so
that we use the always-on timer for clock-source and a different one
from clock-events.

For OMAP, if we are not using the 32k-sync for clock-source, then we are
never going to achieve low power states during idle as we will always
have one gptimer running. And in this case, to your point below, it
would be better to use the always-on for clock-source so that in suspend
we can at least hit low power states and maintain time.

> For now a new DT property has been added to allow the timer code
> to select the timer with the right property.
> 
> It has been pointed out by Santosh Shilimkar and Kevin Hilman
> that such a change will result in soc-idle never being achieved
> on AM33XX. There are other reasons why soc-idle does not look
> feasible on AM33XX so for now we go ahead with the interchange
> of the the timers. If at a later point of time we do come up
> with an approach which makes soc-idle possible on AM33XX, this
> can be revisited.

Right, but this would also be true for OMAP if we don't use the 32k-sync
as we only have one gptimer in the wake-up domain.

Cheers
Jon

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 13/18] ARM: OMAP2+: AM33XX: timer: Interchance clkevt and clksrc timers
@ 2013-01-24 22:30     ` Jon Hunter
  0 siblings, 0 replies; 148+ messages in thread
From: Jon Hunter @ 2013-01-24 22:30 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Vaibhav,

On 12/31/2012 07:07 AM, Vaibhav Bedia wrote:
> AM33XX has two timers (DTIMER0/1) in the WKUP domain.
> On GP devices the source of DMTIMER0 is fixed to an
> inaccurate internal 32k RC oscillator and this makes
> the DMTIMER0 practically either as a clocksource or
> as clockevent.
> 
> Currently the timer instance in WKUP domain is used
> as the clockevent and the timer in non-WKUP domain
> as the clocksource. DMTIMER1 in WKUP domain can keep
> running in suspend from a 32K clock fed from external
> OSC and can serve as the persistent clock for the kernel.
> To enable this, interchange the timers used as clocksource
> and clockevent for AM33XX.

I have been thinking about this some more. In the case where we are
using gptimers for both clock-events and clock-source (on both AM33xx
and OMAP) and I am wondering if it makes sense to switch the timers so
that we use the always-on timer for clock-source and a different one
from clock-events.

For OMAP, if we are not using the 32k-sync for clock-source, then we are
never going to achieve low power states during idle as we will always
have one gptimer running. And in this case, to your point below, it
would be better to use the always-on for clock-source so that in suspend
we can at least hit low power states and maintain time.

> For now a new DT property has been added to allow the timer code
> to select the timer with the right property.
> 
> It has been pointed out by Santosh Shilimkar and Kevin Hilman
> that such a change will result in soc-idle never being achieved
> on AM33XX. There are other reasons why soc-idle does not look
> feasible on AM33XX so for now we go ahead with the interchange
> of the the timers. If at a later point of time we do come up
> with an approach which makes soc-idle possible on AM33XX, this
> can be revisited.

Right, but this would also be true for OMAP if we don't use the 32k-sync
as we only have one gptimer in the wake-up domain.

Cheers
Jon

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 12/18] ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent device
  2013-01-21  7:22             ` Bedia, Vaibhav
@ 2013-01-30 17:46               ` Jon Hunter
  -1 siblings, 0 replies; 148+ messages in thread
From: Jon Hunter @ 2013-01-30 17:46 UTC (permalink / raw)
  To: Bedia, Vaibhav
  Cc: Shilimkar, Santosh, linux-omap, linux-arm-kernel, tony, khilman,
	Cousson, Benoit, Paul Walmsley, Hiremath, Vaibhav


On 01/21/2013 01:22 AM, Bedia, Vaibhav wrote:
> On Fri, Jan 18, 2013 at 10:55:43, Shilimkar, Santosh wrote:
>> On Friday 18 January 2013 12:15 AM, Jon Hunter wrote:
>>>
>>> On 01/10/2013 10:37 PM, Bedia, Vaibhav wrote:
>>>> On Tue, Jan 08, 2013 at 20:45:10, Shilimkar, Santosh wrote:
>>>>> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
>>>>>> The current OMAP timer code registers two timers -
>>>>>> one as clocksource and one as clockevent.
>>>>>> AM33XX has only one usable timer in the WKUP domain
>>>>>> so one of the timers needs suspend-resume support
>>>>>> to restore the configuration to pre-suspend state.
>>>>>>
>>>>>> commit adc78e6 (timekeeping: Add suspend and resume
>>>>>> of clock event devices) introduced .suspend and .resume
>>>>>> callbacks for clock event devices. Leverages these
>>>>>> callbacks to have AM33XX clockevent timer which is
>>>>>> in not in WKUP domain to behave properly across system
>>>>>> suspend.
>>>>>>
>>>>>> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
>>>>>> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>>>>> Cc: Benoit Cousson <b-cousson@ti.com>
>>>>>> Cc: Paul Walmsley <paul@pwsan.com>
>>>>>> Cc: Kevin Hilman <khilman@deeprootsystems.com>
>>>>>> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
>>>>>> Cc: Jon Hunter <jon-hunter@ti.com>
>>>>>> ---
>>>>>> v1->v2:
>>>>>> 	Get rid of harcoded timer id.
>>>>>> 	Note: since a platform device is not created for these timer
>>>>>> 	instances and because there's very minimal change needed for
>>>>>> 	restarting the timer a full blown context save and restore
>>>>>> 	has been skipped.
>>>>>>
>>>>>>    arch/arm/mach-omap2/timer.c |   33 +++++++++++++++++++++++++++++++++
>>>>>>    1 files changed, 33 insertions(+), 0 deletions(-)
>>>>>>
>>>>>> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
>>>>>> index 691aa67..38f9cbc 100644
>>>>>> --- a/arch/arm/mach-omap2/timer.c
>>>>>> +++ b/arch/arm/mach-omap2/timer.c
>>>>>> @@ -128,6 +128,36 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
>>>>>>    	}
>>>>>>    }
>>>>>>
>>>>>> +static void omap_clkevt_suspend(struct clock_event_device *unused)
>>>>>> +{
>>>>>> +	char name[10];
>>>>>> +	struct omap_hwmod *oh;
>>>>>> +
>>>>>> +	sprintf(name, "timer%d", clkev.id);
>>>>>> +	oh = omap_hwmod_lookup(name);
>>>>>> +	if (!oh)
>>>>>> +		return;
>>>>>> +
>>>>>> +	__omap_dm_timer_stop(&clkev, 1, clkev.rate);
>>>>>> +	omap_hwmod_idle(oh);
>>>>>> +}
>>>>>> +
>>>>>> +static void omap_clkevt_resume(struct clock_event_device *unused)
>>>>>> +{
>>>>>> +	char name[10];
>>>>>> +	struct omap_hwmod *oh;
>>>>>> +
>>>>>> +	sprintf(name, "timer%d", clkev.id);
>>>>>> +	oh = omap_hwmod_lookup(name);
>>>>>> +	if (!oh)
>>>>>> +		return;
>>>>>> +
>>>>>> +	omap_hwmod_enable(oh);
>>>>>> +	__omap_dm_timer_load_start(&clkev,
>>>>>> +			OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
>>>>>> +	__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
>>>>>> +}
>>>>>> +
>>>>> Am still bit uncomfortable with direct hwmod usage in the suspend/resmue
>>>>> hooks.
>>>>>
>>>>> Jon, Any alternatives you can think of ?
>>>>>
>>>>
>>>> Jon,
>>>>
>>>> Any suggestions here?
>>>
>>> Sorry completed this missed this!
>>>
>>> Unfortunately, I don't have any good suggestions here. However, I am
>>> wondering if the suspend/resume handlers can just be calls to
>>> omap_hwmod_idle/enable and we can remove these __omap_dm_timer_xxxx
>>> calls (I don't think they are needed). Furthermore, my understanding is
>>> this is only needed for AM335x (per the changelog), and so we should not
>>> add suspend/resume handlers for all OMAP2+ based devices.
>>>
>> I agree with the direction.
>>
> 
> I need to retain the call to enable the interrupt but the others can be dropped.
> Will take care of this and the comment on invoking the suspend/resume handlers
> only for AM335x in the next version.

Ok fair enough. By the way, I posted a patch today [1] that will use the
hwmod name as the clockevent timer name. Care to try on top of that
patch and then we can eliminate the sprintf.

Cheers
Jon

[1] http://www.spinics.net/lists/arm-kernel/msg221262.html


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 12/18] ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent device
@ 2013-01-30 17:46               ` Jon Hunter
  0 siblings, 0 replies; 148+ messages in thread
From: Jon Hunter @ 2013-01-30 17:46 UTC (permalink / raw)
  To: linux-arm-kernel


On 01/21/2013 01:22 AM, Bedia, Vaibhav wrote:
> On Fri, Jan 18, 2013 at 10:55:43, Shilimkar, Santosh wrote:
>> On Friday 18 January 2013 12:15 AM, Jon Hunter wrote:
>>>
>>> On 01/10/2013 10:37 PM, Bedia, Vaibhav wrote:
>>>> On Tue, Jan 08, 2013 at 20:45:10, Shilimkar, Santosh wrote:
>>>>> On Monday 31 December 2012 06:37 PM, Vaibhav Bedia wrote:
>>>>>> The current OMAP timer code registers two timers -
>>>>>> one as clocksource and one as clockevent.
>>>>>> AM33XX has only one usable timer in the WKUP domain
>>>>>> so one of the timers needs suspend-resume support
>>>>>> to restore the configuration to pre-suspend state.
>>>>>>
>>>>>> commit adc78e6 (timekeeping: Add suspend and resume
>>>>>> of clock event devices) introduced .suspend and .resume
>>>>>> callbacks for clock event devices. Leverages these
>>>>>> callbacks to have AM33XX clockevent timer which is
>>>>>> in not in WKUP domain to behave properly across system
>>>>>> suspend.
>>>>>>
>>>>>> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
>>>>>> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
>>>>>> Cc: Benoit Cousson <b-cousson@ti.com>
>>>>>> Cc: Paul Walmsley <paul@pwsan.com>
>>>>>> Cc: Kevin Hilman <khilman@deeprootsystems.com>
>>>>>> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
>>>>>> Cc: Jon Hunter <jon-hunter@ti.com>
>>>>>> ---
>>>>>> v1->v2:
>>>>>> 	Get rid of harcoded timer id.
>>>>>> 	Note: since a platform device is not created for these timer
>>>>>> 	instances and because there's very minimal change needed for
>>>>>> 	restarting the timer a full blown context save and restore
>>>>>> 	has been skipped.
>>>>>>
>>>>>>    arch/arm/mach-omap2/timer.c |   33 +++++++++++++++++++++++++++++++++
>>>>>>    1 files changed, 33 insertions(+), 0 deletions(-)
>>>>>>
>>>>>> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
>>>>>> index 691aa67..38f9cbc 100644
>>>>>> --- a/arch/arm/mach-omap2/timer.c
>>>>>> +++ b/arch/arm/mach-omap2/timer.c
>>>>>> @@ -128,6 +128,36 @@ static void omap2_gp_timer_set_mode(enum clock_event_mode mode,
>>>>>>    	}
>>>>>>    }
>>>>>>
>>>>>> +static void omap_clkevt_suspend(struct clock_event_device *unused)
>>>>>> +{
>>>>>> +	char name[10];
>>>>>> +	struct omap_hwmod *oh;
>>>>>> +
>>>>>> +	sprintf(name, "timer%d", clkev.id);
>>>>>> +	oh = omap_hwmod_lookup(name);
>>>>>> +	if (!oh)
>>>>>> +		return;
>>>>>> +
>>>>>> +	__omap_dm_timer_stop(&clkev, 1, clkev.rate);
>>>>>> +	omap_hwmod_idle(oh);
>>>>>> +}
>>>>>> +
>>>>>> +static void omap_clkevt_resume(struct clock_event_device *unused)
>>>>>> +{
>>>>>> +	char name[10];
>>>>>> +	struct omap_hwmod *oh;
>>>>>> +
>>>>>> +	sprintf(name, "timer%d", clkev.id);
>>>>>> +	oh = omap_hwmod_lookup(name);
>>>>>> +	if (!oh)
>>>>>> +		return;
>>>>>> +
>>>>>> +	omap_hwmod_enable(oh);
>>>>>> +	__omap_dm_timer_load_start(&clkev,
>>>>>> +			OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR, 0, 1);
>>>>>> +	__omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW);
>>>>>> +}
>>>>>> +
>>>>> Am still bit uncomfortable with direct hwmod usage in the suspend/resmue
>>>>> hooks.
>>>>>
>>>>> Jon, Any alternatives you can think of ?
>>>>>
>>>>
>>>> Jon,
>>>>
>>>> Any suggestions here?
>>>
>>> Sorry completed this missed this!
>>>
>>> Unfortunately, I don't have any good suggestions here. However, I am
>>> wondering if the suspend/resume handlers can just be calls to
>>> omap_hwmod_idle/enable and we can remove these __omap_dm_timer_xxxx
>>> calls (I don't think they are needed). Furthermore, my understanding is
>>> this is only needed for AM335x (per the changelog), and so we should not
>>> add suspend/resume handlers for all OMAP2+ based devices.
>>>
>> I agree with the direction.
>>
> 
> I need to retain the call to enable the interrupt but the others can be dropped.
> Will take care of this and the comment on invoking the suspend/resume handlers
> only for AM335x in the next version.

Ok fair enough. By the way, I posted a patch today [1] that will use the
hwmod name as the clockevent timer name. Care to try on top of that
patch and then we can eliminate the sprintf.

Cheers
Jon

[1] http://www.spinics.net/lists/arm-kernel/msg221262.html

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 13/18] ARM: OMAP2+: AM33XX: timer: Interchance clkevt and clksrc timers
  2013-01-24 22:30     ` Jon Hunter
@ 2013-01-30 17:48       ` Jon Hunter
  -1 siblings, 0 replies; 148+ messages in thread
From: Jon Hunter @ 2013-01-30 17:48 UTC (permalink / raw)
  To: Vaibhav Bedia
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Paul Walmsley,
	Benoit Cousson, Vaibhav Hiremath, Santosh Shilimkar


On 01/24/2013 04:30 PM, Jon Hunter wrote:
> Hi Vaibhav,
> 
> On 12/31/2012 07:07 AM, Vaibhav Bedia wrote:
>> AM33XX has two timers (DTIMER0/1) in the WKUP domain.
>> On GP devices the source of DMTIMER0 is fixed to an
>> inaccurate internal 32k RC oscillator and this makes
>> the DMTIMER0 practically either as a clocksource or
>> as clockevent.
>>
>> Currently the timer instance in WKUP domain is used
>> as the clockevent and the timer in non-WKUP domain
>> as the clocksource. DMTIMER1 in WKUP domain can keep
>> running in suspend from a 32K clock fed from external
>> OSC and can serve as the persistent clock for the kernel.
>> To enable this, interchange the timers used as clocksource
>> and clockevent for AM33XX.
> 
> I have been thinking about this some more. In the case where we are
> using gptimers for both clock-events and clock-source (on both AM33xx
> and OMAP) and I am wondering if it makes sense to switch the timers so
> that we use the always-on timer for clock-source and a different one
> from clock-events.
> 
> For OMAP, if we are not using the 32k-sync for clock-source, then we are
> never going to achieve low power states during idle as we will always
> have one gptimer running. And in this case, to your point below, it
> would be better to use the always-on for clock-source so that in suspend
> we can at least hit low power states and maintain time.

I have posted a patch today [1] that I hope will address this issue for
you. Can you give that a try?

Cheers
Jon

[1] http://www.spinics.net/lists/arm-kernel/msg221265.html

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 13/18] ARM: OMAP2+: AM33XX: timer: Interchance clkevt and clksrc timers
@ 2013-01-30 17:48       ` Jon Hunter
  0 siblings, 0 replies; 148+ messages in thread
From: Jon Hunter @ 2013-01-30 17:48 UTC (permalink / raw)
  To: linux-arm-kernel


On 01/24/2013 04:30 PM, Jon Hunter wrote:
> Hi Vaibhav,
> 
> On 12/31/2012 07:07 AM, Vaibhav Bedia wrote:
>> AM33XX has two timers (DTIMER0/1) in the WKUP domain.
>> On GP devices the source of DMTIMER0 is fixed to an
>> inaccurate internal 32k RC oscillator and this makes
>> the DMTIMER0 practically either as a clocksource or
>> as clockevent.
>>
>> Currently the timer instance in WKUP domain is used
>> as the clockevent and the timer in non-WKUP domain
>> as the clocksource. DMTIMER1 in WKUP domain can keep
>> running in suspend from a 32K clock fed from external
>> OSC and can serve as the persistent clock for the kernel.
>> To enable this, interchange the timers used as clocksource
>> and clockevent for AM33XX.
> 
> I have been thinking about this some more. In the case where we are
> using gptimers for both clock-events and clock-source (on both AM33xx
> and OMAP) and I am wondering if it makes sense to switch the timers so
> that we use the always-on timer for clock-source and a different one
> from clock-events.
> 
> For OMAP, if we are not using the 32k-sync for clock-source, then we are
> never going to achieve low power states during idle as we will always
> have one gptimer running. And in this case, to your point below, it
> would be better to use the always-on for clock-source so that in suspend
> we can at least hit low power states and maintain time.

I have posted a patch today [1] that I hope will address this issue for
you. Can you give that a try?

Cheers
Jon

[1] http://www.spinics.net/lists/arm-kernel/msg221265.html

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 13/18] ARM: OMAP2+: AM33XX: timer: Interchance clkevt and clksrc timers
  2013-01-30 17:48       ` Jon Hunter
@ 2013-01-30 17:49         ` Jon Hunter
  -1 siblings, 0 replies; 148+ messages in thread
From: Jon Hunter @ 2013-01-30 17:49 UTC (permalink / raw)
  To: Vaibhav Bedia
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Paul Walmsley,
	Benoit Cousson, Vaibhav Hiremath, Santosh Shilimkar


On 01/30/2013 11:48 AM, Jon Hunter wrote:
> 
> On 01/24/2013 04:30 PM, Jon Hunter wrote:
>> Hi Vaibhav,
>>
>> On 12/31/2012 07:07 AM, Vaibhav Bedia wrote:
>>> AM33XX has two timers (DTIMER0/1) in the WKUP domain.
>>> On GP devices the source of DMTIMER0 is fixed to an
>>> inaccurate internal 32k RC oscillator and this makes
>>> the DMTIMER0 practically either as a clocksource or
>>> as clockevent.
>>>
>>> Currently the timer instance in WKUP domain is used
>>> as the clockevent and the timer in non-WKUP domain
>>> as the clocksource. DMTIMER1 in WKUP domain can keep
>>> running in suspend from a 32K clock fed from external
>>> OSC and can serve as the persistent clock for the kernel.
>>> To enable this, interchange the timers used as clocksource
>>> and clockevent for AM33XX.
>>
>> I have been thinking about this some more. In the case where we are
>> using gptimers for both clock-events and clock-source (on both AM33xx
>> and OMAP) and I am wondering if it makes sense to switch the timers so
>> that we use the always-on timer for clock-source and a different one
>> from clock-events.
>>
>> For OMAP, if we are not using the 32k-sync for clock-source, then we are
>> never going to achieve low power states during idle as we will always
>> have one gptimer running. And in this case, to your point below, it
>> would be better to use the always-on for clock-source so that in suspend
>> we can at least hit low power states and maintain time.
> 
> I have posted a patch today [1] that I hope will address this issue for
> you. Can you give that a try?

By the way, this need to be applied on top of the fix I sent yesterday
to pass the property.

Cheers
Jon

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 13/18] ARM: OMAP2+: AM33XX: timer: Interchance clkevt and clksrc timers
@ 2013-01-30 17:49         ` Jon Hunter
  0 siblings, 0 replies; 148+ messages in thread
From: Jon Hunter @ 2013-01-30 17:49 UTC (permalink / raw)
  To: linux-arm-kernel


On 01/30/2013 11:48 AM, Jon Hunter wrote:
> 
> On 01/24/2013 04:30 PM, Jon Hunter wrote:
>> Hi Vaibhav,
>>
>> On 12/31/2012 07:07 AM, Vaibhav Bedia wrote:
>>> AM33XX has two timers (DTIMER0/1) in the WKUP domain.
>>> On GP devices the source of DMTIMER0 is fixed to an
>>> inaccurate internal 32k RC oscillator and this makes
>>> the DMTIMER0 practically either as a clocksource or
>>> as clockevent.
>>>
>>> Currently the timer instance in WKUP domain is used
>>> as the clockevent and the timer in non-WKUP domain
>>> as the clocksource. DMTIMER1 in WKUP domain can keep
>>> running in suspend from a 32K clock fed from external
>>> OSC and can serve as the persistent clock for the kernel.
>>> To enable this, interchange the timers used as clocksource
>>> and clockevent for AM33XX.
>>
>> I have been thinking about this some more. In the case where we are
>> using gptimers for both clock-events and clock-source (on both AM33xx
>> and OMAP) and I am wondering if it makes sense to switch the timers so
>> that we use the always-on timer for clock-source and a different one
>> from clock-events.
>>
>> For OMAP, if we are not using the 32k-sync for clock-source, then we are
>> never going to achieve low power states during idle as we will always
>> have one gptimer running. And in this case, to your point below, it
>> would be better to use the always-on for clock-source so that in suspend
>> we can at least hit low power states and maintain time.
> 
> I have posted a patch today [1] that I hope will address this issue for
> you. Can you give that a try?

By the way, this need to be applied on top of the fix I sent yesterday
to pass the property.

Cheers
Jon

^ permalink raw reply	[flat|nested] 148+ messages in thread

* RE: [RFC v2 12/18] ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent device
  2013-01-30 17:46               ` Jon Hunter
@ 2013-01-31 11:17                 ` Bedia, Vaibhav
  -1 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-31 11:17 UTC (permalink / raw)
  To: Hunter, Jon
  Cc: Shilimkar, Santosh, linux-omap, linux-arm-kernel, tony, khilman,
	Cousson, Benoit, Paul Walmsley, Hiremath, Vaibhav

On Wed, Jan 30, 2013 at 23:16:34, Hunter, Jon wrote:
> 
> Ok fair enough. By the way, I posted a patch today [1] that will use the
> hwmod name as the clockevent timer name. Care to try on top of that
> patch and then we can eliminate the sprintf.
> 

Thanks. Will try it out later today.

Regards,
Vaibhav


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 12/18] ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent device
@ 2013-01-31 11:17                 ` Bedia, Vaibhav
  0 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-31 11:17 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jan 30, 2013 at 23:16:34, Hunter, Jon wrote:
> 
> Ok fair enough. By the way, I posted a patch today [1] that will use the
> hwmod name as the clockevent timer name. Care to try on top of that
> patch and then we can eliminate the sprintf.
> 

Thanks. Will try it out later today.

Regards,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* RE: [RFC v2 13/18] ARM: OMAP2+: AM33XX: timer: Interchance clkevt and clksrc timers
  2013-01-30 17:49         ` Jon Hunter
@ 2013-01-31 11:29           ` Bedia, Vaibhav
  -1 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-31 11:29 UTC (permalink / raw)
  To: Hunter, Jon
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Paul Walmsley,
	Cousson, Benoit, Hiremath, Vaibhav, Shilimkar, Santosh

On Wed, Jan 30, 2013 at 23:19:34, Hunter, Jon wrote:
> 
> By the way, this need to be applied on top of the fix I sent yesterday
> to pass the property.
> 

Ok. Thanks for pointing this out.
 


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 13/18] ARM: OMAP2+: AM33XX: timer: Interchance clkevt and clksrc timers
@ 2013-01-31 11:29           ` Bedia, Vaibhav
  0 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-01-31 11:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jan 30, 2013 at 23:19:34, Hunter, Jon wrote:
> 
> By the way, this need to be applied on top of the fix I sent yesterday
> to pass the property.
> 

Ok. Thanks for pointing this out.
 

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 07/18] ARM: OMAP2+: AM33XX: hwmod: Update TPTC0 hwmod with the right flags
  2012-12-31 13:07   ` Vaibhav Bedia
@ 2013-02-11 23:33     ` Kevin Hilman
  -1 siblings, 0 replies; 148+ messages in thread
From: Kevin Hilman @ 2013-02-11 23:33 UTC (permalink / raw)
  To: Vaibhav Bedia
  Cc: linux-omap, linux-arm-kernel, tony, Santosh Shilimkar,
	Benoit Cousson, Paul Walmsley, Vaibhav Hiremath

Vaibhav Bedia <vaibhav.bedia@ti.com> writes:

> TPTC0 needs to be idled and put to standby under SW control.

Please elaborate about why (e.g. HW support not available, HW support
broken/buggy, etc.) since these blocks are not well documented in the
docs that I have (spruh73f.)

Thanks,

Kevin

> Add the appropriate flags in the TPTC0 hwmod entry.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
> v1->v2:
> 	No change
>
>  arch/arm/mach-omap2/omap_hwmod_33xx_data.c |    1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
> index 5e50e68..5c34d4b 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
> @@ -1823,6 +1823,7 @@ static struct omap_hwmod am33xx_tptc0_hwmod = {
>  	.class		= &am33xx_tptc_hwmod_class,
>  	.clkdm_name	= "l3_clkdm",
>  	.mpu_irqs	= am33xx_tptc0_irqs,
> +	.flags		= (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY),
>  	.main_clk	= "l3_gclk",
>  	.prcm		= {
>  		.omap4	= {

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 07/18] ARM: OMAP2+: AM33XX: hwmod: Update TPTC0 hwmod with the right flags
@ 2013-02-11 23:33     ` Kevin Hilman
  0 siblings, 0 replies; 148+ messages in thread
From: Kevin Hilman @ 2013-02-11 23:33 UTC (permalink / raw)
  To: linux-arm-kernel

Vaibhav Bedia <vaibhav.bedia@ti.com> writes:

> TPTC0 needs to be idled and put to standby under SW control.

Please elaborate about why (e.g. HW support not available, HW support
broken/buggy, etc.) since these blocks are not well documented in the
docs that I have (spruh73f.)

Thanks,

Kevin

> Add the appropriate flags in the TPTC0 hwmod entry.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Vaibhav Hiremath <hvaibhav@ti.com>
> ---
> v1->v2:
> 	No change
>
>  arch/arm/mach-omap2/omap_hwmod_33xx_data.c |    1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
> index 5e50e68..5c34d4b 100644
> --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
> +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c
> @@ -1823,6 +1823,7 @@ static struct omap_hwmod am33xx_tptc0_hwmod = {
>  	.class		= &am33xx_tptc_hwmod_class,
>  	.clkdm_name	= "l3_clkdm",
>  	.mpu_irqs	= am33xx_tptc0_irqs,
> +	.flags		= (HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY),
>  	.main_clk	= "l3_gclk",
>  	.prcm		= {
>  		.omap4	= {

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support
  2012-12-31 13:07   ` Vaibhav Bedia
@ 2013-02-12  1:27     ` Kevin Hilman
  -1 siblings, 0 replies; 148+ messages in thread
From: Kevin Hilman @ 2013-02-12  1:27 UTC (permalink / raw)
  To: Vaibhav Bedia
  Cc: linux-omap, linux-arm-kernel, tony, Santosh Shilimkar,
	Benoit Cousson, Paul Walmsley

Hi Viabhav,

Vaibhav Bedia <vaibhav.bedia@ti.com> writes:

> AM335x supports various low power modes as documented
> in section 8.1.4.3 of the AM335x TRM which is available
> @ http://www.ti.com/litv/pdf/spruh73f
>
> DeepSleep0 mode offers the lowest power mode with limited
> wakeup sources without a system reboot and is mapped as
> the suspend state in the kernel. In this state, MPU and
> PER domains are turned off with the internal RAM held in
> retention to facilitate resume process. As part of the boot
> process, the assembly code is copied over to OCMCRAM using
> the OMAP SRAM code.
>
> AM335x has a Cortex-M3 (WKUP_M3) which assists the MPU
> in DeepSleep0 entry and exit. WKUP_M3 takes care of the
> clockdomain and powerdomain transitions based on the
> intended low power state. MPU needs to load the appropriate
> WKUP_M3 binary onto the WKUP_M3 memory space before it can
> leverage any of the PM features like DeepSleep.
>
> The IPC mechanism between MPU and WKUP_M3 uses a mailbox
> sub-module and 8 IPC registers in the Control module. MPU
> uses the assigned Mailbox for issuing an interrupt to
> WKUP_M3 which then goes and checks the IPC registers for
> the payload. WKUP_M3 has the ability to trigger on interrupt
> to MPU by executing the "sev" instruction.
>
> In the current implementation when the suspend process
> is initiated MPU interrupts the WKUP_M3 to let it know about
> the intent of entering DeepSleep0 and waits for an ACK. When
> the ACK is received MPU continues with its suspend process
> to suspend all the drivers and then jumps to assembly in
> OCMC RAM. The assembly code puts the PLLs in bypass, puts the
> external RAM in self-refresh mode and then finally execute the
> WFI instruction. Execution of the WFI instruction triggers another
> interrupt to the WKUP_M3 which then continues wiht the power down
> sequence wherein the clockdomain and powerdomain transition takes
> place. As part of the sleep sequence, WKUP_M3 unmasks the interrupt
> lines for the wakeup sources. WFI execution on WKUP_M3 causes the
> hardware to disable the main oscillator of the SoC.
>
> When a wakeup event occurs, WKUP_M3 starts the power-up
> sequence by switching on the power domains and finally
> enabling the clock to MPU. Since the MPU gets powered down
> as part of the sleep sequence in the resume path ROM code
> starts executing. The ROM code detects a wakeup from sleep
> and then jumps to the resume location in OCMC which was
> populated in one of the IPC registers as part of the suspend
> sequence.
>
> The low level code in OCMC relocks the PLLs, enables access
> to external RAM and then jumps to the cpu_resume code of
> the kernel to finish the resume process.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Tony Lingren <tony@atomide.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>

Thanks for the updated series here, and my apologies for the delayed
review.

I've just had a quick scan of this patch, and have a few general
comments, I'll probably have a few more comments after a closer look.

> ---
> v1->v2:
> 	Move assembly code addition, control module access
> 	and hookup in OMAP PM framework in separate patches.
> 	Address other comments from Kevin Hilman and Santosh
> 	Shilimkar on v1. The discussion on v1 is present @
> 	http://lists.infradead.org/pipermail/linux-arm-kernel/2012-November/129979.html
> 	Note: The mailbox change will need slight rework once
> 	the driver is finalized.
>
>  arch/arm/mach-omap2/pm33xx.c |  469 ++++++++++++++++++++++++++++++++++++++++++
>  arch/arm/mach-omap2/pm33xx.h |   56 +++++
>  2 files changed, 525 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-omap2/pm33xx.c
>  create mode 100644 arch/arm/mach-omap2/pm33xx.h
>
> diff --git a/arch/arm/mach-omap2/pm33xx.c b/arch/arm/mach-omap2/pm33xx.c
> new file mode 100644
> index 0000000..aaa4daa
> --- /dev/null
> +++ b/arch/arm/mach-omap2/pm33xx.c
> @@ -0,0 +1,469 @@
> +/*
> + * AM33XX Power Management Routines
> + *
> + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
> + * Vaibhav Bedia <vaibhav.bedia@ti.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation version 2.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> + * kind, whether express or implied; without even the implied warranty
> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/err.h>
> +#include <linux/firmware.h>
> +#include <linux/io.h>
> +#include <linux/platform_device.h>
> +#include <linux/sched.h>
> +#include <linux/suspend.h>
> +#include <linux/completion.h>
> +#include <linux/module.h>
> +#include <linux/mailbox.h>
> +#include <linux/interrupt.h>
> +
> +#include <asm/suspend.h>
> +#include <asm/proc-fns.h>
> +#include <asm/sizes.h>
> +#include <asm/fncpy.h>
> +#include <asm/system_misc.h>
> +
> +#include "pm.h"
> +#include "cm33xx.h"
> +#include "pm33xx.h"
> +#include "control.h"
> +#include "clockdomain.h"
> +#include "powerdomain.h"
> +#include "omap_hwmod.h"
> +#include "omap_device.h"
> +#include "soc.h"
> +#include "sram.h"
> +
> +void (*am33xx_do_wfi_sram)(void);

static?

> +static void __iomem *am33xx_emif_base;
> +static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm, *per_pwrdm;
> +static struct clockdomain *gfx_l4ls_clkdm;
> +static struct omap_hwmod *usb_oh, *cpsw_oh, *tptc0_oh, *tptc1_oh, *tptc2_oh;
> +static struct wkup_m3_context *wkup_m3;
> +
> +static DECLARE_COMPLETION(wkup_m3_sync);
> +
> +#ifdef CONFIG_SUSPEND
> +static int am33xx_do_sram_idle(long unsigned int unused)
> +{
> +	am33xx_do_wfi_sram();
> +	return 0;
> +}
> +
> +static int am33xx_pm_suspend(void)
> +{
> +	int status, ret = 0;
> +
> +	/*
> +	 * By default the following IPs do not have MSTANDBY asserted
> +	 * which is necessary for PER domain transition. If the drivers
> +	 * are not compiled into the kernel HWMOD code will not change the
> +	 * state of the IPs if the IP was not never enabled. To ensure
> +	 * that there no issues with or without the drivers being compiled
> +	 * in the kernel, we forcefully put these IPs to idle.
> +	 */
> +	omap_hwmod_enable(usb_oh);
> +	omap_hwmod_enable(tptc0_oh);
> +	omap_hwmod_enable(tptc1_oh);
> +	omap_hwmod_enable(tptc2_oh);
> +	omap_hwmod_enable(cpsw_oh);
> +
> +	omap_hwmod_idle(usb_oh);
> +	omap_hwmod_idle(tptc0_oh);
> +	omap_hwmod_idle(tptc1_oh);
> +	omap_hwmod_idle(tptc2_oh);
> +	omap_hwmod_idle(cpsw_oh);

I think I asked this in my review of v1, but why does this need to
happen on every suspend attempt?

This should happen once on init, which will handle the case where there
are no drivers, and if there are drivers, then the drivers need to
handle this properly.  

I don't like this happening here on every suspend attempt, because it
will surely hide bugs where drivers are not properly managing their own PM.

> +	/* Try to put GFX to sleep */
> +	pwrdm_set_next_fpwrst(gfx_pwrdm, PWRDM_FUNC_PWRST_OFF);
> +
> +	ret = cpu_suspend(0, am33xx_do_sram_idle);
> +	status = pwrdm_read_fpwrst(gfx_pwrdm);
> +	if (status != PWRDM_FUNC_PWRST_OFF)
> +		pr_err("GFX domain did not transition\n");
> +	else
> +		pr_info("GFX domain entered low power state\n");

Do you really want this printed every time?

> +	/*
> +	 * GFX_L4LS clock domain needs to be woken up to
> +	 * ensure thet L4LS clock domain does not get stuck in transition
> +	 * If that happens L3 module does not get disabled, thereby leading
> +	 * to PER power domain transition failing
> +	 *
> +	 * The clock framework should take care of ensuring
> +	 * that the clock domain is in the right state when
> +	 * GFX driver is active.

Are you suggesting that the clock framework is not doing this already?

> +	 */
> +	clkdm_wakeup(gfx_l4ls_clkdm);
> +	clkdm_sleep(gfx_l4ls_clkdm);
> +
> +	if (ret) {
> +		pr_err("Kernel suspend failure\n");
> +	} else {
> +		status = omap_ctrl_readl(AM33XX_CONTROL_IPC_MSG_REG1);

We're trying to git rid of direct control module register access, and
consolidate them into control.c (for an eventual move to a driver.)  I
see you've mostly done that in other parts of the series, but here's one
that needs to move.

> +		status &= IPC_RESP_MASK;
> +		status >>= __ffs(IPC_RESP_MASK);
> +
> +		switch (status) {
> +		case 0:
> +			pr_info("Successfully put all powerdomains to target state\n");
> +			/*
> +			 * XXX: Leads to loss of logic state in PER power domain
> +			 * Use SOC specific ops for this?
> +			 */

huh?

> +			break;
> +		case 1:
> +			pr_err("Could not transition all powerdomains to target state\n");
> +			ret = -1;
> +			break;
> +		default:
> +			pr_err("Something went wrong :(\nStatus = %d\n",
> +				status);
> +			ret = -1;
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +static int am33xx_pm_enter(suspend_state_t suspend_state)
> +{
> +	int ret = 0;
> +
> +	switch (suspend_state) {
> +	case PM_SUSPEND_STANDBY:
> +	case PM_SUSPEND_MEM:
> +		ret = am33xx_pm_suspend();
> +		break;
> +	default:
> +		ret = -EINVAL;
> +	}
> +
> +	return ret;
> +}
> +
> +static int am33xx_pm_begin(suspend_state_t state)
> +{
> +	int ret = 0;
> +	struct mailbox_msg dummy_msg;
> +
> +	disable_hlt();
> +
> +	MAILBOX_FILL_HEADER_MSG(dummy_msg, 0xABCDABCD);
> +
> +	wkup_m3->ipc_data.sleep_mode = IPC_CMD_DS0;
> +	wkup_m3->ipc_data.param1  = DS_IPC_DEFAULT;
> +	wkup_m3->ipc_data.param2  = DS_IPC_DEFAULT;
> +
> +	am33xx_wkup_m3_ipc_cmd(&wkup_m3->ipc_data);
> +
> +	wkup_m3->state = M3_STATE_MSG_FOR_LP;
> +
> +	mailbox_enable_irq(wkup_m3->mbox, IRQ_RX);
> +
> +	ret = mailbox_msg_send(wkup_m3->mbox, &dummy_msg);
> +	if (ret) {
> +		pr_err("A8<->CM3 MSG for LP failed\n");
> +		am33xx_m3_state_machine_reset();
> +		ret = -1;
> +	}
> +
> +	/* Give some time to M3 to respond. 500msec is a random value here */

random?  really?

> +	if (!wait_for_completion_timeout(&wkup_m3_sync,
> +					msecs_to_jiffies(500))) {
> +		pr_err("A8<->CM3 sync failure\n");
> +		am33xx_m3_state_machine_reset();
> +		ret = -1;
> +	} else {
> +		pr_debug("Message sent for entering DeepSleep mode\n");
> +		mailbox_disable_irq(wkup_m3->mbox, IRQ_RX);
> +	}
> +
> +	return ret;
> +}
> +
> +static void am33xx_pm_end(void)
> +{
> +	mailbox_enable_irq(wkup_m3->mbox, IRQ_RX);
> +
> +	am33xx_m3_state_machine_reset();
> +
> +	enable_hlt();
> +
> +	return;
> +}
> +
> +static const struct platform_suspend_ops am33xx_pm_ops = {
> +	.begin		= am33xx_pm_begin,
> +	.end		= am33xx_pm_end,
> +	.enter		= am33xx_pm_enter,
> +	.valid		= suspend_valid_only_mem,
> +};
> +
> +static void am33xx_m3_state_machine_reset(void)
> +{
> +	int ret = 0;
> +	struct mailbox_msg dummy_msg;
> +
> +	MAILBOX_FILL_HEADER_MSG(dummy_msg, 0xABCDABCD);
> +
> +	wkup_m3->ipc_data.sleep_mode	= IPC_CMD_RESET;
> +	wkup_m3->ipc_data.param1	= DS_IPC_DEFAULT;
> +	wkup_m3->ipc_data.param2	= DS_IPC_DEFAULT;
> +
> +	am33xx_wkup_m3_ipc_cmd(&wkup_m3->ipc_data);
> +
> +	wkup_m3->state = M3_STATE_MSG_FOR_RESET;
> +
> +	ret = mailbox_msg_send(wkup_m3->mbox, &dummy_msg);
> +	if (!ret) {
> +		pr_debug("Message sent for resetting M3 state machine\n");
> +		/* Give some to M3 to respond. 500msec is a random value here */
> +		if (!wait_for_completion_timeout(&wkup_m3_sync,
> +						msecs_to_jiffies(500)))
> +			pr_err("A8<->CM3 sync failure\n");
> +	} else {
> +		pr_err("Could not reset M3 state machine!!!\n");
> +		wkup_m3->state = M3_STATE_UNKNOWN;
> +	}
> +}
> +#endif /* CONFIG_SUSPEND */
> +
> +/*
> + * Dummy notifier for the mailbox
> + * XXX: Get rid of this requirement once the MBX driver has been finalized

IIRC, I suggested a trivial fix to the mailbox driver that would remove
the need for this, which could be done today.

> + */
> +static int wkup_mbox_msg(struct notifier_block *self, unsigned long len,
> +		void *msg)
> +{
> +	return 0;
> +}
> +
> +static struct notifier_block wkup_mbox_notifier = {
> +	.notifier_call = wkup_mbox_msg,
> +};
> +
> +static irqreturn_t wkup_m3_txev_handler(int irq, void *unused)
> +{
> +	am33xx_txev_eoi();
> +
> +	switch (wkup_m3->state) {
> +	case M3_STATE_RESET:
> +		wkup_m3->state = M3_STATE_INITED;
> +		break;
> +	case M3_STATE_MSG_FOR_RESET:
> +		wkup_m3->state = M3_STATE_INITED;
> +		mailbox_rx_flush(wkup_m3->mbox);
> +		complete(&wkup_m3_sync);
> +		break;
> +	case M3_STATE_MSG_FOR_LP:
> +		mailbox_rx_flush(wkup_m3->mbox);
> +		complete(&wkup_m3_sync);
> +		break;
> +	case M3_STATE_UNKNOWN:
> +		pr_err("IRQ %d with WKUP_M3 in unknown state\n", irq);
> +		mailbox_rx_flush(wkup_m3->mbox);
> +		return IRQ_NONE;
> +	}
> +
> +	am33xx_txev_enable();
> +	return IRQ_HANDLED;
> +}
> +
> +static void am33xx_pm_firmware_cb(const struct firmware *fw, void *context)
> +{
> +	struct wkup_m3_context *wkup_m3_context = context;
> +	struct platform_device *pdev = to_platform_device(wkup_m3_context->dev);
> +	int ret = 0;
> +
> +	/* no firmware found */
> +	if (!fw) {
> +		dev_err(wkup_m3_context->dev, "request_firmware failed\n");
> +		goto err;
> +	}
> +
> +	memcpy((void *)wkup_m3_context->code, fw->data, fw->size);
> +	pr_info("Copied the M3 firmware to UMEM\n");
> +
> +	wkup_m3->state = M3_STATE_RESET;
> +
> +	ret = omap_device_deassert_hardreset(pdev, "wkup_m3");
> +	if (ret) {
> +		pr_err("Could not deassert the reset for WKUP_M3\n");
> +		goto err;
> +	} else {
> +#ifdef CONFIG_SUSPEND
> +		suspend_set_ops(&am33xx_pm_ops);
> +		/*
> +		 * Physical resume address to be used by ROM code
> +		 */
> +		wkup_m3->ipc_data.resume_addr = (AM33XX_OCMC_END -
> +				am33xx_do_wfi_sz + am33xx_resume_offset + 0x4);
> +#endif
> +		return;
> +	}
> +
> +err:
> +	mailbox_put(wkup_m3_context->mbox, &wkup_mbox_notifier);
> +}
> +
> +static int wkup_m3_init(void)
> +{
> +	int irq, ret = 0;
> +	struct resource *mem;
> +	struct platform_device *pdev = to_platform_device(wkup_m3->dev);
> +
> +	omap_device_enable_hwmods(to_omap_device(pdev));

Why not omap_device_enable(pdev) ?

> +
> +	/* Reserve the MBOX for sending messages to M3 */
> +	wkup_m3->mbox = mailbox_get("wkup_m3", &wkup_mbox_notifier);
> +	if (IS_ERR(wkup_m3->mbox)) {
> +		pr_err("Could not reserve mailbox for A8->M3 IPC\n");
> +		ret = -ENODEV;
> +		goto exit;
> +	}
> +
> +	irq = platform_get_irq(pdev, 0);
> +	if (!irq) {
> +		dev_err(wkup_m3->dev, "no irq resource\n");
> +		ret = -ENXIO;
> +		goto err;
> +	}
> +
> +	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!mem) {
> +		dev_err(wkup_m3->dev, "no memory resource\n");
> +		ret = -ENXIO;
> +		goto err;
> +	}
> +
> +	wkup_m3->code = devm_request_and_ioremap(wkup_m3->dev, mem);
> +	if (!wkup_m3->code) {
> +		dev_err(wkup_m3->dev, "could not ioremap\n");
> +		ret = -EADDRNOTAVAIL;
> +		goto err;
> +	}
> +
> +	ret = devm_request_irq(wkup_m3->dev, irq, wkup_m3_txev_handler,
> +		  IRQF_DISABLED, "wkup_m3_txev", NULL);
> +	if (ret) {
> +		dev_err(wkup_m3->dev, "request_irq failed\n");
> +		goto err;
> +	} else {
> +		am33xx_txev_enable();
> +	}
> +
> +	pr_info("Trying to load am335x-pm-firmware.bin");
> +
> +	/* We don't want to delay boot */
> +	request_firmware_nowait(THIS_MODULE, 0, "am335x-pm-firmware.bin",
> +				wkup_m3->dev, GFP_KERNEL, wkup_m3,
> +				am33xx_pm_firmware_cb);
> +	return 0;
> +
> +err:
> +	mailbox_put(wkup_m3->mbox, &wkup_mbox_notifier);
> +exit:
> +	return ret;
> +}

Kevin

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support
@ 2013-02-12  1:27     ` Kevin Hilman
  0 siblings, 0 replies; 148+ messages in thread
From: Kevin Hilman @ 2013-02-12  1:27 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Viabhav,

Vaibhav Bedia <vaibhav.bedia@ti.com> writes:

> AM335x supports various low power modes as documented
> in section 8.1.4.3 of the AM335x TRM which is available
> @ http://www.ti.com/litv/pdf/spruh73f
>
> DeepSleep0 mode offers the lowest power mode with limited
> wakeup sources without a system reboot and is mapped as
> the suspend state in the kernel. In this state, MPU and
> PER domains are turned off with the internal RAM held in
> retention to facilitate resume process. As part of the boot
> process, the assembly code is copied over to OCMCRAM using
> the OMAP SRAM code.
>
> AM335x has a Cortex-M3 (WKUP_M3) which assists the MPU
> in DeepSleep0 entry and exit. WKUP_M3 takes care of the
> clockdomain and powerdomain transitions based on the
> intended low power state. MPU needs to load the appropriate
> WKUP_M3 binary onto the WKUP_M3 memory space before it can
> leverage any of the PM features like DeepSleep.
>
> The IPC mechanism between MPU and WKUP_M3 uses a mailbox
> sub-module and 8 IPC registers in the Control module. MPU
> uses the assigned Mailbox for issuing an interrupt to
> WKUP_M3 which then goes and checks the IPC registers for
> the payload. WKUP_M3 has the ability to trigger on interrupt
> to MPU by executing the "sev" instruction.
>
> In the current implementation when the suspend process
> is initiated MPU interrupts the WKUP_M3 to let it know about
> the intent of entering DeepSleep0 and waits for an ACK. When
> the ACK is received MPU continues with its suspend process
> to suspend all the drivers and then jumps to assembly in
> OCMC RAM. The assembly code puts the PLLs in bypass, puts the
> external RAM in self-refresh mode and then finally execute the
> WFI instruction. Execution of the WFI instruction triggers another
> interrupt to the WKUP_M3 which then continues wiht the power down
> sequence wherein the clockdomain and powerdomain transition takes
> place. As part of the sleep sequence, WKUP_M3 unmasks the interrupt
> lines for the wakeup sources. WFI execution on WKUP_M3 causes the
> hardware to disable the main oscillator of the SoC.
>
> When a wakeup event occurs, WKUP_M3 starts the power-up
> sequence by switching on the power domains and finally
> enabling the clock to MPU. Since the MPU gets powered down
> as part of the sleep sequence in the resume path ROM code
> starts executing. The ROM code detects a wakeup from sleep
> and then jumps to the resume location in OCMC which was
> populated in one of the IPC registers as part of the suspend
> sequence.
>
> The low level code in OCMC relocks the PLLs, enables access
> to external RAM and then jumps to the cpu_resume code of
> the kernel to finish the resume process.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Tony Lingren <tony@atomide.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>

Thanks for the updated series here, and my apologies for the delayed
review.

I've just had a quick scan of this patch, and have a few general
comments, I'll probably have a few more comments after a closer look.

> ---
> v1->v2:
> 	Move assembly code addition, control module access
> 	and hookup in OMAP PM framework in separate patches.
> 	Address other comments from Kevin Hilman and Santosh
> 	Shilimkar on v1. The discussion on v1 is present @
> 	http://lists.infradead.org/pipermail/linux-arm-kernel/2012-November/129979.html
> 	Note: The mailbox change will need slight rework once
> 	the driver is finalized.
>
>  arch/arm/mach-omap2/pm33xx.c |  469 ++++++++++++++++++++++++++++++++++++++++++
>  arch/arm/mach-omap2/pm33xx.h |   56 +++++
>  2 files changed, 525 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-omap2/pm33xx.c
>  create mode 100644 arch/arm/mach-omap2/pm33xx.h
>
> diff --git a/arch/arm/mach-omap2/pm33xx.c b/arch/arm/mach-omap2/pm33xx.c
> new file mode 100644
> index 0000000..aaa4daa
> --- /dev/null
> +++ b/arch/arm/mach-omap2/pm33xx.c
> @@ -0,0 +1,469 @@
> +/*
> + * AM33XX Power Management Routines
> + *
> + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
> + * Vaibhav Bedia <vaibhav.bedia@ti.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation version 2.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> + * kind, whether express or implied; without even the implied warranty
> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/err.h>
> +#include <linux/firmware.h>
> +#include <linux/io.h>
> +#include <linux/platform_device.h>
> +#include <linux/sched.h>
> +#include <linux/suspend.h>
> +#include <linux/completion.h>
> +#include <linux/module.h>
> +#include <linux/mailbox.h>
> +#include <linux/interrupt.h>
> +
> +#include <asm/suspend.h>
> +#include <asm/proc-fns.h>
> +#include <asm/sizes.h>
> +#include <asm/fncpy.h>
> +#include <asm/system_misc.h>
> +
> +#include "pm.h"
> +#include "cm33xx.h"
> +#include "pm33xx.h"
> +#include "control.h"
> +#include "clockdomain.h"
> +#include "powerdomain.h"
> +#include "omap_hwmod.h"
> +#include "omap_device.h"
> +#include "soc.h"
> +#include "sram.h"
> +
> +void (*am33xx_do_wfi_sram)(void);

static?

> +static void __iomem *am33xx_emif_base;
> +static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm, *per_pwrdm;
> +static struct clockdomain *gfx_l4ls_clkdm;
> +static struct omap_hwmod *usb_oh, *cpsw_oh, *tptc0_oh, *tptc1_oh, *tptc2_oh;
> +static struct wkup_m3_context *wkup_m3;
> +
> +static DECLARE_COMPLETION(wkup_m3_sync);
> +
> +#ifdef CONFIG_SUSPEND
> +static int am33xx_do_sram_idle(long unsigned int unused)
> +{
> +	am33xx_do_wfi_sram();
> +	return 0;
> +}
> +
> +static int am33xx_pm_suspend(void)
> +{
> +	int status, ret = 0;
> +
> +	/*
> +	 * By default the following IPs do not have MSTANDBY asserted
> +	 * which is necessary for PER domain transition. If the drivers
> +	 * are not compiled into the kernel HWMOD code will not change the
> +	 * state of the IPs if the IP was not never enabled. To ensure
> +	 * that there no issues with or without the drivers being compiled
> +	 * in the kernel, we forcefully put these IPs to idle.
> +	 */
> +	omap_hwmod_enable(usb_oh);
> +	omap_hwmod_enable(tptc0_oh);
> +	omap_hwmod_enable(tptc1_oh);
> +	omap_hwmod_enable(tptc2_oh);
> +	omap_hwmod_enable(cpsw_oh);
> +
> +	omap_hwmod_idle(usb_oh);
> +	omap_hwmod_idle(tptc0_oh);
> +	omap_hwmod_idle(tptc1_oh);
> +	omap_hwmod_idle(tptc2_oh);
> +	omap_hwmod_idle(cpsw_oh);

I think I asked this in my review of v1, but why does this need to
happen on every suspend attempt?

This should happen once on init, which will handle the case where there
are no drivers, and if there are drivers, then the drivers need to
handle this properly.  

I don't like this happening here on every suspend attempt, because it
will surely hide bugs where drivers are not properly managing their own PM.

> +	/* Try to put GFX to sleep */
> +	pwrdm_set_next_fpwrst(gfx_pwrdm, PWRDM_FUNC_PWRST_OFF);
> +
> +	ret = cpu_suspend(0, am33xx_do_sram_idle);
> +	status = pwrdm_read_fpwrst(gfx_pwrdm);
> +	if (status != PWRDM_FUNC_PWRST_OFF)
> +		pr_err("GFX domain did not transition\n");
> +	else
> +		pr_info("GFX domain entered low power state\n");

Do you really want this printed every time?

> +	/*
> +	 * GFX_L4LS clock domain needs to be woken up to
> +	 * ensure thet L4LS clock domain does not get stuck in transition
> +	 * If that happens L3 module does not get disabled, thereby leading
> +	 * to PER power domain transition failing
> +	 *
> +	 * The clock framework should take care of ensuring
> +	 * that the clock domain is in the right state when
> +	 * GFX driver is active.

Are you suggesting that the clock framework is not doing this already?

> +	 */
> +	clkdm_wakeup(gfx_l4ls_clkdm);
> +	clkdm_sleep(gfx_l4ls_clkdm);
> +
> +	if (ret) {
> +		pr_err("Kernel suspend failure\n");
> +	} else {
> +		status = omap_ctrl_readl(AM33XX_CONTROL_IPC_MSG_REG1);

We're trying to git rid of direct control module register access, and
consolidate them into control.c (for an eventual move to a driver.)  I
see you've mostly done that in other parts of the series, but here's one
that needs to move.

> +		status &= IPC_RESP_MASK;
> +		status >>= __ffs(IPC_RESP_MASK);
> +
> +		switch (status) {
> +		case 0:
> +			pr_info("Successfully put all powerdomains to target state\n");
> +			/*
> +			 * XXX: Leads to loss of logic state in PER power domain
> +			 * Use SOC specific ops for this?
> +			 */

huh?

> +			break;
> +		case 1:
> +			pr_err("Could not transition all powerdomains to target state\n");
> +			ret = -1;
> +			break;
> +		default:
> +			pr_err("Something went wrong :(\nStatus = %d\n",
> +				status);
> +			ret = -1;
> +		}
> +	}
> +
> +	return ret;
> +}
> +
> +static int am33xx_pm_enter(suspend_state_t suspend_state)
> +{
> +	int ret = 0;
> +
> +	switch (suspend_state) {
> +	case PM_SUSPEND_STANDBY:
> +	case PM_SUSPEND_MEM:
> +		ret = am33xx_pm_suspend();
> +		break;
> +	default:
> +		ret = -EINVAL;
> +	}
> +
> +	return ret;
> +}
> +
> +static int am33xx_pm_begin(suspend_state_t state)
> +{
> +	int ret = 0;
> +	struct mailbox_msg dummy_msg;
> +
> +	disable_hlt();
> +
> +	MAILBOX_FILL_HEADER_MSG(dummy_msg, 0xABCDABCD);
> +
> +	wkup_m3->ipc_data.sleep_mode = IPC_CMD_DS0;
> +	wkup_m3->ipc_data.param1  = DS_IPC_DEFAULT;
> +	wkup_m3->ipc_data.param2  = DS_IPC_DEFAULT;
> +
> +	am33xx_wkup_m3_ipc_cmd(&wkup_m3->ipc_data);
> +
> +	wkup_m3->state = M3_STATE_MSG_FOR_LP;
> +
> +	mailbox_enable_irq(wkup_m3->mbox, IRQ_RX);
> +
> +	ret = mailbox_msg_send(wkup_m3->mbox, &dummy_msg);
> +	if (ret) {
> +		pr_err("A8<->CM3 MSG for LP failed\n");
> +		am33xx_m3_state_machine_reset();
> +		ret = -1;
> +	}
> +
> +	/* Give some time to M3 to respond. 500msec is a random value here */

random?  really?

> +	if (!wait_for_completion_timeout(&wkup_m3_sync,
> +					msecs_to_jiffies(500))) {
> +		pr_err("A8<->CM3 sync failure\n");
> +		am33xx_m3_state_machine_reset();
> +		ret = -1;
> +	} else {
> +		pr_debug("Message sent for entering DeepSleep mode\n");
> +		mailbox_disable_irq(wkup_m3->mbox, IRQ_RX);
> +	}
> +
> +	return ret;
> +}
> +
> +static void am33xx_pm_end(void)
> +{
> +	mailbox_enable_irq(wkup_m3->mbox, IRQ_RX);
> +
> +	am33xx_m3_state_machine_reset();
> +
> +	enable_hlt();
> +
> +	return;
> +}
> +
> +static const struct platform_suspend_ops am33xx_pm_ops = {
> +	.begin		= am33xx_pm_begin,
> +	.end		= am33xx_pm_end,
> +	.enter		= am33xx_pm_enter,
> +	.valid		= suspend_valid_only_mem,
> +};
> +
> +static void am33xx_m3_state_machine_reset(void)
> +{
> +	int ret = 0;
> +	struct mailbox_msg dummy_msg;
> +
> +	MAILBOX_FILL_HEADER_MSG(dummy_msg, 0xABCDABCD);
> +
> +	wkup_m3->ipc_data.sleep_mode	= IPC_CMD_RESET;
> +	wkup_m3->ipc_data.param1	= DS_IPC_DEFAULT;
> +	wkup_m3->ipc_data.param2	= DS_IPC_DEFAULT;
> +
> +	am33xx_wkup_m3_ipc_cmd(&wkup_m3->ipc_data);
> +
> +	wkup_m3->state = M3_STATE_MSG_FOR_RESET;
> +
> +	ret = mailbox_msg_send(wkup_m3->mbox, &dummy_msg);
> +	if (!ret) {
> +		pr_debug("Message sent for resetting M3 state machine\n");
> +		/* Give some to M3 to respond. 500msec is a random value here */
> +		if (!wait_for_completion_timeout(&wkup_m3_sync,
> +						msecs_to_jiffies(500)))
> +			pr_err("A8<->CM3 sync failure\n");
> +	} else {
> +		pr_err("Could not reset M3 state machine!!!\n");
> +		wkup_m3->state = M3_STATE_UNKNOWN;
> +	}
> +}
> +#endif /* CONFIG_SUSPEND */
> +
> +/*
> + * Dummy notifier for the mailbox
> + * XXX: Get rid of this requirement once the MBX driver has been finalized

IIRC, I suggested a trivial fix to the mailbox driver that would remove
the need for this, which could be done today.

> + */
> +static int wkup_mbox_msg(struct notifier_block *self, unsigned long len,
> +		void *msg)
> +{
> +	return 0;
> +}
> +
> +static struct notifier_block wkup_mbox_notifier = {
> +	.notifier_call = wkup_mbox_msg,
> +};
> +
> +static irqreturn_t wkup_m3_txev_handler(int irq, void *unused)
> +{
> +	am33xx_txev_eoi();
> +
> +	switch (wkup_m3->state) {
> +	case M3_STATE_RESET:
> +		wkup_m3->state = M3_STATE_INITED;
> +		break;
> +	case M3_STATE_MSG_FOR_RESET:
> +		wkup_m3->state = M3_STATE_INITED;
> +		mailbox_rx_flush(wkup_m3->mbox);
> +		complete(&wkup_m3_sync);
> +		break;
> +	case M3_STATE_MSG_FOR_LP:
> +		mailbox_rx_flush(wkup_m3->mbox);
> +		complete(&wkup_m3_sync);
> +		break;
> +	case M3_STATE_UNKNOWN:
> +		pr_err("IRQ %d with WKUP_M3 in unknown state\n", irq);
> +		mailbox_rx_flush(wkup_m3->mbox);
> +		return IRQ_NONE;
> +	}
> +
> +	am33xx_txev_enable();
> +	return IRQ_HANDLED;
> +}
> +
> +static void am33xx_pm_firmware_cb(const struct firmware *fw, void *context)
> +{
> +	struct wkup_m3_context *wkup_m3_context = context;
> +	struct platform_device *pdev = to_platform_device(wkup_m3_context->dev);
> +	int ret = 0;
> +
> +	/* no firmware found */
> +	if (!fw) {
> +		dev_err(wkup_m3_context->dev, "request_firmware failed\n");
> +		goto err;
> +	}
> +
> +	memcpy((void *)wkup_m3_context->code, fw->data, fw->size);
> +	pr_info("Copied the M3 firmware to UMEM\n");
> +
> +	wkup_m3->state = M3_STATE_RESET;
> +
> +	ret = omap_device_deassert_hardreset(pdev, "wkup_m3");
> +	if (ret) {
> +		pr_err("Could not deassert the reset for WKUP_M3\n");
> +		goto err;
> +	} else {
> +#ifdef CONFIG_SUSPEND
> +		suspend_set_ops(&am33xx_pm_ops);
> +		/*
> +		 * Physical resume address to be used by ROM code
> +		 */
> +		wkup_m3->ipc_data.resume_addr = (AM33XX_OCMC_END -
> +				am33xx_do_wfi_sz + am33xx_resume_offset + 0x4);
> +#endif
> +		return;
> +	}
> +
> +err:
> +	mailbox_put(wkup_m3_context->mbox, &wkup_mbox_notifier);
> +}
> +
> +static int wkup_m3_init(void)
> +{
> +	int irq, ret = 0;
> +	struct resource *mem;
> +	struct platform_device *pdev = to_platform_device(wkup_m3->dev);
> +
> +	omap_device_enable_hwmods(to_omap_device(pdev));

Why not omap_device_enable(pdev) ?

> +
> +	/* Reserve the MBOX for sending messages to M3 */
> +	wkup_m3->mbox = mailbox_get("wkup_m3", &wkup_mbox_notifier);
> +	if (IS_ERR(wkup_m3->mbox)) {
> +		pr_err("Could not reserve mailbox for A8->M3 IPC\n");
> +		ret = -ENODEV;
> +		goto exit;
> +	}
> +
> +	irq = platform_get_irq(pdev, 0);
> +	if (!irq) {
> +		dev_err(wkup_m3->dev, "no irq resource\n");
> +		ret = -ENXIO;
> +		goto err;
> +	}
> +
> +	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +	if (!mem) {
> +		dev_err(wkup_m3->dev, "no memory resource\n");
> +		ret = -ENXIO;
> +		goto err;
> +	}
> +
> +	wkup_m3->code = devm_request_and_ioremap(wkup_m3->dev, mem);
> +	if (!wkup_m3->code) {
> +		dev_err(wkup_m3->dev, "could not ioremap\n");
> +		ret = -EADDRNOTAVAIL;
> +		goto err;
> +	}
> +
> +	ret = devm_request_irq(wkup_m3->dev, irq, wkup_m3_txev_handler,
> +		  IRQF_DISABLED, "wkup_m3_txev", NULL);
> +	if (ret) {
> +		dev_err(wkup_m3->dev, "request_irq failed\n");
> +		goto err;
> +	} else {
> +		am33xx_txev_enable();
> +	}
> +
> +	pr_info("Trying to load am335x-pm-firmware.bin");
> +
> +	/* We don't want to delay boot */
> +	request_firmware_nowait(THIS_MODULE, 0, "am335x-pm-firmware.bin",
> +				wkup_m3->dev, GFP_KERNEL, wkup_m3,
> +				am33xx_pm_firmware_cb);
> +	return 0;
> +
> +err:
> +	mailbox_put(wkup_m3->mbox, &wkup_mbox_notifier);
> +exit:
> +	return ret;
> +}

Kevin

^ permalink raw reply	[flat|nested] 148+ messages in thread

* RE: [RFC v2 07/18] ARM: OMAP2+: AM33XX: hwmod: Update TPTC0 hwmod with the right flags
  2013-02-11 23:33     ` Kevin Hilman
@ 2013-02-13 10:56       ` Bedia, Vaibhav
  -1 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-02-13 10:56 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-omap, linux-arm-kernel, tony, Shilimkar, Santosh, Cousson,
	Benoit, Paul Walmsley, Hiremath, Vaibhav

Hi Kevin,

On Tue, Feb 12, 2013 at 05:03:23, Kevin Hilman wrote:
> Vaibhav Bedia <vaibhav.bedia@ti.com> writes:
> 
> > TPTC0 needs to be idled and put to standby under SW control.
> 
> Please elaborate about why (e.g. HW support not available, HW support
> broken/buggy, etc.) since these blocks are not well documented in the
> docs that I have (spruh73f.)
> 

This change was picked up for v3.9. I'll submit a follow-up patch adding
in a comment in the hwmod file for this.

Regards,
Vaibhav 


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 07/18] ARM: OMAP2+: AM33XX: hwmod: Update TPTC0 hwmod with the right flags
@ 2013-02-13 10:56       ` Bedia, Vaibhav
  0 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-02-13 10:56 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Kevin,

On Tue, Feb 12, 2013 at 05:03:23, Kevin Hilman wrote:
> Vaibhav Bedia <vaibhav.bedia@ti.com> writes:
> 
> > TPTC0 needs to be idled and put to standby under SW control.
> 
> Please elaborate about why (e.g. HW support not available, HW support
> broken/buggy, etc.) since these blocks are not well documented in the
> docs that I have (spruh73f.)
> 

This change was picked up for v3.9. I'll submit a follow-up patch adding
in a comment in the hwmod file for this.

Regards,
Vaibhav 

^ permalink raw reply	[flat|nested] 148+ messages in thread

* RE: [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support
  2013-02-12  1:27     ` Kevin Hilman
@ 2013-02-13 13:43       ` Bedia, Vaibhav
  -1 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-02-13 13:43 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-omap, linux-arm-kernel, tony, Shilimkar, Santosh, Cousson,
	Benoit, Paul Walmsley

Hi Kevin,

On Tue, Feb 12, 2013 at 06:57:50, Kevin Hilman wrote:
[...]
> > +
> > +void (*am33xx_do_wfi_sram)(void);
> 
> static?

Will fix.

[...]

> > +
> > +	/*
> > +	 * By default the following IPs do not have MSTANDBY asserted
> > +	 * which is necessary for PER domain transition. If the drivers
> > +	 * are not compiled into the kernel HWMOD code will not change the
> > +	 * state of the IPs if the IP was not never enabled. To ensure
> > +	 * that there no issues with or without the drivers being compiled
> > +	 * in the kernel, we forcefully put these IPs to idle.
> > +	 */
> > +	omap_hwmod_enable(usb_oh);
> > +	omap_hwmod_enable(tptc0_oh);
> > +	omap_hwmod_enable(tptc1_oh);
> > +	omap_hwmod_enable(tptc2_oh);
> > +	omap_hwmod_enable(cpsw_oh);
> > +
> > +	omap_hwmod_idle(usb_oh);
> > +	omap_hwmod_idle(tptc0_oh);
> > +	omap_hwmod_idle(tptc1_oh);
> > +	omap_hwmod_idle(tptc2_oh);
> > +	omap_hwmod_idle(cpsw_oh);
> 
> I think I asked this in my review of v1, but why does this need to
> happen on every suspend attempt?
> 
> This should happen once on init, which will handle the case where there
> are no drivers, and if there are drivers, then the drivers need to
> handle this properly.  
> 
> I don't like this happening here on every suspend attempt, because it
> will surely hide bugs where drivers are not properly managing their own PM.
> 

By default these IPs don't have MSTANDBY asserted. When a low power transition
happens, the peripheral power domain loses context and hence the forced
MSTANDBY configuration in the IP is lost. To work around this problem we need
to assert MSTANDBY in every suspend-resume iteration.

I agree that this might hide PM bugs in the driver but to solve this problem we
need some mechanism for the PM code to know whether or not a driver is bound
to the corresponding platform devices. Any suggestions on this?

> > +	/* Try to put GFX to sleep */
> > +	pwrdm_set_next_fpwrst(gfx_pwrdm, PWRDM_FUNC_PWRST_OFF);
> > +
> > +	ret = cpu_suspend(0, am33xx_do_sram_idle);
> > +	status = pwrdm_read_fpwrst(gfx_pwrdm);
> > +	if (status != PWRDM_FUNC_PWRST_OFF)
> > +		pr_err("GFX domain did not transition\n");
> > +	else
> > +		pr_info("GFX domain entered low power state\n");
> 
> Do you really want this printed every time?
> 

Hmm... it could perhaps be clubbed with the overall status that's
printed. I kept it here since the GFX power domain is completely
under MPU control and hence this information would be useful in
finding out if there's a problem with the GFX suspend-resume.

> > +	/*
> > +	 * GFX_L4LS clock domain needs to be woken up to
> > +	 * ensure thet L4LS clock domain does not get stuck in transition
> > +	 * If that happens L3 module does not get disabled, thereby leading
> > +	 * to PER power domain transition failing
> > +	 *
> > +	 * The clock framework should take care of ensuring
> > +	 * that the clock domain is in the right state when
> > +	 * GFX driver is active.
> 
> Are you suggesting that the clock framework is not doing this already?
> 

No. This clkdm_*() calls are here to work-around an issue that I observed
when implementing suspend-resume. The force wakeup and sleep of the gfx_l4ls
clock domain across every suspend-resume is something I don't think can
be pushed to the clock framework.

> > +	 */
> > +	clkdm_wakeup(gfx_l4ls_clkdm);
> > +	clkdm_sleep(gfx_l4ls_clkdm);
> > +
> > +	if (ret) {
> > +		pr_err("Kernel suspend failure\n");
> > +	} else {
> > +		status = omap_ctrl_readl(AM33XX_CONTROL_IPC_MSG_REG1);
> 
> We're trying to git rid of direct control module register access, and
> consolidate them into control.c (for an eventual move to a driver.)  I
> see you've mostly done that in other parts of the series, but here's one
> that needs to move.

Yes, I somehow missed this one. Will take care of it in the next version.

> 
> > +		status &= IPC_RESP_MASK;
> > +		status >>= __ffs(IPC_RESP_MASK);
> > +
> > +		switch (status) {
> > +		case 0:
> > +			pr_info("Successfully put all powerdomains to target state\n");
> > +			/*
> > +			 * XXX: Leads to loss of logic state in PER power domain
> > +			 * Use SOC specific ops for this?
> > +			 */
> 
> huh?
> 

Ah... this is more of a TODO. There's no previous state entered information
in the PRCM registers. So to ensure that the drivers get the right information
when they check with the PM layer about the loss of context and hence the need
to restore the registers, I need to update the logic and membank state counters
for the PER power domain manually. I was thinking of leveraging the SoC specific
power domain ops for doing this.

[...]

> > +
> > +	/* Give some time to M3 to respond. 500msec is a random value here */
> 
> random?  really?

Sort of. I don't have any numbers from the h/w guys on the worst
case delay in getting an interrupt from M3 to MPU. At the same time
I want to handle the scenario where something goes wrong on the M3
side and it doesn't respond.

[...]

> > +
> > +/*
> > + * Dummy notifier for the mailbox
> > + * XXX: Get rid of this requirement once the MBX driver has been finalized
> 
> IIRC, I suggested a trivial fix to the mailbox driver that would remove
> the need for this, which could be done today.
> 

Yes. I plan to do that once the mailbox code movement to drivers/ along with
other changes to make it generic enough are finalized. It was adding in one
more dependency and hence I kept this as a TODO in this version.

[...]

> > +static int wkup_m3_init(void)
> > +{
> > +	int irq, ret = 0;
> > +	struct resource *mem;
> > +	struct platform_device *pdev = to_platform_device(wkup_m3->dev);
> > +
> > +	omap_device_enable_hwmods(to_omap_device(pdev));
> 
> Why not omap_device_enable(pdev) ?
> 

The objective is to leverage the hwmod code to get the WKUP-M3
functional and not have OMAP runtime PM code coming in the way. 
Using omap_device_enable() triggers the following dev_warn()
from omap_device_enable().

[    2.033718] platform 44d00000.wkup_m3: omap_device_late_idle: enabled but no driver.  Idling
[    2.042676] ------------[ cut here ]------------
[    2.047572] WARNING: at arch/arm/mach-omap2/omap_hwmod.c:2187 _idle+0x164/0x1c0()
[    2.055459] omap_hwmod: wkup_m3: idle state can only be entered from enabled state
[    2.063435] Modules linked in:
[    2.066712] [<c001afe4>] (unwind_backtrace+0x0/0xf0) from [<c004380c>] (warn_slowpath_common+0x4c/0x64)
[    2.076626] [<c004380c>] (warn_slowpath_common+0x4c/0x64) from [<c00438b8>] (warn_slowpath_fmt+0x30/0x40)
[    2.086720] [<c00438b8>] (warn_slowpath_fmt+0x30/0x40) from [<c002aad0>] (_idle+0x164/0x1c0)
[    2.095624] [<c002aad0>] (_idle+0x164/0x1c0) from [<c002af98>] (omap_hwmod_idle+0x24/0x40)
[    2.104348] [<c002af98>] (omap_hwmod_idle+0x24/0x40) from [<c002bd60>] (omap_device_idle_hwmods+0x24/0x3c)
[    2.114536] [<c002bd60>] (omap_device_idle_hwmods+0x24/0x3c) from [<c002bf4c>] (_omap_device_deactivate+0x98/0x134)
[    2.125546] [<c002bf4c>] (_omap_device_deactivate+0x98/0x134) from [<c002c87c>] (omap_device_idle+0x28/0x54)
[    2.135921] [<c002c87c>] (omap_device_idle+0x28/0x54) from [<c06ec00c>] (omap_device_late_idle+0x44/0x54)
[    2.146025] [<c06ec00c>] (omap_device_late_idle+0x44/0x54) from [<c031f850>] (bus_for_each_dev+0x50/0x7c)
[    2.156120] [<c031f850>] (bus_for_each_dev+0x50/0x7c) from [<c06ebe10>] (omap_device_late_init+0x18/0x28)
[    2.166216] [<c06ebe10>] (omap_device_late_init+0x18/0x28) from [<c00086e4>] (do_one_initcall+0x34/0x180)
[    2.176314] [<c00086e4>] (do_one_initcall+0x34/0x180) from [<c06df8f8>] (kernel_init_freeable+0xfc/0x1cc)
[    2.186408] [<c06df8f8>] (kernel_init_freeable+0xfc/0x1cc) from [<c04d4b20>] (kernel_init+0x8/0xe4)
[    2.195962] [<c04d4b20>] (kernel_init+0x8/0xe4) from [<c0013410>] (ret_from_fork+0x14/0x24)
[    2.204905] ---[ end trace 8f61b319779f6e57 ]---

Regards,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support
@ 2013-02-13 13:43       ` Bedia, Vaibhav
  0 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-02-13 13:43 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Kevin,

On Tue, Feb 12, 2013 at 06:57:50, Kevin Hilman wrote:
[...]
> > +
> > +void (*am33xx_do_wfi_sram)(void);
> 
> static?

Will fix.

[...]

> > +
> > +	/*
> > +	 * By default the following IPs do not have MSTANDBY asserted
> > +	 * which is necessary for PER domain transition. If the drivers
> > +	 * are not compiled into the kernel HWMOD code will not change the
> > +	 * state of the IPs if the IP was not never enabled. To ensure
> > +	 * that there no issues with or without the drivers being compiled
> > +	 * in the kernel, we forcefully put these IPs to idle.
> > +	 */
> > +	omap_hwmod_enable(usb_oh);
> > +	omap_hwmod_enable(tptc0_oh);
> > +	omap_hwmod_enable(tptc1_oh);
> > +	omap_hwmod_enable(tptc2_oh);
> > +	omap_hwmod_enable(cpsw_oh);
> > +
> > +	omap_hwmod_idle(usb_oh);
> > +	omap_hwmod_idle(tptc0_oh);
> > +	omap_hwmod_idle(tptc1_oh);
> > +	omap_hwmod_idle(tptc2_oh);
> > +	omap_hwmod_idle(cpsw_oh);
> 
> I think I asked this in my review of v1, but why does this need to
> happen on every suspend attempt?
> 
> This should happen once on init, which will handle the case where there
> are no drivers, and if there are drivers, then the drivers need to
> handle this properly.  
> 
> I don't like this happening here on every suspend attempt, because it
> will surely hide bugs where drivers are not properly managing their own PM.
> 

By default these IPs don't have MSTANDBY asserted. When a low power transition
happens, the peripheral power domain loses context and hence the forced
MSTANDBY configuration in the IP is lost. To work around this problem we need
to assert MSTANDBY in every suspend-resume iteration.

I agree that this might hide PM bugs in the driver but to solve this problem we
need some mechanism for the PM code to know whether or not a driver is bound
to the corresponding platform devices. Any suggestions on this?

> > +	/* Try to put GFX to sleep */
> > +	pwrdm_set_next_fpwrst(gfx_pwrdm, PWRDM_FUNC_PWRST_OFF);
> > +
> > +	ret = cpu_suspend(0, am33xx_do_sram_idle);
> > +	status = pwrdm_read_fpwrst(gfx_pwrdm);
> > +	if (status != PWRDM_FUNC_PWRST_OFF)
> > +		pr_err("GFX domain did not transition\n");
> > +	else
> > +		pr_info("GFX domain entered low power state\n");
> 
> Do you really want this printed every time?
> 

Hmm... it could perhaps be clubbed with the overall status that's
printed. I kept it here since the GFX power domain is completely
under MPU control and hence this information would be useful in
finding out if there's a problem with the GFX suspend-resume.

> > +	/*
> > +	 * GFX_L4LS clock domain needs to be woken up to
> > +	 * ensure thet L4LS clock domain does not get stuck in transition
> > +	 * If that happens L3 module does not get disabled, thereby leading
> > +	 * to PER power domain transition failing
> > +	 *
> > +	 * The clock framework should take care of ensuring
> > +	 * that the clock domain is in the right state when
> > +	 * GFX driver is active.
> 
> Are you suggesting that the clock framework is not doing this already?
> 

No. This clkdm_*() calls are here to work-around an issue that I observed
when implementing suspend-resume. The force wakeup and sleep of the gfx_l4ls
clock domain across every suspend-resume is something I don't think can
be pushed to the clock framework.

> > +	 */
> > +	clkdm_wakeup(gfx_l4ls_clkdm);
> > +	clkdm_sleep(gfx_l4ls_clkdm);
> > +
> > +	if (ret) {
> > +		pr_err("Kernel suspend failure\n");
> > +	} else {
> > +		status = omap_ctrl_readl(AM33XX_CONTROL_IPC_MSG_REG1);
> 
> We're trying to git rid of direct control module register access, and
> consolidate them into control.c (for an eventual move to a driver.)  I
> see you've mostly done that in other parts of the series, but here's one
> that needs to move.

Yes, I somehow missed this one. Will take care of it in the next version.

> 
> > +		status &= IPC_RESP_MASK;
> > +		status >>= __ffs(IPC_RESP_MASK);
> > +
> > +		switch (status) {
> > +		case 0:
> > +			pr_info("Successfully put all powerdomains to target state\n");
> > +			/*
> > +			 * XXX: Leads to loss of logic state in PER power domain
> > +			 * Use SOC specific ops for this?
> > +			 */
> 
> huh?
> 

Ah... this is more of a TODO. There's no previous state entered information
in the PRCM registers. So to ensure that the drivers get the right information
when they check with the PM layer about the loss of context and hence the need
to restore the registers, I need to update the logic and membank state counters
for the PER power domain manually. I was thinking of leveraging the SoC specific
power domain ops for doing this.

[...]

> > +
> > +	/* Give some time to M3 to respond. 500msec is a random value here */
> 
> random?  really?

Sort of. I don't have any numbers from the h/w guys on the worst
case delay in getting an interrupt from M3 to MPU. At the same time
I want to handle the scenario where something goes wrong on the M3
side and it doesn't respond.

[...]

> > +
> > +/*
> > + * Dummy notifier for the mailbox
> > + * XXX: Get rid of this requirement once the MBX driver has been finalized
> 
> IIRC, I suggested a trivial fix to the mailbox driver that would remove
> the need for this, which could be done today.
> 

Yes. I plan to do that once the mailbox code movement to drivers/ along with
other changes to make it generic enough are finalized. It was adding in one
more dependency and hence I kept this as a TODO in this version.

[...]

> > +static int wkup_m3_init(void)
> > +{
> > +	int irq, ret = 0;
> > +	struct resource *mem;
> > +	struct platform_device *pdev = to_platform_device(wkup_m3->dev);
> > +
> > +	omap_device_enable_hwmods(to_omap_device(pdev));
> 
> Why not omap_device_enable(pdev) ?
> 

The objective is to leverage the hwmod code to get the WKUP-M3
functional and not have OMAP runtime PM code coming in the way. 
Using omap_device_enable() triggers the following dev_warn()
from omap_device_enable().

[    2.033718] platform 44d00000.wkup_m3: omap_device_late_idle: enabled but no driver.  Idling
[    2.042676] ------------[ cut here ]------------
[    2.047572] WARNING: at arch/arm/mach-omap2/omap_hwmod.c:2187 _idle+0x164/0x1c0()
[    2.055459] omap_hwmod: wkup_m3: idle state can only be entered from enabled state
[    2.063435] Modules linked in:
[    2.066712] [<c001afe4>] (unwind_backtrace+0x0/0xf0) from [<c004380c>] (warn_slowpath_common+0x4c/0x64)
[    2.076626] [<c004380c>] (warn_slowpath_common+0x4c/0x64) from [<c00438b8>] (warn_slowpath_fmt+0x30/0x40)
[    2.086720] [<c00438b8>] (warn_slowpath_fmt+0x30/0x40) from [<c002aad0>] (_idle+0x164/0x1c0)
[    2.095624] [<c002aad0>] (_idle+0x164/0x1c0) from [<c002af98>] (omap_hwmod_idle+0x24/0x40)
[    2.104348] [<c002af98>] (omap_hwmod_idle+0x24/0x40) from [<c002bd60>] (omap_device_idle_hwmods+0x24/0x3c)
[    2.114536] [<c002bd60>] (omap_device_idle_hwmods+0x24/0x3c) from [<c002bf4c>] (_omap_device_deactivate+0x98/0x134)
[    2.125546] [<c002bf4c>] (_omap_device_deactivate+0x98/0x134) from [<c002c87c>] (omap_device_idle+0x28/0x54)
[    2.135921] [<c002c87c>] (omap_device_idle+0x28/0x54) from [<c06ec00c>] (omap_device_late_idle+0x44/0x54)
[    2.146025] [<c06ec00c>] (omap_device_late_idle+0x44/0x54) from [<c031f850>] (bus_for_each_dev+0x50/0x7c)
[    2.156120] [<c031f850>] (bus_for_each_dev+0x50/0x7c) from [<c06ebe10>] (omap_device_late_init+0x18/0x28)
[    2.166216] [<c06ebe10>] (omap_device_late_init+0x18/0x28) from [<c00086e4>] (do_one_initcall+0x34/0x180)
[    2.176314] [<c00086e4>] (do_one_initcall+0x34/0x180) from [<c06df8f8>] (kernel_init_freeable+0xfc/0x1cc)
[    2.186408] [<c06df8f8>] (kernel_init_freeable+0xfc/0x1cc) from [<c04d4b20>] (kernel_init+0x8/0xe4)
[    2.195962] [<c04d4b20>] (kernel_init+0x8/0xe4) from [<c0013410>] (ret_from_fork+0x14/0x24)
[    2.204905] ---[ end trace 8f61b319779f6e57 ]---

Regards,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support
  2013-02-13 13:43       ` Bedia, Vaibhav
@ 2013-02-18 16:11         ` Kevin Hilman
  -1 siblings, 0 replies; 148+ messages in thread
From: Kevin Hilman @ 2013-02-18 16:11 UTC (permalink / raw)
  To: Bedia, Vaibhav
  Cc: linux-omap, linux-arm-kernel, tony, Shilimkar, Santosh, Cousson,
	Benoit, Paul Walmsley

"Bedia, Vaibhav" <vaibhav.bedia@ti.com> writes:

> Hi Kevin,
>
> On Tue, Feb 12, 2013 at 06:57:50, Kevin Hilman wrote:
> [...]
>> > +
>> > +void (*am33xx_do_wfi_sram)(void);
>> 
>> static?
>
> Will fix.
>
> [...]
>
>> > +
>> > +	/*
>> > +	 * By default the following IPs do not have MSTANDBY asserted
>> > +	 * which is necessary for PER domain transition. If the drivers
>> > +	 * are not compiled into the kernel HWMOD code will not change the
>> > +	 * state of the IPs if the IP was not never enabled. To ensure
>> > +	 * that there no issues with or without the drivers being compiled
>> > +	 * in the kernel, we forcefully put these IPs to idle.
>> > +	 */
>> > +	omap_hwmod_enable(usb_oh);
>> > +	omap_hwmod_enable(tptc0_oh);
>> > +	omap_hwmod_enable(tptc1_oh);
>> > +	omap_hwmod_enable(tptc2_oh);
>> > +	omap_hwmod_enable(cpsw_oh);
>> > +
>> > +	omap_hwmod_idle(usb_oh);
>> > +	omap_hwmod_idle(tptc0_oh);
>> > +	omap_hwmod_idle(tptc1_oh);
>> > +	omap_hwmod_idle(tptc2_oh);
>> > +	omap_hwmod_idle(cpsw_oh);
>> 
>> I think I asked this in my review of v1, but why does this need to
>> happen on every suspend attempt?
>> 
>> This should happen once on init, which will handle the case where there
>> are no drivers, and if there are drivers, then the drivers need to
>> handle this properly.  
>> 
>> I don't like this happening here on every suspend attempt, because it
>> will surely hide bugs where drivers are not properly managing their own PM.
>> 
>
> By default these IPs don't have MSTANDBY asserted.

When you say "by default", I guess you mean after reset (and/or context
loss), right?

> When a low power transition happens, the peripheral power domain loses
> context and hence the forced MSTANDBY configuration in the IP is
> lost. To work around this problem we need to assert MSTANDBY in every
> suspend-resume iteration.

Yuck.  More clever hardware.  ;)

> I agree that this might hide PM bugs in the driver but to solve this problem we
> need some mechanism for the PM code to know whether or not a driver is bound
> to the corresponding platform devices. Any suggestions on this?

Driver bound status can be tracked easily using bus notifiers.  You can
see an example in the omap_device core.

>> > +	/* Try to put GFX to sleep */
>> > +	pwrdm_set_next_fpwrst(gfx_pwrdm, PWRDM_FUNC_PWRST_OFF);
>> > +
>> > +	ret = cpu_suspend(0, am33xx_do_sram_idle);
>> > +	status = pwrdm_read_fpwrst(gfx_pwrdm);
>> > +	if (status != PWRDM_FUNC_PWRST_OFF)
>> > +		pr_err("GFX domain did not transition\n");
>> > +	else
>> > +		pr_info("GFX domain entered low power state\n");
>> 
>> Do you really want this printed every time?
>> 
>
> Hmm... it could perhaps be clubbed with the overall status that's
> printed. I kept it here since the GFX power domain is completely
> under MPU control and hence this information would be useful in
> finding out if there's a problem with the GFX suspend-resume.

OK.

>> > +	/*
>> > +	 * GFX_L4LS clock domain needs to be woken up to
>> > +	 * ensure thet L4LS clock domain does not get stuck in transition
>> > +	 * If that happens L3 module does not get disabled, thereby leading
>> > +	 * to PER power domain transition failing
>> > +	 *
>> > +	 * The clock framework should take care of ensuring
>> > +	 * that the clock domain is in the right state when
>> > +	 * GFX driver is active.
>> 
>> Are you suggesting that the clock framework is not doing this already?
>> 
>
> No. This clkdm_*() calls are here to work-around an issue that I observed
> when implementing suspend-resume. The force wakeup and sleep of the gfx_l4ls
> clock domain across every suspend-resume is something I don't think can
> be pushed to the clock framework.

I still don't follow what you're suggesting the clock framework "should"
do.  Are you describing the case when there is a GFX driver vs. when
there isn't a driver?  If so, it needs to be more clear.

Also, some more description about why the device gets 'stuck in
transition' would be helpful.  Is this an erratum workaround?

>> > +	 */
>> > +	clkdm_wakeup(gfx_l4ls_clkdm);
>> > +	clkdm_sleep(gfx_l4ls_clkdm);
>> > +
>> > +	if (ret) {
>> > +		pr_err("Kernel suspend failure\n");
>> > +	} else {
>> > +		status = omap_ctrl_readl(AM33XX_CONTROL_IPC_MSG_REG1);
>> 
>> We're trying to git rid of direct control module register access, and
>> consolidate them into control.c (for an eventual move to a driver.)  I
>> see you've mostly done that in other parts of the series, but here's one
>> that needs to move.
>
> Yes, I somehow missed this one. Will take care of it in the next version.
>
>> 
>> > +		status &= IPC_RESP_MASK;
>> > +		status >>= __ffs(IPC_RESP_MASK);
>> > +
>> > +		switch (status) {
>> > +		case 0:
>> > +			pr_info("Successfully put all powerdomains to target state\n");
>> > +			/*
>> > +			 * XXX: Leads to loss of logic state in PER power domain
>> > +			 * Use SOC specific ops for this?
>> > +			 */
>> 
>> huh?
>> 
>
> Ah... this is more of a TODO. There's no previous state entered information
> in the PRCM registers. So to ensure that the drivers get the right information
> when they check with the PM layer about the loss of context and hence the need
> to restore the registers, I need to update the logic and membank state counters
> for the PER power domain manually. I was thinking of leveraging the SoC specific
> power domain ops for doing this.
>
> [...]

I see, then probably a TODO here with more description would be more
helpful. 

So, IIUC, without implemeting this, the drivers will never be able to
detect loss of context, correct?  Sounds like something that should be
decribed in the changelog as that's a rather important limitation to
this implementaion.

>> > +
>> > +	/* Give some time to M3 to respond. 500msec is a random value here */
>> 
>> random?  really?
>
> Sort of. I don't have any numbers from the h/w guys on the worst
> case delay in getting an interrupt from M3 to MPU. At the same time
> I want to handle the scenario where something goes wrong on the M3
> side and it doesn't respond.

OK, then it's not random.  You have some reasoning behind the number
that should be documented.

That being said, in the absence of numbers from HW folks, can't you
measure the typical times so you know roughly what's "normal".  

>
>> > +
>> > +/*
>> > + * Dummy notifier for the mailbox
>> > + * XXX: Get rid of this requirement once the MBX driver has been finalized
>> 
>> IIRC, I suggested a trivial fix to the mailbox driver that would remove
>> the need for this, which could be done today.
>> 
>
> Yes. I plan to do that once the mailbox code movement to drivers/ along with
> other changes to make it generic enough are finalized. It was adding in one
> more dependency and hence I kept this as a TODO in this version.

OK, fair enough.

>> > +static int wkup_m3_init(void)
>> > +{
>> > +	int irq, ret = 0;
>> > +	struct resource *mem;
>> > +	struct platform_device *pdev = to_platform_device(wkup_m3->dev);
>> > +
>> > +	omap_device_enable_hwmods(to_omap_device(pdev));
>> 
>> Why not omap_device_enable(pdev) ?
>> 
>
> The objective is to leverage the hwmod code to get the WKUP-M3
> functional and not have OMAP runtime PM code coming in the way. 

FWIW, it is not runtime PM getting in the way.

> Using omap_device_enable() triggers the following dev_warn()
> from omap_device_enable().

Looking closer at the trace, you'll see it's not omap_device_enable()
that is triggering this warning.  What is happening is that omap_device
has a late_initcall which forcibly idles omap_devices that have been
enabled, but that don't have a driver.  You're hacking around that.

IMO, this would be a much cleaner implementation if you just created a
small driver for the wkup_m3.  You're already doing a bunch of
driver-like stuff for it (requesting base/IRQs, mapping regions,
firmware, etc.)  I think this should separated out into a real driver.
Then it will be bound to the right omap_device, and normal PM operations
will work as expected.

Also, doing it this way will be more flexible for those wanting to use
their own firmware on the M3, or customize the current firmware.

> [    2.033718] platform 44d00000.wkup_m3: omap_device_late_idle: enabled but no driver.  Idling
> [    2.042676] ------------[ cut here ]------------
> [    2.047572] WARNING: at arch/arm/mach-omap2/omap_hwmod.c:2187 _idle+0x164/0x1c0()
> [    2.055459] omap_hwmod: wkup_m3: idle state can only be entered from enabled state
> [    2.063435] Modules linked in:
> [    2.066712] [<c001afe4>] (unwind_backtrace+0x0/0xf0) from [<c004380c>] (warn_slowpath_common+0x4c/0x64)
> [ 2.076626] [<c004380c>] (warn_slowpath_common+0x4c/0x64) from
> [<c00438b8>] (warn_slowpath_fmt+0x30/0x40)
> [    2.086720] [<c00438b8>] (warn_slowpath_fmt+0x30/0x40) from [<c002aad0>] (_idle+0x164/0x1c0)
> [    2.095624] [<c002aad0>] (_idle+0x164/0x1c0) from [<c002af98>] (omap_hwmod_idle+0x24/0x40)
> [ 2.104348] [<c002af98>] (omap_hwmod_idle+0x24/0x40) from [<c002bd60>]
> (omap_device_idle_hwmods+0x24/0x3c)
> [ 2.114536] [<c002bd60>] (omap_device_idle_hwmods+0x24/0x3c) from
> [<c002bf4c>] (_omap_device_deactivate+0x98/0x134)
> [ 2.125546] [<c002bf4c>] (_omap_device_deactivate+0x98/0x134) from
> [<c002c87c>] (omap_device_idle+0x28/0x54)
> [ 2.135921] [<c002c87c>] (omap_device_idle+0x28/0x54) from
> [<c06ec00c>] (omap_device_late_idle+0x44/0x54)
> [ 2.146025] [<c06ec00c>] (omap_device_late_idle+0x44/0x54) from
> [<c031f850>] (bus_for_each_dev+0x50/0x7c)
> [ 2.156120] [<c031f850>] (bus_for_each_dev+0x50/0x7c) from
> [<c06ebe10>] (omap_device_late_init+0x18/0x28)
> [ 2.166216] [<c06ebe10>] (omap_device_late_init+0x18/0x28) from
> [<c00086e4>] (do_one_initcall+0x34/0x180)
> [ 2.176314] [<c00086e4>] (do_one_initcall+0x34/0x180) from
> [<c06df8f8>] (kernel_init_freeable+0xfc/0x1cc)
> [    2.186408] [<c06df8f8>] (kernel_init_freeable+0xfc/0x1cc) from [<c04d4b20>] (kernel_init+0x8/0xe4)
> [    2.195962] [<c04d4b20>] (kernel_init+0x8/0xe4) from [<c0013410>] (ret_from_fork+0x14/0x24)
> [    2.204905] ---[ end trace 8f61b319779f6e57 ]---

Kevin


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support
@ 2013-02-18 16:11         ` Kevin Hilman
  0 siblings, 0 replies; 148+ messages in thread
From: Kevin Hilman @ 2013-02-18 16:11 UTC (permalink / raw)
  To: linux-arm-kernel

"Bedia, Vaibhav" <vaibhav.bedia@ti.com> writes:

> Hi Kevin,
>
> On Tue, Feb 12, 2013 at 06:57:50, Kevin Hilman wrote:
> [...]
>> > +
>> > +void (*am33xx_do_wfi_sram)(void);
>> 
>> static?
>
> Will fix.
>
> [...]
>
>> > +
>> > +	/*
>> > +	 * By default the following IPs do not have MSTANDBY asserted
>> > +	 * which is necessary for PER domain transition. If the drivers
>> > +	 * are not compiled into the kernel HWMOD code will not change the
>> > +	 * state of the IPs if the IP was not never enabled. To ensure
>> > +	 * that there no issues with or without the drivers being compiled
>> > +	 * in the kernel, we forcefully put these IPs to idle.
>> > +	 */
>> > +	omap_hwmod_enable(usb_oh);
>> > +	omap_hwmod_enable(tptc0_oh);
>> > +	omap_hwmod_enable(tptc1_oh);
>> > +	omap_hwmod_enable(tptc2_oh);
>> > +	omap_hwmod_enable(cpsw_oh);
>> > +
>> > +	omap_hwmod_idle(usb_oh);
>> > +	omap_hwmod_idle(tptc0_oh);
>> > +	omap_hwmod_idle(tptc1_oh);
>> > +	omap_hwmod_idle(tptc2_oh);
>> > +	omap_hwmod_idle(cpsw_oh);
>> 
>> I think I asked this in my review of v1, but why does this need to
>> happen on every suspend attempt?
>> 
>> This should happen once on init, which will handle the case where there
>> are no drivers, and if there are drivers, then the drivers need to
>> handle this properly.  
>> 
>> I don't like this happening here on every suspend attempt, because it
>> will surely hide bugs where drivers are not properly managing their own PM.
>> 
>
> By default these IPs don't have MSTANDBY asserted.

When you say "by default", I guess you mean after reset (and/or context
loss), right?

> When a low power transition happens, the peripheral power domain loses
> context and hence the forced MSTANDBY configuration in the IP is
> lost. To work around this problem we need to assert MSTANDBY in every
> suspend-resume iteration.

Yuck.  More clever hardware.  ;)

> I agree that this might hide PM bugs in the driver but to solve this problem we
> need some mechanism for the PM code to know whether or not a driver is bound
> to the corresponding platform devices. Any suggestions on this?

Driver bound status can be tracked easily using bus notifiers.  You can
see an example in the omap_device core.

>> > +	/* Try to put GFX to sleep */
>> > +	pwrdm_set_next_fpwrst(gfx_pwrdm, PWRDM_FUNC_PWRST_OFF);
>> > +
>> > +	ret = cpu_suspend(0, am33xx_do_sram_idle);
>> > +	status = pwrdm_read_fpwrst(gfx_pwrdm);
>> > +	if (status != PWRDM_FUNC_PWRST_OFF)
>> > +		pr_err("GFX domain did not transition\n");
>> > +	else
>> > +		pr_info("GFX domain entered low power state\n");
>> 
>> Do you really want this printed every time?
>> 
>
> Hmm... it could perhaps be clubbed with the overall status that's
> printed. I kept it here since the GFX power domain is completely
> under MPU control and hence this information would be useful in
> finding out if there's a problem with the GFX suspend-resume.

OK.

>> > +	/*
>> > +	 * GFX_L4LS clock domain needs to be woken up to
>> > +	 * ensure thet L4LS clock domain does not get stuck in transition
>> > +	 * If that happens L3 module does not get disabled, thereby leading
>> > +	 * to PER power domain transition failing
>> > +	 *
>> > +	 * The clock framework should take care of ensuring
>> > +	 * that the clock domain is in the right state when
>> > +	 * GFX driver is active.
>> 
>> Are you suggesting that the clock framework is not doing this already?
>> 
>
> No. This clkdm_*() calls are here to work-around an issue that I observed
> when implementing suspend-resume. The force wakeup and sleep of the gfx_l4ls
> clock domain across every suspend-resume is something I don't think can
> be pushed to the clock framework.

I still don't follow what you're suggesting the clock framework "should"
do.  Are you describing the case when there is a GFX driver vs. when
there isn't a driver?  If so, it needs to be more clear.

Also, some more description about why the device gets 'stuck in
transition' would be helpful.  Is this an erratum workaround?

>> > +	 */
>> > +	clkdm_wakeup(gfx_l4ls_clkdm);
>> > +	clkdm_sleep(gfx_l4ls_clkdm);
>> > +
>> > +	if (ret) {
>> > +		pr_err("Kernel suspend failure\n");
>> > +	} else {
>> > +		status = omap_ctrl_readl(AM33XX_CONTROL_IPC_MSG_REG1);
>> 
>> We're trying to git rid of direct control module register access, and
>> consolidate them into control.c (for an eventual move to a driver.)  I
>> see you've mostly done that in other parts of the series, but here's one
>> that needs to move.
>
> Yes, I somehow missed this one. Will take care of it in the next version.
>
>> 
>> > +		status &= IPC_RESP_MASK;
>> > +		status >>= __ffs(IPC_RESP_MASK);
>> > +
>> > +		switch (status) {
>> > +		case 0:
>> > +			pr_info("Successfully put all powerdomains to target state\n");
>> > +			/*
>> > +			 * XXX: Leads to loss of logic state in PER power domain
>> > +			 * Use SOC specific ops for this?
>> > +			 */
>> 
>> huh?
>> 
>
> Ah... this is more of a TODO. There's no previous state entered information
> in the PRCM registers. So to ensure that the drivers get the right information
> when they check with the PM layer about the loss of context and hence the need
> to restore the registers, I need to update the logic and membank state counters
> for the PER power domain manually. I was thinking of leveraging the SoC specific
> power domain ops for doing this.
>
> [...]

I see, then probably a TODO here with more description would be more
helpful. 

So, IIUC, without implemeting this, the drivers will never be able to
detect loss of context, correct?  Sounds like something that should be
decribed in the changelog as that's a rather important limitation to
this implementaion.

>> > +
>> > +	/* Give some time to M3 to respond. 500msec is a random value here */
>> 
>> random?  really?
>
> Sort of. I don't have any numbers from the h/w guys on the worst
> case delay in getting an interrupt from M3 to MPU. At the same time
> I want to handle the scenario where something goes wrong on the M3
> side and it doesn't respond.

OK, then it's not random.  You have some reasoning behind the number
that should be documented.

That being said, in the absence of numbers from HW folks, can't you
measure the typical times so you know roughly what's "normal".  

>
>> > +
>> > +/*
>> > + * Dummy notifier for the mailbox
>> > + * XXX: Get rid of this requirement once the MBX driver has been finalized
>> 
>> IIRC, I suggested a trivial fix to the mailbox driver that would remove
>> the need for this, which could be done today.
>> 
>
> Yes. I plan to do that once the mailbox code movement to drivers/ along with
> other changes to make it generic enough are finalized. It was adding in one
> more dependency and hence I kept this as a TODO in this version.

OK, fair enough.

>> > +static int wkup_m3_init(void)
>> > +{
>> > +	int irq, ret = 0;
>> > +	struct resource *mem;
>> > +	struct platform_device *pdev = to_platform_device(wkup_m3->dev);
>> > +
>> > +	omap_device_enable_hwmods(to_omap_device(pdev));
>> 
>> Why not omap_device_enable(pdev) ?
>> 
>
> The objective is to leverage the hwmod code to get the WKUP-M3
> functional and not have OMAP runtime PM code coming in the way. 

FWIW, it is not runtime PM getting in the way.

> Using omap_device_enable() triggers the following dev_warn()
> from omap_device_enable().

Looking closer at the trace, you'll see it's not omap_device_enable()
that is triggering this warning.  What is happening is that omap_device
has a late_initcall which forcibly idles omap_devices that have been
enabled, but that don't have a driver.  You're hacking around that.

IMO, this would be a much cleaner implementation if you just created a
small driver for the wkup_m3.  You're already doing a bunch of
driver-like stuff for it (requesting base/IRQs, mapping regions,
firmware, etc.)  I think this should separated out into a real driver.
Then it will be bound to the right omap_device, and normal PM operations
will work as expected.

Also, doing it this way will be more flexible for those wanting to use
their own firmware on the M3, or customize the current firmware.

> [    2.033718] platform 44d00000.wkup_m3: omap_device_late_idle: enabled but no driver.  Idling
> [    2.042676] ------------[ cut here ]------------
> [    2.047572] WARNING: at arch/arm/mach-omap2/omap_hwmod.c:2187 _idle+0x164/0x1c0()
> [    2.055459] omap_hwmod: wkup_m3: idle state can only be entered from enabled state
> [    2.063435] Modules linked in:
> [    2.066712] [<c001afe4>] (unwind_backtrace+0x0/0xf0) from [<c004380c>] (warn_slowpath_common+0x4c/0x64)
> [ 2.076626] [<c004380c>] (warn_slowpath_common+0x4c/0x64) from
> [<c00438b8>] (warn_slowpath_fmt+0x30/0x40)
> [    2.086720] [<c00438b8>] (warn_slowpath_fmt+0x30/0x40) from [<c002aad0>] (_idle+0x164/0x1c0)
> [    2.095624] [<c002aad0>] (_idle+0x164/0x1c0) from [<c002af98>] (omap_hwmod_idle+0x24/0x40)
> [ 2.104348] [<c002af98>] (omap_hwmod_idle+0x24/0x40) from [<c002bd60>]
> (omap_device_idle_hwmods+0x24/0x3c)
> [ 2.114536] [<c002bd60>] (omap_device_idle_hwmods+0x24/0x3c) from
> [<c002bf4c>] (_omap_device_deactivate+0x98/0x134)
> [ 2.125546] [<c002bf4c>] (_omap_device_deactivate+0x98/0x134) from
> [<c002c87c>] (omap_device_idle+0x28/0x54)
> [ 2.135921] [<c002c87c>] (omap_device_idle+0x28/0x54) from
> [<c06ec00c>] (omap_device_late_idle+0x44/0x54)
> [ 2.146025] [<c06ec00c>] (omap_device_late_idle+0x44/0x54) from
> [<c031f850>] (bus_for_each_dev+0x50/0x7c)
> [ 2.156120] [<c031f850>] (bus_for_each_dev+0x50/0x7c) from
> [<c06ebe10>] (omap_device_late_init+0x18/0x28)
> [ 2.166216] [<c06ebe10>] (omap_device_late_init+0x18/0x28) from
> [<c00086e4>] (do_one_initcall+0x34/0x180)
> [ 2.176314] [<c00086e4>] (do_one_initcall+0x34/0x180) from
> [<c06df8f8>] (kernel_init_freeable+0xfc/0x1cc)
> [    2.186408] [<c06df8f8>] (kernel_init_freeable+0xfc/0x1cc) from [<c04d4b20>] (kernel_init+0x8/0xe4)
> [    2.195962] [<c04d4b20>] (kernel_init+0x8/0xe4) from [<c0013410>] (ret_from_fork+0x14/0x24)
> [    2.204905] ---[ end trace 8f61b319779f6e57 ]---

Kevin

^ permalink raw reply	[flat|nested] 148+ messages in thread

* RE: [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support
  2013-02-18 16:11         ` Kevin Hilman
@ 2013-02-20  9:21           ` Bedia, Vaibhav
  -1 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-02-20  9:21 UTC (permalink / raw)
  To: Kevin Hilman
  Cc: linux-omap, linux-arm-kernel, tony, Shilimkar, Santosh, Cousson,
	Benoit, Paul Walmsley

On Mon, Feb 18, 2013 at 21:41:49, Kevin Hilman wrote:
[...]
> > By default these IPs don't have MSTANDBY asserted.
> 
> When you say "by default", I guess you mean after reset (and/or context
> loss), right?
> 

Yes
> > When a low power transition happens, the peripheral power domain loses
> > context and hence the forced MSTANDBY configuration in the IP is
> > lost. To work around this problem we need to assert MSTANDBY in every
> > suspend-resume iteration.
> 
> Yuck.  More clever hardware.  ;)

We are getting this gradually :)

> 
> > I agree that this might hide PM bugs in the driver but to solve this problem we
> > need some mechanism for the PM code to know whether or not a driver is bound
> > to the corresponding platform devices. Any suggestions on this?
> 
> Driver bound status can be tracked easily using bus notifiers.  You can
> see an example in the omap_device core.

Ok. I'll try to use the driver bound status in the next version.

[...]

> >> > +	/*
> >> > +	 * GFX_L4LS clock domain needs to be woken up to
> >> > +	 * ensure thet L4LS clock domain does not get stuck in transition
> >> > +	 * If that happens L3 module does not get disabled, thereby leading
> >> > +	 * to PER power domain transition failing
> >> > +	 *
> >> > +	 * The clock framework should take care of ensuring
> >> > +	 * that the clock domain is in the right state when
> >> > +	 * GFX driver is active.
> >> 
> >> Are you suggesting that the clock framework is not doing this already?
> >> 
> >
> > No. This clkdm_*() calls are here to work-around an issue that I observed
> > when implementing suspend-resume. The force wakeup and sleep of the gfx_l4ls
> > clock domain across every suspend-resume is something I don't think can
> > be pushed to the clock framework.
> 
> I still don't follow what you're suggesting the clock framework "should"
> do.  Are you describing the case when there is a GFX driver vs. when
> there isn't a driver?  If so, it needs to be more clear.
>

No. The issue with GFX_L4LS happens irrespective of the state of the GFX driver and
needs to be handled in the suspend-resume sequence. I guess the second part of
comment is what created the confusion. I'll get rid of that.
 
> Also, some more description about why the device gets 'stuck in
> transition' would be helpful.  Is this an erratum workaround?
> 

I'll follow up with the design folks to find out more. From some past discussions
this is not expected so looks like we need to an erratum published for this issue.

> 
> I see, then probably a TODO here with more description would be more
> helpful. 
> 
> So, IIUC, without implemeting this, the drivers will never be able to
> detect loss of context, correct?  Sounds like something that should be
> decribed in the changelog as that's a rather important limitation to
> this implementaion.
> 

Ok. I'll address this limitation in the next version and improve the changelog.

> >> > +
> >> > +	/* Give some time to M3 to respond. 500msec is a random value here */
> >> 
> >> random?  really?
> >
> > Sort of. I don't have any numbers from the h/w guys on the worst
> > case delay in getting an interrupt from M3 to MPU. At the same time
> > I want to handle the scenario where something goes wrong on the M3
> > side and it doesn't respond.
> 
> OK, then it's not random.  You have some reasoning behind the number
> that should be documented.

Will do.

> 
> That being said, in the absence of numbers from HW folks, can't you
> measure the typical times so you know roughly what's "normal".  

I'll do some timer based profiling and get rough numbers for this.

[...]

> >> 
> >> Why not omap_device_enable(pdev) ?
> >> 
> >
> > The objective is to leverage the hwmod code to get the WKUP-M3
> > functional and not have OMAP runtime PM code coming in the way. 
> 
> FWIW, it is not runtime PM getting in the way.
> 
> > Using omap_device_enable() triggers the following dev_warn()
> > from omap_device_enable().
> 
> Looking closer at the trace, you'll see it's not omap_device_enable()
> that is triggering this warning.  What is happening is that omap_device
> has a late_initcall which forcibly idles omap_devices that have been
> enabled, but that don't have a driver.  You're hacking around that.
> 

Thanks for the explanation. I should have looked closer :(

> IMO, this would be a much cleaner implementation if you just created a
> small driver for the wkup_m3.  You're already doing a bunch of
> driver-like stuff for it (requesting base/IRQs, mapping regions,
> firmware, etc.)  I think this should separated out into a real driver.
> Then it will be bound to the right omap_device, and normal PM operations
> will work as expected.
> 
> Also, doing it this way will be more flexible for those wanting to use
> their own firmware on the M3, or customize the current firmware.

Hmm... that definitely sounds more flexible. It should also help in the next SoC
AM437x which has a similar PM architecture. Where would you suggest placing
this minimal driver?

Regards,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support
@ 2013-02-20  9:21           ` Bedia, Vaibhav
  0 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-02-20  9:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Feb 18, 2013 at 21:41:49, Kevin Hilman wrote:
[...]
> > By default these IPs don't have MSTANDBY asserted.
> 
> When you say "by default", I guess you mean after reset (and/or context
> loss), right?
> 

Yes
> > When a low power transition happens, the peripheral power domain loses
> > context and hence the forced MSTANDBY configuration in the IP is
> > lost. To work around this problem we need to assert MSTANDBY in every
> > suspend-resume iteration.
> 
> Yuck.  More clever hardware.  ;)

We are getting this gradually :)

> 
> > I agree that this might hide PM bugs in the driver but to solve this problem we
> > need some mechanism for the PM code to know whether or not a driver is bound
> > to the corresponding platform devices. Any suggestions on this?
> 
> Driver bound status can be tracked easily using bus notifiers.  You can
> see an example in the omap_device core.

Ok. I'll try to use the driver bound status in the next version.

[...]

> >> > +	/*
> >> > +	 * GFX_L4LS clock domain needs to be woken up to
> >> > +	 * ensure thet L4LS clock domain does not get stuck in transition
> >> > +	 * If that happens L3 module does not get disabled, thereby leading
> >> > +	 * to PER power domain transition failing
> >> > +	 *
> >> > +	 * The clock framework should take care of ensuring
> >> > +	 * that the clock domain is in the right state when
> >> > +	 * GFX driver is active.
> >> 
> >> Are you suggesting that the clock framework is not doing this already?
> >> 
> >
> > No. This clkdm_*() calls are here to work-around an issue that I observed
> > when implementing suspend-resume. The force wakeup and sleep of the gfx_l4ls
> > clock domain across every suspend-resume is something I don't think can
> > be pushed to the clock framework.
> 
> I still don't follow what you're suggesting the clock framework "should"
> do.  Are you describing the case when there is a GFX driver vs. when
> there isn't a driver?  If so, it needs to be more clear.
>

No. The issue with GFX_L4LS happens irrespective of the state of the GFX driver and
needs to be handled in the suspend-resume sequence. I guess the second part of
comment is what created the confusion. I'll get rid of that.
 
> Also, some more description about why the device gets 'stuck in
> transition' would be helpful.  Is this an erratum workaround?
> 

I'll follow up with the design folks to find out more. From some past discussions
this is not expected so looks like we need to an erratum published for this issue.

> 
> I see, then probably a TODO here with more description would be more
> helpful. 
> 
> So, IIUC, without implemeting this, the drivers will never be able to
> detect loss of context, correct?  Sounds like something that should be
> decribed in the changelog as that's a rather important limitation to
> this implementaion.
> 

Ok. I'll address this limitation in the next version and improve the changelog.

> >> > +
> >> > +	/* Give some time to M3 to respond. 500msec is a random value here */
> >> 
> >> random?  really?
> >
> > Sort of. I don't have any numbers from the h/w guys on the worst
> > case delay in getting an interrupt from M3 to MPU. At the same time
> > I want to handle the scenario where something goes wrong on the M3
> > side and it doesn't respond.
> 
> OK, then it's not random.  You have some reasoning behind the number
> that should be documented.

Will do.

> 
> That being said, in the absence of numbers from HW folks, can't you
> measure the typical times so you know roughly what's "normal".  

I'll do some timer based profiling and get rough numbers for this.

[...]

> >> 
> >> Why not omap_device_enable(pdev) ?
> >> 
> >
> > The objective is to leverage the hwmod code to get the WKUP-M3
> > functional and not have OMAP runtime PM code coming in the way. 
> 
> FWIW, it is not runtime PM getting in the way.
> 
> > Using omap_device_enable() triggers the following dev_warn()
> > from omap_device_enable().
> 
> Looking closer at the trace, you'll see it's not omap_device_enable()
> that is triggering this warning.  What is happening is that omap_device
> has a late_initcall which forcibly idles omap_devices that have been
> enabled, but that don't have a driver.  You're hacking around that.
> 

Thanks for the explanation. I should have looked closer :(

> IMO, this would be a much cleaner implementation if you just created a
> small driver for the wkup_m3.  You're already doing a bunch of
> driver-like stuff for it (requesting base/IRQs, mapping regions,
> firmware, etc.)  I think this should separated out into a real driver.
> Then it will be bound to the right omap_device, and normal PM operations
> will work as expected.
> 
> Also, doing it this way will be more flexible for those wanting to use
> their own firmware on the M3, or customize the current firmware.

Hmm... that definitely sounds more flexible. It should also help in the next SoC
AM437x which has a similar PM architecture. Where would you suggest placing
this minimal driver?

Regards,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support
  2013-02-20  9:21           ` Bedia, Vaibhav
@ 2013-02-20 14:30             ` Kevin Hilman
  -1 siblings, 0 replies; 148+ messages in thread
From: Kevin Hilman @ 2013-02-20 14:30 UTC (permalink / raw)
  To: Bedia, Vaibhav
  Cc: linux-omap, linux-arm-kernel, tony, Shilimkar, Santosh, Cousson,
	Benoit, Paul Walmsley

"Bedia, Vaibhav" <vaibhav.bedia@ti.com> writes:

[...]

>> IMO, this would be a much cleaner implementation if you just created a
>> small driver for the wkup_m3.  You're already doing a bunch of
>> driver-like stuff for it (requesting base/IRQs, mapping regions,
>> firmware, etc.)  I think this should separated out into a real driver.
>> Then it will be bound to the right omap_device, and normal PM operations
>> will work as expected.
>> 
>> Also, doing it this way will be more flexible for those wanting to use
>> their own firmware on the M3, or customize the current firmware.
>
> Hmm... that definitely sounds more flexible. It should also help in the next SoC
> AM437x which has a similar PM architecture. Where would you suggest placing
> this minimal driver?

For now, just leave it in mach-omap2 and we can figure out the right
home for it eventually.

Kevin


^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support
@ 2013-02-20 14:30             ` Kevin Hilman
  0 siblings, 0 replies; 148+ messages in thread
From: Kevin Hilman @ 2013-02-20 14:30 UTC (permalink / raw)
  To: linux-arm-kernel

"Bedia, Vaibhav" <vaibhav.bedia@ti.com> writes:

[...]

>> IMO, this would be a much cleaner implementation if you just created a
>> small driver for the wkup_m3.  You're already doing a bunch of
>> driver-like stuff for it (requesting base/IRQs, mapping regions,
>> firmware, etc.)  I think this should separated out into a real driver.
>> Then it will be bound to the right omap_device, and normal PM operations
>> will work as expected.
>> 
>> Also, doing it this way will be more flexible for those wanting to use
>> their own firmware on the M3, or customize the current firmware.
>
> Hmm... that definitely sounds more flexible. It should also help in the next SoC
> AM437x which has a similar PM architecture. Where would you suggest placing
> this minimal driver?

For now, just leave it in mach-omap2 and we can figure out the right
home for it eventually.

Kevin

^ permalink raw reply	[flat|nested] 148+ messages in thread

* Re: [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support
  2012-12-31 13:07   ` Vaibhav Bedia
@ 2013-04-03 11:52     ` Daniel Mack
  -1 siblings, 0 replies; 148+ messages in thread
From: Daniel Mack @ 2013-04-03 11:52 UTC (permalink / raw)
  To: Vaibhav Bedia
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Paul Walmsley,
	Santosh Shilimkar, Benoit Cousson

Hi Vaibhav,

On Mon, Dec 31, 2012 at 2:07 PM, Vaibhav Bedia <vaibhav.bedia@ti.com> wrote:
> AM335x supports various low power modes as documented
> in section 8.1.4.3 of the AM335x TRM which is available
> @ http://www.ti.com/litv/pdf/spruh73f

May I ask about the plans for this series? Will you be re-spinning
them for a current
tree, and what's the planned merge window for it?


Many thanks,
Daniel




>
> DeepSleep0 mode offers the lowest power mode with limited
> wakeup sources without a system reboot and is mapped as
> the suspend state in the kernel. In this state, MPU and
> PER domains are turned off with the internal RAM held in
> retention to facilitate resume process. As part of the boot
> process, the assembly code is copied over to OCMCRAM using
> the OMAP SRAM code.
>
> AM335x has a Cortex-M3 (WKUP_M3) which assists the MPU
> in DeepSleep0 entry and exit. WKUP_M3 takes care of the
> clockdomain and powerdomain transitions based on the
> intended low power state. MPU needs to load the appropriate
> WKUP_M3 binary onto the WKUP_M3 memory space before it can
> leverage any of the PM features like DeepSleep.
>
> The IPC mechanism between MPU and WKUP_M3 uses a mailbox
> sub-module and 8 IPC registers in the Control module. MPU
> uses the assigned Mailbox for issuing an interrupt to
> WKUP_M3 which then goes and checks the IPC registers for
> the payload. WKUP_M3 has the ability to trigger on interrupt
> to MPU by executing the "sev" instruction.
>
> In the current implementation when the suspend process
> is initiated MPU interrupts the WKUP_M3 to let it know about
> the intent of entering DeepSleep0 and waits for an ACK. When
> the ACK is received MPU continues with its suspend process
> to suspend all the drivers and then jumps to assembly in
> OCMC RAM. The assembly code puts the PLLs in bypass, puts the
> external RAM in self-refresh mode and then finally execute the
> WFI instruction. Execution of the WFI instruction triggers another
> interrupt to the WKUP_M3 which then continues wiht the power down
> sequence wherein the clockdomain and powerdomain transition takes
> place. As part of the sleep sequence, WKUP_M3 unmasks the interrupt
> lines for the wakeup sources. WFI execution on WKUP_M3 causes the
> hardware to disable the main oscillator of the SoC.
>
> When a wakeup event occurs, WKUP_M3 starts the power-up
> sequence by switching on the power domains and finally
> enabling the clock to MPU. Since the MPU gets powered down
> as part of the sleep sequence in the resume path ROM code
> starts executing. The ROM code detects a wakeup from sleep
> and then jumps to the resume location in OCMC which was
> populated in one of the IPC registers as part of the suspend
> sequence.
>
> The low level code in OCMC relocks the PLLs, enables access
> to external RAM and then jumps to the cpu_resume code of
> the kernel to finish the resume process.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Tony Lingren <tony@atomide.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> ---
> v1->v2:
>         Move assembly code addition, control module access
>         and hookup in OMAP PM framework in separate patches.
>         Address other comments from Kevin Hilman and Santosh
>         Shilimkar on v1. The discussion on v1 is present @
>         http://lists.infradead.org/pipermail/linux-arm-kernel/2012-November/129979.html
>         Note: The mailbox change will need slight rework once
>         the driver is finalized.
>
>  arch/arm/mach-omap2/pm33xx.c |  469 ++++++++++++++++++++++++++++++++++++++++++
>  arch/arm/mach-omap2/pm33xx.h |   56 +++++
>  2 files changed, 525 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-omap2/pm33xx.c
>  create mode 100644 arch/arm/mach-omap2/pm33xx.h
>
> diff --git a/arch/arm/mach-omap2/pm33xx.c b/arch/arm/mach-omap2/pm33xx.c
> new file mode 100644
> index 0000000..aaa4daa
> --- /dev/null
> +++ b/arch/arm/mach-omap2/pm33xx.c
> @@ -0,0 +1,469 @@
> +/*
> + * AM33XX Power Management Routines
> + *
> + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
> + * Vaibhav Bedia <vaibhav.bedia@ti.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation version 2.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> + * kind, whether express or implied; without even the implied warranty
> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/err.h>
> +#include <linux/firmware.h>
> +#include <linux/io.h>
> +#include <linux/platform_device.h>
> +#include <linux/sched.h>
> +#include <linux/suspend.h>
> +#include <linux/completion.h>
> +#include <linux/module.h>
> +#include <linux/mailbox.h>
> +#include <linux/interrupt.h>
> +
> +#include <asm/suspend.h>
> +#include <asm/proc-fns.h>
> +#include <asm/sizes.h>
> +#include <asm/fncpy.h>
> +#include <asm/system_misc.h>
> +
> +#include "pm.h"
> +#include "cm33xx.h"
> +#include "pm33xx.h"
> +#include "control.h"
> +#include "clockdomain.h"
> +#include "powerdomain.h"
> +#include "omap_hwmod.h"
> +#include "omap_device.h"
> +#include "soc.h"
> +#include "sram.h"
> +
> +void (*am33xx_do_wfi_sram)(void);
> +
> +static void __iomem *am33xx_emif_base;
> +static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm, *per_pwrdm;
> +static struct clockdomain *gfx_l4ls_clkdm;
> +static struct omap_hwmod *usb_oh, *cpsw_oh, *tptc0_oh, *tptc1_oh, *tptc2_oh;
> +static struct wkup_m3_context *wkup_m3;
> +
> +static DECLARE_COMPLETION(wkup_m3_sync);
> +
> +#ifdef CONFIG_SUSPEND
> +static int am33xx_do_sram_idle(long unsigned int unused)
> +{
> +       am33xx_do_wfi_sram();
> +       return 0;
> +}
> +
> +static int am33xx_pm_suspend(void)
> +{
> +       int status, ret = 0;
> +
> +       /*
> +        * By default the following IPs do not have MSTANDBY asserted
> +        * which is necessary for PER domain transition. If the drivers
> +        * are not compiled into the kernel HWMOD code will not change the
> +        * state of the IPs if the IP was not never enabled. To ensure
> +        * that there no issues with or without the drivers being compiled
> +        * in the kernel, we forcefully put these IPs to idle.
> +        */
> +       omap_hwmod_enable(usb_oh);
> +       omap_hwmod_enable(tptc0_oh);
> +       omap_hwmod_enable(tptc1_oh);
> +       omap_hwmod_enable(tptc2_oh);
> +       omap_hwmod_enable(cpsw_oh);
> +
> +       omap_hwmod_idle(usb_oh);
> +       omap_hwmod_idle(tptc0_oh);
> +       omap_hwmod_idle(tptc1_oh);
> +       omap_hwmod_idle(tptc2_oh);
> +       omap_hwmod_idle(cpsw_oh);
> +
> +       /* Try to put GFX to sleep */
> +       pwrdm_set_next_fpwrst(gfx_pwrdm, PWRDM_FUNC_PWRST_OFF);
> +
> +       ret = cpu_suspend(0, am33xx_do_sram_idle);
> +
> +       status = pwrdm_read_fpwrst(gfx_pwrdm);
> +       if (status != PWRDM_FUNC_PWRST_OFF)
> +               pr_err("GFX domain did not transition\n");
> +       else
> +               pr_info("GFX domain entered low power state\n");
> +
> +       /*
> +        * GFX_L4LS clock domain needs to be woken up to
> +        * ensure thet L4LS clock domain does not get stuck in transition
> +        * If that happens L3 module does not get disabled, thereby leading
> +        * to PER power domain transition failing
> +        *
> +        * The clock framework should take care of ensuring
> +        * that the clock domain is in the right state when
> +        * GFX driver is active.
> +        */
> +       clkdm_wakeup(gfx_l4ls_clkdm);
> +       clkdm_sleep(gfx_l4ls_clkdm);
> +
> +       if (ret) {
> +               pr_err("Kernel suspend failure\n");
> +       } else {
> +               status = omap_ctrl_readl(AM33XX_CONTROL_IPC_MSG_REG1);
> +               status &= IPC_RESP_MASK;
> +               status >>= __ffs(IPC_RESP_MASK);
> +
> +               switch (status) {
> +               case 0:
> +                       pr_info("Successfully put all powerdomains to target state\n");
> +                       /*
> +                        * XXX: Leads to loss of logic state in PER power domain
> +                        * Use SOC specific ops for this?
> +                        */
> +                       break;
> +               case 1:
> +                       pr_err("Could not transition all powerdomains to target state\n");
> +                       ret = -1;
> +                       break;
> +               default:
> +                       pr_err("Something went wrong :(\nStatus = %d\n",
> +                               status);
> +                       ret = -1;
> +               }
> +       }
> +
> +       return ret;
> +}
> +
> +static int am33xx_pm_enter(suspend_state_t suspend_state)
> +{
> +       int ret = 0;
> +
> +       switch (suspend_state) {
> +       case PM_SUSPEND_STANDBY:
> +       case PM_SUSPEND_MEM:
> +               ret = am33xx_pm_suspend();
> +               break;
> +       default:
> +               ret = -EINVAL;
> +       }
> +
> +       return ret;
> +}
> +
> +static int am33xx_pm_begin(suspend_state_t state)
> +{
> +       int ret = 0;
> +       struct mailbox_msg dummy_msg;
> +
> +       disable_hlt();
> +
> +       MAILBOX_FILL_HEADER_MSG(dummy_msg, 0xABCDABCD);
> +
> +       wkup_m3->ipc_data.sleep_mode = IPC_CMD_DS0;
> +       wkup_m3->ipc_data.param1  = DS_IPC_DEFAULT;
> +       wkup_m3->ipc_data.param2  = DS_IPC_DEFAULT;
> +
> +       am33xx_wkup_m3_ipc_cmd(&wkup_m3->ipc_data);
> +
> +       wkup_m3->state = M3_STATE_MSG_FOR_LP;
> +
> +       mailbox_enable_irq(wkup_m3->mbox, IRQ_RX);
> +
> +       ret = mailbox_msg_send(wkup_m3->mbox, &dummy_msg);
> +       if (ret) {
> +               pr_err("A8<->CM3 MSG for LP failed\n");
> +               am33xx_m3_state_machine_reset();
> +               ret = -1;
> +       }
> +
> +       /* Give some time to M3 to respond. 500msec is a random value here */
> +       if (!wait_for_completion_timeout(&wkup_m3_sync,
> +                                       msecs_to_jiffies(500))) {
> +               pr_err("A8<->CM3 sync failure\n");
> +               am33xx_m3_state_machine_reset();
> +               ret = -1;
> +       } else {
> +               pr_debug("Message sent for entering DeepSleep mode\n");
> +               mailbox_disable_irq(wkup_m3->mbox, IRQ_RX);
> +       }
> +
> +       return ret;
> +}
> +
> +static void am33xx_pm_end(void)
> +{
> +       mailbox_enable_irq(wkup_m3->mbox, IRQ_RX);
> +
> +       am33xx_m3_state_machine_reset();
> +
> +       enable_hlt();
> +
> +       return;
> +}
> +
> +static const struct platform_suspend_ops am33xx_pm_ops = {
> +       .begin          = am33xx_pm_begin,
> +       .end            = am33xx_pm_end,
> +       .enter          = am33xx_pm_enter,
> +       .valid          = suspend_valid_only_mem,
> +};
> +
> +static void am33xx_m3_state_machine_reset(void)
> +{
> +       int ret = 0;
> +       struct mailbox_msg dummy_msg;
> +
> +       MAILBOX_FILL_HEADER_MSG(dummy_msg, 0xABCDABCD);
> +
> +       wkup_m3->ipc_data.sleep_mode    = IPC_CMD_RESET;
> +       wkup_m3->ipc_data.param1        = DS_IPC_DEFAULT;
> +       wkup_m3->ipc_data.param2        = DS_IPC_DEFAULT;
> +
> +       am33xx_wkup_m3_ipc_cmd(&wkup_m3->ipc_data);
> +
> +       wkup_m3->state = M3_STATE_MSG_FOR_RESET;
> +
> +       ret = mailbox_msg_send(wkup_m3->mbox, &dummy_msg);
> +       if (!ret) {
> +               pr_debug("Message sent for resetting M3 state machine\n");
> +               /* Give some to M3 to respond. 500msec is a random value here */
> +               if (!wait_for_completion_timeout(&wkup_m3_sync,
> +                                               msecs_to_jiffies(500)))
> +                       pr_err("A8<->CM3 sync failure\n");
> +       } else {
> +               pr_err("Could not reset M3 state machine!!!\n");
> +               wkup_m3->state = M3_STATE_UNKNOWN;
> +       }
> +}
> +#endif /* CONFIG_SUSPEND */
> +
> +/*
> + * Dummy notifier for the mailbox
> + * XXX: Get rid of this requirement once the MBX driver has been finalized
> + */
> +static int wkup_mbox_msg(struct notifier_block *self, unsigned long len,
> +               void *msg)
> +{
> +       return 0;
> +}
> +
> +static struct notifier_block wkup_mbox_notifier = {
> +       .notifier_call = wkup_mbox_msg,
> +};
> +
> +static irqreturn_t wkup_m3_txev_handler(int irq, void *unused)
> +{
> +       am33xx_txev_eoi();
> +
> +       switch (wkup_m3->state) {
> +       case M3_STATE_RESET:
> +               wkup_m3->state = M3_STATE_INITED;
> +               break;
> +       case M3_STATE_MSG_FOR_RESET:
> +               wkup_m3->state = M3_STATE_INITED;
> +               mailbox_rx_flush(wkup_m3->mbox);
> +               complete(&wkup_m3_sync);
> +               break;
> +       case M3_STATE_MSG_FOR_LP:
> +               mailbox_rx_flush(wkup_m3->mbox);
> +               complete(&wkup_m3_sync);
> +               break;
> +       case M3_STATE_UNKNOWN:
> +               pr_err("IRQ %d with WKUP_M3 in unknown state\n", irq);
> +               mailbox_rx_flush(wkup_m3->mbox);
> +               return IRQ_NONE;
> +       }
> +
> +       am33xx_txev_enable();
> +       return IRQ_HANDLED;
> +}
> +
> +static void am33xx_pm_firmware_cb(const struct firmware *fw, void *context)
> +{
> +       struct wkup_m3_context *wkup_m3_context = context;
> +       struct platform_device *pdev = to_platform_device(wkup_m3_context->dev);
> +       int ret = 0;
> +
> +       /* no firmware found */
> +       if (!fw) {
> +               dev_err(wkup_m3_context->dev, "request_firmware failed\n");
> +               goto err;
> +       }
> +
> +       memcpy((void *)wkup_m3_context->code, fw->data, fw->size);
> +       pr_info("Copied the M3 firmware to UMEM\n");
> +
> +       wkup_m3->state = M3_STATE_RESET;
> +
> +       ret = omap_device_deassert_hardreset(pdev, "wkup_m3");
> +       if (ret) {
> +               pr_err("Could not deassert the reset for WKUP_M3\n");
> +               goto err;
> +       } else {
> +#ifdef CONFIG_SUSPEND
> +               suspend_set_ops(&am33xx_pm_ops);
> +               /*
> +                * Physical resume address to be used by ROM code
> +                */
> +               wkup_m3->ipc_data.resume_addr = (AM33XX_OCMC_END -
> +                               am33xx_do_wfi_sz + am33xx_resume_offset + 0x4);
> +#endif
> +               return;
> +       }
> +
> +err:
> +       mailbox_put(wkup_m3_context->mbox, &wkup_mbox_notifier);
> +}
> +
> +static int wkup_m3_init(void)
> +{
> +       int irq, ret = 0;
> +       struct resource *mem;
> +       struct platform_device *pdev = to_platform_device(wkup_m3->dev);
> +
> +       omap_device_enable_hwmods(to_omap_device(pdev));
> +
> +       /* Reserve the MBOX for sending messages to M3 */
> +       wkup_m3->mbox = mailbox_get("wkup_m3", &wkup_mbox_notifier);
> +       if (IS_ERR(wkup_m3->mbox)) {
> +               pr_err("Could not reserve mailbox for A8->M3 IPC\n");
> +               ret = -ENODEV;
> +               goto exit;
> +       }
> +
> +       irq = platform_get_irq(pdev, 0);
> +       if (!irq) {
> +               dev_err(wkup_m3->dev, "no irq resource\n");
> +               ret = -ENXIO;
> +               goto err;
> +       }
> +
> +       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       if (!mem) {
> +               dev_err(wkup_m3->dev, "no memory resource\n");
> +               ret = -ENXIO;
> +               goto err;
> +       }
> +
> +       wkup_m3->code = devm_request_and_ioremap(wkup_m3->dev, mem);
> +       if (!wkup_m3->code) {
> +               dev_err(wkup_m3->dev, "could not ioremap\n");
> +               ret = -EADDRNOTAVAIL;
> +               goto err;
> +       }
> +
> +       ret = devm_request_irq(wkup_m3->dev, irq, wkup_m3_txev_handler,
> +                 IRQF_DISABLED, "wkup_m3_txev", NULL);
> +       if (ret) {
> +               dev_err(wkup_m3->dev, "request_irq failed\n");
> +               goto err;
> +       } else {
> +               am33xx_txev_enable();
> +       }
> +
> +       pr_info("Trying to load am335x-pm-firmware.bin");
> +
> +       /* We don't want to delay boot */
> +       request_firmware_nowait(THIS_MODULE, 0, "am335x-pm-firmware.bin",
> +                               wkup_m3->dev, GFP_KERNEL, wkup_m3,
> +                               am33xx_pm_firmware_cb);
> +       return 0;
> +
> +err:
> +       mailbox_put(wkup_m3->mbox, &wkup_mbox_notifier);
> +exit:
> +       return ret;
> +}
> +
> +/*
> + * Push the minimal suspend-resume code to SRAM
> + */
> +void am33xx_push_sram_idle(void)
> +{
> +       am33xx_do_wfi_sram = (void *)omap_sram_push
> +                                       (am33xx_do_wfi, am33xx_do_wfi_sz);
> +}
> +
> +static int __init am33xx_map_emif(void)
> +{
> +       am33xx_emif_base = ioremap(AM33XX_EMIF_BASE, SZ_32K);
> +
> +       if (!am33xx_emif_base)
> +               return -ENOMEM;
> +
> +       return 0;
> +}
> +
> +void __iomem *am33xx_get_emif_base(void)
> +{
> +       return am33xx_emif_base;
> +}
> +
> +int __init am33xx_pm_init(void)
> +{
> +       int ret;
> +
> +       if (!soc_is_am33xx())
> +               return -ENODEV;
> +
> +       pr_info("Power Management for AM33XX family\n");
> +
> +       /*
> +        * By default the following IPs do not have MSTANDBY asserted
> +        * which is necessary for PER domain transition. If the drivers
> +        * are not compiled into the kernel HWMOD code will not change the
> +        * state of the IPs if the IP was not never enabled
> +        */
> +       usb_oh          = omap_hwmod_lookup("usb_otg_hs");
> +       tptc0_oh        = omap_hwmod_lookup("tptc0");
> +       tptc1_oh        = omap_hwmod_lookup("tptc1");
> +       tptc2_oh        = omap_hwmod_lookup("tptc2");
> +       cpsw_oh         = omap_hwmod_lookup("cpgmac0");
> +
> +       gfx_pwrdm = pwrdm_lookup("gfx_pwrdm");
> +       per_pwrdm = pwrdm_lookup("per_pwrdm");
> +
> +       gfx_l4ls_clkdm = clkdm_lookup("gfx_l4ls_gfx_clkdm");
> +
> +       if ((!usb_oh) || (!tptc0_oh) || (!tptc1_oh) || (!tptc2_oh) ||
> +               (!cpsw_oh) || (!gfx_pwrdm) || (!per_pwrdm) ||
> +               (!gfx_l4ls_clkdm)) {
> +               ret = -ENODEV;
> +               goto err;
> +       }
> +
> +       wkup_m3 = kzalloc(sizeof(struct wkup_m3_context), GFP_KERNEL);
> +       if (!wkup_m3) {
> +               pr_err("Memory allocation failed\n");
> +               ret = -ENOMEM;
> +               goto err;
> +       }
> +
> +       ret = am33xx_map_emif();
> +       if (ret) {
> +               pr_err("Could not ioremap EMIF\n");
> +               goto err;
> +       }
> +
> +       (void) clkdm_for_each(omap_pm_clkdms_setup, NULL);
> +
> +       /* CEFUSE domain can be turned off post bootup */
> +       cefuse_pwrdm = pwrdm_lookup("cefuse_pwrdm");
> +       if (cefuse_pwrdm)
> +               pwrdm_set_next_fpwrst(cefuse_pwrdm, PWRDM_FUNC_PWRST_OFF);
> +       else
> +               pr_err("Failed to get cefuse_pwrdm\n");
> +
> +       wkup_m3->dev = omap_device_get_by_hwmod_name("wkup_m3");
> +
> +       ret = wkup_m3_init();
> +       if (ret)
> +               pr_err("Could not initialise firmware loading\n");
> +
> +err:
> +       return ret;
> +}
> diff --git a/arch/arm/mach-omap2/pm33xx.h b/arch/arm/mach-omap2/pm33xx.h
> new file mode 100644
> index 0000000..13a2c85
> --- /dev/null
> +++ b/arch/arm/mach-omap2/pm33xx.h
> @@ -0,0 +1,56 @@
> +/*
> + * AM33XX Power Management Routines
> + *
> + * Copyright (C) 2012 Texas Instruments Inc.
> + * Vaibhav Bedia <vaibhav.bedia@ti.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation version 2.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> + * kind, whether express or implied; without even the implied warranty
> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +#ifndef __ARCH_ARM_MACH_OMAP2_PM33XX_H
> +#define __ARCH_ARM_MACH_OMAP2_PM33XX_H
> +
> +#include "control.h"
> +
> +#ifndef __ASSEMBLER__
> +struct wkup_m3_context {
> +       struct am33xx_ipc_data  ipc_data;
> +       struct device           *dev;
> +       struct firmware         *firmware;
> +       struct mailbox          *mbox;
> +       void __iomem            *code;
> +       u8                      state;
> +};
> +
> +#ifdef CONFIG_SUSPEND
> +static void am33xx_m3_state_machine_reset(void);
> +#else
> +static inline void am33xx_m3_state_machine_reset(void) {}
> +#endif /* CONFIG_SUSPEND */
> +
> +extern void __iomem *am33xx_get_emif_base(void);
> +#endif
> +
> +#define        IPC_CMD_DS0                     0x3
> +#define IPC_CMD_RESET                   0xe
> +#define DS_IPC_DEFAULT                 0xffffffff
> +
> +#define IPC_RESP_SHIFT                 16
> +#define IPC_RESP_MASK                  (0xffff << 16)
> +
> +#define M3_STATE_UNKNOWN               0
> +#define M3_STATE_RESET                 1
> +#define M3_STATE_INITED                        2
> +#define M3_STATE_MSG_FOR_LP            3
> +#define M3_STATE_MSG_FOR_RESET         4
> +
> +#define AM33XX_OCMC_END                        0x40310000
> +#define AM33XX_EMIF_BASE               0x4C000000
> +
> +#endif
> --
> 1.7.0.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support
@ 2013-04-03 11:52     ` Daniel Mack
  0 siblings, 0 replies; 148+ messages in thread
From: Daniel Mack @ 2013-04-03 11:52 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Vaibhav,

On Mon, Dec 31, 2012 at 2:07 PM, Vaibhav Bedia <vaibhav.bedia@ti.com> wrote:
> AM335x supports various low power modes as documented
> in section 8.1.4.3 of the AM335x TRM which is available
> @ http://www.ti.com/litv/pdf/spruh73f

May I ask about the plans for this series? Will you be re-spinning
them for a current
tree, and what's the planned merge window for it?


Many thanks,
Daniel




>
> DeepSleep0 mode offers the lowest power mode with limited
> wakeup sources without a system reboot and is mapped as
> the suspend state in the kernel. In this state, MPU and
> PER domains are turned off with the internal RAM held in
> retention to facilitate resume process. As part of the boot
> process, the assembly code is copied over to OCMCRAM using
> the OMAP SRAM code.
>
> AM335x has a Cortex-M3 (WKUP_M3) which assists the MPU
> in DeepSleep0 entry and exit. WKUP_M3 takes care of the
> clockdomain and powerdomain transitions based on the
> intended low power state. MPU needs to load the appropriate
> WKUP_M3 binary onto the WKUP_M3 memory space before it can
> leverage any of the PM features like DeepSleep.
>
> The IPC mechanism between MPU and WKUP_M3 uses a mailbox
> sub-module and 8 IPC registers in the Control module. MPU
> uses the assigned Mailbox for issuing an interrupt to
> WKUP_M3 which then goes and checks the IPC registers for
> the payload. WKUP_M3 has the ability to trigger on interrupt
> to MPU by executing the "sev" instruction.
>
> In the current implementation when the suspend process
> is initiated MPU interrupts the WKUP_M3 to let it know about
> the intent of entering DeepSleep0 and waits for an ACK. When
> the ACK is received MPU continues with its suspend process
> to suspend all the drivers and then jumps to assembly in
> OCMC RAM. The assembly code puts the PLLs in bypass, puts the
> external RAM in self-refresh mode and then finally execute the
> WFI instruction. Execution of the WFI instruction triggers another
> interrupt to the WKUP_M3 which then continues wiht the power down
> sequence wherein the clockdomain and powerdomain transition takes
> place. As part of the sleep sequence, WKUP_M3 unmasks the interrupt
> lines for the wakeup sources. WFI execution on WKUP_M3 causes the
> hardware to disable the main oscillator of the SoC.
>
> When a wakeup event occurs, WKUP_M3 starts the power-up
> sequence by switching on the power domains and finally
> enabling the clock to MPU. Since the MPU gets powered down
> as part of the sleep sequence in the resume path ROM code
> starts executing. The ROM code detects a wakeup from sleep
> and then jumps to the resume location in OCMC which was
> populated in one of the IPC registers as part of the suspend
> sequence.
>
> The low level code in OCMC relocks the PLLs, enables access
> to external RAM and then jumps to the cpu_resume code of
> the kernel to finish the resume process.
>
> Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
> Cc: Tony Lingren <tony@atomide.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> ---
> v1->v2:
>         Move assembly code addition, control module access
>         and hookup in OMAP PM framework in separate patches.
>         Address other comments from Kevin Hilman and Santosh
>         Shilimkar on v1. The discussion on v1 is present @
>         http://lists.infradead.org/pipermail/linux-arm-kernel/2012-November/129979.html
>         Note: The mailbox change will need slight rework once
>         the driver is finalized.
>
>  arch/arm/mach-omap2/pm33xx.c |  469 ++++++++++++++++++++++++++++++++++++++++++
>  arch/arm/mach-omap2/pm33xx.h |   56 +++++
>  2 files changed, 525 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-omap2/pm33xx.c
>  create mode 100644 arch/arm/mach-omap2/pm33xx.h
>
> diff --git a/arch/arm/mach-omap2/pm33xx.c b/arch/arm/mach-omap2/pm33xx.c
> new file mode 100644
> index 0000000..aaa4daa
> --- /dev/null
> +++ b/arch/arm/mach-omap2/pm33xx.c
> @@ -0,0 +1,469 @@
> +/*
> + * AM33XX Power Management Routines
> + *
> + * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
> + * Vaibhav Bedia <vaibhav.bedia@ti.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation version 2.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> + * kind, whether express or implied; without even the implied warranty
> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/err.h>
> +#include <linux/firmware.h>
> +#include <linux/io.h>
> +#include <linux/platform_device.h>
> +#include <linux/sched.h>
> +#include <linux/suspend.h>
> +#include <linux/completion.h>
> +#include <linux/module.h>
> +#include <linux/mailbox.h>
> +#include <linux/interrupt.h>
> +
> +#include <asm/suspend.h>
> +#include <asm/proc-fns.h>
> +#include <asm/sizes.h>
> +#include <asm/fncpy.h>
> +#include <asm/system_misc.h>
> +
> +#include "pm.h"
> +#include "cm33xx.h"
> +#include "pm33xx.h"
> +#include "control.h"
> +#include "clockdomain.h"
> +#include "powerdomain.h"
> +#include "omap_hwmod.h"
> +#include "omap_device.h"
> +#include "soc.h"
> +#include "sram.h"
> +
> +void (*am33xx_do_wfi_sram)(void);
> +
> +static void __iomem *am33xx_emif_base;
> +static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm, *per_pwrdm;
> +static struct clockdomain *gfx_l4ls_clkdm;
> +static struct omap_hwmod *usb_oh, *cpsw_oh, *tptc0_oh, *tptc1_oh, *tptc2_oh;
> +static struct wkup_m3_context *wkup_m3;
> +
> +static DECLARE_COMPLETION(wkup_m3_sync);
> +
> +#ifdef CONFIG_SUSPEND
> +static int am33xx_do_sram_idle(long unsigned int unused)
> +{
> +       am33xx_do_wfi_sram();
> +       return 0;
> +}
> +
> +static int am33xx_pm_suspend(void)
> +{
> +       int status, ret = 0;
> +
> +       /*
> +        * By default the following IPs do not have MSTANDBY asserted
> +        * which is necessary for PER domain transition. If the drivers
> +        * are not compiled into the kernel HWMOD code will not change the
> +        * state of the IPs if the IP was not never enabled. To ensure
> +        * that there no issues with or without the drivers being compiled
> +        * in the kernel, we forcefully put these IPs to idle.
> +        */
> +       omap_hwmod_enable(usb_oh);
> +       omap_hwmod_enable(tptc0_oh);
> +       omap_hwmod_enable(tptc1_oh);
> +       omap_hwmod_enable(tptc2_oh);
> +       omap_hwmod_enable(cpsw_oh);
> +
> +       omap_hwmod_idle(usb_oh);
> +       omap_hwmod_idle(tptc0_oh);
> +       omap_hwmod_idle(tptc1_oh);
> +       omap_hwmod_idle(tptc2_oh);
> +       omap_hwmod_idle(cpsw_oh);
> +
> +       /* Try to put GFX to sleep */
> +       pwrdm_set_next_fpwrst(gfx_pwrdm, PWRDM_FUNC_PWRST_OFF);
> +
> +       ret = cpu_suspend(0, am33xx_do_sram_idle);
> +
> +       status = pwrdm_read_fpwrst(gfx_pwrdm);
> +       if (status != PWRDM_FUNC_PWRST_OFF)
> +               pr_err("GFX domain did not transition\n");
> +       else
> +               pr_info("GFX domain entered low power state\n");
> +
> +       /*
> +        * GFX_L4LS clock domain needs to be woken up to
> +        * ensure thet L4LS clock domain does not get stuck in transition
> +        * If that happens L3 module does not get disabled, thereby leading
> +        * to PER power domain transition failing
> +        *
> +        * The clock framework should take care of ensuring
> +        * that the clock domain is in the right state when
> +        * GFX driver is active.
> +        */
> +       clkdm_wakeup(gfx_l4ls_clkdm);
> +       clkdm_sleep(gfx_l4ls_clkdm);
> +
> +       if (ret) {
> +               pr_err("Kernel suspend failure\n");
> +       } else {
> +               status = omap_ctrl_readl(AM33XX_CONTROL_IPC_MSG_REG1);
> +               status &= IPC_RESP_MASK;
> +               status >>= __ffs(IPC_RESP_MASK);
> +
> +               switch (status) {
> +               case 0:
> +                       pr_info("Successfully put all powerdomains to target state\n");
> +                       /*
> +                        * XXX: Leads to loss of logic state in PER power domain
> +                        * Use SOC specific ops for this?
> +                        */
> +                       break;
> +               case 1:
> +                       pr_err("Could not transition all powerdomains to target state\n");
> +                       ret = -1;
> +                       break;
> +               default:
> +                       pr_err("Something went wrong :(\nStatus = %d\n",
> +                               status);
> +                       ret = -1;
> +               }
> +       }
> +
> +       return ret;
> +}
> +
> +static int am33xx_pm_enter(suspend_state_t suspend_state)
> +{
> +       int ret = 0;
> +
> +       switch (suspend_state) {
> +       case PM_SUSPEND_STANDBY:
> +       case PM_SUSPEND_MEM:
> +               ret = am33xx_pm_suspend();
> +               break;
> +       default:
> +               ret = -EINVAL;
> +       }
> +
> +       return ret;
> +}
> +
> +static int am33xx_pm_begin(suspend_state_t state)
> +{
> +       int ret = 0;
> +       struct mailbox_msg dummy_msg;
> +
> +       disable_hlt();
> +
> +       MAILBOX_FILL_HEADER_MSG(dummy_msg, 0xABCDABCD);
> +
> +       wkup_m3->ipc_data.sleep_mode = IPC_CMD_DS0;
> +       wkup_m3->ipc_data.param1  = DS_IPC_DEFAULT;
> +       wkup_m3->ipc_data.param2  = DS_IPC_DEFAULT;
> +
> +       am33xx_wkup_m3_ipc_cmd(&wkup_m3->ipc_data);
> +
> +       wkup_m3->state = M3_STATE_MSG_FOR_LP;
> +
> +       mailbox_enable_irq(wkup_m3->mbox, IRQ_RX);
> +
> +       ret = mailbox_msg_send(wkup_m3->mbox, &dummy_msg);
> +       if (ret) {
> +               pr_err("A8<->CM3 MSG for LP failed\n");
> +               am33xx_m3_state_machine_reset();
> +               ret = -1;
> +       }
> +
> +       /* Give some time to M3 to respond. 500msec is a random value here */
> +       if (!wait_for_completion_timeout(&wkup_m3_sync,
> +                                       msecs_to_jiffies(500))) {
> +               pr_err("A8<->CM3 sync failure\n");
> +               am33xx_m3_state_machine_reset();
> +               ret = -1;
> +       } else {
> +               pr_debug("Message sent for entering DeepSleep mode\n");
> +               mailbox_disable_irq(wkup_m3->mbox, IRQ_RX);
> +       }
> +
> +       return ret;
> +}
> +
> +static void am33xx_pm_end(void)
> +{
> +       mailbox_enable_irq(wkup_m3->mbox, IRQ_RX);
> +
> +       am33xx_m3_state_machine_reset();
> +
> +       enable_hlt();
> +
> +       return;
> +}
> +
> +static const struct platform_suspend_ops am33xx_pm_ops = {
> +       .begin          = am33xx_pm_begin,
> +       .end            = am33xx_pm_end,
> +       .enter          = am33xx_pm_enter,
> +       .valid          = suspend_valid_only_mem,
> +};
> +
> +static void am33xx_m3_state_machine_reset(void)
> +{
> +       int ret = 0;
> +       struct mailbox_msg dummy_msg;
> +
> +       MAILBOX_FILL_HEADER_MSG(dummy_msg, 0xABCDABCD);
> +
> +       wkup_m3->ipc_data.sleep_mode    = IPC_CMD_RESET;
> +       wkup_m3->ipc_data.param1        = DS_IPC_DEFAULT;
> +       wkup_m3->ipc_data.param2        = DS_IPC_DEFAULT;
> +
> +       am33xx_wkup_m3_ipc_cmd(&wkup_m3->ipc_data);
> +
> +       wkup_m3->state = M3_STATE_MSG_FOR_RESET;
> +
> +       ret = mailbox_msg_send(wkup_m3->mbox, &dummy_msg);
> +       if (!ret) {
> +               pr_debug("Message sent for resetting M3 state machine\n");
> +               /* Give some to M3 to respond. 500msec is a random value here */
> +               if (!wait_for_completion_timeout(&wkup_m3_sync,
> +                                               msecs_to_jiffies(500)))
> +                       pr_err("A8<->CM3 sync failure\n");
> +       } else {
> +               pr_err("Could not reset M3 state machine!!!\n");
> +               wkup_m3->state = M3_STATE_UNKNOWN;
> +       }
> +}
> +#endif /* CONFIG_SUSPEND */
> +
> +/*
> + * Dummy notifier for the mailbox
> + * XXX: Get rid of this requirement once the MBX driver has been finalized
> + */
> +static int wkup_mbox_msg(struct notifier_block *self, unsigned long len,
> +               void *msg)
> +{
> +       return 0;
> +}
> +
> +static struct notifier_block wkup_mbox_notifier = {
> +       .notifier_call = wkup_mbox_msg,
> +};
> +
> +static irqreturn_t wkup_m3_txev_handler(int irq, void *unused)
> +{
> +       am33xx_txev_eoi();
> +
> +       switch (wkup_m3->state) {
> +       case M3_STATE_RESET:
> +               wkup_m3->state = M3_STATE_INITED;
> +               break;
> +       case M3_STATE_MSG_FOR_RESET:
> +               wkup_m3->state = M3_STATE_INITED;
> +               mailbox_rx_flush(wkup_m3->mbox);
> +               complete(&wkup_m3_sync);
> +               break;
> +       case M3_STATE_MSG_FOR_LP:
> +               mailbox_rx_flush(wkup_m3->mbox);
> +               complete(&wkup_m3_sync);
> +               break;
> +       case M3_STATE_UNKNOWN:
> +               pr_err("IRQ %d with WKUP_M3 in unknown state\n", irq);
> +               mailbox_rx_flush(wkup_m3->mbox);
> +               return IRQ_NONE;
> +       }
> +
> +       am33xx_txev_enable();
> +       return IRQ_HANDLED;
> +}
> +
> +static void am33xx_pm_firmware_cb(const struct firmware *fw, void *context)
> +{
> +       struct wkup_m3_context *wkup_m3_context = context;
> +       struct platform_device *pdev = to_platform_device(wkup_m3_context->dev);
> +       int ret = 0;
> +
> +       /* no firmware found */
> +       if (!fw) {
> +               dev_err(wkup_m3_context->dev, "request_firmware failed\n");
> +               goto err;
> +       }
> +
> +       memcpy((void *)wkup_m3_context->code, fw->data, fw->size);
> +       pr_info("Copied the M3 firmware to UMEM\n");
> +
> +       wkup_m3->state = M3_STATE_RESET;
> +
> +       ret = omap_device_deassert_hardreset(pdev, "wkup_m3");
> +       if (ret) {
> +               pr_err("Could not deassert the reset for WKUP_M3\n");
> +               goto err;
> +       } else {
> +#ifdef CONFIG_SUSPEND
> +               suspend_set_ops(&am33xx_pm_ops);
> +               /*
> +                * Physical resume address to be used by ROM code
> +                */
> +               wkup_m3->ipc_data.resume_addr = (AM33XX_OCMC_END -
> +                               am33xx_do_wfi_sz + am33xx_resume_offset + 0x4);
> +#endif
> +               return;
> +       }
> +
> +err:
> +       mailbox_put(wkup_m3_context->mbox, &wkup_mbox_notifier);
> +}
> +
> +static int wkup_m3_init(void)
> +{
> +       int irq, ret = 0;
> +       struct resource *mem;
> +       struct platform_device *pdev = to_platform_device(wkup_m3->dev);
> +
> +       omap_device_enable_hwmods(to_omap_device(pdev));
> +
> +       /* Reserve the MBOX for sending messages to M3 */
> +       wkup_m3->mbox = mailbox_get("wkup_m3", &wkup_mbox_notifier);
> +       if (IS_ERR(wkup_m3->mbox)) {
> +               pr_err("Could not reserve mailbox for A8->M3 IPC\n");
> +               ret = -ENODEV;
> +               goto exit;
> +       }
> +
> +       irq = platform_get_irq(pdev, 0);
> +       if (!irq) {
> +               dev_err(wkup_m3->dev, "no irq resource\n");
> +               ret = -ENXIO;
> +               goto err;
> +       }
> +
> +       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
> +       if (!mem) {
> +               dev_err(wkup_m3->dev, "no memory resource\n");
> +               ret = -ENXIO;
> +               goto err;
> +       }
> +
> +       wkup_m3->code = devm_request_and_ioremap(wkup_m3->dev, mem);
> +       if (!wkup_m3->code) {
> +               dev_err(wkup_m3->dev, "could not ioremap\n");
> +               ret = -EADDRNOTAVAIL;
> +               goto err;
> +       }
> +
> +       ret = devm_request_irq(wkup_m3->dev, irq, wkup_m3_txev_handler,
> +                 IRQF_DISABLED, "wkup_m3_txev", NULL);
> +       if (ret) {
> +               dev_err(wkup_m3->dev, "request_irq failed\n");
> +               goto err;
> +       } else {
> +               am33xx_txev_enable();
> +       }
> +
> +       pr_info("Trying to load am335x-pm-firmware.bin");
> +
> +       /* We don't want to delay boot */
> +       request_firmware_nowait(THIS_MODULE, 0, "am335x-pm-firmware.bin",
> +                               wkup_m3->dev, GFP_KERNEL, wkup_m3,
> +                               am33xx_pm_firmware_cb);
> +       return 0;
> +
> +err:
> +       mailbox_put(wkup_m3->mbox, &wkup_mbox_notifier);
> +exit:
> +       return ret;
> +}
> +
> +/*
> + * Push the minimal suspend-resume code to SRAM
> + */
> +void am33xx_push_sram_idle(void)
> +{
> +       am33xx_do_wfi_sram = (void *)omap_sram_push
> +                                       (am33xx_do_wfi, am33xx_do_wfi_sz);
> +}
> +
> +static int __init am33xx_map_emif(void)
> +{
> +       am33xx_emif_base = ioremap(AM33XX_EMIF_BASE, SZ_32K);
> +
> +       if (!am33xx_emif_base)
> +               return -ENOMEM;
> +
> +       return 0;
> +}
> +
> +void __iomem *am33xx_get_emif_base(void)
> +{
> +       return am33xx_emif_base;
> +}
> +
> +int __init am33xx_pm_init(void)
> +{
> +       int ret;
> +
> +       if (!soc_is_am33xx())
> +               return -ENODEV;
> +
> +       pr_info("Power Management for AM33XX family\n");
> +
> +       /*
> +        * By default the following IPs do not have MSTANDBY asserted
> +        * which is necessary for PER domain transition. If the drivers
> +        * are not compiled into the kernel HWMOD code will not change the
> +        * state of the IPs if the IP was not never enabled
> +        */
> +       usb_oh          = omap_hwmod_lookup("usb_otg_hs");
> +       tptc0_oh        = omap_hwmod_lookup("tptc0");
> +       tptc1_oh        = omap_hwmod_lookup("tptc1");
> +       tptc2_oh        = omap_hwmod_lookup("tptc2");
> +       cpsw_oh         = omap_hwmod_lookup("cpgmac0");
> +
> +       gfx_pwrdm = pwrdm_lookup("gfx_pwrdm");
> +       per_pwrdm = pwrdm_lookup("per_pwrdm");
> +
> +       gfx_l4ls_clkdm = clkdm_lookup("gfx_l4ls_gfx_clkdm");
> +
> +       if ((!usb_oh) || (!tptc0_oh) || (!tptc1_oh) || (!tptc2_oh) ||
> +               (!cpsw_oh) || (!gfx_pwrdm) || (!per_pwrdm) ||
> +               (!gfx_l4ls_clkdm)) {
> +               ret = -ENODEV;
> +               goto err;
> +       }
> +
> +       wkup_m3 = kzalloc(sizeof(struct wkup_m3_context), GFP_KERNEL);
> +       if (!wkup_m3) {
> +               pr_err("Memory allocation failed\n");
> +               ret = -ENOMEM;
> +               goto err;
> +       }
> +
> +       ret = am33xx_map_emif();
> +       if (ret) {
> +               pr_err("Could not ioremap EMIF\n");
> +               goto err;
> +       }
> +
> +       (void) clkdm_for_each(omap_pm_clkdms_setup, NULL);
> +
> +       /* CEFUSE domain can be turned off post bootup */
> +       cefuse_pwrdm = pwrdm_lookup("cefuse_pwrdm");
> +       if (cefuse_pwrdm)
> +               pwrdm_set_next_fpwrst(cefuse_pwrdm, PWRDM_FUNC_PWRST_OFF);
> +       else
> +               pr_err("Failed to get cefuse_pwrdm\n");
> +
> +       wkup_m3->dev = omap_device_get_by_hwmod_name("wkup_m3");
> +
> +       ret = wkup_m3_init();
> +       if (ret)
> +               pr_err("Could not initialise firmware loading\n");
> +
> +err:
> +       return ret;
> +}
> diff --git a/arch/arm/mach-omap2/pm33xx.h b/arch/arm/mach-omap2/pm33xx.h
> new file mode 100644
> index 0000000..13a2c85
> --- /dev/null
> +++ b/arch/arm/mach-omap2/pm33xx.h
> @@ -0,0 +1,56 @@
> +/*
> + * AM33XX Power Management Routines
> + *
> + * Copyright (C) 2012 Texas Instruments Inc.
> + * Vaibhav Bedia <vaibhav.bedia@ti.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation version 2.
> + *
> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any
> + * kind, whether express or implied; without even the implied warranty
> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +#ifndef __ARCH_ARM_MACH_OMAP2_PM33XX_H
> +#define __ARCH_ARM_MACH_OMAP2_PM33XX_H
> +
> +#include "control.h"
> +
> +#ifndef __ASSEMBLER__
> +struct wkup_m3_context {
> +       struct am33xx_ipc_data  ipc_data;
> +       struct device           *dev;
> +       struct firmware         *firmware;
> +       struct mailbox          *mbox;
> +       void __iomem            *code;
> +       u8                      state;
> +};
> +
> +#ifdef CONFIG_SUSPEND
> +static void am33xx_m3_state_machine_reset(void);
> +#else
> +static inline void am33xx_m3_state_machine_reset(void) {}
> +#endif /* CONFIG_SUSPEND */
> +
> +extern void __iomem *am33xx_get_emif_base(void);
> +#endif
> +
> +#define        IPC_CMD_DS0                     0x3
> +#define IPC_CMD_RESET                   0xe
> +#define DS_IPC_DEFAULT                 0xffffffff
> +
> +#define IPC_RESP_SHIFT                 16
> +#define IPC_RESP_MASK                  (0xffff << 16)
> +
> +#define M3_STATE_UNKNOWN               0
> +#define M3_STATE_RESET                 1
> +#define M3_STATE_INITED                        2
> +#define M3_STATE_MSG_FOR_LP            3
> +#define M3_STATE_MSG_FOR_RESET         4
> +
> +#define AM33XX_OCMC_END                        0x40310000
> +#define AM33XX_EMIF_BASE               0x4C000000
> +
> +#endif
> --
> 1.7.0.4
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

^ permalink raw reply	[flat|nested] 148+ messages in thread

* RE: [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support
  2013-04-03 11:52     ` Daniel Mack
@ 2013-04-04  8:47       ` Bedia, Vaibhav
  -1 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-04-04  8:47 UTC (permalink / raw)
  To: Daniel Mack
  Cc: linux-omap, linux-arm-kernel, tony, khilman, Paul Walmsley,
	Shilimkar, Santosh, Cousson, Benoit

Hi Daniel,

On Wed, Apr 03, 2013 at 17:22:41, Daniel Mack wrote:
> Hi Vaibhav,
> 
> On Mon, Dec 31, 2012 at 2:07 PM, Vaibhav Bedia <vaibhav.bedia@ti.com> wrote:
> > AM335x supports various low power modes as documented
> > in section 8.1.4.3 of the AM335x TRM which is available
> > @ http://www.ti.com/litv/pdf/spruh73f
> 
> May I ask about the plans for this series? Will you be re-spinning
> them for a current
> tree, and what's the planned merge window for it?
> 

I am tied up in some other stuff right now. I plan to address Kevin's comments
and repost the patches soon. Since rc5 is already out i think v3.10 is not
a realistic target any more but I do hope to have this accepted for v3.11.

Regards,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

* [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support
@ 2013-04-04  8:47       ` Bedia, Vaibhav
  0 siblings, 0 replies; 148+ messages in thread
From: Bedia, Vaibhav @ 2013-04-04  8:47 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Daniel,

On Wed, Apr 03, 2013 at 17:22:41, Daniel Mack wrote:
> Hi Vaibhav,
> 
> On Mon, Dec 31, 2012 at 2:07 PM, Vaibhav Bedia <vaibhav.bedia@ti.com> wrote:
> > AM335x supports various low power modes as documented
> > in section 8.1.4.3 of the AM335x TRM which is available
> > @ http://www.ti.com/litv/pdf/spruh73f
> 
> May I ask about the plans for this series? Will you be re-spinning
> them for a current
> tree, and what's the planned merge window for it?
> 

I am tied up in some other stuff right now. I plan to address Kevin's comments
and repost the patches soon. Since rc5 is already out i think v3.10 is not
a realistic target any more but I do hope to have this accepted for v3.11.

Regards,
Vaibhav

^ permalink raw reply	[flat|nested] 148+ messages in thread

end of thread, other threads:[~2013-04-04  8:47 UTC | newest]

Thread overview: 148+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-12-31 13:06 [RFC v2 00/18] ARM: OMAP2+: AM33XX: Add suspend-resume support Vaibhav Bedia
2012-12-31 13:06 ` Vaibhav Bedia
2012-12-31 13:06 ` [RFC v2 01/18] mailbox: OMAP2+: Add support for AM33XX Vaibhav Bedia
2012-12-31 13:06   ` Vaibhav Bedia
2013-01-01 18:25   ` Tony Lindgren
2013-01-01 18:25     ` Tony Lindgren
2013-01-02 11:09     ` Bedia, Vaibhav
2013-01-02 11:09       ` Bedia, Vaibhav
2013-01-08 13:53   ` Santosh Shilimkar
2013-01-08 13:53     ` Santosh Shilimkar
2013-01-09  5:16     ` Bedia, Vaibhav
2013-01-09  5:16       ` Bedia, Vaibhav
2012-12-31 13:06 ` [RFC v2 02/18] mailbox: Add an API for flushing the FIFO Vaibhav Bedia
2012-12-31 13:06   ` Vaibhav Bedia
2013-01-08 13:56   ` Santosh Shilimkar
2013-01-08 13:56     ` Santosh Shilimkar
2013-01-09  5:16     ` Bedia, Vaibhav
2013-01-09  5:16       ` Bedia, Vaibhav
2012-12-31 13:06 ` [RFC v2 03/18] memory: emif: Move EMIF related header file to include/linux/ Vaibhav Bedia
2012-12-31 13:06   ` Vaibhav Bedia
2013-01-08 14:04   ` Santosh Shilimkar
2013-01-08 14:04     ` Santosh Shilimkar
2013-01-09  5:31     ` Bedia, Vaibhav
2013-01-09  5:31       ` Bedia, Vaibhav
2012-12-31 13:06 ` [RFC v2 04/18] ARM: OMAP2+: AM33XX: CM: Get rid of unncessary header inclusions Vaibhav Bedia
2012-12-31 13:06   ` Vaibhav Bedia
2013-01-08 15:00   ` Santosh Shilimkar
2013-01-08 15:00     ` Santosh Shilimkar
2012-12-31 13:06 ` [RFC v2 05/18] ARM: OMAP2+: AM33XX: CM/PRM: Use __ASSEMBLER__ macros in header files Vaibhav Bedia
2012-12-31 13:06   ` Vaibhav Bedia
2013-01-08 15:01   ` Santosh Shilimkar
2013-01-08 15:01     ` Santosh Shilimkar
2013-01-09  5:31     ` Bedia, Vaibhav
2013-01-09  5:31       ` Bedia, Vaibhav
2012-12-31 13:06 ` [RFC v2 06/18] ARM: OMAP2+: AM33XX: hwmod: Register OCMC RAM hwmod Vaibhav Bedia
2012-12-31 13:06   ` Vaibhav Bedia
2013-01-08 15:04   ` Santosh Shilimkar
2013-01-08 15:04     ` Santosh Shilimkar
2012-12-31 13:07 ` [RFC v2 07/18] ARM: OMAP2+: AM33XX: hwmod: Update TPTC0 hwmod with the right flags Vaibhav Bedia
2012-12-31 13:07   ` Vaibhav Bedia
2013-01-08 15:05   ` Santosh Shilimkar
2013-01-08 15:05     ` Santosh Shilimkar
2013-01-09  6:02     ` Bedia, Vaibhav
2013-01-09  6:02       ` Bedia, Vaibhav
2013-02-11 23:33   ` Kevin Hilman
2013-02-11 23:33     ` Kevin Hilman
2013-02-13 10:56     ` Bedia, Vaibhav
2013-02-13 10:56       ` Bedia, Vaibhav
2012-12-31 13:07 ` [RFC v2 08/18] ARM: OMAP2+: AM33XX: hwmod: Fixup cpgmac0 hwmod entry Vaibhav Bedia
2012-12-31 13:07   ` Vaibhav Bedia
2013-01-08 15:08   ` Santosh Shilimkar
2013-01-08 15:08     ` Santosh Shilimkar
2012-12-31 13:07 ` [RFC v2 09/18] ARM: OMAP2+: AM33XX: hwmod: Update the WKUP-M3 hwmod with reset status bit Vaibhav Bedia
2012-12-31 13:07   ` Vaibhav Bedia
2013-01-08 15:09   ` Santosh Shilimkar
2013-01-08 15:09     ` Santosh Shilimkar
2012-12-31 13:07 ` [RFC v2 10/18] ARM: OMAP2+: AM33XX: Update the hardreset API Vaibhav Bedia
2012-12-31 13:07   ` Vaibhav Bedia
2013-01-08 15:10   ` Santosh Shilimkar
2013-01-08 15:10     ` Santosh Shilimkar
2012-12-31 13:07 ` [RFC v2 11/18] ARM: DTS: AM33XX: Add nodes for OCMC RAM and WKUP-M3 Vaibhav Bedia
2012-12-31 13:07   ` Vaibhav Bedia
2013-01-08 15:12   ` Santosh Shilimkar
2013-01-08 15:12     ` Santosh Shilimkar
2012-12-31 13:07 ` [RFC v2 12/18] ARM: OMAP2+: timer: Add suspend-resume callbacks for clockevent device Vaibhav Bedia
2012-12-31 13:07   ` Vaibhav Bedia
2013-01-08 15:15   ` Santosh Shilimkar
2013-01-08 15:15     ` Santosh Shilimkar
2013-01-11  4:37     ` Bedia, Vaibhav
2013-01-11  4:37       ` Bedia, Vaibhav
2013-01-17 18:45       ` Jon Hunter
2013-01-17 18:45         ` Jon Hunter
2013-01-18  5:25         ` Santosh Shilimkar
2013-01-18  5:25           ` Santosh Shilimkar
2013-01-21  7:22           ` Bedia, Vaibhav
2013-01-21  7:22             ` Bedia, Vaibhav
2013-01-30 17:46             ` Jon Hunter
2013-01-30 17:46               ` Jon Hunter
2013-01-31 11:17               ` Bedia, Vaibhav
2013-01-31 11:17                 ` Bedia, Vaibhav
2013-01-17 18:40   ` Jon Hunter
2013-01-17 18:40     ` Jon Hunter
2013-01-21  7:22     ` Bedia, Vaibhav
2013-01-21  7:22       ` Bedia, Vaibhav
2012-12-31 13:07 ` [RFC v2 13/18] ARM: OMAP2+: AM33XX: timer: Interchance clkevt and clksrc timers Vaibhav Bedia
2012-12-31 13:07   ` Vaibhav Bedia
2013-01-08 15:17   ` Santosh Shilimkar
2013-01-08 15:17     ` Santosh Shilimkar
2013-01-09  5:31     ` Bedia, Vaibhav
2013-01-09  5:31       ` Bedia, Vaibhav
2013-01-17 19:09   ` Jon Hunter
2013-01-17 19:09     ` Jon Hunter
2013-01-24 22:30   ` Jon Hunter
2013-01-24 22:30     ` Jon Hunter
2013-01-30 17:48     ` Jon Hunter
2013-01-30 17:48       ` Jon Hunter
2013-01-30 17:49       ` Jon Hunter
2013-01-30 17:49         ` Jon Hunter
2013-01-31 11:29         ` Bedia, Vaibhav
2013-01-31 11:29           ` Bedia, Vaibhav
2012-12-31 13:07 ` [RFC v2 14/18] ARM: OMAP2+: AM33XX: control: Add some control module registers and APIs Vaibhav Bedia
2012-12-31 13:07   ` Vaibhav Bedia
2013-01-08 15:21   ` Santosh Shilimkar
2013-01-08 15:21     ` Santosh Shilimkar
2013-01-09  5:38     ` Bedia, Vaibhav
2013-01-09  5:38       ` Bedia, Vaibhav
2013-01-09  7:31       ` Santosh Shilimkar
2013-01-09  7:31         ` Santosh Shilimkar
2013-01-09  9:37         ` Bedia, Vaibhav
2013-01-09  9:37           ` Bedia, Vaibhav
2013-01-09  9:53           ` Santosh Shilimkar
2013-01-09  9:53             ` Santosh Shilimkar
2012-12-31 13:07 ` [RFC v2 15/18] ARM: OMAP2+: AM33XX: Add assembly code for PM operations Vaibhav Bedia
2012-12-31 13:07   ` Vaibhav Bedia
2012-12-31 13:07 ` [RFC v2 16/18] ARM: OMAP2+: AM33XX: Basic suspend resume support Vaibhav Bedia
2012-12-31 13:07   ` Vaibhav Bedia
2013-01-17 14:27   ` Peter Korsgaard
2013-01-17 14:27     ` Peter Korsgaard
2013-01-21 10:37     ` Bedia, Vaibhav
2013-01-21 10:37       ` Bedia, Vaibhav
2013-01-22 12:50       ` Peter Korsgaard
2013-01-22 12:50         ` Peter Korsgaard
2013-02-12  1:27   ` Kevin Hilman
2013-02-12  1:27     ` Kevin Hilman
2013-02-13 13:43     ` Bedia, Vaibhav
2013-02-13 13:43       ` Bedia, Vaibhav
2013-02-18 16:11       ` Kevin Hilman
2013-02-18 16:11         ` Kevin Hilman
2013-02-20  9:21         ` Bedia, Vaibhav
2013-02-20  9:21           ` Bedia, Vaibhav
2013-02-20 14:30           ` Kevin Hilman
2013-02-20 14:30             ` Kevin Hilman
2013-04-03 11:52   ` Daniel Mack
2013-04-03 11:52     ` Daniel Mack
2013-04-04  8:47     ` Bedia, Vaibhav
2013-04-04  8:47       ` Bedia, Vaibhav
2012-12-31 13:07 ` [RFC v2 17/18] ARM: OMAP2+: AM33XX: Select Mailbox when PM is enabled Vaibhav Bedia
2012-12-31 13:07   ` Vaibhav Bedia
2013-01-08 15:22   ` Santosh Shilimkar
2013-01-08 15:22     ` Santosh Shilimkar
2013-01-09  5:38     ` Bedia, Vaibhav
2013-01-09  5:38       ` Bedia, Vaibhav
2012-12-31 13:07 ` [RFC v2 18/18] ARM: OMAP2+: AM33XX: Hookup AM33XX PM code into OMAP builds Vaibhav Bedia
2012-12-31 13:07   ` Vaibhav Bedia
2013-01-08 15:31 ` [RFC v2 00/18] ARM: OMAP2+: AM33XX: Add suspend-resume support Santosh Shilimkar
2013-01-08 15:31   ` Santosh Shilimkar
2013-01-09  5:38   ` Bedia, Vaibhav
2013-01-09  5:38     ` Bedia, Vaibhav

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.