summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorLuke Huang <lhuang@nvidia.com>2010-06-23 15:28:03 -0700
committerGary King <gking@nvidia.com>2010-06-26 09:55:02 -0700
commitf73e9712a20da75c44071ff7d35d041c77d8fdc1 (patch)
treec5a58fcd194c78177aff08782ebebd82504c3218 /arch
parentd1e13717c02766f06f4e0af193978b98bcaaf726 (diff)
tegra gpio module: Using regulator module for GPIO power rail control
Modify gpio module to use regulator module for controlling GPIO power rail. Since there are some issues related to init sequence after this change, using "postcore_initcall_sync" to involve regulator module, as well as modifying NvRmOpenNew routine are required. Bug Id 697774 Change-Id: Ie8002f1190da83355c0554496f9fef24d18207f5 Reviewed-on: http://git-master/r/3103 Reviewed-by: Gary King <gking@nvidia.com> Tested-by: Gary King <gking@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-tegra/board-nvodm.c120
-rw-r--r--arch/arm/mach-tegra/clock_nvrm.c2
-rw-r--r--arch/arm/mach-tegra/gpio.c86
-rw-r--r--arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_init.c26
-rw-r--r--arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_private.h5
-rw-r--r--arch/arm/mach-tegra/nvrm/core/ap15/nvrm_clocks.c2
-rw-r--r--arch/arm/mach-tegra/nvrm/core/common/nvrm_clocks.h7
7 files changed, 176 insertions, 72 deletions
diff --git a/arch/arm/mach-tegra/board-nvodm.c b/arch/arm/mach-tegra/board-nvodm.c
index fa84dc2db108..68107e4d1614 100644
--- a/arch/arm/mach-tegra/board-nvodm.c
+++ b/arch/arm/mach-tegra/board-nvodm.c
@@ -848,6 +848,52 @@ static struct regulator_consumer_supply tegra_soc_consumers[] = {
.supply = "soc_main",
},
};
+static struct regulator_consumer_supply tegra_vdd_bb_consumers[] = {
+ [0] = {
+ .supply = "vddio bb",
+ },
+};
+static struct regulator_consumer_supply tegra_vdd_lcd_consumers[] = {
+ [0] = {
+ .supply = "vddio lcd",
+ },
+};
+static struct regulator_consumer_supply tegra_vdd_vi_consumers[] = {
+ [0] = {
+ .supply = "vddio vi",
+ },
+};
+static struct regulator_consumer_supply tegra_vdd_uart_consumers[] = {
+ [0] = {
+ .supply = "vddio uart",
+ },
+};
+static struct regulator_consumer_supply tegra_vdd_ddr_consumers[] = {
+ [0] = {
+ .supply = "vddio ddr",
+ },
+};
+static struct regulator_consumer_supply tegra_vdd_nand_consumers[] = {
+ [0] = {
+ .supply = "vddio nand",
+ },
+};
+static struct regulator_consumer_supply tegra_vdd_sys_consumers[] = {
+ [0] = {
+ .supply = "vdd_ldo4",
+ },
+};
+static struct regulator_consumer_supply tegra_vdd_audio_consumers[] = {
+ [0] = {
+ .supply = "vddio audio",
+ },
+};
+static struct regulator_consumer_supply tegra_vdd_sd_consumers[] = {
+ [0] = {
+ .supply = "vddio sd",
+ },
+};
+
#ifdef CONFIG_TEGRA_USB_CHARGE
static struct regulator_consumer_supply tegra_vbus_consumers[] = {
[0] = {
@@ -878,11 +924,74 @@ static struct tegra_regulator_entry tegra_regulators[] = {
.consumers = tegra_soc_consumers,
.nr_consumers = ARRAY_SIZE(tegra_soc_consumers),
},
-#ifdef CONFIG_TEGRA_USB_CHARGE
[3] = {
+ .guid = NV_VDD_BB_ODM_ID,
+ .name = "vddio bb",
+ .id = 3,
+ .consumers = tegra_vdd_bb_consumers,
+ .nr_consumers = ARRAY_SIZE(tegra_vdd_bb_consumers),
+ },
+ [4] = {
+ .guid = NV_VDD_LCD_ODM_ID,
+ .name = "vddio lcd",
+ .id = 4,
+ .consumers = tegra_vdd_lcd_consumers,
+ .nr_consumers = ARRAY_SIZE(tegra_vdd_lcd_consumers),
+ },
+ [5] = {
+ .guid = NV_VDD_VI_ODM_ID,
+ .name = "vddio vi",
+ .id = 5,
+ .consumers = tegra_vdd_vi_consumers,
+ .nr_consumers = ARRAY_SIZE(tegra_vdd_vi_consumers),
+ },
+ [6] = {
+ .guid = NV_VDD_UART_ODM_ID,
+ .name = "vddio uart",
+ .id = 6,
+ .consumers = tegra_vdd_uart_consumers,
+ .nr_consumers = ARRAY_SIZE(tegra_vdd_uart_consumers),
+ },
+ [7] = {
+ .guid = NV_VDD_DDR_ODM_ID,
+ .name = "vddio ddr",
+ .id = 7,
+ .consumers = tegra_vdd_ddr_consumers,
+ .nr_consumers = ARRAY_SIZE(tegra_vdd_ddr_consumers),
+ },
+ [8] = {
+ .guid = NV_VDD_NAND_ODM_ID,
+ .name = "vddio nand",
+ .id = 8,
+ .consumers = tegra_vdd_nand_consumers,
+ .nr_consumers = ARRAY_SIZE(tegra_vdd_nand_consumers),
+ },
+ [9] = {
+ .guid = NV_VDD_SYS_ODM_ID,
+ .name = "vddio sys",
+ .id = 9,
+ .consumers = tegra_vdd_sys_consumers,
+ .nr_consumers = ARRAY_SIZE(tegra_vdd_sys_consumers),
+ },
+ [10] = {
+ .guid = NV_VDD_AUD_ODM_ID,
+ .name = "vddio audio",
+ .id = 10,
+ .consumers = tegra_vdd_audio_consumers,
+ .nr_consumers = ARRAY_SIZE(tegra_vdd_audio_consumers),
+ },
+ [11] = {
+ .guid = NV_VDD_SDIO_ODM_ID,
+ .name = "vddio sd",
+ .id = 11,
+ .consumers = tegra_vdd_sd_consumers,
+ .nr_consumers = ARRAY_SIZE(tegra_vdd_sd_consumers),
+ },
+#ifdef CONFIG_TEGRA_USB_CHARGE
+ [12] = {
.charging_path = NvRmPmuChargingPath_UsbBus,
.name = "vbus_draw",
- .id = 3,
+ .id = 12,
.consumers = tegra_vbus_consumers,
.nr_consumers = ARRAY_SIZE(tegra_vbus_consumers),
.is_charger = true,
@@ -1411,6 +1520,12 @@ do_register:
tegra_init_idle(plat);
}
+void __init tegra_setup_data(void)
+{
+ platform_add_devices(nvodm_devices, ARRAY_SIZE(nvodm_devices));
+}
+postcore_initcall(tegra_setup_data);
+
void __init tegra_setup_nvodm(bool standard_i2c, bool standard_spi)
{
NvRmGpioOpen(s_hRmGlobal, &s_hGpioGlobal);
@@ -1426,7 +1541,6 @@ void __init tegra_setup_nvodm(bool standard_i2c, bool standard_spi)
if (standard_spi)
tegra_setup_spi();
tegra_setup_w1();
- platform_add_devices(nvodm_devices, ARRAY_SIZE(nvodm_devices));
pm_power_off = tegra_system_power_off;
tegra_setup_suspend();
}
diff --git a/arch/arm/mach-tegra/clock_nvrm.c b/arch/arm/mach-tegra/clock_nvrm.c
index 69a5c8aeb8dd..c94dfd6a54a7 100644
--- a/arch/arm/mach-tegra/clock_nvrm.c
+++ b/arch/arm/mach-tegra/clock_nvrm.c
@@ -398,6 +398,8 @@ void __init tegra_init_clock(void)
e = NvRmOpenNew(&s_hRmGlobal);
BUG_ON(e!=NvSuccess);
+
+ NvRmPrivPostRegulatorInit(s_hRmGlobal);
NvRmPowerRegister(s_hRmGlobal, 0, &clk_pwr_client);
tegra2_init_clocks();
diff --git a/arch/arm/mach-tegra/gpio.c b/arch/arm/mach-tegra/gpio.c
index 8ec4266d2021..2583236668e6 100644
--- a/arch/arm/mach-tegra/gpio.c
+++ b/arch/arm/mach-tegra/gpio.c
@@ -24,6 +24,7 @@
#include <linux/io.h>
#include <linux/gpio.h>
+#include <linux/regulator/consumer.h>
#include <mach/iomap.h>
#include <mach/pinmux.h>
@@ -383,52 +384,6 @@ static struct irq_chip tegra_gpio_irq_chip = {
*/
static struct lock_class_key gpio_lock_class;
-struct gpio_power_rail_info {
- NvU64 guid;
- NvU32 address;
- NvU32 mv;
-};
-
-static struct gpio_power_rail_info gpio_power_rail_table[] = {
- [TEGRA_VDDIO_BB] = {.guid = NV_VDD_BB_ODM_ID,},
- [TEGRA_VDDIO_LCD] = {.guid = NV_VDD_LCD_ODM_ID,},
- [TEGRA_VDDIO_VI] = {.guid = NV_VDD_VI_ODM_ID,},
- [TEGRA_VDDIO_UART] = {.guid = NV_VDD_UART_ODM_ID,},
- [TEGRA_VDDIO_DDR] = {.guid = NV_VDD_DDR_ODM_ID,},
- [TEGRA_VDDIO_NAND] = {.guid = NV_VDD_NAND_ODM_ID,},
- [TEGRA_VDDIO_SYS] = {.guid = NV_VDD_SYS_ODM_ID,},
- [TEGRA_VDDIO_AUDIO] = {.guid = NV_VDD_AUD_ODM_ID,},
- [TEGRA_VDDIO_SD] = {.guid = NV_VDD_SDIO_ODM_ID,},
-};
-
-static void gpio_rail_init(void)
-{
- unsigned int i;
-
- if (!s_hRmGlobal) {
- NvError e = NvRmOpenNew(&s_hRmGlobal);
- if (e != NvSuccess) {
- WARN_ON(1);
- return;
- }
- }
-
- for (i = 0; i < NV_ARRAY_SIZE(gpio_power_rail_table); i++) {
- struct gpio_power_rail_info *rail = &gpio_power_rail_table[i];
- const NvOdmPeripheralConnectivity *conn;
- NvRmPmuVddRailCapabilities caps;
-
- conn = NvOdmPeripheralGetGuid(rail->guid);
- if (!conn || !conn->NumAddress)
- continue;
-
- rail->address = conn->AddressList[0].Address;
-
- NvRmPmuGetCapabilities(s_hRmGlobal, rail->address, &caps);
- rail->mv = caps.requestMilliVolts;
- }
-}
-
static int __init tegra_gpio_init(void)
{
struct tegra_gpio_bank *bank;
@@ -464,7 +419,6 @@ static int __init tegra_gpio_init(void)
spin_lock_init(&bank->lvl_lock[j]);
}
- gpio_rail_init();
return 0;
}
@@ -518,13 +472,26 @@ static int __init tegra_gpio_debuginit(void)
late_initcall(tegra_gpio_debuginit);
#endif
+static char *tegra_gpio_rail_names[] = {
+ [TEGRA_VDDIO_BB] = "vddio bb",
+ [TEGRA_VDDIO_LCD] = "vddio lcd",
+ [TEGRA_VDDIO_VI] = "vddio vi",
+ [TEGRA_VDDIO_UART] = "vddio uart",
+ [TEGRA_VDDIO_DDR] = "vddio ddr",
+ [TEGRA_VDDIO_NAND] = "vddio nand",
+ [TEGRA_VDDIO_SYS] = "vddio sys",
+ [TEGRA_VDDIO_AUDIO] = "vddio audio",
+ [TEGRA_VDDIO_SD] = "vddio sd",
+};
+
int tegra_gpio_io_power_config(int gpio_nr, unsigned int enable)
{
- struct gpio_power_rail_info *rail;
+ struct regulator *regulator = NULL;
tegra_pingroup_t pg;
- NvU32 settle;
+ const char* railName;
int vddio_id;
+
pg = gpio_get_pinmux_group(gpio_nr);
if (pg < 0)
return pg;
@@ -532,18 +499,19 @@ int tegra_gpio_io_power_config(int gpio_nr, unsigned int enable)
if(vddio_id < 0)
return vddio_id;
- if (unlikely(!s_hRmGlobal))
- return 0;
+ railName = tegra_gpio_rail_names[vddio_id];
- rail = &gpio_power_rail_table[vddio_id];
- if (!rail->address || !rail->mv)
- return 0;
-
- NvRmPmuSetVoltage(s_hRmGlobal, rail->address,
- (enable) ? rail->mv : ODM_VOLTAGE_OFF, &settle);
+ regulator = regulator_get(NULL, railName);
+ if (IS_ERR_OR_NULL(regulator)) {
+ printk(KERN_ERR "Unable to get regulator for %s, vddid 0x%x\n",
+ railName, vddio_id);
+ return PTR_ERR(regulator);
+ }
- if (settle)
- udelay(settle);
+ if (enable)
+ regulator_enable(regulator);
+ else
+ regulator_disable(regulator);
return 0;
}
diff --git a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_init.c b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_init.c
index 582d922e7328..c52181117473 100644
--- a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_init.c
+++ b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_init.c
@@ -362,14 +362,6 @@ NvRmOpenNew(NvRmDeviceHandle *pHandle)
// set the mc & emc tuning parameters
NvRmPrivSetupMc(rm);
- if (!NvRmIsSimulation())
- {
- // Configure PLL rails, boost core power and clocks
- // Initialize and start temperature monitoring
- NvRmPrivPllRailsInit(rm);
- NvRmPrivBoostClocks(rm);
- NvRmPrivDttInit(rm);
- }
// Asynchronous interrupts must be disabled until the very end of
// RmOpen. They can be enabled just before releasing rm mutex after
@@ -417,6 +409,24 @@ fail:
}
void
+NvRmPrivPostRegulatorInit(NvRmDeviceHandle hDevice)
+{
+ NV_ASSERT(hDevice);
+
+ if (!NVOS_IS_WINDOWS_X86)
+ {
+ if (!NvRmIsSimulation())
+ {
+ // Configure PLL rails, boost core power and clocks
+ // Initialize and start temperature monitoring
+ NvRmPrivPllRailsInit(hDevice);
+ NvRmPrivBoostClocks(hDevice);
+ NvRmPrivDttInit(hDevice);
+ }
+ }
+}
+
+void
NvRmClose(NvRmDeviceHandle handle)
{
if( !handle )
diff --git a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_private.h b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_private.h
index ed39fe1826b5..e6c720576dd3 100644
--- a/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_private.h
+++ b/arch/arm/mach-tegra/nvrm/core/ap15/ap15rm_private.h
@@ -101,8 +101,9 @@ NvError
NvRmPrivAp15ChipUniqueId(
NvRmDeviceHandle hDevHandle,
void* pId);
-
-// Initialize/deinitialize for various RM submodules.
+/**
+ * Initialize/deinitialize for various RM submodules.
+ */
NvError NvRmPrivDmaInit(NvRmDeviceHandle hDevice);
void NvRmPrivDmaDeInit(void);
diff --git a/arch/arm/mach-tegra/nvrm/core/ap15/nvrm_clocks.c b/arch/arm/mach-tegra/nvrm/core/ap15/nvrm_clocks.c
index c964604c820c..b6ab9339af28 100644
--- a/arch/arm/mach-tegra/nvrm/core/ap15/nvrm_clocks.c
+++ b/arch/arm/mach-tegra/nvrm/core/ap15/nvrm_clocks.c
@@ -428,6 +428,8 @@ NvRmPrivExternalClockAttach(
}
}
+
+
/*****************************************************************************/
void
diff --git a/arch/arm/mach-tegra/nvrm/core/common/nvrm_clocks.h b/arch/arm/mach-tegra/nvrm/core/common/nvrm_clocks.h
index bef73d86bd9d..21e61b4ec459 100644
--- a/arch/arm/mach-tegra/nvrm/core/common/nvrm_clocks.h
+++ b/arch/arm/mach-tegra/nvrm/core/common/nvrm_clocks.h
@@ -1380,6 +1380,13 @@ NvRmPrivModuleClockSet(
const NvRmModuleClockInfo* pCinfo,
const NvRmModuleClockState* pCstate);
+/*
+ * Init PLL rail, boost pll and power, and init DTT. This function can
+ * be called only after GPIO and regulator module is installed.
+ */
+void NvRmPrivPostRegulatorInit(
+ NvRmDeviceHandle hRmDevice);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */