| 
					
				 | 
			
			
				@@ -74,3 +74,160 @@ struct omap4_cpu_pm_info { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static struct powerdomain *mpuss_pd; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 static void __iomem *sar_base; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Program the wakeup routine address for the CPU0 and CPU1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * used for OFF or DORMANT wakeup. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline void set_cpu_wakeup_addr(unsigned int cpu_id, u32 addr) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__raw_writel(addr, pm_info->wkup_sar_addr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Set the CPUx powerdomain's previous power state 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline void set_cpu_next_pwrst(unsigned int cpu_id, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				unsigned int power_state) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	pwrdm_set_next_pwrst(pm_info->pwrdm, power_state); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Read CPU's previous power state 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline unsigned int read_cpu_prev_pwrst(unsigned int cpu_id) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return pwrdm_read_prev_pwrst(pm_info->pwrdm); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Clear the CPUx powerdomain's previous power state 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline void clear_cpu_prev_pwrst(unsigned int cpu_id) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	pwrdm_clear_all_prev_pwrst(pm_info->pwrdm); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Store the SCU power status value to scratchpad memory 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u32 scu_pwr_st; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	switch (cpu_state) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case PWRDM_POWER_RET: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		scu_pwr_st = SCU_PM_DORMANT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case PWRDM_POWER_OFF: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		scu_pwr_st = SCU_PM_POWEROFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case PWRDM_POWER_ON: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	case PWRDM_POWER_INACTIVE: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		scu_pwr_st = SCU_PM_NORMAL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__raw_writel(scu_pwr_st, pm_info->scu_sar_addr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* Helper functions for MPUSS OSWR */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline void mpuss_clear_prev_logic_pwrst(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u32 reg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	omap4_prminst_write_inst_reg(reg, OMAP4430_PRM_PARTITION, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static inline void cpu_clear_prev_logic_pwrst(unsigned int cpu_id) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u32 reg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	if (cpu_id) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU1_INST, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU1_INST, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU0_INST, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU0_INST, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * omap4_mpuss_read_prev_context_state: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Function returns the MPUSS previous context state 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+u32 omap4_mpuss_read_prev_context_state(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u32 reg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	reg = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		OMAP4430_PRM_MPU_INST, OMAP4_RM_MPU_MPU_CONTEXT_OFFSET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	reg &= OMAP4430_LOSTCONTEXT_DFF_MASK; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	return reg; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Store the CPU cluster state for L2X0 low power operations. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void l2x0_pwrst_prepare(unsigned int cpu_id, unsigned int save_state) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__raw_writel(save_state, pm_info->l2x0_sar_addr); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Save the L2X0 AUXCTRL and POR value to SAR memory. Its used to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * in every restore MPUSS OFF path. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#ifdef CONFIG_CACHE_L2X0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void save_l2x0_context(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	u32 val; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	void __iomem *l2x0_base = omap4_get_l2cache_base(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	val = __raw_readl(l2x0_base + L2X0_AUX_CTRL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	__raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#else 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+static void save_l2x0_context(void) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+#endif 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * omap4_enter_lowpower: OMAP4 MPUSS Low Power Entry Function 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * The purpose of this function is to manage low power programming 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * of OMAP4 MPUSS subsystem 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @cpu : CPU ID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @power_state: Low power state. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * MPUSS states for the context save: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * save_state = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *	0 - Nothing lost and no need to save: MPUSS INACTIVE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *	1 - CPUx L1 and logic lost: MPUSS CSWR 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *	2 - CPUx L1 and logic lost + GIC lost: MPUSS OSWR 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *	3 - CPUx L1 and logic lost + GIC + L2 lost: DEVICE OFF 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+{ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	unsigned int save_state = 0; 
			 |