arm: tegra12: add support for 0x80 embedded SKU
[linux-3.10.git] / arch / arm / mach-tegra / board-norrin-power.c
1 /*
2  * arch/arm/mach-tegra/board-norrin-power.c
3  *
4  * Copyright (c) 2013-2014 NVIDIA Corporation. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  */
19
20 #include <linux/i2c.h>
21 #include <linux/pda_power.h>
22 #include <linux/platform_device.h>
23 #include <linux/resource.h>
24 #include <linux/io.h>
25 #include <linux/gpio.h>
26 #include <linux/pid_thermal_gov.h>
27 #include <linux/tegra-fuse.h>
28 #include <linux/tegra-pmc.h>
29
30 #include <asm/mach-types.h>
31
32 #include <mach/irqs.h>
33 #include <mach/edp.h>
34 #include <mach/gpio-tegra.h>
35
36 #include "cpu-tegra.h"
37 #include "pm.h"
38 #include "tegra-board-id.h"
39 #include "board.h"
40 #include "gpio-names.h"
41 #include "board-common.h"
42 #include "board-ardbeg.h"
43 #include "tegra_cl_dvfs.h"
44 #include "devices.h"
45 #include "tegra11_soctherm.h"
46 #include "iomap.h"
47
48 static struct tegra_suspend_platform_data norrin_suspend_data = {
49         .cpu_timer      = 2000,
50         .cpu_off_timer  = 2000,
51         .suspend_mode   = TEGRA_SUSPEND_LP0,
52         .core_timer     = 0x7e7e,
53         .core_off_timer = 2000,
54         .corereq_high   = true,
55         .sysclkreq_high = true,
56         .cpu_lp2_min_residency = 1000,
57 };
58
59 #ifdef CONFIG_ARCH_TEGRA_HAS_CL_DVFS
60 /* board parameters for cpu dfll */
61 static struct tegra_cl_dvfs_cfg_param norrin_cl_dvfs_param = {
62         .sample_rate = 12500,
63
64         .force_mode = TEGRA_CL_DVFS_FORCE_FIXED,
65         .cf = 10,
66         .ci = 0,
67         .cg = 2,
68
69         .droop_cut_value = 0xF,
70         .droop_restore_ramp = 0x0,
71         .scale_out_ramp = 0x0,
72 };
73
74 /* Norrin: fixed 10mV steps from 700mV to 1400mV */
75 #define PMU_CPU_VDD_MAP_SIZE ((1400000 - 700000) / 10000 + 1)
76 static struct voltage_reg_map pmu_cpu_vdd_map[PMU_CPU_VDD_MAP_SIZE];
77 static inline void fill_reg_map(struct board_info *board_info)
78 {
79         int i;
80         u32 reg_init_value = 0x0a;
81
82         if ((board_info->board_id == BOARD_PM374) &&
83                         (board_info->fab == 0x01))
84                 reg_init_value = 0x1e;
85
86         for (i = 0; i < PMU_CPU_VDD_MAP_SIZE; i++) {
87                 pmu_cpu_vdd_map[i].reg_value = i + reg_init_value;
88                 pmu_cpu_vdd_map[i].reg_uV = 700000 + 10000 * i;
89         }
90 }
91
92 static struct tegra_cl_dvfs_platform_data norrin_cl_dvfs_data = {
93         .dfll_clk_name = "dfll_cpu",
94         .pmu_if = TEGRA_CL_DVFS_PMU_I2C,
95         .u.pmu_i2c = {
96                 .fs_rate = 400000,
97                 .slave_addr = 0x80,
98                 .reg = 0x00,
99         },
100         .vdd_map = pmu_cpu_vdd_map,
101         .vdd_map_size = PMU_CPU_VDD_MAP_SIZE,
102
103         .cfg_param = &norrin_cl_dvfs_param,
104 };
105
106
107 static const struct of_device_id dfll_of_match[] = {
108         { .compatible   = "nvidia,tegra124-dfll", },
109         { .compatible   = "nvidia,tegra132-dfll", },
110         { },
111 };
112
113 static int __init norrin_cl_dvfs_init(void)
114 {
115         struct board_info board_info;
116         struct device_node *dn = of_find_matching_node(NULL, dfll_of_match);
117
118         /*
119          * Norrin platforms maybe used with different DT variants. Some of them
120          * include DFLL data in DT, some - not. Check DT here, and continue with
121          * platform device registration only if DT DFLL node is not present.
122          */
123         if (dn) {
124                 bool available = of_device_is_available(dn);
125                 of_node_put(dn);
126                 if (available)
127                         return 0;
128         }
129
130         tegra_get_board_info(&board_info);
131
132         fill_reg_map(&board_info);
133         norrin_cl_dvfs_data.flags = TEGRA_CL_DVFS_DYN_OUTPUT_CFG;
134         if (board_info.board_id == BOARD_PM374)
135                 norrin_cl_dvfs_data.flags |= TEGRA_CL_DVFS_DATA_NEW_NO_USE;
136         tegra_cl_dvfs_device.dev.platform_data = &norrin_cl_dvfs_data;
137         platform_device_register(&tegra_cl_dvfs_device);
138
139         return 0;
140 }
141 #endif
142
143 int __init norrin_regulator_init(void)
144 {
145
146 #ifdef CONFIG_ARCH_TEGRA_HAS_CL_DVFS
147         norrin_cl_dvfs_init();
148 #endif
149         tegra_pmc_pmu_interrupt_polarity(true);
150
151         return 0;
152 }
153
154 int __init norrin_suspend_init(void)
155 {
156         tegra_init_suspend(&norrin_suspend_data);
157         return 0;
158 }
159
160 static struct pid_thermal_gov_params soctherm_pid_params = {
161         .max_err_temp = 9000,
162         .max_err_gain = 1000,
163
164         .gain_p = 1000,
165         .gain_d = 0,
166
167         .up_compensation = 20,
168         .down_compensation = 20,
169 };
170
171 static struct thermal_zone_params soctherm_tzp = {
172         .governor_name = "pid_thermal_gov",
173         .governor_params = &soctherm_pid_params,
174 };
175
176 static struct tegra_thermtrip_pmic_data tpdata_as3722 = {
177         .reset_tegra = 1,
178         .pmu_16bit_ops = 0,
179         .controller_type = 0,
180         .pmu_i2c_addr = 0x40,
181         .i2c_controller_id = 4,
182         .poweroff_reg_addr = 0x36,
183         .poweroff_reg_data = 0x2,
184 };
185
186 /* This is really v2 rev of the norrin_soctherm_data structure */
187 static struct soctherm_platform_data norrin_soctherm_data = {
188         .therm = {
189                 [THERM_CPU] = {
190                         .zone_enable = true,
191                         .passive_delay = 1000,
192                         .hotspot_offset = 10000,
193                         .num_trips = 3,
194                         .trips = {
195                                 {
196                                         .cdev_type = "tegra-shutdown",
197                                         .trip_temp = 105000,
198                                         .trip_type = THERMAL_TRIP_CRITICAL,
199                                         .upper = THERMAL_NO_LIMIT,
200                                         .lower = THERMAL_NO_LIMIT,
201                                 },
202                                 {
203                                         .cdev_type = "tegra-heavy",
204                                         .trip_temp = 102000,
205                                         .trip_type = THERMAL_TRIP_HOT,
206                                         .upper = THERMAL_NO_LIMIT,
207                                         .lower = THERMAL_NO_LIMIT,
208                                 },
209                                 {
210                                         .cdev_type = "cpu-balanced",
211                                         .trip_temp = 92000,
212                                         .trip_type = THERMAL_TRIP_PASSIVE,
213                                         .upper = THERMAL_NO_LIMIT,
214                                         .lower = THERMAL_NO_LIMIT,
215                                 },
216                         },
217                         .tzp = &soctherm_tzp,
218                 },
219                 [THERM_GPU] = {
220                         .zone_enable = true,
221                         .passive_delay = 1000,
222                         .hotspot_offset = 5000,
223                         .num_trips = 3,
224                         .trips = {
225                                 {
226                                         .cdev_type = "tegra-shutdown",
227                                         .trip_temp = 101000,
228                                         .trip_type = THERMAL_TRIP_CRITICAL,
229                                         .upper = THERMAL_NO_LIMIT,
230                                         .lower = THERMAL_NO_LIMIT,
231                                 },
232                                 {
233                                         .cdev_type = "tegra-heavy",
234                                         .trip_temp = 99000,
235                                         .trip_type = THERMAL_TRIP_HOT,
236                                         .upper = THERMAL_NO_LIMIT,
237                                         .lower = THERMAL_NO_LIMIT,
238                                 },
239                                 {
240                                         .cdev_type = "gpu-balanced",
241                                         .trip_temp = 89000,
242                                         .trip_type = THERMAL_TRIP_PASSIVE,
243                                         .upper = THERMAL_NO_LIMIT,
244                                         .lower = THERMAL_NO_LIMIT,
245                                 },
246                         },
247                         .tzp = &soctherm_tzp,
248                 },
249                 [THERM_MEM] = {
250                         .zone_enable = true,
251                         .num_trips = 1,
252                         .trips = {
253                                 {
254                                         .cdev_type = "tegra-shutdown",
255                                         .trip_temp = 101000, /* = GPU shut */
256                                         .trip_type = THERMAL_TRIP_CRITICAL,
257                                         .upper = THERMAL_NO_LIMIT,
258                                         .lower = THERMAL_NO_LIMIT,
259                                 },
260                         },
261                         .tzp = &soctherm_tzp,
262                 },
263                 [THERM_PLL] = {
264                         .zone_enable = true,
265                         .tzp = &soctherm_tzp,
266                 },
267         },
268         .throttle = {
269                 [THROTTLE_HEAVY] = {
270                         .priority = 100,
271                         .devs = {
272                                 [THROTTLE_DEV_CPU] = {
273                                         .enable = true,
274                                         .depth = 80,
275                         /* see @PSKIP_CONFIG_NOTE in board-ardbeg-power.c */
276                                         .throttling_depth = "heavy_throttling",
277                                 },
278                                 [THROTTLE_DEV_GPU] = {
279                                         .enable = true,
280                                         .throttling_depth = "heavy_throttling",
281                                 },
282                         },
283                 },
284         },
285 };
286
287 /* Only the diffs from norrin_soctherm_data structure */
288 static struct soctherm_platform_data norrin_v1_soctherm_data = {
289         .therm = {
290                 [THERM_CPU] = {
291                         .zone_enable = true,
292                         .passive_delay = 1000,
293                         .hotspot_offset = 10000,
294                 },
295                 [THERM_PLL] = {
296                         .zone_enable = true,
297                         .passive_delay = 1000,
298                         .num_trips = 3,
299                         .trips = {
300                                 {
301                                         .cdev_type = "tegra-shutdown",
302                                         .trip_temp = 97000,
303                                         .trip_type = THERMAL_TRIP_CRITICAL,
304                                         .upper = THERMAL_NO_LIMIT,
305                                         .lower = THERMAL_NO_LIMIT,
306                                 },
307                                 {
308                                         .cdev_type = "tegra-heavy",
309                                         .trip_temp = 94000,
310                                         .trip_type = THERMAL_TRIP_HOT,
311                                         .upper = THERMAL_NO_LIMIT,
312                                         .lower = THERMAL_NO_LIMIT,
313                                 },
314                                 {
315                                         .cdev_type = "cpu-balanced",
316                                         .trip_temp = 84000,
317                                         .trip_type = THERMAL_TRIP_PASSIVE,
318                                         .upper = THERMAL_NO_LIMIT,
319                                         .lower = THERMAL_NO_LIMIT,
320                                 },
321                         },
322                         .tzp = &soctherm_tzp,
323                 },
324         },
325 };
326
327 int __init norrin_soctherm_init(void)
328 {
329         const int t13x_cpu_edp_temp_margin = 5000,
330                 t13x_gpu_edp_temp_margin = 6000;
331         int cp_rev, ft_rev;
332         struct board_info pmu_board_info;
333         struct board_info board_info;
334         enum soctherm_therm_id therm_cpu = THERM_CPU;
335
336         tegra_get_board_info(&board_info);
337
338         cp_rev = tegra_fuse_calib_base_get_cp(NULL, NULL);
339         ft_rev = tegra_fuse_calib_base_get_ft(NULL, NULL);
340
341         if (cp_rev) {
342                 /* ATE rev is Old or Mid - use PLLx sensor only */
343                 norrin_soctherm_data.therm[THERM_CPU] =
344                         norrin_v1_soctherm_data.therm[THERM_CPU];
345                 norrin_soctherm_data.therm[THERM_PLL] =
346                         norrin_v1_soctherm_data.therm[THERM_PLL];
347                 therm_cpu = THERM_PLL; /* override CPU with PLL zone */
348         }
349
350         /* do this only for supported CP,FT fuses */
351         if ((cp_rev >= 0) && (ft_rev >= 0)) {
352                 tegra_platform_edp_init(
353                         norrin_soctherm_data.therm[therm_cpu].trips,
354                         &norrin_soctherm_data.therm[therm_cpu].num_trips,
355                         t13x_cpu_edp_temp_margin);
356                 tegra_platform_gpu_edp_init(
357                         norrin_soctherm_data.therm[THERM_GPU].trips,
358                         &norrin_soctherm_data.therm[THERM_GPU].num_trips,
359                         t13x_gpu_edp_temp_margin);
360                 tegra_add_cpu_vmax_trips(
361                         norrin_soctherm_data.therm[therm_cpu].trips,
362                         &norrin_soctherm_data.therm[therm_cpu].num_trips);
363                 tegra_add_tgpu_trips(
364                         norrin_soctherm_data.therm[THERM_GPU].trips,
365                         &norrin_soctherm_data.therm[THERM_GPU].num_trips);
366                 tegra_add_core_vmax_trips(
367                         norrin_soctherm_data.therm[THERM_PLL].trips,
368                         &norrin_soctherm_data.therm[THERM_PLL].num_trips);
369         }
370
371         if (board_info.board_id == BOARD_PM374 ||
372                 board_info.board_id == BOARD_PM375 ||
373                 board_info.board_id == BOARD_E1971 ||
374                 board_info.board_id == BOARD_E1991) {
375                 tegra_add_cpu_vmin_trips(
376                         norrin_soctherm_data.therm[therm_cpu].trips,
377                         &norrin_soctherm_data.therm[therm_cpu].num_trips);
378                 tegra_add_gpu_vmin_trips(
379                         norrin_soctherm_data.therm[THERM_GPU].trips,
380                         &norrin_soctherm_data.therm[THERM_GPU].num_trips);
381                 tegra_add_core_vmin_trips(
382                         norrin_soctherm_data.therm[THERM_PLL].trips,
383                         &norrin_soctherm_data.therm[THERM_PLL].num_trips);
384         }
385
386         if (board_info.board_id == BOARD_PM375)
387                 tegra_add_cpu_clk_switch_trips(
388                         norrin_soctherm_data.therm[THERM_CPU].trips,
389                         &norrin_soctherm_data.therm[THERM_CPU].num_trips);
390         tegra_get_pmu_board_info(&pmu_board_info);
391
392         if ((pmu_board_info.board_id == BOARD_PM374) ||
393                 (pmu_board_info.board_id == BOARD_PM375))
394                 norrin_soctherm_data.tshut_pmu_trip_data = &tpdata_as3722;
395         else
396                 pr_warn("soctherm THERMTRIP not supported on PMU (BOARD_P%d)\n",
397                         pmu_board_info.board_id);
398
399         return tegra11_soctherm_init(&norrin_soctherm_data);
400 }