diff options
Diffstat (limited to 'arch/arm/mach-tegra/powergate.c')
| -rw-r--r-- | arch/arm/mach-tegra/powergate.c | 53 | 
1 files changed, 47 insertions, 6 deletions
diff --git a/arch/arm/mach-tegra/powergate.c b/arch/arm/mach-tegra/powergate.c index 948306491a5..c238699ae86 100644 --- a/arch/arm/mach-tegra/powergate.c +++ b/arch/arm/mach-tegra/powergate.c @@ -31,6 +31,8 @@  #include <mach/iomap.h>  #include <mach/powergate.h> +#include "fuse.h" +  #define PWRGATE_TOGGLE		0x30  #define  PWRGATE_TOGGLE_START	(1 << 8) @@ -38,6 +40,16 @@  #define PWRGATE_STATUS		0x38 +static int tegra_num_powerdomains; +static int tegra_num_cpu_domains; +static u8 *tegra_cpu_domains; +static u8 tegra30_cpu_domains[] = { +	TEGRA_POWERGATE_CPU0, +	TEGRA_POWERGATE_CPU1, +	TEGRA_POWERGATE_CPU2, +	TEGRA_POWERGATE_CPU3, +}; +  static DEFINE_SPINLOCK(tegra_powergate_lock);  static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); @@ -75,7 +87,7 @@ static int tegra_powergate_set(int id, bool new_state)  int tegra_powergate_power_on(int id)  { -	if (id < 0 || id >= TEGRA_NUM_POWERGATE) +	if (id < 0 || id >= tegra_num_powerdomains)  		return -EINVAL;  	return tegra_powergate_set(id, true); @@ -83,17 +95,18 @@ int tegra_powergate_power_on(int id)  int tegra_powergate_power_off(int id)  { -	if (id < 0 || id >= TEGRA_NUM_POWERGATE) +	if (id < 0 || id >= tegra_num_powerdomains)  		return -EINVAL;  	return tegra_powergate_set(id, false);  } -static bool tegra_powergate_is_powered(int id) +int tegra_powergate_is_powered(int id)  {  	u32 status; -	WARN_ON(id < 0 || id >= TEGRA_NUM_POWERGATE); +	if (id < 0 || id >= tegra_num_powerdomains) +		return -EINVAL;  	status = pmc_read(PWRGATE_STATUS) & (1 << id);  	return !!status; @@ -103,7 +116,7 @@ int tegra_powergate_remove_clamping(int id)  {  	u32 mask; -	if (id < 0 || id >= TEGRA_NUM_POWERGATE) +	if (id < 0 || id >= tegra_num_powerdomains)  		return -EINVAL;  	/* @@ -156,6 +169,34 @@ err_power:  	return ret;  } +int tegra_cpu_powergate_id(int cpuid) +{ +	if (cpuid > 0 && cpuid < tegra_num_cpu_domains) +		return tegra_cpu_domains[cpuid]; + +	return -EINVAL; +} + +int __init tegra_powergate_init(void) +{ +	switch (tegra_chip_id) { +	case TEGRA20: +		tegra_num_powerdomains = 7; +		break; +	case TEGRA30: +		tegra_num_powerdomains = 14; +		tegra_num_cpu_domains = 4; +		tegra_cpu_domains = tegra30_cpu_domains; +		break; +	default: +		/* Unknown Tegra variant. Disable powergating */ +		tegra_num_powerdomains = 0; +		break; +	} + +	return 0; +} +  #ifdef CONFIG_DEBUG_FS  static const char * const powergate_name[] = { @@ -175,7 +216,7 @@ static int powergate_show(struct seq_file *s, void *data)  	seq_printf(s, " powergate powered\n");  	seq_printf(s, "------------------\n"); -	for (i = 0; i < TEGRA_NUM_POWERGATE; i++) +	for (i = 0; i < tegra_num_powerdomains; i++)  		seq_printf(s, " %9s %7s\n", powergate_name[i],  			tegra_powergate_is_powered(i) ? "yes" : "no");  	return 0;  |