-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
yaml --- r: 235214 b: refs/heads/master c: ce1e326 h: refs/heads/master v: v3
- Loading branch information
Colin Cross
committed
Feb 10, 2011
1 parent
b243ed4
commit c0366bf
Showing
4 changed files
with
254 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
--- | ||
refs/heads/master: d377eb0d95e4a7333afeb5ca4ba8554160480263 | ||
refs/heads/master: ce1e32626951957729d5a1bbe3fa7e5d734df6c0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/* | ||
* drivers/regulator/tegra-regulator.c | ||
* | ||
* Copyright (c) 2010 Google, Inc | ||
* | ||
* Author: | ||
* Colin Cross <ccross@google.com> | ||
* | ||
* This software is licensed under the terms of the GNU General Public | ||
* License version 2, as published by the Free Software Foundation, and | ||
* may be copied, distributed, and modified under those terms. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
*/ | ||
|
||
#ifndef _MACH_TEGRA_POWERGATE_H_ | ||
#define _MACH_TEGRA_POWERGATE_H_ | ||
|
||
#define TEGRA_POWERGATE_CPU 0 | ||
#define TEGRA_POWERGATE_3D 1 | ||
#define TEGRA_POWERGATE_VENC 2 | ||
#define TEGRA_POWERGATE_PCIE 3 | ||
#define TEGRA_POWERGATE_VDEC 4 | ||
#define TEGRA_POWERGATE_L2 5 | ||
#define TEGRA_POWERGATE_MPE 6 | ||
#define TEGRA_NUM_POWERGATE 7 | ||
|
||
int tegra_powergate_power_on(int id); | ||
int tegra_powergate_power_off(int id); | ||
bool tegra_powergate_is_powered(int id); | ||
int tegra_powergate_remove_clamping(int id); | ||
|
||
/* Must be called with clk disabled, and returns with clk enabled */ | ||
int tegra_powergate_sequence_power_up(int id, struct clk *clk); | ||
|
||
#endif /* _MACH_TEGRA_POWERGATE_H_ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
/* | ||
* drivers/powergate/tegra-powergate.c | ||
* | ||
* Copyright (c) 2010 Google, Inc | ||
* | ||
* Author: | ||
* Colin Cross <ccross@google.com> | ||
* | ||
* This software is licensed under the terms of the GNU General Public | ||
* License version 2, as published by the Free Software Foundation, and | ||
* may be copied, distributed, and modified under those terms. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; 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 <linux/clk.h> | ||
#include <linux/debugfs.h> | ||
#include <linux/delay.h> | ||
#include <linux/err.h> | ||
#include <linux/init.h> | ||
#include <linux/io.h> | ||
#include <linux/seq_file.h> | ||
#include <linux/spinlock.h> | ||
|
||
#include <mach/clk.h> | ||
#include <mach/iomap.h> | ||
#include <mach/powergate.h> | ||
|
||
#define PWRGATE_TOGGLE 0x30 | ||
#define PWRGATE_TOGGLE_START (1 << 8) | ||
|
||
#define REMOVE_CLAMPING 0x34 | ||
|
||
#define PWRGATE_STATUS 0x38 | ||
|
||
static DEFINE_SPINLOCK(tegra_powergate_lock); | ||
|
||
static void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); | ||
|
||
static u32 pmc_read(unsigned long reg) | ||
{ | ||
return readl(pmc + reg); | ||
} | ||
|
||
static void pmc_write(u32 val, unsigned long reg) | ||
{ | ||
writel(val, pmc + reg); | ||
} | ||
|
||
static int tegra_powergate_set(int id, bool new_state) | ||
{ | ||
bool status; | ||
unsigned long flags; | ||
|
||
spin_lock_irqsave(&tegra_powergate_lock, flags); | ||
|
||
status = pmc_read(PWRGATE_STATUS) & (1 << id); | ||
|
||
if (status == new_state) { | ||
spin_unlock_irqrestore(&tegra_powergate_lock, flags); | ||
return -EINVAL; | ||
} | ||
|
||
pmc_write(PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE); | ||
|
||
spin_unlock_irqrestore(&tegra_powergate_lock, flags); | ||
|
||
return 0; | ||
} | ||
|
||
int tegra_powergate_power_on(int id) | ||
{ | ||
if (id < 0 || id >= TEGRA_NUM_POWERGATE) | ||
return -EINVAL; | ||
|
||
return tegra_powergate_set(id, true); | ||
} | ||
|
||
int tegra_powergate_power_off(int id) | ||
{ | ||
if (id < 0 || id >= TEGRA_NUM_POWERGATE) | ||
return -EINVAL; | ||
|
||
return tegra_powergate_set(id, false); | ||
} | ||
|
||
bool tegra_powergate_is_powered(int id) | ||
{ | ||
u32 status; | ||
|
||
if (id < 0 || id >= TEGRA_NUM_POWERGATE) | ||
return -EINVAL; | ||
|
||
status = pmc_read(PWRGATE_STATUS) & (1 << id); | ||
return !!status; | ||
} | ||
|
||
int tegra_powergate_remove_clamping(int id) | ||
{ | ||
u32 mask; | ||
|
||
if (id < 0 || id >= TEGRA_NUM_POWERGATE) | ||
return -EINVAL; | ||
|
||
/* | ||
* Tegra 2 has a bug where PCIE and VDE clamping masks are | ||
* swapped relatively to the partition ids | ||
*/ | ||
if (id == TEGRA_POWERGATE_VDEC) | ||
mask = (1 << TEGRA_POWERGATE_PCIE); | ||
else if (id == TEGRA_POWERGATE_PCIE) | ||
mask = (1 << TEGRA_POWERGATE_VDEC); | ||
else | ||
mask = (1 << id); | ||
|
||
pmc_write(mask, REMOVE_CLAMPING); | ||
|
||
return 0; | ||
} | ||
|
||
/* Must be called with clk disabled, and returns with clk enabled */ | ||
int tegra_powergate_sequence_power_up(int id, struct clk *clk) | ||
{ | ||
int ret; | ||
|
||
tegra_periph_reset_assert(clk); | ||
|
||
ret = tegra_powergate_power_on(id); | ||
if (ret) | ||
goto err_power; | ||
|
||
ret = clk_enable(clk); | ||
if (ret) | ||
goto err_clk; | ||
|
||
udelay(10); | ||
|
||
ret = tegra_powergate_remove_clamping(id); | ||
if (ret) | ||
goto err_clamp; | ||
|
||
udelay(10); | ||
tegra_periph_reset_deassert(clk); | ||
|
||
return 0; | ||
|
||
err_clamp: | ||
clk_disable(clk); | ||
err_clk: | ||
tegra_powergate_power_off(id); | ||
err_power: | ||
return ret; | ||
} | ||
|
||
#ifdef CONFIG_DEBUG_FS | ||
|
||
static const char * const powergate_name[] = { | ||
[TEGRA_POWERGATE_CPU] = "cpu", | ||
[TEGRA_POWERGATE_3D] = "3d", | ||
[TEGRA_POWERGATE_VENC] = "venc", | ||
[TEGRA_POWERGATE_VDEC] = "vdec", | ||
[TEGRA_POWERGATE_PCIE] = "pcie", | ||
[TEGRA_POWERGATE_L2] = "l2", | ||
[TEGRA_POWERGATE_MPE] = "mpe", | ||
}; | ||
|
||
static int powergate_show(struct seq_file *s, void *data) | ||
{ | ||
int i; | ||
|
||
seq_printf(s, " powergate powered\n"); | ||
seq_printf(s, "------------------\n"); | ||
|
||
for (i = 0; i < TEGRA_NUM_POWERGATE; i++) | ||
seq_printf(s, " %9s %7s\n", powergate_name[i], | ||
tegra_powergate_is_powered(i) ? "yes" : "no"); | ||
return 0; | ||
} | ||
|
||
static int powergate_open(struct inode *inode, struct file *file) | ||
{ | ||
return single_open(file, powergate_show, inode->i_private); | ||
} | ||
|
||
static const struct file_operations powergate_fops = { | ||
.open = powergate_open, | ||
.read = seq_read, | ||
.llseek = seq_lseek, | ||
.release = single_release, | ||
}; | ||
|
||
static int __init powergate_debugfs_init(void) | ||
{ | ||
struct dentry *d; | ||
int err = -ENOMEM; | ||
|
||
d = debugfs_create_file("powergate", S_IRUGO, NULL, NULL, | ||
&powergate_fops); | ||
if (!d) | ||
return -ENOMEM; | ||
|
||
return err; | ||
} | ||
|
||
late_initcall(powergate_debugfs_init); | ||
|
||
#endif |