diff options
Diffstat (limited to 'arch/arm/mach-tegra/board-harmony-power.c')
-rw-r--r-- | arch/arm/mach-tegra/board-harmony-power.c | 267 |
1 files changed, 240 insertions, 27 deletions
diff --git a/arch/arm/mach-tegra/board-harmony-power.c b/arch/arm/mach-tegra/board-harmony-power.c index 5ad8b2f94f8..39473f5d9a3 100644 --- a/arch/arm/mach-tegra/board-harmony-power.c +++ b/arch/arm/mach-tegra/board-harmony-power.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2010 NVIDIA, Inc. | 2 | * Copyright (C) 2010-2011 NVIDIA, Inc. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify | 4 | * This program is free software; you can redistribute it and/or modify |
5 | * it under the terms of the GNU General Public License version 2 as | 5 | * it under the terms of the GNU General Public License version 2 as |
@@ -20,35 +20,176 @@ | |||
20 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
21 | 21 | ||
22 | #include <linux/regulator/machine.h> | 22 | #include <linux/regulator/machine.h> |
23 | #include <linux/regulator/fixed.h> | ||
23 | #include <linux/mfd/tps6586x.h> | 24 | #include <linux/mfd/tps6586x.h> |
25 | #include <linux/io.h> | ||
24 | 26 | ||
27 | #include <mach/iomap.h> | ||
25 | #include <mach/irqs.h> | 28 | #include <mach/irqs.h> |
26 | 29 | ||
27 | #include "board-harmony.h" | 30 | #include "board-harmony.h" |
31 | #include "pm.h" | ||
28 | 32 | ||
29 | #define PMC_CTRL 0x0 | 33 | #define PMC_CTRL 0x0 |
30 | #define PMC_CTRL_INTR_LOW (1 << 17) | 34 | #define PMC_CTRL_INTR_LOW (1 << 17) |
31 | 35 | ||
36 | static struct regulator_consumer_supply tps658621_sm0_supply[] = { | ||
37 | REGULATOR_SUPPLY("vdd_core", NULL), | ||
38 | }; | ||
39 | |||
40 | static struct regulator_consumer_supply tps658621_sm1_supply[] = { | ||
41 | REGULATOR_SUPPLY("vdd_cpu", NULL), | ||
42 | }; | ||
43 | |||
44 | static struct regulator_consumer_supply tps658621_sm2_supply[] = { | ||
45 | REGULATOR_SUPPLY("vdd_sm2", NULL), | ||
46 | }; | ||
47 | |||
32 | static struct regulator_consumer_supply tps658621_ldo0_supply[] = { | 48 | static struct regulator_consumer_supply tps658621_ldo0_supply[] = { |
33 | REGULATOR_SUPPLY("pex_clk", NULL), | 49 | REGULATOR_SUPPLY("p_cam_avdd", NULL), |
50 | }; | ||
51 | |||
52 | static struct regulator_consumer_supply tps658621_ldo1_supply[] = { | ||
53 | REGULATOR_SUPPLY("avdd_pll", NULL), | ||
54 | }; | ||
55 | |||
56 | static struct regulator_consumer_supply tps658621_ldo2_supply[] = { | ||
57 | REGULATOR_SUPPLY("vdd_rtc", NULL), | ||
58 | }; | ||
59 | |||
60 | static struct regulator_consumer_supply tps658621_ldo3_supply[] = { | ||
61 | REGULATOR_SUPPLY("avdd_usb", NULL), | ||
62 | REGULATOR_SUPPLY("avdd_usb_pll", NULL), | ||
63 | REGULATOR_SUPPLY("avdd_lvds", NULL), | ||
64 | }; | ||
65 | |||
66 | static struct regulator_consumer_supply tps658621_ldo4_supply[] = { | ||
67 | REGULATOR_SUPPLY("avdd_osc", NULL), | ||
68 | REGULATOR_SUPPLY("vddio_sys", "panjit_touch"), | ||
69 | }; | ||
70 | |||
71 | static struct regulator_consumer_supply tps658621_ldo5_supply[] = { | ||
72 | REGULATOR_SUPPLY("vcore_mmc", "sdhci-tegra.1"), | ||
73 | REGULATOR_SUPPLY("vcore_mmc", "sdhci-tegra.3"), | ||
74 | }; | ||
75 | |||
76 | static struct regulator_consumer_supply tps658621_ldo6_supply[] = { | ||
77 | REGULATOR_SUPPLY("avdd_vdac", NULL), | ||
78 | }; | ||
79 | |||
80 | static struct regulator_consumer_supply tps658621_ldo7_supply[] = { | ||
81 | REGULATOR_SUPPLY("avdd_hdmi", NULL), | ||
82 | REGULATOR_SUPPLY("vdd_fuse", NULL), | ||
83 | }; | ||
84 | |||
85 | static struct regulator_consumer_supply tps658621_ldo8_supply[] = { | ||
86 | REGULATOR_SUPPLY("avdd_hdmi_pll", NULL), | ||
87 | }; | ||
88 | |||
89 | static struct regulator_consumer_supply tps658621_ldo9_supply[] = { | ||
90 | REGULATOR_SUPPLY("avdd_2v85", NULL), | ||
91 | REGULATOR_SUPPLY("vdd_ddr_rx", NULL), | ||
92 | REGULATOR_SUPPLY("avdd_amp", NULL), | ||
93 | }; | ||
94 | |||
95 | /* regulator supplies power to WWAN - by default disable */ | ||
96 | static struct regulator_consumer_supply vdd_1v5_consumer_supply[] = { | ||
97 | REGULATOR_SUPPLY("vdd_1v5", NULL), | ||
98 | }; | ||
99 | |||
100 | static struct regulator_init_data vdd_1v5_initdata = { | ||
101 | .consumer_supplies = vdd_1v5_consumer_supply, | ||
102 | .num_consumer_supplies = 1, | ||
103 | .constraints = { | ||
104 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
105 | .always_on = 0, | ||
106 | }, | ||
107 | }; | ||
108 | |||
109 | static struct fixed_voltage_config vdd_1v5 = { | ||
110 | .supply_name = "vdd_1v5", | ||
111 | .microvolts = 1500000, /* Enable 1.5V */ | ||
112 | .gpio = TPS_GPIO_EN_1V5, /* GPIO BASE+0 */ | ||
113 | .startup_delay = 0, | ||
114 | .enable_high = 0, | ||
115 | .enabled_at_boot = 0, | ||
116 | .init_data = &vdd_1v5_initdata, | ||
117 | }; | ||
118 | |||
119 | /* regulator supplies power to WLAN - enable here, to satisfy SDIO probing */ | ||
120 | static struct regulator_consumer_supply vdd_1v2_consumer_supply[] = { | ||
121 | REGULATOR_SUPPLY("vdd_1v2", NULL), | ||
122 | }; | ||
123 | |||
124 | static struct regulator_init_data vdd_1v2_initdata = { | ||
125 | .consumer_supplies = vdd_1v2_consumer_supply, | ||
126 | .num_consumer_supplies = 1, | ||
127 | .constraints = { | ||
128 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
129 | .always_on = 1, | ||
130 | }, | ||
131 | }; | ||
132 | |||
133 | static struct fixed_voltage_config vdd_1v2 = { | ||
134 | .supply_name = "vdd_1v2", | ||
135 | .microvolts = 1200000, /* Enable 1.2V */ | ||
136 | .gpio = TPS_GPIO_EN_1V2, /* GPIO BASE+1 */ | ||
137 | .startup_delay = 0, | ||
138 | .enable_high = 1, | ||
139 | .enabled_at_boot = 1, | ||
140 | .init_data = &vdd_1v2_initdata, | ||
141 | }; | ||
142 | |||
143 | /* regulator supplies power to PLL - enable here */ | ||
144 | static struct regulator_consumer_supply vdd_1v05_consumer_supply[] = { | ||
145 | REGULATOR_SUPPLY("vdd_1v05", NULL), | ||
34 | }; | 146 | }; |
35 | 147 | ||
36 | static struct regulator_init_data ldo0_data = { | 148 | static struct regulator_init_data vdd_1v05_initdata = { |
149 | .consumer_supplies = vdd_1v05_consumer_supply, | ||
150 | .num_consumer_supplies = 1, | ||
37 | .constraints = { | 151 | .constraints = { |
38 | .min_uV = 1250 * 1000, | 152 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, |
39 | .max_uV = 3300 * 1000, | 153 | .always_on = 1, |
40 | .valid_modes_mask = (REGULATOR_MODE_NORMAL | | ||
41 | REGULATOR_MODE_STANDBY), | ||
42 | .valid_ops_mask = (REGULATOR_CHANGE_MODE | | ||
43 | REGULATOR_CHANGE_STATUS | | ||
44 | REGULATOR_CHANGE_VOLTAGE), | ||
45 | }, | 154 | }, |
46 | .num_consumer_supplies = ARRAY_SIZE(tps658621_ldo0_supply), | ||
47 | .consumer_supplies = tps658621_ldo0_supply, | ||
48 | }; | 155 | }; |
49 | 156 | ||
50 | #define HARMONY_REGULATOR_INIT(_id, _minmv, _maxmv) \ | 157 | static struct fixed_voltage_config vdd_1v05 = { |
51 | static struct regulator_init_data _id##_data = { \ | 158 | .supply_name = "vdd_1v05", |
159 | .microvolts = 1050000, /* Enable 1.05V */ | ||
160 | .gpio = TPS_GPIO_EN_1V05, /* BASE+2 */ | ||
161 | .startup_delay = 0, | ||
162 | .enable_high = 1, | ||
163 | .enabled_at_boot = 0, | ||
164 | .init_data = &vdd_1v05_initdata, | ||
165 | }; | ||
166 | |||
167 | /* mode pin for 1.05V regulator - enable here */ | ||
168 | static struct regulator_consumer_supply vdd_1v05_mode_consumer_supply[] = { | ||
169 | REGULATOR_SUPPLY("vdd_1v05_mode", NULL), | ||
170 | }; | ||
171 | |||
172 | static struct regulator_init_data vdd_1v05_mode_initdata = { | ||
173 | .consumer_supplies = vdd_1v05_mode_consumer_supply, | ||
174 | .num_consumer_supplies = 1, | ||
175 | .constraints = { | ||
176 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
177 | .always_on = 1, | ||
178 | }, | ||
179 | }; | ||
180 | |||
181 | static struct fixed_voltage_config vdd_1v05_mode = { | ||
182 | .supply_name = "vdd_1v05_mode", | ||
183 | .microvolts = 1050000, /* Enable 1.05V */ | ||
184 | .gpio = TPS_GPIO_MODE_1V05, /* BASE+3 */ | ||
185 | .startup_delay = 0, | ||
186 | .enable_high = 1, | ||
187 | .enabled_at_boot = 0, | ||
188 | .init_data = &vdd_1v05_mode_initdata, | ||
189 | }; | ||
190 | |||
191 | #define REGULATOR_INIT(_id, _minmv, _maxmv) \ | ||
192 | { \ | ||
52 | .constraints = { \ | 193 | .constraints = { \ |
53 | .min_uV = (_minmv)*1000, \ | 194 | .min_uV = (_minmv)*1000, \ |
54 | .max_uV = (_maxmv)*1000, \ | 195 | .max_uV = (_maxmv)*1000, \ |
@@ -58,20 +199,33 @@ static struct regulator_init_data ldo0_data = { | |||
58 | REGULATOR_CHANGE_STATUS | \ | 199 | REGULATOR_CHANGE_STATUS | \ |
59 | REGULATOR_CHANGE_VOLTAGE), \ | 200 | REGULATOR_CHANGE_VOLTAGE), \ |
60 | }, \ | 201 | }, \ |
202 | .num_consumer_supplies = ARRAY_SIZE(tps658621_##_id##_supply),\ | ||
203 | .consumer_supplies = tps658621_##_id##_supply, \ | ||
61 | } | 204 | } |
62 | 205 | ||
63 | HARMONY_REGULATOR_INIT(sm0, 725, 1500); | 206 | static struct regulator_init_data sm0_data = REGULATOR_INIT(sm0, 725, 1500); |
64 | HARMONY_REGULATOR_INIT(sm1, 725, 1500); | 207 | static struct regulator_init_data sm1_data = REGULATOR_INIT(sm1, 725, 1500); |
65 | HARMONY_REGULATOR_INIT(sm2, 3000, 4550); | 208 | static struct regulator_init_data sm2_data = REGULATOR_INIT(sm2, 3000, 4550); |
66 | HARMONY_REGULATOR_INIT(ldo1, 725, 1500); | 209 | static struct regulator_init_data ldo0_data = REGULATOR_INIT(ldo0, 1250, 3300); |
67 | HARMONY_REGULATOR_INIT(ldo2, 725, 1500); | 210 | static struct regulator_init_data ldo1_data = REGULATOR_INIT(ldo1, 725, 1500); |
68 | HARMONY_REGULATOR_INIT(ldo3, 1250, 3300); | 211 | static struct regulator_init_data ldo2_data = REGULATOR_INIT(ldo2, 725, 1500); |
69 | HARMONY_REGULATOR_INIT(ldo4, 1700, 2475); | 212 | static struct regulator_init_data ldo3_data = REGULATOR_INIT(ldo3, 1250, 3300); |
70 | HARMONY_REGULATOR_INIT(ldo5, 1250, 3300); | 213 | static struct regulator_init_data ldo4_data = REGULATOR_INIT(ldo4, 1700, 2475); |
71 | HARMONY_REGULATOR_INIT(ldo6, 1250, 3300); | 214 | static struct regulator_init_data ldo5_data = REGULATOR_INIT(ldo5, 1250, 3300); |
72 | HARMONY_REGULATOR_INIT(ldo7, 1250, 3300); | 215 | static struct regulator_init_data ldo6_data = REGULATOR_INIT(ldo6, 1250, 3300); |
73 | HARMONY_REGULATOR_INIT(ldo8, 1250, 3300); | 216 | static struct regulator_init_data ldo7_data = REGULATOR_INIT(ldo7, 1250, 3300); |
74 | HARMONY_REGULATOR_INIT(ldo9, 1250, 3300); | 217 | static struct regulator_init_data ldo8_data = REGULATOR_INIT(ldo8, 1250, 3300); |
218 | static struct regulator_init_data ldo9_data = REGULATOR_INIT(ldo9, 1250, 3300); | ||
219 | |||
220 | static struct tps6586x_rtc_platform_data rtc_data = { | ||
221 | .irq = TEGRA_NR_IRQS + TPS6586X_INT_RTC_ALM1, | ||
222 | .start = { | ||
223 | .year = 2009, | ||
224 | .month = 1, | ||
225 | .day = 1, | ||
226 | }, | ||
227 | .cl_sel = TPS6586X_RTC_CL_SEL_1_5PF /* use lowest (external 20pF cap) */ | ||
228 | }; | ||
75 | 229 | ||
76 | #define TPS_REG(_id, _data) \ | 230 | #define TPS_REG(_id, _data) \ |
77 | { \ | 231 | { \ |
@@ -80,6 +234,13 @@ HARMONY_REGULATOR_INIT(ldo9, 1250, 3300); | |||
80 | .platform_data = _data, \ | 234 | .platform_data = _data, \ |
81 | } | 235 | } |
82 | 236 | ||
237 | #define TPS_GPIO_FIXED_REG(_id, _data) \ | ||
238 | { \ | ||
239 | .id = _id, \ | ||
240 | .name = "reg-fixed-voltage", \ | ||
241 | .platform_data = _data, \ | ||
242 | } | ||
243 | |||
83 | static struct tps6586x_subdev_info tps_devs[] = { | 244 | static struct tps6586x_subdev_info tps_devs[] = { |
84 | TPS_REG(SM_0, &sm0_data), | 245 | TPS_REG(SM_0, &sm0_data), |
85 | TPS_REG(SM_1, &sm1_data), | 246 | TPS_REG(SM_1, &sm1_data), |
@@ -94,6 +255,15 @@ static struct tps6586x_subdev_info tps_devs[] = { | |||
94 | TPS_REG(LDO_7, &ldo7_data), | 255 | TPS_REG(LDO_7, &ldo7_data), |
95 | TPS_REG(LDO_8, &ldo8_data), | 256 | TPS_REG(LDO_8, &ldo8_data), |
96 | TPS_REG(LDO_9, &ldo9_data), | 257 | TPS_REG(LDO_9, &ldo9_data), |
258 | TPS_GPIO_FIXED_REG(0, &vdd_1v5), | ||
259 | TPS_GPIO_FIXED_REG(1, &vdd_1v2), | ||
260 | TPS_GPIO_FIXED_REG(2, &vdd_1v05), | ||
261 | TPS_GPIO_FIXED_REG(3, &vdd_1v05_mode), | ||
262 | { | ||
263 | .id = 0, | ||
264 | .name = "tps6586x-rtc", | ||
265 | .platform_data = &rtc_data, | ||
266 | }, | ||
97 | }; | 267 | }; |
98 | 268 | ||
99 | static struct tps6586x_platform_data tps_platform = { | 269 | static struct tps6586x_platform_data tps_platform = { |
@@ -101,6 +271,7 @@ static struct tps6586x_platform_data tps_platform = { | |||
101 | .num_subdevs = ARRAY_SIZE(tps_devs), | 271 | .num_subdevs = ARRAY_SIZE(tps_devs), |
102 | .subdevs = tps_devs, | 272 | .subdevs = tps_devs, |
103 | .gpio_base = HARMONY_GPIO_TPS6586X(0), | 273 | .gpio_base = HARMONY_GPIO_TPS6586X(0), |
274 | .use_power_off = true, | ||
104 | }; | 275 | }; |
105 | 276 | ||
106 | static struct i2c_board_info __initdata harmony_regulators[] = { | 277 | static struct i2c_board_info __initdata harmony_regulators[] = { |
@@ -111,9 +282,51 @@ static struct i2c_board_info __initdata harmony_regulators[] = { | |||
111 | }, | 282 | }, |
112 | }; | 283 | }; |
113 | 284 | ||
285 | static void harmony_board_suspend(int lp_state, enum suspend_stage stg) | ||
286 | { | ||
287 | if ((lp_state == TEGRA_SUSPEND_LP1) && (stg == TEGRA_SUSPEND_BEFORE_CPU)) | ||
288 | tegra_console_uart_suspend(); | ||
289 | } | ||
290 | |||
291 | static void harmony_board_resume(int lp_state, enum resume_stage stg) | ||
292 | { | ||
293 | if ((lp_state == TEGRA_SUSPEND_LP1) && (stg == TEGRA_RESUME_AFTER_CPU)) | ||
294 | tegra_console_uart_resume(); | ||
295 | } | ||
296 | |||
297 | static struct tegra_suspend_platform_data harmony_suspend_data = { | ||
298 | /* | ||
299 | * Check power on time and crystal oscillator start time | ||
300 | * for appropriate settings. | ||
301 | */ | ||
302 | .cpu_timer = 5000, | ||
303 | .cpu_off_timer = 5000, | ||
304 | .suspend_mode = TEGRA_SUSPEND_LP0, | ||
305 | .core_timer = 0x7e7e, | ||
306 | .core_off_timer = 0x7f, | ||
307 | .corereq_high = false, | ||
308 | .sysclkreq_high = true, | ||
309 | .board_suspend = harmony_board_suspend, | ||
310 | .board_resume = harmony_board_resume, | ||
311 | }; | ||
312 | |||
313 | int __init harmony_suspend_init(void) | ||
314 | { | ||
315 | tegra_init_suspend(&harmony_suspend_data); | ||
316 | return 0; | ||
317 | } | ||
318 | |||
114 | int __init harmony_regulator_init(void) | 319 | int __init harmony_regulator_init(void) |
115 | { | 320 | { |
116 | i2c_register_board_info(3, harmony_regulators, 1); | 321 | void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE); |
322 | u32 pmc_ctrl; | ||
323 | |||
324 | /* configure the power management controller to trigger PMU | ||
325 | * interrupts when low */ | ||
326 | pmc_ctrl = readl(pmc + PMC_CTRL); | ||
327 | writel(pmc_ctrl | PMC_CTRL_INTR_LOW, pmc + PMC_CTRL); | ||
328 | |||
329 | i2c_register_board_info(4, harmony_regulators, 1); | ||
117 | 330 | ||
118 | return 0; | 331 | return 0; |
119 | } | 332 | } |