ARM: tegra: power: Add package mask to IO pad control
Alex Frid [Sun, 24 Jul 2011 03:14:25 +0000 (20:14 -0700)]
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

Original-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>

Rebase-Id: R46208845c32e25340de6b1cebfb6b617c6c7ce4d

arch/arm/mach-tegra/fuse.h
arch/arm/mach-tegra/powerdetect.c
arch/arm/mach-tegra/tegra3_speedo.c

index 4c6b74b..bf3d724 100644 (file)
@@ -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; }
index aed8026..1cbbb57 100644 (file)
@@ -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;
index ec84c3c..78c804f 100644 (file)
@@ -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;
+}