diff options
| -rw-r--r-- | arch/arm/mach-omap2/Makefile | 5 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/clockdomain2xxx_3xxx.c | 340 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/clockdomain33xx.c | 74 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/clockdomain44xx.c | 151 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/cm2xxx.c | 89 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/cm2xxx_3xxx.h | 12 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/cm33xx.c | 56 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/cm3xxx.c | 174 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/cminst44xx.c | 142 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/prm2xxx.c | 17 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/prm2xxx.h | 6 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/prm2xxx_3xxx.c | 43 | ||||
| -rw-r--r-- | arch/arm/mach-omap2/prm2xxx_3xxx.h | 8 | 
13 files changed, 543 insertions, 574 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 56a33869c8b..3751d56853e 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -133,22 +133,17 @@ obj-$(CONFIG_SOC_OMAP5)			+= $(powerdomain-common)  # PRCM clockdomain control  clockdomain-common			+= clockdomain.o  obj-$(CONFIG_ARCH_OMAP2)		+= $(clockdomain-common) -obj-$(CONFIG_ARCH_OMAP2)		+= clockdomain2xxx_3xxx.o  obj-$(CONFIG_ARCH_OMAP2)		+= clockdomains2xxx_3xxx_data.o  obj-$(CONFIG_SOC_OMAP2420)		+= clockdomains2420_data.o  obj-$(CONFIG_SOC_OMAP2430)		+= clockdomains2430_data.o  obj-$(CONFIG_ARCH_OMAP3)		+= $(clockdomain-common) -obj-$(CONFIG_ARCH_OMAP3)		+= clockdomain2xxx_3xxx.o  obj-$(CONFIG_ARCH_OMAP3)		+= clockdomains2xxx_3xxx_data.o  obj-$(CONFIG_ARCH_OMAP3)		+= clockdomains3xxx_data.o  obj-$(CONFIG_ARCH_OMAP4)		+= $(clockdomain-common) -obj-$(CONFIG_ARCH_OMAP4)		+= clockdomain44xx.o  obj-$(CONFIG_ARCH_OMAP4)		+= clockdomains44xx_data.o  obj-$(CONFIG_SOC_AM33XX)		+= $(clockdomain-common) -obj-$(CONFIG_SOC_AM33XX)		+= clockdomain33xx.o  obj-$(CONFIG_SOC_AM33XX)		+= clockdomains33xx_data.o  obj-$(CONFIG_SOC_OMAP5)			+= $(clockdomain-common) -obj-$(CONFIG_SOC_OMAP5)			+= clockdomain44xx.o  # Clock framework  obj-$(CONFIG_ARCH_OMAP2)		+= $(clock-common) clock2xxx.o diff --git a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c b/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c deleted file mode 100644 index 658487c34cb..00000000000 --- a/arch/arm/mach-omap2/clockdomain2xxx_3xxx.c +++ /dev/null @@ -1,340 +0,0 @@ -/* - * OMAP2 and OMAP3 clockdomain control - * - * Copyright (C) 2008-2010 Texas Instruments, Inc. - * Copyright (C) 2008-2010 Nokia Corporation - * - * Derived from mach-omap2/clockdomain.c written by Paul Walmsley - * Rajendra Nayak <rnayak@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. - */ - -#include <linux/types.h> -#include <plat/prcm.h> -#include "prm.h" -#include "prm2xxx_3xxx.h" -#include "cm.h" -#include "cm2xxx.h" -#include "cm3xxx.h" -#include "cm-regbits-24xx.h" -#include "cm-regbits-34xx.h" -#include "prm-regbits-24xx.h" -#include "clockdomain.h" - -static int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1, -						struct clockdomain *clkdm2) -{ -	omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit), -				clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP); -	return 0; -} - -static int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1, -						 struct clockdomain *clkdm2) -{ -	omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit), -				clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP); -	return 0; -} - -static int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1, -						 struct clockdomain *clkdm2) -{ -	return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, -				PM_WKDEP, (1 << clkdm2->dep_bit)); -} - -static int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm) -{ -	struct clkdm_dep *cd; -	u32 mask = 0; - -	for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) { -		if (!cd->clkdm) -			continue; /* only happens if data is erroneous */ - -		/* PRM accesses are slow, so minimize them */ -		mask |= 1 << cd->clkdm->dep_bit; -		atomic_set(&cd->wkdep_usecount, 0); -	} - -	omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, -				 PM_WKDEP); -	return 0; -} - -static int omap3_clkdm_add_sleepdep(struct clockdomain *clkdm1, -						 struct clockdomain *clkdm2) -{ -	omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit), -				clkdm1->pwrdm.ptr->prcm_offs, -				OMAP3430_CM_SLEEPDEP); -	return 0; -} - -static int omap3_clkdm_del_sleepdep(struct clockdomain *clkdm1, -						 struct clockdomain *clkdm2) -{ -	omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit), -				clkdm1->pwrdm.ptr->prcm_offs, -				OMAP3430_CM_SLEEPDEP); -	return 0; -} - -static int omap3_clkdm_read_sleepdep(struct clockdomain *clkdm1, -						 struct clockdomain *clkdm2) -{ -	return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, -				OMAP3430_CM_SLEEPDEP, (1 << clkdm2->dep_bit)); -} - -static int omap3_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm) -{ -	struct clkdm_dep *cd; -	u32 mask = 0; - -	for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) { -		if (!cd->clkdm) -			continue; /* only happens if data is erroneous */ - -		/* PRM accesses are slow, so minimize them */ -		mask |= 1 << cd->clkdm->dep_bit; -		atomic_set(&cd->sleepdep_usecount, 0); -	} -	omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, -				OMAP3430_CM_SLEEPDEP); -	return 0; -} - -static int omap2_clkdm_sleep(struct clockdomain *clkdm) -{ -	omap2_cm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK, -				clkdm->pwrdm.ptr->prcm_offs, -				OMAP2_PM_PWSTCTRL); -	return 0; -} - -static int omap2_clkdm_wakeup(struct clockdomain *clkdm) -{ -	omap2_cm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK, -				clkdm->pwrdm.ptr->prcm_offs, -				OMAP2_PM_PWSTCTRL); -	return 0; -} - -static void omap2_clkdm_allow_idle(struct clockdomain *clkdm) -{ -	if (atomic_read(&clkdm->usecount) > 0) -		_clkdm_add_autodeps(clkdm); - -	omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, -				clkdm->clktrctrl_mask); -} - -static void omap2_clkdm_deny_idle(struct clockdomain *clkdm) -{ -	omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, -				clkdm->clktrctrl_mask); - -	if (atomic_read(&clkdm->usecount) > 0) -		_clkdm_del_autodeps(clkdm); -} - -static void _enable_hwsup(struct clockdomain *clkdm) -{ -	if (cpu_is_omap24xx()) -		omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, -					       clkdm->clktrctrl_mask); -	else if (cpu_is_omap34xx()) -		omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, -					       clkdm->clktrctrl_mask); -} - -static void _disable_hwsup(struct clockdomain *clkdm) -{ -	if (cpu_is_omap24xx()) -		omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, -						clkdm->clktrctrl_mask); -	else if (cpu_is_omap34xx()) -		omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, -						clkdm->clktrctrl_mask); -} - -static int omap3_clkdm_sleep(struct clockdomain *clkdm) -{ -	omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs, -				clkdm->clktrctrl_mask); -	return 0; -} - -static int omap3_clkdm_wakeup(struct clockdomain *clkdm) -{ -	omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs, -				clkdm->clktrctrl_mask); -	return 0; -} - -static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm) -{ -	bool hwsup = false; - -	if (!clkdm->clktrctrl_mask) -		return 0; - -	hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, -					      clkdm->clktrctrl_mask); - -	if (hwsup) { -		/* Disable HW transitions when we are changing deps */ -		_disable_hwsup(clkdm); -		_clkdm_add_autodeps(clkdm); -		_enable_hwsup(clkdm); -	} else { -		if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) -			omap2_clkdm_wakeup(clkdm); -	} - -	return 0; -} - -static int omap2xxx_clkdm_clk_disable(struct clockdomain *clkdm) -{ -	bool hwsup = false; - -	if (!clkdm->clktrctrl_mask) -		return 0; - -	hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, -					      clkdm->clktrctrl_mask); - -	if (hwsup) { -		/* Disable HW transitions when we are changing deps */ -		_disable_hwsup(clkdm); -		_clkdm_del_autodeps(clkdm); -		_enable_hwsup(clkdm); -	} else { -		if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP) -			omap2_clkdm_sleep(clkdm); -	} - -	return 0; -} - -static void omap3_clkdm_allow_idle(struct clockdomain *clkdm) -{ -	if (atomic_read(&clkdm->usecount) > 0) -		_clkdm_add_autodeps(clkdm); - -	omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, -				clkdm->clktrctrl_mask); -} - -static void omap3_clkdm_deny_idle(struct clockdomain *clkdm) -{ -	omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, -				clkdm->clktrctrl_mask); - -	if (atomic_read(&clkdm->usecount) > 0) -		_clkdm_del_autodeps(clkdm); -} - -static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm) -{ -	bool hwsup = false; - -	if (!clkdm->clktrctrl_mask) -		return 0; - -	/* -	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has -	 * more details on the unpleasant problem this is working -	 * around -	 */ -	if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) && -	    (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) { -		omap3_clkdm_wakeup(clkdm); -		return 0; -	} - -	hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, -					      clkdm->clktrctrl_mask); - -	if (hwsup) { -		/* Disable HW transitions when we are changing deps */ -		_disable_hwsup(clkdm); -		_clkdm_add_autodeps(clkdm); -		_enable_hwsup(clkdm); -	} else { -		if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) -			omap3_clkdm_wakeup(clkdm); -	} - -	return 0; -} - -static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm) -{ -	bool hwsup = false; - -	if (!clkdm->clktrctrl_mask) -		return 0; - -	/* -	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has -	 * more details on the unpleasant problem this is working -	 * around -	 */ -	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING && -	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) { -		_enable_hwsup(clkdm); -		return 0; -	} - -	hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, -					      clkdm->clktrctrl_mask); - -	if (hwsup) { -		/* Disable HW transitions when we are changing deps */ -		_disable_hwsup(clkdm); -		_clkdm_del_autodeps(clkdm); -		_enable_hwsup(clkdm); -	} else { -		if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP) -			omap3_clkdm_sleep(clkdm); -	} - -	return 0; -} - -struct clkdm_ops omap2_clkdm_operations = { -	.clkdm_add_wkdep	= omap2_clkdm_add_wkdep, -	.clkdm_del_wkdep	= omap2_clkdm_del_wkdep, -	.clkdm_read_wkdep	= omap2_clkdm_read_wkdep, -	.clkdm_clear_all_wkdeps	= omap2_clkdm_clear_all_wkdeps, -	.clkdm_sleep		= omap2_clkdm_sleep, -	.clkdm_wakeup		= omap2_clkdm_wakeup, -	.clkdm_allow_idle	= omap2_clkdm_allow_idle, -	.clkdm_deny_idle	= omap2_clkdm_deny_idle, -	.clkdm_clk_enable	= omap2xxx_clkdm_clk_enable, -	.clkdm_clk_disable	= omap2xxx_clkdm_clk_disable, -}; - -struct clkdm_ops omap3_clkdm_operations = { -	.clkdm_add_wkdep	= omap2_clkdm_add_wkdep, -	.clkdm_del_wkdep	= omap2_clkdm_del_wkdep, -	.clkdm_read_wkdep	= omap2_clkdm_read_wkdep, -	.clkdm_clear_all_wkdeps	= omap2_clkdm_clear_all_wkdeps, -	.clkdm_add_sleepdep	= omap3_clkdm_add_sleepdep, -	.clkdm_del_sleepdep	= omap3_clkdm_del_sleepdep, -	.clkdm_read_sleepdep	= omap3_clkdm_read_sleepdep, -	.clkdm_clear_all_sleepdeps	= omap3_clkdm_clear_all_sleepdeps, -	.clkdm_sleep		= omap3_clkdm_sleep, -	.clkdm_wakeup		= omap3_clkdm_wakeup, -	.clkdm_allow_idle	= omap3_clkdm_allow_idle, -	.clkdm_deny_idle	= omap3_clkdm_deny_idle, -	.clkdm_clk_enable	= omap3xxx_clkdm_clk_enable, -	.clkdm_clk_disable	= omap3xxx_clkdm_clk_disable, -}; diff --git a/arch/arm/mach-omap2/clockdomain33xx.c b/arch/arm/mach-omap2/clockdomain33xx.c deleted file mode 100644 index aca6388fad7..00000000000 --- a/arch/arm/mach-omap2/clockdomain33xx.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * AM33XX clockdomain control - * - * Copyright (C) 2011-2012 Texas Instruments Incorporated - http://www.ti.com/ - * Vaibhav Hiremath <hvaibhav@ti.com> - * - * Derived from mach-omap2/clockdomain44xx.c written by Rajendra Nayak - * - * 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 "clockdomain.h" -#include "cm33xx.h" - - -static int am33xx_clkdm_sleep(struct clockdomain *clkdm) -{ -	am33xx_cm_clkdm_force_sleep(clkdm->cm_inst, clkdm->clkdm_offs); -	return 0; -} - -static int am33xx_clkdm_wakeup(struct clockdomain *clkdm) -{ -	am33xx_cm_clkdm_force_wakeup(clkdm->cm_inst, clkdm->clkdm_offs); -	return 0; -} - -static void am33xx_clkdm_allow_idle(struct clockdomain *clkdm) -{ -	am33xx_cm_clkdm_enable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); -} - -static void am33xx_clkdm_deny_idle(struct clockdomain *clkdm) -{ -	am33xx_cm_clkdm_disable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); -} - -static int am33xx_clkdm_clk_enable(struct clockdomain *clkdm) -{ -	if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) -		return am33xx_clkdm_wakeup(clkdm); - -	return 0; -} - -static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm) -{ -	bool hwsup = false; - -	hwsup = am33xx_cm_is_clkdm_in_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); - -	if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) -		am33xx_clkdm_sleep(clkdm); - -	return 0; -} - -struct clkdm_ops am33xx_clkdm_operations = { -	.clkdm_sleep		= am33xx_clkdm_sleep, -	.clkdm_wakeup		= am33xx_clkdm_wakeup, -	.clkdm_allow_idle	= am33xx_clkdm_allow_idle, -	.clkdm_deny_idle	= am33xx_clkdm_deny_idle, -	.clkdm_clk_enable	= am33xx_clkdm_clk_enable, -	.clkdm_clk_disable	= am33xx_clkdm_clk_disable, -}; diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c deleted file mode 100644 index 6fc6155625b..00000000000 --- a/arch/arm/mach-omap2/clockdomain44xx.c +++ /dev/null @@ -1,151 +0,0 @@ -/* - * OMAP4 clockdomain control - * - * Copyright (C) 2008-2010 Texas Instruments, Inc. - * Copyright (C) 2008-2010 Nokia Corporation - * - * Derived from mach-omap2/clockdomain.c written by Paul Walmsley - * Rajendra Nayak <rnayak@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. - */ - -#include <linux/kernel.h> -#include "clockdomain.h" -#include "cminst44xx.h" -#include "cm44xx.h" - -static int omap4_clkdm_add_wkup_sleep_dep(struct clockdomain *clkdm1, -					struct clockdomain *clkdm2) -{ -	omap4_cminst_set_inst_reg_bits((1 << clkdm2->dep_bit), -					clkdm1->prcm_partition, -					clkdm1->cm_inst, clkdm1->clkdm_offs + -					OMAP4_CM_STATICDEP); -	return 0; -} - -static int omap4_clkdm_del_wkup_sleep_dep(struct clockdomain *clkdm1, -					struct clockdomain *clkdm2) -{ -	omap4_cminst_clear_inst_reg_bits((1 << clkdm2->dep_bit), -					clkdm1->prcm_partition, -					clkdm1->cm_inst, clkdm1->clkdm_offs + -					OMAP4_CM_STATICDEP); -	return 0; -} - -static int omap4_clkdm_read_wkup_sleep_dep(struct clockdomain *clkdm1, -					struct clockdomain *clkdm2) -{ -	return omap4_cminst_read_inst_reg_bits(clkdm1->prcm_partition, -					clkdm1->cm_inst, clkdm1->clkdm_offs + -					OMAP4_CM_STATICDEP, -					(1 << clkdm2->dep_bit)); -} - -static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm) -{ -	struct clkdm_dep *cd; -	u32 mask = 0; - -	if (!clkdm->prcm_partition) -		return 0; - -	for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) { -		if (!cd->clkdm) -			continue; /* only happens if data is erroneous */ - -		mask |= 1 << cd->clkdm->dep_bit; -		atomic_set(&cd->wkdep_usecount, 0); -	} - -	omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition, -					clkdm->cm_inst, clkdm->clkdm_offs + -					OMAP4_CM_STATICDEP); -	return 0; -} - -static int omap4_clkdm_sleep(struct clockdomain *clkdm) -{ -	omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition, -					clkdm->cm_inst, clkdm->clkdm_offs); -	return 0; -} - -static int omap4_clkdm_wakeup(struct clockdomain *clkdm) -{ -	omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition, -					clkdm->cm_inst, clkdm->clkdm_offs); -	return 0; -} - -static void omap4_clkdm_allow_idle(struct clockdomain *clkdm) -{ -	omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition, -					clkdm->cm_inst, clkdm->clkdm_offs); -} - -static void omap4_clkdm_deny_idle(struct clockdomain *clkdm) -{ -	if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) -		omap4_clkdm_wakeup(clkdm); -	else -		omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition, -						 clkdm->cm_inst, -						 clkdm->clkdm_offs); -} - -static int omap4_clkdm_clk_enable(struct clockdomain *clkdm) -{ -	if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) -		return omap4_clkdm_wakeup(clkdm); - -	return 0; -} - -static int omap4_clkdm_clk_disable(struct clockdomain *clkdm) -{ -	bool hwsup = false; - -	if (!clkdm->prcm_partition) -		return 0; - -	/* -	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has -	 * more details on the unpleasant problem this is working -	 * around -	 */ -	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING && -	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) { -		omap4_clkdm_allow_idle(clkdm); -		return 0; -	} - -	hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition, -					clkdm->cm_inst, clkdm->clkdm_offs); - -	if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) -		omap4_clkdm_sleep(clkdm); - -	return 0; -} - -struct clkdm_ops omap4_clkdm_operations = { -	.clkdm_add_wkdep	= omap4_clkdm_add_wkup_sleep_dep, -	.clkdm_del_wkdep	= omap4_clkdm_del_wkup_sleep_dep, -	.clkdm_read_wkdep	= omap4_clkdm_read_wkup_sleep_dep, -	.clkdm_clear_all_wkdeps	= omap4_clkdm_clear_all_wkup_sleep_deps, -	.clkdm_add_sleepdep	= omap4_clkdm_add_wkup_sleep_dep, -	.clkdm_del_sleepdep	= omap4_clkdm_del_wkup_sleep_dep, -	.clkdm_read_sleepdep	= omap4_clkdm_read_wkup_sleep_dep, -	.clkdm_clear_all_sleepdeps	= omap4_clkdm_clear_all_wkup_sleep_deps, -	.clkdm_sleep		= omap4_clkdm_sleep, -	.clkdm_wakeup		= omap4_clkdm_wakeup, -	.clkdm_allow_idle	= omap4_clkdm_allow_idle, -	.clkdm_deny_idle	= omap4_clkdm_deny_idle, -	.clkdm_clk_enable	= omap4_clkdm_clk_enable, -	.clkdm_clk_disable	= omap4_clkdm_clk_disable, -}; diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c index 05134937071..64165013daf 100644 --- a/arch/arm/mach-omap2/cm2xxx.c +++ b/arch/arm/mach-omap2/cm2xxx.c @@ -2,8 +2,9 @@   * OMAP2xxx CM module functions   *   * Copyright (C) 2009 Nokia Corporation - * Copyright (C) 2012 Texas Instruments, Inc. + * Copyright (C) 2008-2010, 2012 Texas Instruments, Inc.   * Paul Walmsley + * Rajendra Nayak <rnayak@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 @@ -20,9 +21,11 @@  #include "soc.h"  #include "iomap.h"  #include "common.h" +#include "prm2xxx.h"  #include "cm.h"  #include "cm2xxx.h"  #include "cm-regbits-24xx.h" +#include "clockdomain.h"  /* CM_AUTOIDLE_PLL.AUTO_* bit values for DPLLs */  #define DPLL_AUTOIDLE_DISABLE				0x0 @@ -166,3 +169,87 @@ int omap2xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)  	return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;  } + +/* Clockdomain low-level functions */ + +static void omap2xxx_clkdm_allow_idle(struct clockdomain *clkdm) +{ +	if (atomic_read(&clkdm->usecount) > 0) +		_clkdm_add_autodeps(clkdm); + +	omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, +				       clkdm->clktrctrl_mask); +} + +static void omap2xxx_clkdm_deny_idle(struct clockdomain *clkdm) +{ +	omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, +					clkdm->clktrctrl_mask); + +	if (atomic_read(&clkdm->usecount) > 0) +		_clkdm_del_autodeps(clkdm); +} + +static int omap2xxx_clkdm_clk_enable(struct clockdomain *clkdm) +{ +	bool hwsup = false; + +	if (!clkdm->clktrctrl_mask) +		return 0; + +	hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, +					      clkdm->clktrctrl_mask); + +	if (hwsup) { +		/* Disable HW transitions when we are changing deps */ +		omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, +						clkdm->clktrctrl_mask); +		_clkdm_add_autodeps(clkdm); +		omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, +					       clkdm->clktrctrl_mask); +	} else { +		if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) +			omap2xxx_clkdm_wakeup(clkdm); +	} + +	return 0; +} + +static int omap2xxx_clkdm_clk_disable(struct clockdomain *clkdm) +{ +	bool hwsup = false; + +	if (!clkdm->clktrctrl_mask) +		return 0; + +	hwsup = omap2xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, +					      clkdm->clktrctrl_mask); + +	if (hwsup) { +		/* Disable HW transitions when we are changing deps */ +		omap2xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, +						clkdm->clktrctrl_mask); +		_clkdm_del_autodeps(clkdm); +		omap2xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, +					       clkdm->clktrctrl_mask); +	} else { +		if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP) +			omap2xxx_clkdm_sleep(clkdm); +	} + +	return 0; +} + +struct clkdm_ops omap2_clkdm_operations = { +	.clkdm_add_wkdep	= omap2_clkdm_add_wkdep, +	.clkdm_del_wkdep	= omap2_clkdm_del_wkdep, +	.clkdm_read_wkdep	= omap2_clkdm_read_wkdep, +	.clkdm_clear_all_wkdeps	= omap2_clkdm_clear_all_wkdeps, +	.clkdm_sleep		= omap2xxx_clkdm_sleep, +	.clkdm_wakeup		= omap2xxx_clkdm_wakeup, +	.clkdm_allow_idle	= omap2xxx_clkdm_allow_idle, +	.clkdm_deny_idle	= omap2xxx_clkdm_deny_idle, +	.clkdm_clk_enable	= omap2xxx_clkdm_clk_enable, +	.clkdm_clk_disable	= omap2xxx_clkdm_clk_disable, +}; + diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.h b/arch/arm/mach-omap2/cm2xxx_3xxx.h index 865d332f6fb..0e26bb1bf7e 100644 --- a/arch/arm/mach-omap2/cm2xxx_3xxx.h +++ b/arch/arm/mach-omap2/cm2xxx_3xxx.h @@ -74,6 +74,18 @@ static inline u32 omap2_cm_rmw_mod_reg_bits(u32 mask, u32 bits, s16 module,  	return v;  } +/* Read a CM register, AND it, and shift the result down to bit 0 */ +static inline u32 omap2_cm_read_mod_bits_shift(s16 domain, s16 idx, u32 mask) +{ +	u32 v; + +	v = omap2_cm_read_mod_reg(domain, idx); +	v &= mask; +	v >>= __ffs(mask); + +	return v; +} +  static inline u32 omap2_cm_set_mod_reg_bits(u32 bits, s16 module, s16 idx)  {  	return omap2_cm_rmw_mod_reg_bits(bits, bits, module, idx); diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c index 13f56eafef0..9b3bcff127f 100644 --- a/arch/arm/mach-omap2/cm33xx.c +++ b/arch/arm/mach-omap2/cm33xx.c @@ -24,6 +24,7 @@  #include <plat/common.h> +#include "clockdomain.h"  #include "cm.h"  #include "cm33xx.h"  #include "cm-regbits-34xx.h" @@ -311,3 +312,58 @@ void am33xx_cm_module_disable(u16 inst, s16 cdoffs, u16 clkctrl_offs)  	v &= ~AM33XX_MODULEMODE_MASK;  	am33xx_cm_write_reg(v, inst, clkctrl_offs);  } + +/* + * Clockdomain low-level functions + */ + +static int am33xx_clkdm_sleep(struct clockdomain *clkdm) +{ +	am33xx_cm_clkdm_force_sleep(clkdm->cm_inst, clkdm->clkdm_offs); +	return 0; +} + +static int am33xx_clkdm_wakeup(struct clockdomain *clkdm) +{ +	am33xx_cm_clkdm_force_wakeup(clkdm->cm_inst, clkdm->clkdm_offs); +	return 0; +} + +static void am33xx_clkdm_allow_idle(struct clockdomain *clkdm) +{ +	am33xx_cm_clkdm_enable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); +} + +static void am33xx_clkdm_deny_idle(struct clockdomain *clkdm) +{ +	am33xx_cm_clkdm_disable_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); +} + +static int am33xx_clkdm_clk_enable(struct clockdomain *clkdm) +{ +	if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) +		return am33xx_clkdm_wakeup(clkdm); + +	return 0; +} + +static int am33xx_clkdm_clk_disable(struct clockdomain *clkdm) +{ +	bool hwsup = false; + +	hwsup = am33xx_cm_is_clkdm_in_hwsup(clkdm->cm_inst, clkdm->clkdm_offs); + +	if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) +		am33xx_clkdm_sleep(clkdm); + +	return 0; +} + +struct clkdm_ops am33xx_clkdm_operations = { +	.clkdm_sleep		= am33xx_clkdm_sleep, +	.clkdm_wakeup		= am33xx_clkdm_wakeup, +	.clkdm_allow_idle	= am33xx_clkdm_allow_idle, +	.clkdm_deny_idle	= am33xx_clkdm_deny_idle, +	.clkdm_clk_enable	= am33xx_clkdm_clk_enable, +	.clkdm_clk_disable	= am33xx_clkdm_clk_disable, +}; diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c index 8f92c56e225..8b03ec2f439 100644 --- a/arch/arm/mach-omap2/cm3xxx.c +++ b/arch/arm/mach-omap2/cm3xxx.c @@ -1,9 +1,10 @@  /* - * OMAP2/3 CM module functions + * OMAP3xxx CM module functions   *   * Copyright (C) 2009 Nokia Corporation - * Copyright (C) 2012 Texas Instruments, Inc. + * Copyright (C) 2008-2010, 2012 Texas Instruments, Inc.   * Paul Walmsley + * Rajendra Nayak <rnayak@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 @@ -20,9 +21,11 @@  #include "soc.h"  #include "iomap.h"  #include "common.h" +#include "prm2xxx_3xxx.h"  #include "cm.h"  #include "cm3xxx.h"  #include "cm-regbits-34xx.h" +#include "clockdomain.h"  static const u8 omap3xxx_cm_idlest_offs[] = {  	CM_IDLEST1, CM_IDLEST2, OMAP2430_CM_IDLEST3 @@ -107,6 +110,173 @@ int omap3xxx_cm_wait_module_ready(s16 prcm_mod, u8 idlest_id, u8 idlest_shift)  	return (i < MAX_MODULE_READY_TIME) ? 0 : -EBUSY;  } +/* Clockdomain low-level operations */ + +static int omap3xxx_clkdm_add_sleepdep(struct clockdomain *clkdm1, +				       struct clockdomain *clkdm2) +{ +	omap2_cm_set_mod_reg_bits((1 << clkdm2->dep_bit), +				  clkdm1->pwrdm.ptr->prcm_offs, +				  OMAP3430_CM_SLEEPDEP); +	return 0; +} + +static int omap3xxx_clkdm_del_sleepdep(struct clockdomain *clkdm1, +				       struct clockdomain *clkdm2) +{ +	omap2_cm_clear_mod_reg_bits((1 << clkdm2->dep_bit), +				    clkdm1->pwrdm.ptr->prcm_offs, +				    OMAP3430_CM_SLEEPDEP); +	return 0; +} + +static int omap3xxx_clkdm_read_sleepdep(struct clockdomain *clkdm1, +					struct clockdomain *clkdm2) +{ +	return omap2_cm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, +					    OMAP3430_CM_SLEEPDEP, +					    (1 << clkdm2->dep_bit)); +} + +static int omap3xxx_clkdm_clear_all_sleepdeps(struct clockdomain *clkdm) +{ +	struct clkdm_dep *cd; +	u32 mask = 0; + +	for (cd = clkdm->sleepdep_srcs; cd && cd->clkdm_name; cd++) { +		if (!cd->clkdm) +			continue; /* only happens if data is erroneous */ + +		mask |= 1 << cd->clkdm->dep_bit; +		atomic_set(&cd->sleepdep_usecount, 0); +	} +	omap2_cm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, +				    OMAP3430_CM_SLEEPDEP); +	return 0; +} + +static int omap3xxx_clkdm_sleep(struct clockdomain *clkdm) +{ +	omap3xxx_cm_clkdm_force_sleep(clkdm->pwrdm.ptr->prcm_offs, +				      clkdm->clktrctrl_mask); +	return 0; +} + +static int omap3xxx_clkdm_wakeup(struct clockdomain *clkdm) +{ +	omap3xxx_cm_clkdm_force_wakeup(clkdm->pwrdm.ptr->prcm_offs, +				       clkdm->clktrctrl_mask); +	return 0; +} + +static void omap3xxx_clkdm_allow_idle(struct clockdomain *clkdm) +{ +	if (atomic_read(&clkdm->usecount) > 0) +		_clkdm_add_autodeps(clkdm); + +	omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, +				       clkdm->clktrctrl_mask); +} + +static void omap3xxx_clkdm_deny_idle(struct clockdomain *clkdm) +{ +	omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, +					clkdm->clktrctrl_mask); + +	if (atomic_read(&clkdm->usecount) > 0) +		_clkdm_del_autodeps(clkdm); +} + +static int omap3xxx_clkdm_clk_enable(struct clockdomain *clkdm) +{ +	bool hwsup = false; + +	if (!clkdm->clktrctrl_mask) +		return 0; + +	/* +	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has +	 * more details on the unpleasant problem this is working +	 * around +	 */ +	if ((clkdm->flags & CLKDM_MISSING_IDLE_REPORTING) && +	    (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP)) { +		omap3xxx_clkdm_wakeup(clkdm); +		return 0; +	} + +	hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, +					      clkdm->clktrctrl_mask); + +	if (hwsup) { +		/* Disable HW transitions when we are changing deps */ +		omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, +						clkdm->clktrctrl_mask); +		_clkdm_add_autodeps(clkdm); +		omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, +					       clkdm->clktrctrl_mask); +	} else { +		if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) +			omap3xxx_clkdm_wakeup(clkdm); +	} + +	return 0; +} + +static int omap3xxx_clkdm_clk_disable(struct clockdomain *clkdm) +{ +	bool hwsup = false; + +	if (!clkdm->clktrctrl_mask) +		return 0; + +	/* +	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has +	 * more details on the unpleasant problem this is working +	 * around +	 */ +	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING && +	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) { +		omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, +					       clkdm->clktrctrl_mask); +		return 0; +	} + +	hwsup = omap3xxx_cm_is_clkdm_in_hwsup(clkdm->pwrdm.ptr->prcm_offs, +					      clkdm->clktrctrl_mask); + +	if (hwsup) { +		/* Disable HW transitions when we are changing deps */ +		omap3xxx_cm_clkdm_disable_hwsup(clkdm->pwrdm.ptr->prcm_offs, +						clkdm->clktrctrl_mask); +		_clkdm_del_autodeps(clkdm); +		omap3xxx_cm_clkdm_enable_hwsup(clkdm->pwrdm.ptr->prcm_offs, +					       clkdm->clktrctrl_mask); +	} else { +		if (clkdm->flags & CLKDM_CAN_FORCE_SLEEP) +			omap3xxx_clkdm_sleep(clkdm); +	} + +	return 0; +} + +struct clkdm_ops omap3_clkdm_operations = { +	.clkdm_add_wkdep	= omap2_clkdm_add_wkdep, +	.clkdm_del_wkdep	= omap2_clkdm_del_wkdep, +	.clkdm_read_wkdep	= omap2_clkdm_read_wkdep, +	.clkdm_clear_all_wkdeps	= omap2_clkdm_clear_all_wkdeps, +	.clkdm_add_sleepdep	= omap3xxx_clkdm_add_sleepdep, +	.clkdm_del_sleepdep	= omap3xxx_clkdm_del_sleepdep, +	.clkdm_read_sleepdep	= omap3xxx_clkdm_read_sleepdep, +	.clkdm_clear_all_sleepdeps	= omap3xxx_clkdm_clear_all_sleepdeps, +	.clkdm_sleep		= omap3xxx_clkdm_sleep, +	.clkdm_wakeup		= omap3xxx_clkdm_wakeup, +	.clkdm_allow_idle	= omap3xxx_clkdm_allow_idle, +	.clkdm_deny_idle	= omap3xxx_clkdm_deny_idle, +	.clkdm_clk_enable	= omap3xxx_clkdm_clk_enable, +	.clkdm_clk_disable	= omap3xxx_clkdm_clk_disable, +}; +  /*   * Context save/restore code - OMAP3 only   */ diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c index 1894015ff04..7f9a464f01e 100644 --- a/arch/arm/mach-omap2/cminst44xx.c +++ b/arch/arm/mach-omap2/cminst44xx.c @@ -2,8 +2,9 @@   * OMAP4 CM instance functions   *   * Copyright (C) 2009 Nokia Corporation - * Copyright (C) 2011 Texas Instruments, Inc. + * Copyright (C) 2008-2011 Texas Instruments, Inc.   * Paul Walmsley + * Rajendra Nayak <rnayak@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 @@ -22,6 +23,7 @@  #include "iomap.h"  #include "common.h" +#include "clockdomain.h"  #include "cm.h"  #include "cm1_44xx.h"  #include "cm2_44xx.h" @@ -343,3 +345,141 @@ void omap4_cminst_module_disable(u8 part, u16 inst, s16 cdoffs,  	v &= ~OMAP4430_MODULEMODE_MASK;  	omap4_cminst_write_inst_reg(v, part, inst, clkctrl_offs);  } + +/* + * Clockdomain low-level functions + */ + +static int omap4_clkdm_add_wkup_sleep_dep(struct clockdomain *clkdm1, +					struct clockdomain *clkdm2) +{ +	omap4_cminst_set_inst_reg_bits((1 << clkdm2->dep_bit), +				       clkdm1->prcm_partition, +				       clkdm1->cm_inst, clkdm1->clkdm_offs + +				       OMAP4_CM_STATICDEP); +	return 0; +} + +static int omap4_clkdm_del_wkup_sleep_dep(struct clockdomain *clkdm1, +					struct clockdomain *clkdm2) +{ +	omap4_cminst_clear_inst_reg_bits((1 << clkdm2->dep_bit), +					 clkdm1->prcm_partition, +					 clkdm1->cm_inst, clkdm1->clkdm_offs + +					 OMAP4_CM_STATICDEP); +	return 0; +} + +static int omap4_clkdm_read_wkup_sleep_dep(struct clockdomain *clkdm1, +					struct clockdomain *clkdm2) +{ +	return omap4_cminst_read_inst_reg_bits(clkdm1->prcm_partition, +					       clkdm1->cm_inst, +					       clkdm1->clkdm_offs + +					       OMAP4_CM_STATICDEP, +					       (1 << clkdm2->dep_bit)); +} + +static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm) +{ +	struct clkdm_dep *cd; +	u32 mask = 0; + +	if (!clkdm->prcm_partition) +		return 0; + +	for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) { +		if (!cd->clkdm) +			continue; /* only happens if data is erroneous */ + +		mask |= 1 << cd->clkdm->dep_bit; +		atomic_set(&cd->wkdep_usecount, 0); +	} + +	omap4_cminst_clear_inst_reg_bits(mask, clkdm->prcm_partition, +					 clkdm->cm_inst, clkdm->clkdm_offs + +					 OMAP4_CM_STATICDEP); +	return 0; +} + +static int omap4_clkdm_sleep(struct clockdomain *clkdm) +{ +	omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition, +					clkdm->cm_inst, clkdm->clkdm_offs); +	return 0; +} + +static int omap4_clkdm_wakeup(struct clockdomain *clkdm) +{ +	omap4_cminst_clkdm_force_wakeup(clkdm->prcm_partition, +					clkdm->cm_inst, clkdm->clkdm_offs); +	return 0; +} + +static void omap4_clkdm_allow_idle(struct clockdomain *clkdm) +{ +	omap4_cminst_clkdm_enable_hwsup(clkdm->prcm_partition, +					clkdm->cm_inst, clkdm->clkdm_offs); +} + +static void omap4_clkdm_deny_idle(struct clockdomain *clkdm) +{ +	if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) +		omap4_clkdm_wakeup(clkdm); +	else +		omap4_cminst_clkdm_disable_hwsup(clkdm->prcm_partition, +						 clkdm->cm_inst, +						 clkdm->clkdm_offs); +} + +static int omap4_clkdm_clk_enable(struct clockdomain *clkdm) +{ +	if (clkdm->flags & CLKDM_CAN_FORCE_WAKEUP) +		return omap4_clkdm_wakeup(clkdm); + +	return 0; +} + +static int omap4_clkdm_clk_disable(struct clockdomain *clkdm) +{ +	bool hwsup = false; + +	if (!clkdm->prcm_partition) +		return 0; + +	/* +	 * The CLKDM_MISSING_IDLE_REPORTING flag documentation has +	 * more details on the unpleasant problem this is working +	 * around +	 */ +	if (clkdm->flags & CLKDM_MISSING_IDLE_REPORTING && +	    !(clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) { +		omap4_clkdm_allow_idle(clkdm); +		return 0; +	} + +	hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition, +					clkdm->cm_inst, clkdm->clkdm_offs); + +	if (!hwsup && (clkdm->flags & CLKDM_CAN_FORCE_SLEEP)) +		omap4_clkdm_sleep(clkdm); + +	return 0; +} + +struct clkdm_ops omap4_clkdm_operations = { +	.clkdm_add_wkdep	= omap4_clkdm_add_wkup_sleep_dep, +	.clkdm_del_wkdep	= omap4_clkdm_del_wkup_sleep_dep, +	.clkdm_read_wkdep	= omap4_clkdm_read_wkup_sleep_dep, +	.clkdm_clear_all_wkdeps	= omap4_clkdm_clear_all_wkup_sleep_deps, +	.clkdm_add_sleepdep	= omap4_clkdm_add_wkup_sleep_dep, +	.clkdm_del_sleepdep	= omap4_clkdm_del_wkup_sleep_dep, +	.clkdm_read_sleepdep	= omap4_clkdm_read_wkup_sleep_dep, +	.clkdm_clear_all_sleepdeps	= omap4_clkdm_clear_all_wkup_sleep_deps, +	.clkdm_sleep		= omap4_clkdm_sleep, +	.clkdm_wakeup		= omap4_clkdm_wakeup, +	.clkdm_allow_idle	= omap4_clkdm_allow_idle, +	.clkdm_deny_idle	= omap4_clkdm_deny_idle, +	.clkdm_clk_enable	= omap4_clkdm_clk_enable, +	.clkdm_clk_disable	= omap4_clkdm_clk_disable, +}; diff --git a/arch/arm/mach-omap2/prm2xxx.c b/arch/arm/mach-omap2/prm2xxx.c index 218ef6a1f11..9cdb4e5e3d8 100644 --- a/arch/arm/mach-omap2/prm2xxx.c +++ b/arch/arm/mach-omap2/prm2xxx.c @@ -24,10 +24,27 @@  #include "vp.h"  #include "powerdomain.h" +#include "clockdomain.h"  #include "prm2xxx.h"  #include "cm2xxx_3xxx.h"  #include "prm-regbits-24xx.h" +int omap2xxx_clkdm_sleep(struct clockdomain *clkdm) +{ +	omap2_prm_set_mod_reg_bits(OMAP24XX_FORCESTATE_MASK, +				   clkdm->pwrdm.ptr->prcm_offs, +				   OMAP2_PM_PWSTCTRL); +	return 0; +} + +int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm) +{ +	omap2_prm_clear_mod_reg_bits(OMAP24XX_FORCESTATE_MASK, +				     clkdm->pwrdm.ptr->prcm_offs, +				     OMAP2_PM_PWSTCTRL); +	return 0; +} +  struct pwrdm_ops omap2_pwrdm_operations = {  	.pwrdm_set_next_pwrst	= omap2_pwrdm_set_next_pwrst,  	.pwrdm_read_next_pwrst	= omap2_pwrdm_read_next_pwrst, diff --git a/arch/arm/mach-omap2/prm2xxx.h b/arch/arm/mach-omap2/prm2xxx.h index 6490e1a580e..6d76716a1ea 100644 --- a/arch/arm/mach-omap2/prm2xxx.h +++ b/arch/arm/mach-omap2/prm2xxx.h @@ -119,4 +119,10 @@  #define OMAP24XX_PRCM_IRQSTATUS_IVA			0x00f8  #define OMAP24XX_PRCM_IRQENABLE_IVA			0x00fc +#ifndef __ASSEMBLER__ +/* Function prototypes */ +extern int omap2xxx_clkdm_sleep(struct clockdomain *clkdm); +extern int omap2xxx_clkdm_wakeup(struct clockdomain *clkdm); +#endif +  #endif diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c index bdddf5ca67c..30517f5af70 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.c +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c @@ -20,6 +20,7 @@  #include "powerdomain.h"  #include "prm2xxx_3xxx.h"  #include "prm-regbits-24xx.h" +#include "clockdomain.h"  /**   * omap2_prm_is_hardreset_asserted - read the HW reset line state of @@ -208,3 +209,45 @@ int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm)  	return 0;  } +int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1, +			  struct clockdomain *clkdm2) +{ +	omap2_prm_set_mod_reg_bits((1 << clkdm2->dep_bit), +				   clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP); +	return 0; +} + +int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1, +			  struct clockdomain *clkdm2) +{ +	omap2_prm_clear_mod_reg_bits((1 << clkdm2->dep_bit), +				     clkdm1->pwrdm.ptr->prcm_offs, PM_WKDEP); +	return 0; +} + +int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1, +			   struct clockdomain *clkdm2) +{ +	return omap2_prm_read_mod_bits_shift(clkdm1->pwrdm.ptr->prcm_offs, +					     PM_WKDEP, (1 << clkdm2->dep_bit)); +} + +int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm) +{ +	struct clkdm_dep *cd; +	u32 mask = 0; + +	for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) { +		if (!cd->clkdm) +			continue; /* only happens if data is erroneous */ + +		/* PRM accesses are slow, so minimize them */ +		mask |= 1 << cd->clkdm->dep_bit; +		atomic_set(&cd->wkdep_usecount, 0); +	} + +	omap2_prm_clear_mod_reg_bits(mask, clkdm->pwrdm.ptr->prcm_offs, +				     PM_WKDEP); +	return 0; +} + diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h index 706b0262f3f..22a405a1543 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.h +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h @@ -116,6 +116,14 @@ extern int omap2_pwrdm_read_mem_retst(struct powerdomain *pwrdm, u8 bank);  extern int omap2_pwrdm_set_logic_retst(struct powerdomain *pwrdm, u8 pwrst);  extern int omap2_pwrdm_wait_transition(struct powerdomain *pwrdm); +extern int omap2_clkdm_add_wkdep(struct clockdomain *clkdm1, +				 struct clockdomain *clkdm2); +extern int omap2_clkdm_del_wkdep(struct clockdomain *clkdm1, +				 struct clockdomain *clkdm2); +extern int omap2_clkdm_read_wkdep(struct clockdomain *clkdm1, +				  struct clockdomain *clkdm2); +extern int omap2_clkdm_clear_all_wkdeps(struct clockdomain *clkdm); +  #endif /* __ASSEMBLER */  /*  |