ARM: OMAP: AM33XX: Restore padconf across low power state
authorVaibhav Bedia <vaibhav.bedia@ti.com>
Fri, 9 Mar 2012 18:52:25 +0000 (00:22 +0530)
committerVaibhav Bedia <vaibhav.bedia@ti.com>
Fri, 9 Mar 2012 19:08:37 +0000 (00:38 +0530)
Some specific padconf registers need to be saved and restored
in low power state. For now this is being done in the PM
code. One alternative to be explored is the usage of callbacks
functions in the various drivers to save and restore the padconf.

Signed-off-by: Vaibhav Bedia <vaibhav.bedia@ti.com>
arch/arm/mach-omap2/pm33xx.c
arch/arm/mach-omap2/pm33xx.h

index 23e122da4ac6f11a99bc33a0a028ceffc3f9e922..0c4378d8e9de5406a64f6bc1aa39183ee20094ff 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "pm.h"
 #include "pm33xx.h"
+#include "control.h"
 #include "clockdomain.h"
 #include "powerdomain.h"
 
@@ -58,6 +59,9 @@ static struct omap_mbox *m3_mbox;
 static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm;
 static struct clockdomain *gfx_l3_clkdm, *gfx_l4ls_clkdm;
 
+static struct am33xx_padconf lp_padconf;
+static int gmii_sel;
+
 static int core_suspend_stat = -1;
 static int m3_state = M3_STATE_UNKNOWN;
 
@@ -67,6 +71,64 @@ static void am33xx_m3_state_machine_reset(void);
 
 static DECLARE_COMPLETION(a8_m3_sync);
 
+static void save_padconf(void)
+{
+       lp_padconf.mii1_col     = readl(AM33XX_CTRL_REGADDR(0x0908));
+       lp_padconf.mii1_crs     = readl(AM33XX_CTRL_REGADDR(0x090c));
+       lp_padconf.mii1_rxerr   = readl(AM33XX_CTRL_REGADDR(0x0910));
+       lp_padconf.mii1_txen    = readl(AM33XX_CTRL_REGADDR(0x0914));
+       lp_padconf.mii1_rxdv    = readl(AM33XX_CTRL_REGADDR(0x0918));
+       lp_padconf.mii1_txd3    = readl(AM33XX_CTRL_REGADDR(0x091c));
+       lp_padconf.mii1_txd2    = readl(AM33XX_CTRL_REGADDR(0x0920));
+       lp_padconf.mii1_txd1    = readl(AM33XX_CTRL_REGADDR(0x0924));
+       lp_padconf.mii1_txd0    = readl(AM33XX_CTRL_REGADDR(0x0928));
+       lp_padconf.mii1_txclk   = readl(AM33XX_CTRL_REGADDR(0x092c));
+       lp_padconf.mii1_rxclk   = readl(AM33XX_CTRL_REGADDR(0x0930));
+       lp_padconf.mii1_rxd3    = readl(AM33XX_CTRL_REGADDR(0x0934));
+       lp_padconf.mii1_rxd2    = readl(AM33XX_CTRL_REGADDR(0x0938));
+       lp_padconf.mii1_rxd1    = readl(AM33XX_CTRL_REGADDR(0x093c));
+       lp_padconf.mii1_rxd0    = readl(AM33XX_CTRL_REGADDR(0x0940));
+       lp_padconf.rmii1_refclk = readl(AM33XX_CTRL_REGADDR(0x0944));
+       lp_padconf.mdio_data    = readl(AM33XX_CTRL_REGADDR(0x0948));
+       lp_padconf.mdio_clk     = readl(AM33XX_CTRL_REGADDR(0x094c));
+       gmii_sel                = readl(AM33XX_CTRL_REGADDR(0x0650));
+}
+
+static void restore_padconf(void)
+{
+       writel(lp_padconf.mii1_col, AM33XX_CTRL_REGADDR(0x0908));
+       writel(lp_padconf.mii1_crs, AM33XX_CTRL_REGADDR(0x090c));
+       writel(lp_padconf.mii1_rxerr, AM33XX_CTRL_REGADDR(0x0910));
+       writel(lp_padconf.mii1_txen, AM33XX_CTRL_REGADDR(0x0914));
+       writel(lp_padconf.mii1_rxdv, AM33XX_CTRL_REGADDR(0x0918));
+       writel(lp_padconf.mii1_txd3, AM33XX_CTRL_REGADDR(0x091c));
+       writel(lp_padconf.mii1_txd2, AM33XX_CTRL_REGADDR(0x0920));
+       writel(lp_padconf.mii1_txd1, AM33XX_CTRL_REGADDR(0x0924));
+       writel(lp_padconf.mii1_txd0, AM33XX_CTRL_REGADDR(0x0928));
+       writel(lp_padconf.mii1_txclk, AM33XX_CTRL_REGADDR(0x092c));
+       writel(lp_padconf.mii1_rxclk, AM33XX_CTRL_REGADDR(0x0930));
+       writel(lp_padconf.mii1_rxd3, AM33XX_CTRL_REGADDR(0x0934));
+       writel(lp_padconf.mii1_rxd2, AM33XX_CTRL_REGADDR(0x0938));
+       writel(lp_padconf.mii1_rxd1, AM33XX_CTRL_REGADDR(0x093c));
+       writel(lp_padconf.mii1_rxd0, AM33XX_CTRL_REGADDR(0x0940));
+       writel(lp_padconf.rmii1_refclk, AM33XX_CTRL_REGADDR(0x0944));
+       writel(lp_padconf.mdio_data, AM33XX_CTRL_REGADDR(0x0948));
+       writel(lp_padconf.mdio_clk, AM33XX_CTRL_REGADDR(0x094c));
+       writel(gmii_sel, AM33XX_CTRL_REGADDR(0x0650));
+}
+
+
+static int am33xx_pm_prepare_late(void)
+{
+       save_padconf();
+       return 0;
+}
+
+static void am33xx_pm_finish(void)
+{
+       restore_padconf();
+}
+
 static int am33xx_do_sram_idle(long unsigned int state)
 {
        am33xx_do_wfi_sram();
@@ -221,6 +283,8 @@ static const struct platform_suspend_ops am33xx_pm_ops = {
        .end            = am33xx_pm_end,
        .enter          = am33xx_pm_enter,
        .valid          = suspend_valid_only_mem,
+       .prepare        = am33xx_pm_prepare_late,
+       .finish         = am33xx_pm_finish,
 };
 
 int am33xx_ipc_cmd(struct a8_wkup_m3_ipc_data *data)
index 67ec84c34b5ed6475ccecf545bf07fcdbf2c7240..2c24804320d9527d02d50121b77ff0d7751e3923 100644 (file)
@@ -22,6 +22,27 @@ struct a8_wkup_m3_ipc_data {
        int ipc_data1;
        int ipc_data2;
 } am33xx_lp_ipc;
+
+struct am33xx_padconf {
+       int     mii1_col;
+       int     mii1_crs;
+       int     mii1_rxerr;
+       int     mii1_txen;
+       int     mii1_rxdv;
+       int     mii1_txd3;
+       int     mii1_txd2;
+       int     mii1_txd1;
+       int     mii1_txd0;
+       int     mii1_txclk;
+       int     mii1_rxclk;
+       int     mii1_rxd3;
+       int     mii1_rxd2;
+       int     mii1_rxd1;
+       int     mii1_rxd0;
+       int     rmii1_refclk;
+       int     mdio_data;
+       int     mdio_clk;
+};
 #endif /* ASSEMBLER */
 
 #define M3_TXEV_EOI                    (AM33XX_CTRL_BASE + 0x1324)