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.c
arch/arm/mach-tegra/fuse.h
arch/arm/mach-tegra/powerdetect.c
arch/arm/mach-tegra/tegra20_speedo.c
arch/arm/mach-tegra/tegra30_speedo.c

index 861bbbc..10a5ff1 100644 (file)
@@ -63,6 +63,7 @@ int tegra_chip_id;
 int tegra_chip_rev;
 int tegra_cpu_speedo_id;               /* only exist in Tegra30 and later */
 int tegra_soc_speedo_id;
+int tegra_package_id;
 enum tegra_revision tegra_revision;
 static unsigned int tegra_chip_major;
 static unsigned int tegra_chip_minor;
index e19e383..8dd0b7f 100644 (file)
@@ -33,6 +33,7 @@ extern int tegra_cpu_process_id;
 extern int tegra_core_process_id;
 extern int tegra_cpu_speedo_id;                /* only exist in Tegra30 and later */
 extern int tegra_soc_speedo_id;
+extern int tegra_package_id;
 
 extern int tegra_bct_strapping;
 
index ee71cd1..3358cc0 100644 (file)
@@ -28,6 +28,8 @@
 
 #include <mach/iomap.h>
 
+#include "fuse.h"
+
 #define PMC_PWR_IO_DISABLE     0x44
 #define PMC_PWR_DET_ENABLE     0x48
 #define PMC_PWR_DET_LATCH      0x4C
@@ -37,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;
 };
@@ -62,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)
@@ -284,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"
@@ -298,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 fa6eb57..4da5161 100644 (file)
@@ -68,6 +68,8 @@ void tegra20_init_speedo_data(void)
        BUILD_BUG_ON(ARRAY_SIZE(cpu_process_speedos) != SPEEDO_ID_COUNT);
        BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) != SPEEDO_ID_COUNT);
 
+       tegra_package_id = -1;
+
        if (SPEEDO_ID_SELECT_0(tegra_revision))
                tegra_soc_speedo_id = SPEEDO_ID_0;
        else if (SPEEDO_ID_SELECT_1(tegra_sku_id))
index 125cb16..406da8d 100644 (file)
@@ -82,7 +82,6 @@ static const u32 cpu_process_speedos[][CPU_PROCESS_CORNERS_NUM] = {
 };
 
 static int threshold_index;
-static int package_id;
 
 static void fuse_speedo_calib(u32 *speedo_g, u32 *speedo_lp)
 {
@@ -135,7 +134,7 @@ static void rev_sku_to_speedo_ids(int rev, int sku)
                        threshold_index = THRESHOLD_INDEX_1;
                        break;
                case 0x81:
-                       switch (package_id) {
+                       switch (tegra_package_id) {
                        case 1:
                                tegra_cpu_speedo_id = 2;
                                tegra_soc_speedo_id = 2;
@@ -147,13 +146,13 @@ static void rev_sku_to_speedo_ids(int rev, int sku)
                                threshold_index = THRESHOLD_INDEX_7;
                                break;
                        default:
-                               pr_err("Tegra30: Unknown pkg %d\n", package_id);
+                               pr_err("Tegra30: Unknown pkg %d\n", tegra_package_id);
                                BUG();
                                break;
                        }
                        break;
                case 0x80:
-                       switch (package_id) {
+                       switch (tegra_package_id) {
                        case 1:
                                tegra_cpu_speedo_id = 5;
                                tegra_soc_speedo_id = 2;
@@ -165,13 +164,13 @@ static void rev_sku_to_speedo_ids(int rev, int sku)
                                threshold_index = THRESHOLD_INDEX_9;
                                break;
                        default:
-                               pr_err("Tegra30: Unknown pkg %d\n", package_id);
+                               pr_err("Tegra30: Unknown pkg %d\n", tegra_package_id);
                                BUG();
                                break;
                        }
                        break;
                case 0x83:
-                       switch (package_id) {
+                       switch (tegra_package_id) {
                        case 1:
                                tegra_cpu_speedo_id = 7;
                                tegra_soc_speedo_id = 1;
@@ -183,7 +182,7 @@ static void rev_sku_to_speedo_ids(int rev, int sku)
                                threshold_index = THRESHOLD_INDEX_3;
                                break;
                        default:
-                               pr_err("Tegra30: Unknown pkg %d\n", package_id);
+                               pr_err("Tegra30: Unknown pkg %d\n", tegra_package_id);
                                BUG();
                                break;
                        }
@@ -209,7 +208,7 @@ static void rev_sku_to_speedo_ids(int rev, int sku)
                        threshold_index = THRESHOLD_INDEX_6;
                        break;
                case 0:
-                       switch (package_id) {
+                       switch (tegra_package_id) {
                        case 1:
                                tegra_cpu_speedo_id = 2;
                                tegra_soc_speedo_id = 2;
@@ -221,7 +220,7 @@ static void rev_sku_to_speedo_ids(int rev, int sku)
                                threshold_index = THRESHOLD_INDEX_3;
                                break;
                        default:
-                               pr_err("Tegra30: Unknown pkg %d\n", package_id);
+                               pr_err("Tegra30: Unknown pkg %d\n", tegra_package_id);
                                BUG();
                                break;
                        }
@@ -254,7 +253,7 @@ void tegra30_init_speedo_data(void)
        BUILD_BUG_ON(ARRAY_SIZE(core_process_speedos) !=
                        THRESHOLD_INDEX_COUNT);
 
-       package_id = tegra_fuse_readl(FUSE_PACKAGE_INFO) & 0x0F;
+       tegra_package_id = tegra_fuse_readl(FUSE_PACKAGE_INFO) & 0x0F;
 
        rev_sku_to_speedo_ids(tegra_revision, tegra_sku_id);
        fuse_speedo_calib(&cpu_speedo_val, &core_speedo_val);