summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2011-07-23 20:14:25 -0700
committerVarun Colbert <vcolbert@nvidia.com>2011-07-27 11:27:08 -0700
commit8e361c80f5a3262b530b47c364d8e712d07efaba (patch)
treeefc897e8a06ff75370ffda9718d7bdb9bf7ffc69
parentf1b215c9776fcf0de739ffdf8a46a3fbff71844d (diff)
ARM: tegra: power: Add package mask to IO pad control
Modified dynamic IO pad configuration control to support SoC package dependencies: set into "no-io-power state" IO pads that are not bonded out on the particular package. Updated IO power detect table to account for differences in Tegra2 and Tegra3 architecture. Bug 853132 Change-Id: I5f0aedfa784173cc37251ccf4e1dfb4d919db96e Reviewed-on: http://git-master/r/42785 Tested-by: Aleksandr Frid <afrid@nvidia.com> Reviewed-by: Karan Jhavar <kjhavar@nvidia.com> Reviewed-by: Scott Williams <scwilliams@nvidia.com> Reviewed-by: Diwakar Tundlam <dtundlam@nvidia.com> Tested-by: Diwakar Tundlam <dtundlam@nvidia.com> Reviewed-by: Jonathan Mayo <jmayo@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/fuse.h6
-rw-r--r--arch/arm/mach-tegra/powerdetect.c65
-rw-r--r--arch/arm/mach-tegra/tegra3_speedo.c22
3 files changed, 64 insertions, 29 deletions
diff --git a/arch/arm/mach-tegra/fuse.h b/arch/arm/mach-tegra/fuse.h
index 4c6b74b454e3..bf3d7240863a 100644
--- a/arch/arm/mach-tegra/fuse.h
+++ b/arch/arm/mach-tegra/fuse.h
@@ -38,6 +38,12 @@ int tegra_cpu_speedo_id(void);
int tegra_soc_speedo_id(void);
void tegra_init_speedo_data(void);
+#ifndef CONFIG_ARCH_TEGRA_2x_SOC
+int tegra_package_id(void);
+#else
+static inline int tegra_package_id(void) { return -1; }
+#endif
+
#else
static inline int tegra_cpu_process_id(void) { return 0; }
diff --git a/arch/arm/mach-tegra/powerdetect.c b/arch/arm/mach-tegra/powerdetect.c
index aed80261afb5..1cbbb57ffde6 100644
--- a/arch/arm/mach-tegra/powerdetect.c
+++ b/arch/arm/mach-tegra/powerdetect.c
@@ -28,6 +28,7 @@
#include <mach/iomap.h>
#include "board.h"
+#include "fuse.h"
#define PMC_PWR_IO_DISABLE 0x44
#define PMC_PWR_DET_ENABLE 0x48
@@ -38,6 +39,7 @@ struct pwr_detect_cell {
const char *reg_id;
u32 pwrdet_mask;
u32 pwrio_mask;
+ u32 package_mask;
struct notifier_block regulator_nb;
};
@@ -63,28 +65,39 @@ static inline u32 pmc_readl(unsigned long addr)
}
-#define POWER_CELL(_reg_id, _pwrdet_mask, _pwrio_mask) \
- { \
- .reg_id = _reg_id, \
- .pwrdet_mask = _pwrdet_mask, \
- .pwrio_mask = _pwrio_mask, \
+#define POWER_CELL(_reg_id, _pwrdet_mask, _pwrio_mask, _package_mask) \
+ { \
+ .reg_id = _reg_id, \
+ .pwrdet_mask = _pwrdet_mask, \
+ .pwrio_mask = _pwrio_mask, \
+ .package_mask = _package_mask, \
}
/* Some IO pads does not have power detect cells, but still can/should be
* turned off when no power - set pwrdet_mask=0 for such pads */
static struct pwr_detect_cell pwr_detect_cells[] = {
- POWER_CELL("pwrdet_nand", (0x1 << 1), (0x1 << 1)),
- POWER_CELL("pwrdet_uart", (0x1 << 2), (0x1 << 2)),
- POWER_CELL("pwrdet_bb", (0x1 << 3), (0x1 << 3)),
- POWER_CELL("pwrdet_vi", 0, (0x1 << 4)),
- POWER_CELL("pwrdet_audio", (0x1 << 5), (0x1 << 5)),
- POWER_CELL("pwrdet_lcd", (0x1 << 6), (0x1 << 6)),
- POWER_CELL("pwrdet_mipi", 0, (0x1 << 9)),
- POWER_CELL("pwrdet_cam", (0x1 << 10), (0x1 << 10)),
- POWER_CELL("pwrdet_pex_ctl", (0x1 << 11), (0x1 << 11)),
- POWER_CELL("pwrdet_sdmmc1", (0x1 << 12), (0x1 << 12)),
- POWER_CELL("pwrdet_sdmmc3", (0x1 << 13), (0x1 << 13)),
- POWER_CELL("pwrdet_sdmmc4", 0, (0x1 << 14)),
+ POWER_CELL("pwrdet_nand", (0x1 << 1), (0x1 << 1), 0xFFFFFFFF),
+ POWER_CELL("pwrdet_uart", (0x1 << 2), (0x1 << 2), 0xFFFFFFFF),
+ POWER_CELL("pwrdet_bb", (0x1 << 3), (0x1 << 3), 0xFFFFFFFF),
+#ifdef CONFIG_ARCH_TEGRA_3x_SOC
+ /* Tegra3 VI is connected on MID package only (id = 1, mask = 0x2) */
+ POWER_CELL("pwrdet_vi", 0, (0x1 << 4), 0x00000002),
+#else
+ POWER_CELL("pwrdet_vi", 0, (0x1 << 4), 0xFFFFFFFF),
+#endif
+ POWER_CELL("pwrdet_audio", (0x1 << 5), (0x1 << 5), 0xFFFFFFFF),
+ POWER_CELL("pwrdet_lcd", (0x1 << 6), (0x1 << 6), 0xFFFFFFFF),
+#ifdef CONFIG_ARCH_TEGRA_2x_SOC
+ POWER_CELL("pwrdet_sd", 0, (0x1 << 8), 0xFFFFFFFF),
+#endif
+ POWER_CELL("pwrdet_mipi", 0, (0x1 << 9), 0xFFFFFFFF),
+#ifndef CONFIG_ARCH_TEGRA_2x_SOC
+ POWER_CELL("pwrdet_cam", (0x1 << 10), (0x1 << 10), 0xFFFFFFFF),
+ POWER_CELL("pwrdet_pex_ctl", (0x1 << 11), (0x1 << 11), 0xFFFFFFFF),
+ POWER_CELL("pwrdet_sdmmc1", (0x1 << 12), (0x1 << 12), 0xFFFFFFFF),
+ POWER_CELL("pwrdet_sdmmc3", (0x1 << 13), (0x1 << 13), 0xFFFFFFFF),
+ POWER_CELL("pwrdet_sdmmc4", 0, (0x1 << 14), 0xFFFFFFFF),
+#endif
};
static void pwr_detect_reset(u32 pwrdet_mask)
@@ -285,11 +298,26 @@ static int __init pwr_detect_cell_init_one(
int __init tegra_pwr_detect_cell_init(void)
{
int i, ret;
+ u32 package_mask;
unsigned long flags;
bool rails_found = true;
+ i = tegra_package_id();
+ if ((i != -1) && (i & (~0x1F))) {
+ pr_err("tegra: not supported package id %d - io power detection"
+ " is left always on\n", i);
+ return 0;
+ }
+ package_mask = (i == -1) ? i : (0x1 << i);
+
for (i = 0; i < ARRAY_SIZE(pwr_detect_cells); i++) {
struct pwr_detect_cell *cell = &pwr_detect_cells[i];
+
+ if (!(cell->package_mask & package_mask)) {
+ pwrio_disabled_mask |= cell->pwrio_mask;
+ continue;
+ }
+
ret = pwr_detect_cell_init_one(cell, &pwrio_disabled_mask);
if (ret) {
pr_err("tegra: failed to map regulator to power detect"
@@ -299,7 +327,8 @@ int __init tegra_pwr_detect_cell_init(void)
}
if (!rails_found) {
- pr_err("tegra: io power detection is left always on\n");
+ pr_err("tegra: failed regulators mapping - io power detection"
+ " is left always on\n");
return 0;
}
pwrdet_rails_found = true;
diff --git a/arch/arm/mach-tegra/tegra3_speedo.c b/arch/arm/mach-tegra/tegra3_speedo.c
index ec84c3c8e36a..78c804f1f662 100644
--- a/arch/arm/mach-tegra/tegra3_speedo.c
+++ b/arch/arm/mach-tegra/tegra3_speedo.c
@@ -52,12 +52,7 @@ static int cpu_process_id;
static int core_process_id;
static int cpu_speedo_id;
static int soc_speedo_id;
-
-static inline u8 fuse_package_info(void)
-{
- /* Package info: 4 bits - 0,3:reserved 1:MID 2:DSC */
- return tegra_fuse_readl(FUSE_PACKAGE_INFO) & 0x0F;
-}
+static int package_id;
static void fuse_speedo_calib(u32 *speedo_g, u32 *speedo_lp)
{
@@ -75,8 +70,6 @@ static void fuse_speedo_calib(u32 *speedo_g, u32 *speedo_lp)
static void rev_sku_to_speedo_ids(int rev, int sku)
{
- u8 pkg;
-
switch (rev) {
case TEGRA_REVISION_A01:
cpu_speedo_id = 0;
@@ -98,8 +91,7 @@ static void rev_sku_to_speedo_ids(int rev, int sku)
break;
case 0: /* ENG - check PKG_SKU */
pr_info("Tegra3 ENG SKU: Checking pkg info\n");
- pkg = fuse_package_info();
- switch (pkg) {
+ switch (package_id) {
case 1: /* MID => assume T30 */
cpu_speedo_id = 2;
soc_speedo_id = 2;
@@ -110,7 +102,7 @@ static void rev_sku_to_speedo_ids(int rev, int sku)
break;
default:
pr_err("Tegra3 Rev-A02: Reserved pkg info %d\n",
- pkg);
+ package_id);
BUG();
break;
}
@@ -134,6 +126,9 @@ void tegra_init_speedo_data(void)
u32 cpu_speedo_val, core_speedo_val;
int iv;
+ /* Package info: 4 bits - 0,3:reserved 1:MID 2:DSC */
+ package_id = tegra_fuse_readl(FUSE_PACKAGE_INFO) & 0x0F;
+
rev_sku_to_speedo_ids(tegra_get_revision(), tegra_sku_id());
BUG_ON(cpu_speedo_id >= ARRAY_SIZE(cpu_process_speedos));
BUG_ON(soc_speedo_id >= ARRAY_SIZE(core_process_speedos));
@@ -211,3 +206,8 @@ int tegra_soc_speedo_id(void)
{
return soc_speedo_id;
}
+
+int tegra_package_id(void)
+{
+ return package_id;
+}