pm34xx.c (f2d1185824fd3ed631f3164daeff59d0b4e55d79) pm34xx.c (27d59a4a2def42307349079f2e3538d96934c379)
1/*
2 * OMAP3 Power Management Routines
3 *
4 * Copyright (C) 2006-2008 Nokia Corporation
5 * Tony Lindgren <tony@atomide.com>
6 * Jouni Hogander
7 *
8 * Copyright (C) 2007 Texas Instruments, Inc.

--- 49 unchanged lines hidden (view full) ---

58#endif
59 struct list_head node;
60};
61
62static LIST_HEAD(pwrst_list);
63
64static void (*_omap_sram_idle)(u32 *addr, int save_state);
65
1/*
2 * OMAP3 Power Management Routines
3 *
4 * Copyright (C) 2006-2008 Nokia Corporation
5 * Tony Lindgren <tony@atomide.com>
6 * Jouni Hogander
7 *
8 * Copyright (C) 2007 Texas Instruments, Inc.

--- 49 unchanged lines hidden (view full) ---

58#endif
59 struct list_head node;
60};
61
62static LIST_HEAD(pwrst_list);
63
64static void (*_omap_sram_idle)(u32 *addr, int save_state);
65
66static int (*_omap_save_secure_sram)(u32 *addr);
67
66static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
67static struct powerdomain *core_pwrdm, *per_pwrdm;
68
69static int set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
70
71static inline void omap3_per_save_context(void)
72{
73 omap_gpio_save_context();

--- 31 unchanged lines hidden (view full) ---

105 omap3_control_restore_context();
106 /* Restore the GPMC context */
107 omap3_gpmc_restore_context();
108 /* Restore the interrupt controller context */
109 omap_intc_restore_context();
110 omap_dma_global_context_restore();
111}
112
68static struct powerdomain *mpu_pwrdm, *neon_pwrdm;
69static struct powerdomain *core_pwrdm, *per_pwrdm;
70
71static int set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
72
73static inline void omap3_per_save_context(void)
74{
75 omap_gpio_save_context();

--- 31 unchanged lines hidden (view full) ---

107 omap3_control_restore_context();
108 /* Restore the GPMC context */
109 omap3_gpmc_restore_context();
110 /* Restore the interrupt controller context */
111 omap_intc_restore_context();
112 omap_dma_global_context_restore();
113}
114
115static void omap3_save_secure_ram_context(u32 target_mpu_state)
116{
117 u32 ret;
118
119 if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
120 /* Disable dma irq before calling secure rom code API */
121 omap_dma_disable_irq(0);
122 omap_dma_disable_irq(1);
123 /*
124 * MPU next state must be set to POWER_ON temporarily,
125 * otherwise the WFI executed inside the ROM code
126 * will hang the system.
127 */
128 pwrdm_set_next_pwrst(mpu_pwrdm, PWRDM_POWER_ON);
129 ret = _omap_save_secure_sram((u32 *)
130 __pa(omap3_secure_ram_storage));
131 pwrdm_set_next_pwrst(mpu_pwrdm, target_mpu_state);
132 /* Following is for error tracking, it should not happen */
133 if (ret) {
134 printk(KERN_ERR "save_secure_sram() returns %08x\n",
135 ret);
136 while (1)
137 ;
138 }
139 }
140}
141
113/*
114 * PRCM Interrupt Handler Helper Function
115 *
116 * The purpose of this function is to clear any wake-up events latched
117 * in the PRCM PM_WKST_x registers. It is possible that a wake-up event
118 * may occur whilst attempting to clear a PM_WKST_x register and thus
119 * set another bit in this register. A while loop is used to ensure
120 * that any peripheral wake-up events occurring while attempting to

--- 182 unchanged lines hidden (view full) ---

303 if (per_next_state < PWRDM_POWER_ON) {
304 omap_uart_prepare_idle(2);
305 if (per_next_state == PWRDM_POWER_OFF)
306 omap3_per_save_context();
307 }
308 if (core_next_state == PWRDM_POWER_OFF) {
309 omap3_core_save_context();
310 omap3_prcm_save_context();
142/*
143 * PRCM Interrupt Handler Helper Function
144 *
145 * The purpose of this function is to clear any wake-up events latched
146 * in the PRCM PM_WKST_x registers. It is possible that a wake-up event
147 * may occur whilst attempting to clear a PM_WKST_x register and thus
148 * set another bit in this register. A while loop is used to ensure
149 * that any peripheral wake-up events occurring while attempting to

--- 182 unchanged lines hidden (view full) ---

332 if (per_next_state < PWRDM_POWER_ON) {
333 omap_uart_prepare_idle(2);
334 if (per_next_state == PWRDM_POWER_OFF)
335 omap3_per_save_context();
336 }
337 if (core_next_state == PWRDM_POWER_OFF) {
338 omap3_core_save_context();
339 omap3_prcm_save_context();
340 omap3_save_secure_ram_context(mpu_next_state);
311 }
312 /* Enable IO-PAD wakeup */
313 prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
314 }
315
316 /*
317 * omap3_arm_context is the location where ARM registers
318 * get saved. The restore path then reads from this

--- 577 unchanged lines hidden (view full) ---

896 omap2_clkdm_sleep(clkdm);
897 return 0;
898}
899
900void omap_push_sram_idle(void)
901{
902 _omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend,
903 omap34xx_cpu_suspend_sz);
341 }
342 /* Enable IO-PAD wakeup */
343 prm_set_mod_reg_bits(OMAP3430_EN_IO, WKUP_MOD, PM_WKEN);
344 }
345
346 /*
347 * omap3_arm_context is the location where ARM registers
348 * get saved. The restore path then reads from this

--- 577 unchanged lines hidden (view full) ---

926 omap2_clkdm_sleep(clkdm);
927 return 0;
928}
929
930void omap_push_sram_idle(void)
931{
932 _omap_sram_idle = omap_sram_push(omap34xx_cpu_suspend,
933 omap34xx_cpu_suspend_sz);
934 if (omap_type() != OMAP2_DEVICE_TYPE_GP)
935 _omap_save_secure_sram = omap_sram_push(save_secure_ram_context,
936 save_secure_ram_context_sz);
904}
905
906static int __init omap3_pm_init(void)
907{
908 struct power_state *pwrst, *tmp;
909 int ret;
910
911 if (!cpu_is_omap34xx())
912 return -ENODEV;
913
914 printk(KERN_ERR "Power Management for TI OMAP3.\n");
915
916 /* XXX prcm_setup_regs needs to be before enabling hw
917 * supervised mode for powerdomains */
918 prcm_setup_regs();
937}
938
939static int __init omap3_pm_init(void)
940{
941 struct power_state *pwrst, *tmp;
942 int ret;
943
944 if (!cpu_is_omap34xx())
945 return -ENODEV;
946
947 printk(KERN_ERR "Power Management for TI OMAP3.\n");
948
949 /* XXX prcm_setup_regs needs to be before enabling hw
950 * supervised mode for powerdomains */
951 prcm_setup_regs();
919 omap3_save_scratchpad_contents();
920
921 ret = request_irq(INT_34XX_PRCM_MPU_IRQ,
922 (irq_handler_t)prcm_interrupt_handler,
923 IRQF_DISABLED, "prcm", NULL);
924 if (ret) {
925 printk(KERN_ERR "request_irq failed to register for 0x%x\n",
926 INT_34XX_PRCM_MPU_IRQ);
927 goto err1;

--- 28 unchanged lines hidden (view full) ---

956 /*
957 * REVISIT: This wkdep is only necessary when GPIO2-6 are enabled for
958 * IO-pad wakeup. Otherwise it will unnecessarily waste power
959 * waking up PER with every CORE wakeup - see
960 * http://marc.info/?l=linux-omap&m=121852150710062&w=2
961 */
962 pwrdm_add_wkdep(per_pwrdm, core_pwrdm);
963
952
953 ret = request_irq(INT_34XX_PRCM_MPU_IRQ,
954 (irq_handler_t)prcm_interrupt_handler,
955 IRQF_DISABLED, "prcm", NULL);
956 if (ret) {
957 printk(KERN_ERR "request_irq failed to register for 0x%x\n",
958 INT_34XX_PRCM_MPU_IRQ);
959 goto err1;

--- 28 unchanged lines hidden (view full) ---

988 /*
989 * REVISIT: This wkdep is only necessary when GPIO2-6 are enabled for
990 * IO-pad wakeup. Otherwise it will unnecessarily waste power
991 * waking up PER with every CORE wakeup - see
992 * http://marc.info/?l=linux-omap&m=121852150710062&w=2
993 */
994 pwrdm_add_wkdep(per_pwrdm, core_pwrdm);
995
996 if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
997 omap3_secure_ram_storage =
998 kmalloc(0x803F, GFP_KERNEL);
999 if (!omap3_secure_ram_storage)
1000 printk(KERN_ERR "Memory allocation failed when"
1001 "allocating for secure sram context\n");
1002 }
1003 omap3_save_scratchpad_contents();
1004
964err1:
965 return ret;
966err2:
967 free_irq(INT_34XX_PRCM_MPU_IRQ, NULL);
968 list_for_each_entry_safe(pwrst, tmp, &pwrst_list, node) {
969 list_del(&pwrst->node);
970 kfree(pwrst);
971 }
972 return ret;
973}
974
975late_initcall(omap3_pm_init);
1005err1:
1006 return ret;
1007err2:
1008 free_irq(INT_34XX_PRCM_MPU_IRQ, NULL);
1009 list_for_each_entry_safe(pwrst, tmp, &pwrst_list, node) {
1010 list_del(&pwrst->node);
1011 kfree(pwrst);
1012 }
1013 return ret;
1014}
1015
1016late_initcall(omap3_pm_init);