ARM: tegra12: set CPU rate to 2.2GHz for sku 0x87
[linux-3.10.git] / arch / arm / mach-tegra / tegra3_tsensor.c
1 /*
2  * arch/arm/mach-tegra/tegra3_tsensor.c
3  *
4  * Copyright (C) 2011-2013, NVIDIA Corporation. All rights reserved.
5  *
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
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  */
16
17 #include <linux/kernel.h>
18 #include <linux/init.h>
19 #include <linux/io.h>
20 #include <linux/ioport.h>
21 #include <linux/slab.h>
22 #include <linux/tegra-fuse.h>
23
24 #include <mach/tsensor.h>
25 #include <mach/tsensor.h>
26
27 #include "cpu-tegra.h"
28 #include "devices.h"
29 #include "iomap.h"
30 #include "tegra3_tsensor.h"
31
32 /* fuse revision constants used for tsensor */
33 #define TSENSOR_FUSE_REVISION_DECIMAL 8
34 #define TSENSOR_FUSE_REVISION_INTEGER 0
35
36 /* scratch register offsets needed for powering off PMU */
37 #define SCRATCH54_OFFSET                        0x258
38 #define SCRATCH55_OFFSET                        0x25C
39
40 /* scratch 54 register bit field offsets */
41 #define PMU_OFF_DATA_OFFSET                     8
42
43 /* scratch 55 register bit field offsets */
44 #define RESET_TEGRA_OFFSET                      31
45 #define CONTROLLER_TYPE_OFFSET                  30
46 #define I2C_CONTROLLER_ID_OFFSET                27
47 #define PINMUX_OFFSET                           24
48 #define CHECKSUM_OFFSET                         16
49 #define PMU_16BIT_SUPPORT_OFFSET                15
50 /* scratch 55 register bit field masks */
51 #define RESET_TEGRA_MASK                        0x1
52 #define CONTROLLER_TYPE_MASK                    0x1
53 #define I2C_CONTROLLER_ID_MASK                  0x7
54 #define PINMUX_MASK                             0x7
55 #define CHECKSUM_MASK                           0xff
56 #define PMU_16BIT_SUPPORT_MASK                  0x1
57
58 #define TSENSOR_OFFSET  (4000 + 5000)
59 #define TDIODE_OFFSET   (9000 + 1000)
60
61 static struct throttle_table tj_throttle_table[] = {
62                 /* CPU_THROT_LOW cannot be used by other than CPU */
63                 /* NO_CAP cannot be used by CPU */
64                 /*    CPU,    CBUS,    SCLK,     EMC */
65                 { { 1000000,  NO_CAP,  NO_CAP,  NO_CAP } },
66                 { {  760000,  NO_CAP,  NO_CAP,  NO_CAP } },
67                 { {  760000,  NO_CAP,  NO_CAP,  NO_CAP } },
68                 { {  620000,  NO_CAP,  NO_CAP,  NO_CAP } },
69                 { {  620000,  NO_CAP,  NO_CAP,  NO_CAP } },
70                 { {  620000,  437000,  NO_CAP,  NO_CAP } },
71                 { {  620000,  352000,  NO_CAP,  NO_CAP } },
72                 { {  475000,  352000,  NO_CAP,  NO_CAP } },
73                 { {  475000,  352000,  NO_CAP,  NO_CAP } },
74                 { {  475000,  352000,  250000,  375000 } },
75                 { {  475000,  352000,  250000,  375000 } },
76                 { {  475000,  247000,  204000,  375000 } },
77                 { {  475000,  247000,  204000,  204000 } },
78                 { {  475000,  247000,  204000,  204000 } },
79           { { CPU_THROT_LOW,  247000,  204000,  102000 } },
80 };
81
82 static struct balanced_throttle tj_throttle = {
83         .throt_tab_size = ARRAY_SIZE(tj_throttle_table),
84         .throt_tab = tj_throttle_table,
85 };
86
87 static struct tegra_tsensor_platform_data tsensor_data = {
88         .shutdown_temp = 90 + TDIODE_OFFSET - TSENSOR_OFFSET,
89         .passive = {
90                 .trip_temp = 85 + TDIODE_OFFSET - TSENSOR_OFFSET,
91                 .tc1 = 0,
92                 .tc2 = 1,
93                 .passive_delay = 2000,
94         }
95 };
96
97 void __init tegra3_tsensor_init(struct tegra_tsensor_pmu_data *data)
98 {
99         unsigned int reg;
100         int err;
101         u32 val, checksum;
102         void __iomem *pMem = NULL;
103         /* tsensor driver is instantiated based on fuse revision */
104         err = tegra_fuse_get_revision(&reg);
105         if (err)
106                 goto labelEnd;
107         pr_info("\nTegra3 fuse revision %d ", reg);
108         if (reg < TSENSOR_FUSE_REVISION_DECIMAL)
109                 goto labelEnd;
110
111         if (!data)
112                 goto labelSkipPowerOff;
113
114         if (!request_mem_region(TEGRA_PMC_BASE +
115                 SCRATCH54_OFFSET, 8, "tegra-tsensor"))
116                 pr_err(" [%s, line=%d]: Error mem busy\n",
117                         __func__, __LINE__);
118
119         pMem = ioremap(TEGRA_PMC_BASE + SCRATCH54_OFFSET, 8);
120         if (!pMem) {
121                 pr_err(" [%s, line=%d]: can't ioremap "
122                         "pmc iomem\n", __FILE__, __LINE__);
123                 goto labelEnd;
124         }
125
126         /*
127          * Fill scratch registers to power off the device
128          * in case if temperature crosses threshold TH3
129          */
130         val = (data->poweroff_reg_data << PMU_OFF_DATA_OFFSET) |
131                 data->poweroff_reg_addr;
132         writel(val, pMem);
133
134         val = ((data->reset_tegra & RESET_TEGRA_MASK) << RESET_TEGRA_OFFSET) |
135                 ((data->controller_type & CONTROLLER_TYPE_MASK) <<
136                 CONTROLLER_TYPE_OFFSET) |
137                 ((data->i2c_controller_id & I2C_CONTROLLER_ID_MASK) <<
138                 I2C_CONTROLLER_ID_OFFSET) |
139                 ((data->pinmux & PINMUX_MASK) << PINMUX_OFFSET) |
140                 ((data->pmu_16bit_ops & PMU_16BIT_SUPPORT_MASK) <<
141                 PMU_16BIT_SUPPORT_OFFSET) | data->pmu_i2c_addr;
142
143         checksum = data->poweroff_reg_addr +
144                 data->poweroff_reg_data + (val & 0xFF) +
145                 ((val >> 8) & 0xFF) + ((val >> 24) & 0xFF);
146         checksum &= 0xFF;
147         checksum = 0x100 - checksum;
148
149         val |= (checksum << CHECKSUM_OFFSET);
150         writel(val, pMem + 4);
151
152
153 labelSkipPowerOff:
154         /* Thermal throttling */
155         tsensor_data.passive.cdev = balanced_throttle_register(
156                                         &tj_throttle, "tegra-balanced");
157
158         /* set platform data for device before register */
159         tegra_tsensor_device.dev.platform_data = &tsensor_data;
160         platform_device_register(&tegra_tsensor_device);
161
162 labelEnd:
163         return;
164 }