aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2010-12-22 18:08:05 -0500
committerTony Lindgren <tony@atomide.com>2010-12-22 18:08:05 -0500
commit1c4655651f1377297425525b250b2e4b5462015b (patch)
treed06ca3731ce50ca63914f175fa5c9accd51c2b13 /arch
parentf400c82efb474b2ccf01c796b60b36408f7845a3 (diff)
parentb35cecf978e33bf8f4be0f36ffe00fe10f381c4a (diff)
Merge branch 'pm-sr' of ssh://master.kernel.org/pub/scm/linux/kernel/git/khilman/linux-omap-pm into omap-for-linus
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap2/Makefile11
-rw-r--r--arch/arm/mach-omap2/control.h29
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c175
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c168
-rw-r--r--arch/arm/mach-omap2/omap_twl.c277
-rw-r--r--arch/arm/mach-omap2/pm.c102
-rw-r--r--arch/arm/mach-omap2/pm.h28
-rw-r--r--arch/arm/mach-omap2/smartreflex-class3.c59
-rw-r--r--arch/arm/mach-omap2/smartreflex.c1029
-rw-r--r--arch/arm/mach-omap2/sr_device.c146
-rw-r--r--arch/arm/mach-omap2/voltage.c1571
-rw-r--r--arch/arm/plat-omap/Kconfig31
-rw-r--r--arch/arm/plat-omap/include/plat/omap_hwmod.h5
-rw-r--r--arch/arm/plat-omap/include/plat/smartreflex.h245
-rw-r--r--arch/arm/plat-omap/include/plat/voltage.h146
15 files changed, 4019 insertions, 3 deletions
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 1fce382a90a9..4ab82f6f15b1 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -18,6 +18,8 @@ obj-$(CONFIG_ARCH_OMAP4) += prm44xx.o $(hwmod-common)
18 18
19obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o 19obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o
20 20
21obj-$(CONFIG_TWL4030_CORE) += omap_twl.o
22
21# SMP support ONLY available for OMAP4 23# SMP support ONLY available for OMAP4
22obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o 24obj-$(CONFIG_SMP) += omap-smp.o omap-headsmp.o
23obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o 25obj-$(CONFIG_LOCAL_TIMERS) += timer-mpu.o
@@ -57,10 +59,13 @@ endif
57# Power Management 59# Power Management
58ifeq ($(CONFIG_PM),y) 60ifeq ($(CONFIG_PM),y)
59obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o 61obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
60obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o pm_bus.o 62obj-$(CONFIG_ARCH_OMAP2) += sleep24xx.o pm_bus.o voltage.o
61obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o cpuidle34xx.o pm_bus.o 63obj-$(CONFIG_ARCH_OMAP3) += pm34xx.o sleep34xx.o voltage.o \
62obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o pm_bus.o 64 cpuidle34xx.o pm_bus.o
65obj-$(CONFIG_ARCH_OMAP4) += pm44xx.o voltage.o pm_bus.o
63obj-$(CONFIG_PM_DEBUG) += pm-debug.o 66obj-$(CONFIG_PM_DEBUG) += pm-debug.o
67obj-$(CONFIG_OMAP_SMARTREFLEX) += sr_device.o smartreflex.o
68obj-$(CONFIG_OMAP_SMARTREFLEX_CLASS3) += smartreflex-class3.o
64 69
65AFLAGS_sleep24xx.o :=-Wa,-march=armv6 70AFLAGS_sleep24xx.o :=-Wa,-march=armv6
66AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a 71AFLAGS_sleep34xx.o :=-Wa,-march=armv7-a
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
index 208a670c826b..f0629ae04102 100644
--- a/arch/arm/mach-omap2/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -148,6 +148,15 @@
148#define OMAP343X_CONTROL_TEST_KEY_11 (OMAP2_CONTROL_GENERAL + 0x00f4) 148#define OMAP343X_CONTROL_TEST_KEY_11 (OMAP2_CONTROL_GENERAL + 0x00f4)
149#define OMAP343X_CONTROL_TEST_KEY_12 (OMAP2_CONTROL_GENERAL + 0x00f8) 149#define OMAP343X_CONTROL_TEST_KEY_12 (OMAP2_CONTROL_GENERAL + 0x00f8)
150#define OMAP343X_CONTROL_TEST_KEY_13 (OMAP2_CONTROL_GENERAL + 0x00fc) 150#define OMAP343X_CONTROL_TEST_KEY_13 (OMAP2_CONTROL_GENERAL + 0x00fc)
151#define OMAP343X_CONTROL_FUSE_OPP1_VDD1 (OMAP2_CONTROL_GENERAL + 0x0110)
152#define OMAP343X_CONTROL_FUSE_OPP2_VDD1 (OMAP2_CONTROL_GENERAL + 0x0114)
153#define OMAP343X_CONTROL_FUSE_OPP3_VDD1 (OMAP2_CONTROL_GENERAL + 0x0118)
154#define OMAP343X_CONTROL_FUSE_OPP4_VDD1 (OMAP2_CONTROL_GENERAL + 0x011c)
155#define OMAP343X_CONTROL_FUSE_OPP5_VDD1 (OMAP2_CONTROL_GENERAL + 0x0120)
156#define OMAP343X_CONTROL_FUSE_OPP1_VDD2 (OMAP2_CONTROL_GENERAL + 0x0124)
157#define OMAP343X_CONTROL_FUSE_OPP2_VDD2 (OMAP2_CONTROL_GENERAL + 0x0128)
158#define OMAP343X_CONTROL_FUSE_OPP3_VDD2 (OMAP2_CONTROL_GENERAL + 0x012c)
159#define OMAP343X_CONTROL_FUSE_SR (OMAP2_CONTROL_GENERAL + 0x0130)
151#define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190) 160#define OMAP343X_CONTROL_IVA2_BOOTADDR (OMAP2_CONTROL_GENERAL + 0x0190)
152#define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194) 161#define OMAP343X_CONTROL_IVA2_BOOTMOD (OMAP2_CONTROL_GENERAL + 0x0194)
153#define OMAP343X_CONTROL_DEBOBS(i) (OMAP2_CONTROL_GENERAL + 0x01B0 \ 162#define OMAP343X_CONTROL_DEBOBS(i) (OMAP2_CONTROL_GENERAL + 0x01B0 \
@@ -164,6 +173,26 @@
164#define OMAP343X_CONTROL_SRAMLDO5 (OMAP2_CONTROL_GENERAL + 0x02C0) 173#define OMAP343X_CONTROL_SRAMLDO5 (OMAP2_CONTROL_GENERAL + 0x02C0)
165#define OMAP343X_CONTROL_CSI (OMAP2_CONTROL_GENERAL + 0x02C4) 174#define OMAP343X_CONTROL_CSI (OMAP2_CONTROL_GENERAL + 0x02C4)
166 175
176/* OMAP3630 only CONTROL_GENERAL register offsets */
177#define OMAP3630_CONTROL_FUSE_OPP1G_VDD1 (OMAP2_CONTROL_GENERAL + 0x0110)
178#define OMAP3630_CONTROL_FUSE_OPP50_VDD1 (OMAP2_CONTROL_GENERAL + 0x0114)
179#define OMAP3630_CONTROL_FUSE_OPP100_VDD1 (OMAP2_CONTROL_GENERAL + 0x0118)
180#define OMAP3630_CONTROL_FUSE_OPP120_VDD1 (OMAP2_CONTROL_GENERAL + 0x0120)
181#define OMAP3630_CONTROL_FUSE_OPP50_VDD2 (OMAP2_CONTROL_GENERAL + 0x0128)
182#define OMAP3630_CONTROL_FUSE_OPP100_VDD2 (OMAP2_CONTROL_GENERAL + 0x012C)
183
184/* OMAP44xx control efuse offsets */
185#define OMAP44XX_CONTROL_FUSE_IVA_OPP50 0x22C
186#define OMAP44XX_CONTROL_FUSE_IVA_OPP100 0x22F
187#define OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO 0x232
188#define OMAP44XX_CONTROL_FUSE_IVA_OPPNITRO 0x235
189#define OMAP44XX_CONTROL_FUSE_MPU_OPP50 0x240
190#define OMAP44XX_CONTROL_FUSE_MPU_OPP100 0x243
191#define OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO 0x246
192#define OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO 0x249
193#define OMAP44XX_CONTROL_FUSE_CORE_OPP50 0x254
194#define OMAP44XX_CONTROL_FUSE_CORE_OPP100 0x257
195
167/* AM35XX only CONTROL_GENERAL register offsets */ 196/* AM35XX only CONTROL_GENERAL register offsets */
168#define AM35XX_CONTROL_MSUSPENDMUX_6 (OMAP2_CONTROL_GENERAL + 0x0038) 197#define AM35XX_CONTROL_MSUSPENDMUX_6 (OMAP2_CONTROL_GENERAL + 0x0038)
169#define AM35XX_CONTROL_DEVCONF2 (OMAP2_CONTROL_GENERAL + 0x0310) 198#define AM35XX_CONTROL_DEVCONF2 (OMAP2_CONTROL_GENERAL + 0x0310)
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 89a943e9459c..8d8181334f86 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -21,6 +21,7 @@
21#include <plat/l4_3xxx.h> 21#include <plat/l4_3xxx.h>
22#include <plat/i2c.h> 22#include <plat/i2c.h>
23#include <plat/gpio.h> 23#include <plat/gpio.h>
24#include <plat/smartreflex.h>
24 25
25#include "omap_hwmod_common_data.h" 26#include "omap_hwmod_common_data.h"
26 27
@@ -52,6 +53,8 @@ static struct omap_hwmod omap3xxx_gpio3_hwmod;
52static struct omap_hwmod omap3xxx_gpio4_hwmod; 53static struct omap_hwmod omap3xxx_gpio4_hwmod;
53static struct omap_hwmod omap3xxx_gpio5_hwmod; 54static struct omap_hwmod omap3xxx_gpio5_hwmod;
54static struct omap_hwmod omap3xxx_gpio6_hwmod; 55static struct omap_hwmod omap3xxx_gpio6_hwmod;
56static struct omap_hwmod omap34xx_sr1_hwmod;
57static struct omap_hwmod omap34xx_sr2_hwmod;
55 58
56static struct omap_hwmod omap3xxx_dma_system_hwmod; 59static struct omap_hwmod omap3xxx_dma_system_hwmod;
57 60
@@ -262,9 +265,47 @@ static struct omap_hwmod_ocp_if omap3_l4_core__i2c3 = {
262 .user = OCP_USER_MPU | OCP_USER_SDMA, 265 .user = OCP_USER_MPU | OCP_USER_SDMA,
263}; 266};
264 267
268/* L4 CORE -> SR1 interface */
269static struct omap_hwmod_addr_space omap3_sr1_addr_space[] = {
270 {
271 .pa_start = OMAP34XX_SR1_BASE,
272 .pa_end = OMAP34XX_SR1_BASE + SZ_1K - 1,
273 .flags = ADDR_TYPE_RT,
274 },
275};
276
277static struct omap_hwmod_ocp_if omap3_l4_core__sr1 = {
278 .master = &omap3xxx_l4_core_hwmod,
279 .slave = &omap34xx_sr1_hwmod,
280 .clk = "sr_l4_ick",
281 .addr = omap3_sr1_addr_space,
282 .addr_cnt = ARRAY_SIZE(omap3_sr1_addr_space),
283 .user = OCP_USER_MPU,
284};
285
286/* L4 CORE -> SR1 interface */
287static struct omap_hwmod_addr_space omap3_sr2_addr_space[] = {
288 {
289 .pa_start = OMAP34XX_SR2_BASE,
290 .pa_end = OMAP34XX_SR2_BASE + SZ_1K - 1,
291 .flags = ADDR_TYPE_RT,
292 },
293};
294
295static struct omap_hwmod_ocp_if omap3_l4_core__sr2 = {
296 .master = &omap3xxx_l4_core_hwmod,
297 .slave = &omap34xx_sr2_hwmod,
298 .clk = "sr_l4_ick",
299 .addr = omap3_sr2_addr_space,
300 .addr_cnt = ARRAY_SIZE(omap3_sr2_addr_space),
301 .user = OCP_USER_MPU,
302};
303
265/* Slave interfaces on the L4_CORE interconnect */ 304/* Slave interfaces on the L4_CORE interconnect */
266static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = { 305static struct omap_hwmod_ocp_if *omap3xxx_l4_core_slaves[] = {
267 &omap3xxx_l3_main__l4_core, 306 &omap3xxx_l3_main__l4_core,
307 &omap3_l4_core__sr1,
308 &omap3_l4_core__sr2,
268}; 309};
269 310
270/* Master interfaces on the L4_CORE interconnect */ 311/* Master interfaces on the L4_CORE interconnect */
@@ -1186,6 +1227,135 @@ static struct omap_hwmod omap3xxx_dma_system_hwmod = {
1186 .flags = HWMOD_NO_IDLEST, 1227 .flags = HWMOD_NO_IDLEST,
1187}; 1228};
1188 1229
1230/* SR common */
1231static struct omap_hwmod_sysc_fields omap34xx_sr_sysc_fields = {
1232 .clkact_shift = 20,
1233};
1234
1235static struct omap_hwmod_class_sysconfig omap34xx_sr_sysc = {
1236 .sysc_offs = 0x24,
1237 .sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_NO_CACHE),
1238 .clockact = CLOCKACT_TEST_ICLK,
1239 .sysc_fields = &omap34xx_sr_sysc_fields,
1240};
1241
1242static struct omap_hwmod_class omap34xx_smartreflex_hwmod_class = {
1243 .name = "smartreflex",
1244 .sysc = &omap34xx_sr_sysc,
1245 .rev = 1,
1246};
1247
1248static struct omap_hwmod_sysc_fields omap36xx_sr_sysc_fields = {
1249 .sidle_shift = 24,
1250 .enwkup_shift = 26
1251};
1252
1253static struct omap_hwmod_class_sysconfig omap36xx_sr_sysc = {
1254 .sysc_offs = 0x38,
1255 .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
1256 .sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP |
1257 SYSC_NO_CACHE),
1258 .sysc_fields = &omap36xx_sr_sysc_fields,
1259};
1260
1261static struct omap_hwmod_class omap36xx_smartreflex_hwmod_class = {
1262 .name = "smartreflex",
1263 .sysc = &omap36xx_sr_sysc,
1264 .rev = 2,
1265};
1266
1267/* SR1 */
1268static struct omap_hwmod_ocp_if *omap3_sr1_slaves[] = {
1269 &omap3_l4_core__sr1,
1270};
1271
1272static struct omap_hwmod omap34xx_sr1_hwmod = {
1273 .name = "sr1_hwmod",
1274 .class = &omap34xx_smartreflex_hwmod_class,
1275 .main_clk = "sr1_fck",
1276 .vdd_name = "mpu",
1277 .prcm = {
1278 .omap2 = {
1279 .prcm_reg_id = 1,
1280 .module_bit = OMAP3430_EN_SR1_SHIFT,
1281 .module_offs = WKUP_MOD,
1282 .idlest_reg_id = 1,
1283 .idlest_idle_bit = OMAP3430_EN_SR1_SHIFT,
1284 },
1285 },
1286 .slaves = omap3_sr1_slaves,
1287 .slaves_cnt = ARRAY_SIZE(omap3_sr1_slaves),
1288 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2 |
1289 CHIP_IS_OMAP3430ES3_0 |
1290 CHIP_IS_OMAP3430ES3_1),
1291 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
1292};
1293
1294static struct omap_hwmod omap36xx_sr1_hwmod = {
1295 .name = "sr1_hwmod",
1296 .class = &omap36xx_smartreflex_hwmod_class,
1297 .main_clk = "sr1_fck",
1298 .vdd_name = "mpu",
1299 .prcm = {
1300 .omap2 = {
1301 .prcm_reg_id = 1,
1302 .module_bit = OMAP3430_EN_SR1_SHIFT,
1303 .module_offs = WKUP_MOD,
1304 .idlest_reg_id = 1,
1305 .idlest_idle_bit = OMAP3430_EN_SR1_SHIFT,
1306 },
1307 },
1308 .slaves = omap3_sr1_slaves,
1309 .slaves_cnt = ARRAY_SIZE(omap3_sr1_slaves),
1310 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1),
1311};
1312
1313/* SR2 */
1314static struct omap_hwmod_ocp_if *omap3_sr2_slaves[] = {
1315 &omap3_l4_core__sr2,
1316};
1317
1318static struct omap_hwmod omap34xx_sr2_hwmod = {
1319 .name = "sr2_hwmod",
1320 .class = &omap34xx_smartreflex_hwmod_class,
1321 .main_clk = "sr2_fck",
1322 .vdd_name = "core",
1323 .prcm = {
1324 .omap2 = {
1325 .prcm_reg_id = 1,
1326 .module_bit = OMAP3430_EN_SR2_SHIFT,
1327 .module_offs = WKUP_MOD,
1328 .idlest_reg_id = 1,
1329 .idlest_idle_bit = OMAP3430_EN_SR2_SHIFT,
1330 },
1331 },
1332 .slaves = omap3_sr2_slaves,
1333 .slaves_cnt = ARRAY_SIZE(omap3_sr2_slaves),
1334 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3430ES2 |
1335 CHIP_IS_OMAP3430ES3_0 |
1336 CHIP_IS_OMAP3430ES3_1),
1337 .flags = HWMOD_SET_DEFAULT_CLOCKACT,
1338};
1339
1340static struct omap_hwmod omap36xx_sr2_hwmod = {
1341 .name = "sr2_hwmod",
1342 .class = &omap36xx_smartreflex_hwmod_class,
1343 .main_clk = "sr2_fck",
1344 .vdd_name = "core",
1345 .prcm = {
1346 .omap2 = {
1347 .prcm_reg_id = 1,
1348 .module_bit = OMAP3430_EN_SR2_SHIFT,
1349 .module_offs = WKUP_MOD,
1350 .idlest_reg_id = 1,
1351 .idlest_idle_bit = OMAP3430_EN_SR2_SHIFT,
1352 },
1353 },
1354 .slaves = omap3_sr2_slaves,
1355 .slaves_cnt = ARRAY_SIZE(omap3_sr2_slaves),
1356 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP3630ES1),
1357};
1358
1189static __initdata struct omap_hwmod *omap3xxx_hwmods[] = { 1359static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
1190 &omap3xxx_l3_main_hwmod, 1360 &omap3xxx_l3_main_hwmod,
1191 &omap3xxx_l4_core_hwmod, 1361 &omap3xxx_l4_core_hwmod,
@@ -1201,6 +1371,11 @@ static __initdata struct omap_hwmod *omap3xxx_hwmods[] = {
1201 &omap3xxx_i2c1_hwmod, 1371 &omap3xxx_i2c1_hwmod,
1202 &omap3xxx_i2c2_hwmod, 1372 &omap3xxx_i2c2_hwmod,
1203 &omap3xxx_i2c3_hwmod, 1373 &omap3xxx_i2c3_hwmod,
1374 &omap34xx_sr1_hwmod,
1375 &omap34xx_sr2_hwmod,
1376 &omap36xx_sr1_hwmod,
1377 &omap36xx_sr2_hwmod,
1378
1204 1379
1205 /* gpio class */ 1380 /* gpio class */
1206 &omap3xxx_gpio1_hwmod, 1381 &omap3xxx_gpio1_hwmod,
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index c9c98ee81191..e2ad1b6b9c0a 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -1842,6 +1842,169 @@ static struct omap_hwmod omap44xx_dma_system_hwmod = {
1842 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430), 1842 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
1843}; 1843};
1844 1844
1845/*
1846 * 'smartreflex' class
1847 * smartreflex module (monitor silicon performance and outputs a measure of
1848 * performance error)
1849 */
1850
1851/* The IP is not compliant to type1 / type2 scheme */
1852static struct omap_hwmod_sysc_fields omap_hwmod_sysc_type_smartreflex = {
1853 .sidle_shift = 24,
1854 .enwkup_shift = 26,
1855};
1856
1857static struct omap_hwmod_class_sysconfig omap44xx_smartreflex_sysc = {
1858 .sysc_offs = 0x0038,
1859 .sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE),
1860 .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
1861 .sysc_fields = &omap_hwmod_sysc_type_smartreflex,
1862};
1863
1864static struct omap_hwmod_class omap44xx_smartreflex_hwmod_class = {
1865 .name = "smartreflex",
1866 .sysc = &omap44xx_smartreflex_sysc,
1867 .rev = 2,
1868};
1869
1870/* smartreflex_core */
1871static struct omap_hwmod omap44xx_smartreflex_core_hwmod;
1872static struct omap_hwmod_irq_info omap44xx_smartreflex_core_irqs[] = {
1873 { .irq = 19 + OMAP44XX_IRQ_GIC_START },
1874};
1875
1876static struct omap_hwmod_addr_space omap44xx_smartreflex_core_addrs[] = {
1877 {
1878 .pa_start = 0x4a0dd000,
1879 .pa_end = 0x4a0dd03f,
1880 .flags = ADDR_TYPE_RT
1881 },
1882};
1883
1884/* l4_cfg -> smartreflex_core */
1885static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_core = {
1886 .master = &omap44xx_l4_cfg_hwmod,
1887 .slave = &omap44xx_smartreflex_core_hwmod,
1888 .clk = "l4_div_ck",
1889 .addr = omap44xx_smartreflex_core_addrs,
1890 .addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_addrs),
1891 .user = OCP_USER_MPU | OCP_USER_SDMA,
1892};
1893
1894/* smartreflex_core slave ports */
1895static struct omap_hwmod_ocp_if *omap44xx_smartreflex_core_slaves[] = {
1896 &omap44xx_l4_cfg__smartreflex_core,
1897};
1898
1899static struct omap_hwmod omap44xx_smartreflex_core_hwmod = {
1900 .name = "smartreflex_core",
1901 .class = &omap44xx_smartreflex_hwmod_class,
1902 .mpu_irqs = omap44xx_smartreflex_core_irqs,
1903 .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_irqs),
1904 .main_clk = "smartreflex_core_fck",
1905 .vdd_name = "core",
1906 .prcm = {
1907 .omap4 = {
1908 .clkctrl_reg = OMAP4430_CM_ALWON_SR_CORE_CLKCTRL,
1909 },
1910 },
1911 .slaves = omap44xx_smartreflex_core_slaves,
1912 .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_core_slaves),
1913 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
1914};
1915
1916/* smartreflex_iva */
1917static struct omap_hwmod omap44xx_smartreflex_iva_hwmod;
1918static struct omap_hwmod_irq_info omap44xx_smartreflex_iva_irqs[] = {
1919 { .irq = 102 + OMAP44XX_IRQ_GIC_START },
1920};
1921
1922static struct omap_hwmod_addr_space omap44xx_smartreflex_iva_addrs[] = {
1923 {
1924 .pa_start = 0x4a0db000,
1925 .pa_end = 0x4a0db03f,
1926 .flags = ADDR_TYPE_RT
1927 },
1928};
1929
1930/* l4_cfg -> smartreflex_iva */
1931static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_iva = {
1932 .master = &omap44xx_l4_cfg_hwmod,
1933 .slave = &omap44xx_smartreflex_iva_hwmod,
1934 .clk = "l4_div_ck",
1935 .addr = omap44xx_smartreflex_iva_addrs,
1936 .addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_addrs),
1937 .user = OCP_USER_MPU | OCP_USER_SDMA,
1938};
1939
1940/* smartreflex_iva slave ports */
1941static struct omap_hwmod_ocp_if *omap44xx_smartreflex_iva_slaves[] = {
1942 &omap44xx_l4_cfg__smartreflex_iva,
1943};
1944
1945static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = {
1946 .name = "smartreflex_iva",
1947 .class = &omap44xx_smartreflex_hwmod_class,
1948 .mpu_irqs = omap44xx_smartreflex_iva_irqs,
1949 .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_irqs),
1950 .main_clk = "smartreflex_iva_fck",
1951 .vdd_name = "iva",
1952 .prcm = {
1953 .omap4 = {
1954 .clkctrl_reg = OMAP4430_CM_ALWON_SR_IVA_CLKCTRL,
1955 },
1956 },
1957 .slaves = omap44xx_smartreflex_iva_slaves,
1958 .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_iva_slaves),
1959 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
1960};
1961
1962/* smartreflex_mpu */
1963static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod;
1964static struct omap_hwmod_irq_info omap44xx_smartreflex_mpu_irqs[] = {
1965 { .irq = 18 + OMAP44XX_IRQ_GIC_START },
1966};
1967
1968static struct omap_hwmod_addr_space omap44xx_smartreflex_mpu_addrs[] = {
1969 {
1970 .pa_start = 0x4a0d9000,
1971 .pa_end = 0x4a0d903f,
1972 .flags = ADDR_TYPE_RT
1973 },
1974};
1975
1976/* l4_cfg -> smartreflex_mpu */
1977static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_mpu = {
1978 .master = &omap44xx_l4_cfg_hwmod,
1979 .slave = &omap44xx_smartreflex_mpu_hwmod,
1980 .clk = "l4_div_ck",
1981 .addr = omap44xx_smartreflex_mpu_addrs,
1982 .addr_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_addrs),
1983 .user = OCP_USER_MPU | OCP_USER_SDMA,
1984};
1985
1986/* smartreflex_mpu slave ports */
1987static struct omap_hwmod_ocp_if *omap44xx_smartreflex_mpu_slaves[] = {
1988 &omap44xx_l4_cfg__smartreflex_mpu,
1989};
1990
1991static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = {
1992 .name = "smartreflex_mpu",
1993 .class = &omap44xx_smartreflex_hwmod_class,
1994 .mpu_irqs = omap44xx_smartreflex_mpu_irqs,
1995 .mpu_irqs_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_irqs),
1996 .main_clk = "smartreflex_mpu_fck",
1997 .vdd_name = "mpu",
1998 .prcm = {
1999 .omap4 = {
2000 .clkctrl_reg = OMAP4430_CM_ALWON_SR_MPU_CLKCTRL,
2001 },
2002 },
2003 .slaves = omap44xx_smartreflex_mpu_slaves,
2004 .slaves_cnt = ARRAY_SIZE(omap44xx_smartreflex_mpu_slaves),
2005 .omap_chip = OMAP_CHIP_INIT(CHIP_IS_OMAP4430),
2006};
2007
1845static __initdata struct omap_hwmod *omap44xx_hwmods[] = { 2008static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
1846 /* dmm class */ 2009 /* dmm class */
1847 &omap44xx_dmm_hwmod, 2010 &omap44xx_dmm_hwmod,
@@ -1903,6 +2066,11 @@ static __initdata struct omap_hwmod *omap44xx_hwmods[] = {
1903 &omap44xx_wd_timer2_hwmod, 2066 &omap44xx_wd_timer2_hwmod,
1904 &omap44xx_wd_timer3_hwmod, 2067 &omap44xx_wd_timer3_hwmod,
1905 2068
2069 /* smartreflex class */
2070 &omap44xx_smartreflex_core_hwmod,
2071 &omap44xx_smartreflex_iva_hwmod,
2072 &omap44xx_smartreflex_mpu_hwmod,
2073
1906 NULL, 2074 NULL,
1907}; 2075};
1908 2076
diff --git a/arch/arm/mach-omap2/omap_twl.c b/arch/arm/mach-omap2/omap_twl.c
new file mode 100644
index 000000000000..15f8c6c1bb0f
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_twl.c
@@ -0,0 +1,277 @@
1/**
2 * OMAP and TWL PMIC specific intializations.
3 *
4 * Copyright (C) 2010 Texas Instruments Incorporated.
5 * Thara Gopinath
6 * Copyright (C) 2009 Texas Instruments Incorporated.
7 * Nishanth Menon
8 * Copyright (C) 2009 Nokia Corporation
9 * Paul Walmsley
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#include <linux/err.h>
17#include <linux/io.h>
18#include <linux/kernel.h>
19#include <linux/i2c/twl.h>
20
21#include <plat/voltage.h>
22
23#define OMAP3_SRI2C_SLAVE_ADDR 0x12
24#define OMAP3_VDD_MPU_SR_CONTROL_REG 0x00
25#define OMAP3_VDD_CORE_SR_CONTROL_REG 0x01
26#define OMAP3_VP_CONFIG_ERROROFFSET 0x00
27#define OMAP3_VP_VSTEPMIN_VSTEPMIN 0x1
28#define OMAP3_VP_VSTEPMAX_VSTEPMAX 0x04
29#define OMAP3_VP_VLIMITTO_TIMEOUT_US 200
30
31#define OMAP3430_VP1_VLIMITTO_VDDMIN 0x14
32#define OMAP3430_VP1_VLIMITTO_VDDMAX 0x42
33#define OMAP3430_VP2_VLIMITTO_VDDMIN 0x18
34#define OMAP3430_VP2_VLIMITTO_VDDMAX 0x2c
35
36#define OMAP3630_VP1_VLIMITTO_VDDMIN 0x18
37#define OMAP3630_VP1_VLIMITTO_VDDMAX 0x3c
38#define OMAP3630_VP2_VLIMITTO_VDDMIN 0x18
39#define OMAP3630_VP2_VLIMITTO_VDDMAX 0x30
40
41#define OMAP4_SRI2C_SLAVE_ADDR 0x12
42#define OMAP4_VDD_MPU_SR_VOLT_REG 0x55
43#define OMAP4_VDD_IVA_SR_VOLT_REG 0x5B
44#define OMAP4_VDD_CORE_SR_VOLT_REG 0x61
45
46#define OMAP4_VP_CONFIG_ERROROFFSET 0x00
47#define OMAP4_VP_VSTEPMIN_VSTEPMIN 0x01
48#define OMAP4_VP_VSTEPMAX_VSTEPMAX 0x04
49#define OMAP4_VP_VLIMITTO_TIMEOUT_US 200
50
51#define OMAP4_VP_MPU_VLIMITTO_VDDMIN 0xA
52#define OMAP4_VP_MPU_VLIMITTO_VDDMAX 0x39
53#define OMAP4_VP_IVA_VLIMITTO_VDDMIN 0xA
54#define OMAP4_VP_IVA_VLIMITTO_VDDMAX 0x2D
55#define OMAP4_VP_CORE_VLIMITTO_VDDMIN 0xA
56#define OMAP4_VP_CORE_VLIMITTO_VDDMAX 0x28
57
58static bool is_offset_valid;
59static u8 smps_offset;
60
61#define REG_SMPS_OFFSET 0xE0
62
63unsigned long twl4030_vsel_to_uv(const u8 vsel)
64{
65 return (((vsel * 125) + 6000)) * 100;
66}
67
68u8 twl4030_uv_to_vsel(unsigned long uv)
69{
70 return DIV_ROUND_UP(uv - 600000, 12500);
71}
72
73unsigned long twl6030_vsel_to_uv(const u8 vsel)
74{
75 /*
76 * In TWL6030 depending on the value of SMPS_OFFSET
77 * efuse register the voltage range supported in
78 * standard mode can be either between 0.6V - 1.3V or
79 * 0.7V - 1.4V. In TWL6030 ES1.0 SMPS_OFFSET efuse
80 * is programmed to all 0's where as starting from
81 * TWL6030 ES1.1 the efuse is programmed to 1
82 */
83 if (!is_offset_valid) {
84 twl_i2c_read_u8(TWL6030_MODULE_ID0, &smps_offset,
85 REG_SMPS_OFFSET);
86 is_offset_valid = true;
87 }
88
89 /*
90 * There is no specific formula for voltage to vsel
91 * conversion above 1.3V. There are special hardcoded
92 * values for voltages above 1.3V. Currently we are
93 * hardcoding only for 1.35 V which is used for 1GH OPP for
94 * OMAP4430.
95 */
96 if (vsel == 0x3A)
97 return 1350000;
98
99 if (smps_offset & 0x8)
100 return ((((vsel - 1) * 125) + 7000)) * 100;
101 else
102 return ((((vsel - 1) * 125) + 6000)) * 100;
103}
104
105u8 twl6030_uv_to_vsel(unsigned long uv)
106{
107 /*
108 * In TWL6030 depending on the value of SMPS_OFFSET
109 * efuse register the voltage range supported in
110 * standard mode can be either between 0.6V - 1.3V or
111 * 0.7V - 1.4V. In TWL6030 ES1.0 SMPS_OFFSET efuse
112 * is programmed to all 0's where as starting from
113 * TWL6030 ES1.1 the efuse is programmed to 1
114 */
115 if (!is_offset_valid) {
116 twl_i2c_read_u8(TWL6030_MODULE_ID0, &smps_offset,
117 REG_SMPS_OFFSET);
118 is_offset_valid = true;
119 }
120
121 /*
122 * There is no specific formula for voltage to vsel
123 * conversion above 1.3V. There are special hardcoded
124 * values for voltages above 1.3V. Currently we are
125 * hardcoding only for 1.35 V which is used for 1GH OPP for
126 * OMAP4430.
127 */
128 if (uv == 1350000)
129 return 0x3A;
130
131 if (smps_offset & 0x8)
132 return DIV_ROUND_UP(uv - 700000, 12500) + 1;
133 else
134 return DIV_ROUND_UP(uv - 600000, 12500) + 1;
135}
136
137static struct omap_volt_pmic_info omap3_mpu_volt_info = {
138 .slew_rate = 4000,
139 .step_size = 12500,
140 .on_volt = 1200000,
141 .onlp_volt = 1000000,
142 .ret_volt = 975000,
143 .off_volt = 600000,
144 .volt_setup_time = 0xfff,
145 .vp_erroroffset = OMAP3_VP_CONFIG_ERROROFFSET,
146 .vp_vstepmin = OMAP3_VP_VSTEPMIN_VSTEPMIN,
147 .vp_vstepmax = OMAP3_VP_VSTEPMAX_VSTEPMAX,
148 .vp_vddmin = OMAP3430_VP1_VLIMITTO_VDDMIN,
149 .vp_vddmax = OMAP3430_VP1_VLIMITTO_VDDMAX,
150 .vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US,
151 .i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR,
152 .pmic_reg = OMAP3_VDD_MPU_SR_CONTROL_REG,
153 .vsel_to_uv = twl4030_vsel_to_uv,
154 .uv_to_vsel = twl4030_uv_to_vsel,
155};
156
157static struct omap_volt_pmic_info omap3_core_volt_info = {
158 .slew_rate = 4000,
159 .step_size = 12500,
160 .on_volt = 1200000,
161 .onlp_volt = 1000000,
162 .ret_volt = 975000,
163 .off_volt = 600000,
164 .volt_setup_time = 0xfff,
165 .vp_erroroffset = OMAP3_VP_CONFIG_ERROROFFSET,
166 .vp_vstepmin = OMAP3_VP_VSTEPMIN_VSTEPMIN,
167 .vp_vstepmax = OMAP3_VP_VSTEPMAX_VSTEPMAX,
168 .vp_vddmin = OMAP3430_VP2_VLIMITTO_VDDMIN,
169 .vp_vddmax = OMAP3430_VP2_VLIMITTO_VDDMAX,
170 .vp_timeout_us = OMAP3_VP_VLIMITTO_TIMEOUT_US,
171 .i2c_slave_addr = OMAP3_SRI2C_SLAVE_ADDR,
172 .pmic_reg = OMAP3_VDD_CORE_SR_CONTROL_REG,
173 .vsel_to_uv = twl4030_vsel_to_uv,
174 .uv_to_vsel = twl4030_uv_to_vsel,
175};
176
177static struct omap_volt_pmic_info omap4_mpu_volt_info = {
178 .slew_rate = 4000,
179 .step_size = 12500,
180 .on_volt = 1350000,
181 .onlp_volt = 1350000,
182 .ret_volt = 837500,
183 .off_volt = 600000,
184 .volt_setup_time = 0,
185 .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
186 .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
187 .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
188 .vp_vddmin = OMAP4_VP_MPU_VLIMITTO_VDDMIN,
189 .vp_vddmax = OMAP4_VP_MPU_VLIMITTO_VDDMAX,
190 .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
191 .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
192 .pmic_reg = OMAP4_VDD_MPU_SR_VOLT_REG,
193 .vsel_to_uv = twl6030_vsel_to_uv,
194 .uv_to_vsel = twl6030_uv_to_vsel,
195};
196
197static struct omap_volt_pmic_info omap4_iva_volt_info = {
198 .slew_rate = 4000,
199 .step_size = 12500,
200 .on_volt = 1100000,
201 .onlp_volt = 1100000,
202 .ret_volt = 837500,
203 .off_volt = 600000,
204 .volt_setup_time = 0,
205 .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
206 .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
207 .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
208 .vp_vddmin = OMAP4_VP_IVA_VLIMITTO_VDDMIN,
209 .vp_vddmax = OMAP4_VP_IVA_VLIMITTO_VDDMAX,
210 .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
211 .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
212 .pmic_reg = OMAP4_VDD_IVA_SR_VOLT_REG,
213 .vsel_to_uv = twl6030_vsel_to_uv,
214 .uv_to_vsel = twl6030_uv_to_vsel,
215};
216
217static struct omap_volt_pmic_info omap4_core_volt_info = {
218 .slew_rate = 4000,
219 .step_size = 12500,
220 .on_volt = 1100000,
221 .onlp_volt = 1100000,
222 .ret_volt = 837500,
223 .off_volt = 600000,
224 .volt_setup_time = 0,
225 .vp_erroroffset = OMAP4_VP_CONFIG_ERROROFFSET,
226 .vp_vstepmin = OMAP4_VP_VSTEPMIN_VSTEPMIN,
227 .vp_vstepmax = OMAP4_VP_VSTEPMAX_VSTEPMAX,
228 .vp_vddmin = OMAP4_VP_CORE_VLIMITTO_VDDMIN,
229 .vp_vddmax = OMAP4_VP_CORE_VLIMITTO_VDDMAX,
230 .vp_timeout_us = OMAP4_VP_VLIMITTO_TIMEOUT_US,
231 .i2c_slave_addr = OMAP4_SRI2C_SLAVE_ADDR,
232 .pmic_reg = OMAP4_VDD_CORE_SR_VOLT_REG,
233 .vsel_to_uv = twl6030_vsel_to_uv,
234 .uv_to_vsel = twl6030_uv_to_vsel,
235};
236
237int __init omap4_twl_init(void)
238{
239 struct voltagedomain *voltdm;
240
241 if (!cpu_is_omap44xx())
242 return -ENODEV;
243
244 voltdm = omap_voltage_domain_lookup("mpu");
245 omap_voltage_register_pmic(voltdm, &omap4_mpu_volt_info);
246
247 voltdm = omap_voltage_domain_lookup("iva");
248 omap_voltage_register_pmic(voltdm, &omap4_iva_volt_info);
249
250 voltdm = omap_voltage_domain_lookup("core");
251 omap_voltage_register_pmic(voltdm, &omap4_core_volt_info);
252
253 return 0;
254}
255
256int __init omap3_twl_init(void)
257{
258 struct voltagedomain *voltdm;
259
260 if (!cpu_is_omap34xx())
261 return -ENODEV;
262
263 if (cpu_is_omap3630()) {
264 omap3_mpu_volt_info.vp_vddmin = OMAP3630_VP1_VLIMITTO_VDDMIN;
265 omap3_mpu_volt_info.vp_vddmax = OMAP3630_VP1_VLIMITTO_VDDMAX;
266 omap3_core_volt_info.vp_vddmin = OMAP3630_VP2_VLIMITTO_VDDMIN;
267 omap3_core_volt_info.vp_vddmax = OMAP3630_VP2_VLIMITTO_VDDMAX;
268 }
269
270 voltdm = omap_voltage_domain_lookup("mpu");
271 omap_voltage_register_pmic(voltdm, &omap3_mpu_volt_info);
272
273 voltdm = omap_voltage_domain_lookup("core");
274 omap_voltage_register_pmic(voltdm, &omap3_core_volt_info);
275
276 return 0;
277}
diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 9b1db592759f..d5a102c71989 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -13,13 +13,16 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/io.h> 14#include <linux/io.h>
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/opp.h>
16 17
17#include <plat/omap-pm.h> 18#include <plat/omap-pm.h>
18#include <plat/omap_device.h> 19#include <plat/omap_device.h>
19#include <plat/common.h> 20#include <plat/common.h>
21#include <plat/voltage.h>
20 22
21#include "powerdomain.h" 23#include "powerdomain.h"
22#include "clockdomain.h" 24#include "clockdomain.h"
25#include "pm.h"
23 26
24static struct omap_device_pm_latency *pm_lats; 27static struct omap_device_pm_latency *pm_lats;
25 28
@@ -154,6 +157,86 @@ err:
154 return ret; 157 return ret;
155} 158}
156 159
160/*
161 * This API is to be called during init to put the various voltage
162 * domains to the voltage as per the opp table. Typically we boot up
163 * at the nominal voltage. So this function finds out the rate of
164 * the clock associated with the voltage domain, finds out the correct
165 * opp entry and puts the voltage domain to the voltage specifies
166 * in the opp entry
167 */
168static int __init omap2_set_init_voltage(char *vdd_name, char *clk_name,
169 struct device *dev)
170{
171 struct voltagedomain *voltdm;
172 struct clk *clk;
173 struct opp *opp;
174 unsigned long freq, bootup_volt;
175
176 if (!vdd_name || !clk_name || !dev) {
177 printk(KERN_ERR "%s: Invalid parameters!\n", __func__);
178 goto exit;
179 }
180
181 voltdm = omap_voltage_domain_lookup(vdd_name);
182 if (IS_ERR(voltdm)) {
183 printk(KERN_ERR "%s: Unable to get vdd pointer for vdd_%s\n",
184 __func__, vdd_name);
185 goto exit;
186 }
187
188 clk = clk_get(NULL, clk_name);
189 if (IS_ERR(clk)) {
190 printk(KERN_ERR "%s: unable to get clk %s\n",
191 __func__, clk_name);
192 goto exit;
193 }
194
195 freq = clk->rate;
196 clk_put(clk);
197
198 opp = opp_find_freq_ceil(dev, &freq);
199 if (IS_ERR(opp)) {
200 printk(KERN_ERR "%s: unable to find boot up OPP for vdd_%s\n",
201 __func__, vdd_name);
202 goto exit;
203 }
204
205 bootup_volt = opp_get_voltage(opp);
206 if (!bootup_volt) {
207 printk(KERN_ERR "%s: unable to find voltage corresponding"
208 "to the bootup OPP for vdd_%s\n", __func__, vdd_name);
209 goto exit;
210 }
211
212 omap_voltage_scale_vdd(voltdm, bootup_volt);
213 return 0;
214
215exit:
216 printk(KERN_ERR "%s: Unable to put vdd_%s to its init voltage\n\n",
217 __func__, vdd_name);
218 return -EINVAL;
219}
220
221static void __init omap3_init_voltages(void)
222{
223 if (!cpu_is_omap34xx())
224 return;
225
226 omap2_set_init_voltage("mpu", "dpll1_ck", mpu_dev);
227 omap2_set_init_voltage("core", "l3_ick", l3_dev);
228}
229
230static void __init omap4_init_voltages(void)
231{
232 if (!cpu_is_omap44xx())
233 return;
234
235 omap2_set_init_voltage("mpu", "dpll_mpu_ck", mpu_dev);
236 omap2_set_init_voltage("core", "l3_div_ck", l3_dev);
237 omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", iva_dev);
238}
239
157static int __init omap2_common_pm_init(void) 240static int __init omap2_common_pm_init(void)
158{ 241{
159 omap2_init_processor_devices(); 242 omap2_init_processor_devices();
@@ -163,3 +246,22 @@ static int __init omap2_common_pm_init(void)
163} 246}
164postcore_initcall(omap2_common_pm_init); 247postcore_initcall(omap2_common_pm_init);
165 248
249static int __init omap2_common_pm_late_init(void)
250{
251 /* Init the OMAP TWL parameters */
252 omap3_twl_init();
253 omap4_twl_init();
254
255 /* Init the voltage layer */
256 omap_voltage_late_init();
257
258 /* Initialize the voltages */
259 omap3_init_voltages();
260 omap4_init_voltages();
261
262 /* Smartreflex device init */
263 omap_devinit_smartreflex();
264
265 return 0;
266}
267late_initcall(omap2_common_pm_late_init);
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index 482df7fc1585..1c1b0ab5b978 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -11,6 +11,8 @@
11#ifndef __ARCH_ARM_MACH_OMAP2_PM_H 11#ifndef __ARCH_ARM_MACH_OMAP2_PM_H
12#define __ARCH_ARM_MACH_OMAP2_PM_H 12#define __ARCH_ARM_MACH_OMAP2_PM_H
13 13
14#include <linux/err.h>
15
14#include "powerdomain.h" 16#include "powerdomain.h"
15 17
16extern void *omap3_secure_ram_storage; 18extern void *omap3_secure_ram_storage;
@@ -110,4 +112,30 @@ extern void enable_omap3630_toggle_l2_on_restore(void);
110static inline void enable_omap3630_toggle_l2_on_restore(void) { } 112static inline void enable_omap3630_toggle_l2_on_restore(void) { }
111#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */ 113#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */
112 114
115#ifdef CONFIG_OMAP_SMARTREFLEX
116extern int omap_devinit_smartreflex(void);
117extern void omap_enable_smartreflex_on_init(void);
118#else
119static inline int omap_devinit_smartreflex(void)
120{
121 return -EINVAL;
122}
123
124static inline void omap_enable_smartreflex_on_init(void) {}
125#endif
126
127#ifdef CONFIG_TWL4030_CORE
128extern int omap3_twl_init(void);
129extern int omap4_twl_init(void);
130#else
131static inline int omap3_twl_init(void)
132{
133 return -EINVAL;
134}
135static inline int omap4_twl_init(void)
136{
137 return -EINVAL;
138}
139#endif
140
113#endif 141#endif
diff --git a/arch/arm/mach-omap2/smartreflex-class3.c b/arch/arm/mach-omap2/smartreflex-class3.c
new file mode 100644
index 000000000000..60e70552b4c5
--- /dev/null
+++ b/arch/arm/mach-omap2/smartreflex-class3.c
@@ -0,0 +1,59 @@
1/*
2 * Smart reflex Class 3 specific implementations
3 *
4 * Author: Thara Gopinath <thara@ti.com>
5 *
6 * Copyright (C) 2010 Texas Instruments, Inc.
7 * Thara Gopinath <thara@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#include <plat/smartreflex.h>
15
16static int sr_class3_enable(struct voltagedomain *voltdm)
17{
18 unsigned long volt = omap_voltage_get_nom_volt(voltdm);
19
20 if (!volt) {
21 pr_warning("%s: Curr voltage unknown. Cannot enable sr_%s\n",
22 __func__, voltdm->name);
23 return -ENODATA;
24 }
25
26 omap_vp_enable(voltdm);
27 return sr_enable(voltdm, volt);
28}
29
30static int sr_class3_disable(struct voltagedomain *voltdm, int is_volt_reset)
31{
32 omap_vp_disable(voltdm);
33 sr_disable(voltdm);
34 if (is_volt_reset)
35 omap_voltage_reset(voltdm);
36
37 return 0;
38}
39
40static int sr_class3_configure(struct voltagedomain *voltdm)
41{
42 return sr_configure_errgen(voltdm);
43}
44
45/* SR class3 structure */
46static struct omap_sr_class_data class3_data = {
47 .enable = sr_class3_enable,
48 .disable = sr_class3_disable,
49 .configure = sr_class3_configure,
50 .class_type = SR_CLASS3,
51};
52
53/* Smartreflex Class3 init API to be called from board file */
54static int __init sr_class3_init(void)
55{
56 pr_info("SmartReflex Class3 initialized\n");
57 return sr_register_class(&class3_data);
58}
59late_initcall(sr_class3_init);
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
new file mode 100644
index 000000000000..77ecebf3fae2
--- /dev/null
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -0,0 +1,1029 @@
1/*
2 * OMAP SmartReflex Voltage Control
3 *
4 * Author: Thara Gopinath <thara@ti.com>
5 *
6 * Copyright (C) 2010 Texas Instruments, Inc.
7 * Thara Gopinath <thara@ti.com>
8 *
9 * Copyright (C) 2008 Nokia Corporation
10 * Kalle Jokiniemi
11 *
12 * Copyright (C) 2007 Texas Instruments, Inc.
13 * Lesly A M <x0080970@ti.com>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License version 2 as
17 * published by the Free Software Foundation.
18 */
19
20#include <linux/interrupt.h>
21#include <linux/clk.h>
22#include <linux/io.h>
23#include <linux/debugfs.h>
24#include <linux/delay.h>
25#include <linux/slab.h>
26#include <linux/pm_runtime.h>
27
28#include <plat/common.h>
29#include <plat/smartreflex.h>
30
31#include "pm.h"
32
33#define SMARTREFLEX_NAME_LEN 16
34#define NVALUE_NAME_LEN 40
35#define SR_DISABLE_TIMEOUT 200
36
37struct omap_sr {
38 int srid;
39 int ip_type;
40 int nvalue_count;
41 bool autocomp_active;
42 u32 clk_length;
43 u32 err_weight;
44 u32 err_minlimit;
45 u32 err_maxlimit;
46 u32 accum_data;
47 u32 senn_avgweight;
48 u32 senp_avgweight;
49 u32 senp_mod;
50 u32 senn_mod;
51 unsigned int irq;
52 void __iomem *base;
53 struct platform_device *pdev;
54 struct list_head node;
55 struct omap_sr_nvalue_table *nvalue_table;
56 struct voltagedomain *voltdm;
57};
58
59/* sr_list contains all the instances of smartreflex module */
60static LIST_HEAD(sr_list);
61
62static struct omap_sr_class_data *sr_class;
63static struct omap_sr_pmic_data *sr_pmic_data;
64
65static inline void sr_write_reg(struct omap_sr *sr, unsigned offset, u32 value)
66{
67 __raw_writel(value, (sr->base + offset));
68}
69
70static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask,
71 u32 value)
72{
73 u32 reg_val;
74 u32 errconfig_offs = 0, errconfig_mask = 0;
75
76 reg_val = __raw_readl(sr->base + offset);
77 reg_val &= ~mask;
78
79 /*
80 * Smartreflex error config register is special as it contains
81 * certain status bits which if written a 1 into means a clear
82 * of those bits. So in order to make sure no accidental write of
83 * 1 happens to those status bits, do a clear of them in the read
84 * value. This mean this API doesn't rewrite values in these bits
85 * if they are currently set, but does allow the caller to write
86 * those bits.
87 */
88 if (sr->ip_type == SR_TYPE_V1) {
89 errconfig_offs = ERRCONFIG_V1;
90 errconfig_mask = ERRCONFIG_STATUS_V1_MASK;
91 } else if (sr->ip_type == SR_TYPE_V2) {
92 errconfig_offs = ERRCONFIG_V2;
93 errconfig_mask = ERRCONFIG_VPBOUNDINTST_V2;
94 }
95
96 if (offset == errconfig_offs)
97 reg_val &= ~errconfig_mask;
98
99 reg_val |= value;
100
101 __raw_writel(reg_val, (sr->base + offset));
102}
103
104static inline u32 sr_read_reg(struct omap_sr *sr, unsigned offset)
105{
106 return __raw_readl(sr->base + offset);
107}
108
109static struct omap_sr *_sr_lookup(struct voltagedomain *voltdm)
110{
111 struct omap_sr *sr_info;
112
113 if (!voltdm) {
114 pr_err("%s: Null voltage domain passed!\n", __func__);
115 return ERR_PTR(-EINVAL);
116 }
117
118 list_for_each_entry(sr_info, &sr_list, node) {
119 if (voltdm == sr_info->voltdm)
120 return sr_info;
121 }
122
123 return ERR_PTR(-ENODATA);
124}
125
126static irqreturn_t sr_interrupt(int irq, void *data)
127{
128 struct omap_sr *sr_info = (struct omap_sr *)data;
129 u32 status = 0;
130
131 if (sr_info->ip_type == SR_TYPE_V1) {
132 /* Read the status bits */
133 status = sr_read_reg(sr_info, ERRCONFIG_V1);
134
135 /* Clear them by writing back */
136 sr_write_reg(sr_info, ERRCONFIG_V1, status);
137 } else if (sr_info->ip_type == SR_TYPE_V2) {
138 /* Read the status bits */
139 sr_read_reg(sr_info, IRQSTATUS);
140
141 /* Clear them by writing back */
142 sr_write_reg(sr_info, IRQSTATUS, status);
143 }
144
145 if (sr_class->class_type == SR_CLASS2 && sr_class->notify)
146 sr_class->notify(sr_info->voltdm, status);
147
148 return IRQ_HANDLED;
149}
150
151static void sr_set_clk_length(struct omap_sr *sr)
152{
153 struct clk *sys_ck;
154 u32 sys_clk_speed;
155
156 if (cpu_is_omap34xx())
157 sys_ck = clk_get(NULL, "sys_ck");
158 else
159 sys_ck = clk_get(NULL, "sys_clkin_ck");
160
161 if (IS_ERR(sys_ck)) {
162 dev_err(&sr->pdev->dev, "%s: unable to get sys clk\n",
163 __func__);
164 return;
165 }
166 sys_clk_speed = clk_get_rate(sys_ck);
167 clk_put(sys_ck);
168
169 switch (sys_clk_speed) {
170 case 12000000:
171 sr->clk_length = SRCLKLENGTH_12MHZ_SYSCLK;
172 break;
173 case 13000000:
174 sr->clk_length = SRCLKLENGTH_13MHZ_SYSCLK;
175 break;
176 case 19200000:
177 sr->clk_length = SRCLKLENGTH_19MHZ_SYSCLK;
178 break;
179 case 26000000:
180 sr->clk_length = SRCLKLENGTH_26MHZ_SYSCLK;
181 break;
182 case 38400000:
183 sr->clk_length = SRCLKLENGTH_38MHZ_SYSCLK;
184 break;
185 default:
186 dev_err(&sr->pdev->dev, "%s: Invalid sysclk value: %d\n",
187 __func__, sys_clk_speed);
188 break;
189 }
190}
191
192static void sr_set_regfields(struct omap_sr *sr)
193{
194 /*
195 * For time being these values are defined in smartreflex.h
196 * and populated during init. May be they can be moved to board
197 * file or pmic specific data structure. In that case these structure
198 * fields will have to be populated using the pdata or pmic structure.
199 */
200 if (cpu_is_omap34xx() || cpu_is_omap44xx()) {
201 sr->err_weight = OMAP3430_SR_ERRWEIGHT;
202 sr->err_maxlimit = OMAP3430_SR_ERRMAXLIMIT;
203 sr->accum_data = OMAP3430_SR_ACCUMDATA;
204 if (!(strcmp(sr->voltdm->name, "mpu"))) {
205 sr->senn_avgweight = OMAP3430_SR1_SENNAVGWEIGHT;
206 sr->senp_avgweight = OMAP3430_SR1_SENPAVGWEIGHT;
207 } else {
208 sr->senn_avgweight = OMAP3430_SR2_SENNAVGWEIGHT;
209 sr->senp_avgweight = OMAP3430_SR2_SENPAVGWEIGHT;
210 }
211 }
212}
213
214static void sr_start_vddautocomp(struct omap_sr *sr)
215{
216 if (!sr_class || !(sr_class->enable) || !(sr_class->configure)) {
217 dev_warn(&sr->pdev->dev,
218 "%s: smartreflex class driver not registered\n",
219 __func__);
220 return;
221 }
222
223 if (!sr_class->enable(sr->voltdm))
224 sr->autocomp_active = true;
225}
226
227static void sr_stop_vddautocomp(struct omap_sr *sr)
228{
229 if (!sr_class || !(sr_class->disable)) {
230 dev_warn(&sr->pdev->dev,
231 "%s: smartreflex class driver not registered\n",
232 __func__);
233 return;
234 }
235
236 if (sr->autocomp_active) {
237 sr_class->disable(sr->voltdm, 1);
238 sr->autocomp_active = false;
239 }
240}
241
242/*
243 * This function handles the intializations which have to be done
244 * only when both sr device and class driver regiter has
245 * completed. This will be attempted to be called from both sr class
246 * driver register and sr device intializtion API's. Only one call
247 * will ultimately succeed.
248 *
249 * Currenly this function registers interrrupt handler for a particular SR
250 * if smartreflex class driver is already registered and has
251 * requested for interrupts and the SR interrupt line in present.
252 */
253static int sr_late_init(struct omap_sr *sr_info)
254{
255 char *name;
256 struct omap_sr_data *pdata = sr_info->pdev->dev.platform_data;
257 struct resource *mem;
258 int ret = 0;
259
260 if (sr_class->class_type == SR_CLASS2 &&
261 sr_class->notify_flags && sr_info->irq) {
262
263 name = kzalloc(SMARTREFLEX_NAME_LEN + 1, GFP_KERNEL);
264 strcpy(name, "sr_");
265 strcat(name, sr_info->voltdm->name);
266 ret = request_irq(sr_info->irq, sr_interrupt,
267 0, name, (void *)sr_info);
268 if (ret)
269 goto error;
270 }
271
272 if (pdata && pdata->enable_on_init)
273 sr_start_vddautocomp(sr_info);
274
275 return ret;
276
277error:
278 iounmap(sr_info->base);
279 mem = platform_get_resource(sr_info->pdev, IORESOURCE_MEM, 0);
280 release_mem_region(mem->start, resource_size(mem));
281 list_del(&sr_info->node);
282 dev_err(&sr_info->pdev->dev, "%s: ERROR in registering"
283 "interrupt handler. Smartreflex will"
284 "not function as desired\n", __func__);
285 kfree(sr_info);
286 return ret;
287}
288
289static void sr_v1_disable(struct omap_sr *sr)
290{
291 int timeout = 0;
292
293 /* Enable MCUDisableAcknowledge interrupt */
294 sr_modify_reg(sr, ERRCONFIG_V1,
295 ERRCONFIG_MCUDISACKINTEN, ERRCONFIG_MCUDISACKINTEN);
296
297 /* SRCONFIG - disable SR */
298 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0);
299
300 /* Disable all other SR interrupts and clear the status */
301 sr_modify_reg(sr, ERRCONFIG_V1,
302 (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN |
303 ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_VPBOUNDINTEN_V1),
304 (ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST |
305 ERRCONFIG_MCUBOUNDINTST |
306 ERRCONFIG_VPBOUNDINTST_V1));
307
308 /*
309 * Wait for SR to be disabled.
310 * wait until ERRCONFIG.MCUDISACKINTST = 1. Typical latency is 1us.
311 */
312 omap_test_timeout((sr_read_reg(sr, ERRCONFIG_V1) &
313 ERRCONFIG_MCUDISACKINTST), SR_DISABLE_TIMEOUT,
314 timeout);
315
316 if (timeout >= SR_DISABLE_TIMEOUT)
317 dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n",
318 __func__);
319
320 /* Disable MCUDisableAcknowledge interrupt & clear pending interrupt */
321 sr_modify_reg(sr, ERRCONFIG_V1, ERRCONFIG_MCUDISACKINTEN,
322 ERRCONFIG_MCUDISACKINTST);
323}
324
325static void sr_v2_disable(struct omap_sr *sr)
326{
327 int timeout = 0;
328
329 /* Enable MCUDisableAcknowledge interrupt */
330 sr_write_reg(sr, IRQENABLE_SET, IRQENABLE_MCUDISABLEACKINT);
331
332 /* SRCONFIG - disable SR */
333 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0);
334
335 /* Disable all other SR interrupts and clear the status */
336 sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2,
337 ERRCONFIG_VPBOUNDINTST_V2);
338 sr_write_reg(sr, IRQENABLE_CLR, (IRQENABLE_MCUACCUMINT |
339 IRQENABLE_MCUVALIDINT |
340 IRQENABLE_MCUBOUNDSINT));
341 sr_write_reg(sr, IRQSTATUS, (IRQSTATUS_MCUACCUMINT |
342 IRQSTATUS_MCVALIDINT |
343 IRQSTATUS_MCBOUNDSINT));
344
345 /*
346 * Wait for SR to be disabled.
347 * wait until IRQSTATUS.MCUDISACKINTST = 1. Typical latency is 1us.
348 */
349 omap_test_timeout((sr_read_reg(sr, IRQSTATUS) &
350 IRQSTATUS_MCUDISABLEACKINT), SR_DISABLE_TIMEOUT,
351 timeout);
352
353 if (timeout >= SR_DISABLE_TIMEOUT)
354 dev_warn(&sr->pdev->dev, "%s: Smartreflex disable timedout\n",
355 __func__);
356
357 /* Disable MCUDisableAcknowledge interrupt & clear pending interrupt */
358 sr_write_reg(sr, IRQENABLE_CLR, IRQENABLE_MCUDISABLEACKINT);
359 sr_write_reg(sr, IRQSTATUS, IRQSTATUS_MCUDISABLEACKINT);
360}
361
362static u32 sr_retrieve_nvalue(struct omap_sr *sr, u32 efuse_offs)
363{
364 int i;
365
366 if (!sr->nvalue_table) {
367 dev_warn(&sr->pdev->dev, "%s: Missing ntarget value table\n",
368 __func__);
369 return 0;
370 }
371
372 for (i = 0; i < sr->nvalue_count; i++) {
373 if (sr->nvalue_table[i].efuse_offs == efuse_offs)
374 return sr->nvalue_table[i].nvalue;
375 }
376
377 return 0;
378}
379
380/* Public Functions */
381
382/**
383 * sr_configure_errgen() - Configures the smrtreflex to perform AVS using the
384 * error generator module.
385 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
386 *
387 * This API is to be called from the smartreflex class driver to
388 * configure the error generator module inside the smartreflex module.
389 * SR settings if using the ERROR module inside Smartreflex.
390 * SR CLASS 3 by default uses only the ERROR module where as
391 * SR CLASS 2 can choose between ERROR module and MINMAXAVG
392 * module. Returns 0 on success and error value in case of failure.
393 */
394int sr_configure_errgen(struct voltagedomain *voltdm)
395{
396 u32 sr_config, sr_errconfig, errconfig_offs, vpboundint_en;
397 u32 vpboundint_st, senp_en = 0, senn_en = 0;
398 u8 senp_shift, senn_shift;
399 struct omap_sr *sr = _sr_lookup(voltdm);
400
401 if (IS_ERR(sr)) {
402 pr_warning("%s: omap_sr struct for sr_%s not found\n",
403 __func__, voltdm->name);
404 return -EINVAL;
405 }
406
407 if (!sr->clk_length)
408 sr_set_clk_length(sr);
409
410 senp_en = sr->senp_mod;
411 senn_en = sr->senn_mod;
412
413 sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
414 SRCONFIG_SENENABLE | SRCONFIG_ERRGEN_EN;
415
416 if (sr->ip_type == SR_TYPE_V1) {
417 sr_config |= SRCONFIG_DELAYCTRL;
418 senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT;
419 senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT;
420 errconfig_offs = ERRCONFIG_V1;
421 vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V1;
422 vpboundint_st = ERRCONFIG_VPBOUNDINTST_V1;
423 } else if (sr->ip_type == SR_TYPE_V2) {
424 senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT;
425 senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT;
426 errconfig_offs = ERRCONFIG_V2;
427 vpboundint_en = ERRCONFIG_VPBOUNDINTEN_V2;
428 vpboundint_st = ERRCONFIG_VPBOUNDINTST_V2;
429 } else {
430 dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex"
431 "module without specifying the ip\n", __func__);
432 return -EINVAL;
433 }
434
435 sr_config |= ((senn_en << senn_shift) | (senp_en << senp_shift));
436 sr_write_reg(sr, SRCONFIG, sr_config);
437 sr_errconfig = (sr->err_weight << ERRCONFIG_ERRWEIGHT_SHIFT) |
438 (sr->err_maxlimit << ERRCONFIG_ERRMAXLIMIT_SHIFT) |
439 (sr->err_minlimit << ERRCONFIG_ERRMINLIMIT_SHIFT);
440 sr_modify_reg(sr, errconfig_offs, (SR_ERRWEIGHT_MASK |
441 SR_ERRMAXLIMIT_MASK | SR_ERRMINLIMIT_MASK),
442 sr_errconfig);
443
444 /* Enabling the interrupts if the ERROR module is used */
445 sr_modify_reg(sr, errconfig_offs,
446 vpboundint_en, (vpboundint_en | vpboundint_st));
447
448 return 0;
449}
450
451/**
452 * sr_configure_minmax() - Configures the smrtreflex to perform AVS using the
453 * minmaxavg module.
454 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
455 *
456 * This API is to be called from the smartreflex class driver to
457 * configure the minmaxavg module inside the smartreflex module.
458 * SR settings if using the ERROR module inside Smartreflex.
459 * SR CLASS 3 by default uses only the ERROR module where as
460 * SR CLASS 2 can choose between ERROR module and MINMAXAVG
461 * module. Returns 0 on success and error value in case of failure.
462 */
463int sr_configure_minmax(struct voltagedomain *voltdm)
464{
465 u32 sr_config, sr_avgwt;
466 u32 senp_en = 0, senn_en = 0;
467 u8 senp_shift, senn_shift;
468 struct omap_sr *sr = _sr_lookup(voltdm);
469
470 if (IS_ERR(sr)) {
471 pr_warning("%s: omap_sr struct for sr_%s not found\n",
472 __func__, voltdm->name);
473 return -EINVAL;
474 }
475
476 if (!sr->clk_length)
477 sr_set_clk_length(sr);
478
479 senp_en = sr->senp_mod;
480 senn_en = sr->senn_mod;
481
482 sr_config = (sr->clk_length << SRCONFIG_SRCLKLENGTH_SHIFT) |
483 SRCONFIG_SENENABLE |
484 (sr->accum_data << SRCONFIG_ACCUMDATA_SHIFT);
485
486 if (sr->ip_type == SR_TYPE_V1) {
487 sr_config |= SRCONFIG_DELAYCTRL;
488 senn_shift = SRCONFIG_SENNENABLE_V1_SHIFT;
489 senp_shift = SRCONFIG_SENPENABLE_V1_SHIFT;
490 } else if (sr->ip_type == SR_TYPE_V2) {
491 senn_shift = SRCONFIG_SENNENABLE_V2_SHIFT;
492 senp_shift = SRCONFIG_SENPENABLE_V2_SHIFT;
493 } else {
494 dev_err(&sr->pdev->dev, "%s: Trying to Configure smartreflex"
495 "module without specifying the ip\n", __func__);
496 return -EINVAL;
497 }
498
499 sr_config |= ((senn_en << senn_shift) | (senp_en << senp_shift));
500 sr_write_reg(sr, SRCONFIG, sr_config);
501 sr_avgwt = (sr->senp_avgweight << AVGWEIGHT_SENPAVGWEIGHT_SHIFT) |
502 (sr->senn_avgweight << AVGWEIGHT_SENNAVGWEIGHT_SHIFT);
503 sr_write_reg(sr, AVGWEIGHT, sr_avgwt);
504
505 /*
506 * Enabling the interrupts if MINMAXAVG module is used.
507 * TODO: check if all the interrupts are mandatory
508 */
509 if (sr->ip_type == SR_TYPE_V1) {
510 sr_modify_reg(sr, ERRCONFIG_V1,
511 (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN |
512 ERRCONFIG_MCUBOUNDINTEN),
513 (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUACCUMINTST |
514 ERRCONFIG_MCUVALIDINTEN | ERRCONFIG_MCUVALIDINTST |
515 ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_MCUBOUNDINTST));
516 } else if (sr->ip_type == SR_TYPE_V2) {
517 sr_write_reg(sr, IRQSTATUS,
518 IRQSTATUS_MCUACCUMINT | IRQSTATUS_MCVALIDINT |
519 IRQSTATUS_MCBOUNDSINT | IRQSTATUS_MCUDISABLEACKINT);
520 sr_write_reg(sr, IRQENABLE_SET,
521 IRQENABLE_MCUACCUMINT | IRQENABLE_MCUVALIDINT |
522 IRQENABLE_MCUBOUNDSINT | IRQENABLE_MCUDISABLEACKINT);
523 }
524
525 return 0;
526}
527
528/**
529 * sr_enable() - Enables the smartreflex module.
530 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
531 * @volt: The voltage at which the Voltage domain associated with
532 * the smartreflex module is operating at.
533 * This is required only to program the correct Ntarget value.
534 *
535 * This API is to be called from the smartreflex class driver to
536 * enable a smartreflex module. Returns 0 on success. Returns error
537 * value if the voltage passed is wrong or if ntarget value is wrong.
538 */
539int sr_enable(struct voltagedomain *voltdm, unsigned long volt)
540{
541 u32 nvalue_reciprocal;
542 struct omap_volt_data *volt_data;
543 struct omap_sr *sr = _sr_lookup(voltdm);
544 int ret;
545
546 if (IS_ERR(sr)) {
547 pr_warning("%s: omap_sr struct for sr_%s not found\n",
548 __func__, voltdm->name);
549 return -EINVAL;
550 }
551
552 volt_data = omap_voltage_get_voltdata(sr->voltdm, volt);
553
554 if (IS_ERR(volt_data)) {
555 dev_warn(&sr->pdev->dev, "%s: Unable to get voltage table"
556 "for nominal voltage %ld\n", __func__, volt);
557 return -ENODATA;
558 }
559
560 nvalue_reciprocal = sr_retrieve_nvalue(sr, volt_data->sr_efuse_offs);
561
562 if (!nvalue_reciprocal) {
563 dev_warn(&sr->pdev->dev, "%s: NVALUE = 0 at voltage %ld\n",
564 __func__, volt);
565 return -ENODATA;
566 }
567
568 /* errminlimit is opp dependent and hence linked to voltage */
569 sr->err_minlimit = volt_data->sr_errminlimit;
570
571 pm_runtime_get_sync(&sr->pdev->dev);
572
573 /* Check if SR is already enabled. If yes do nothing */
574 if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE)
575 return 0;
576
577 /* Configure SR */
578 ret = sr_class->configure(voltdm);
579 if (ret)
580 return ret;
581
582 sr_write_reg(sr, NVALUERECIPROCAL, nvalue_reciprocal);
583
584 /* SRCONFIG - enable SR */
585 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, SRCONFIG_SRENABLE);
586 return 0;
587}
588
589/**
590 * sr_disable() - Disables the smartreflex module.
591 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
592 *
593 * This API is to be called from the smartreflex class driver to
594 * disable a smartreflex module.
595 */
596void sr_disable(struct voltagedomain *voltdm)
597{
598 struct omap_sr *sr = _sr_lookup(voltdm);
599
600 if (IS_ERR(sr)) {
601 pr_warning("%s: omap_sr struct for sr_%s not found\n",
602 __func__, voltdm->name);
603 return;
604 }
605
606 /* Check if SR clocks are already disabled. If yes do nothing */
607 if (pm_runtime_suspended(&sr->pdev->dev))
608 return;
609
610 /*
611 * Disable SR if only it is indeed enabled. Else just
612 * disable the clocks.
613 */
614 if (sr_read_reg(sr, SRCONFIG) & SRCONFIG_SRENABLE) {
615 if (sr->ip_type == SR_TYPE_V1)
616 sr_v1_disable(sr);
617 else if (sr->ip_type == SR_TYPE_V2)
618 sr_v2_disable(sr);
619 }
620
621 pm_runtime_put_sync(&sr->pdev->dev);
622}
623
624/**
625 * sr_register_class() - API to register a smartreflex class parameters.
626 * @class_data: The structure containing various sr class specific data.
627 *
628 * This API is to be called by the smartreflex class driver to register itself
629 * with the smartreflex driver during init. Returns 0 on success else the
630 * error value.
631 */
632int sr_register_class(struct omap_sr_class_data *class_data)
633{
634 struct omap_sr *sr_info;
635
636 if (!class_data) {
637 pr_warning("%s:, Smartreflex class data passed is NULL\n",
638 __func__);
639 return -EINVAL;
640 }
641
642 if (sr_class) {
643 pr_warning("%s: Smartreflex class driver already registered\n",
644 __func__);
645 return -EBUSY;
646 }
647
648 sr_class = class_data;
649
650 /*
651 * Call into late init to do intializations that require
652 * both sr driver and sr class driver to be initiallized.
653 */
654 list_for_each_entry(sr_info, &sr_list, node)
655 sr_late_init(sr_info);
656
657 return 0;
658}
659
660/**
661 * omap_sr_enable() - API to enable SR clocks and to call into the
662 * registered smartreflex class enable API.
663 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
664 *
665 * This API is to be called from the kernel in order to enable
666 * a particular smartreflex module. This API will do the initial
667 * configurations to turn on the smartreflex module and in turn call
668 * into the registered smartreflex class enable API.
669 */
670void omap_sr_enable(struct voltagedomain *voltdm)
671{
672 struct omap_sr *sr = _sr_lookup(voltdm);
673
674 if (IS_ERR(sr)) {
675 pr_warning("%s: omap_sr struct for sr_%s not found\n",
676 __func__, voltdm->name);
677 return;
678 }
679
680 if (!sr->autocomp_active)
681 return;
682
683 if (!sr_class || !(sr_class->enable) || !(sr_class->configure)) {
684 dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not"
685 "registered\n", __func__);
686 return;
687 }
688
689 sr_class->enable(voltdm);
690}
691
692/**
693 * omap_sr_disable() - API to disable SR without resetting the voltage
694 * processor voltage
695 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
696 *
697 * This API is to be called from the kernel in order to disable
698 * a particular smartreflex module. This API will in turn call
699 * into the registered smartreflex class disable API. This API will tell
700 * the smartreflex class disable not to reset the VP voltage after
701 * disabling smartreflex.
702 */
703void omap_sr_disable(struct voltagedomain *voltdm)
704{
705 struct omap_sr *sr = _sr_lookup(voltdm);
706
707 if (IS_ERR(sr)) {
708 pr_warning("%s: omap_sr struct for sr_%s not found\n",
709 __func__, voltdm->name);
710 return;
711 }
712
713 if (!sr->autocomp_active)
714 return;
715
716 if (!sr_class || !(sr_class->disable)) {
717 dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not"
718 "registered\n", __func__);
719 return;
720 }
721
722 sr_class->disable(voltdm, 0);
723}
724
725/**
726 * omap_sr_disable_reset_volt() - API to disable SR and reset the
727 * voltage processor voltage
728 * @voltdm: VDD pointer to which the SR module to be configured belongs to.
729 *
730 * This API is to be called from the kernel in order to disable
731 * a particular smartreflex module. This API will in turn call
732 * into the registered smartreflex class disable API. This API will tell
733 * the smartreflex class disable to reset the VP voltage after
734 * disabling smartreflex.
735 */
736void omap_sr_disable_reset_volt(struct voltagedomain *voltdm)
737{
738 struct omap_sr *sr = _sr_lookup(voltdm);
739
740 if (IS_ERR(sr)) {
741 pr_warning("%s: omap_sr struct for sr_%s not found\n",
742 __func__, voltdm->name);
743 return;
744 }
745
746 if (!sr->autocomp_active)
747 return;
748
749 if (!sr_class || !(sr_class->disable)) {
750 dev_warn(&sr->pdev->dev, "%s: smartreflex class driver not"
751 "registered\n", __func__);
752 return;
753 }
754
755 sr_class->disable(voltdm, 1);
756}
757
758/**
759 * omap_sr_register_pmic() - API to register pmic specific info.
760 * @pmic_data: The structure containing pmic specific data.
761 *
762 * This API is to be called from the PMIC specific code to register with
763 * smartreflex driver pmic specific info. Currently the only info required
764 * is the smartreflex init on the PMIC side.
765 */
766void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data)
767{
768 if (!pmic_data) {
769 pr_warning("%s: Trying to register NULL PMIC data structure"
770 "with smartreflex\n", __func__);
771 return;
772 }
773
774 sr_pmic_data = pmic_data;
775}
776
777/* PM Debug Fs enteries to enable disable smartreflex. */
778static int omap_sr_autocomp_show(void *data, u64 *val)
779{
780 struct omap_sr *sr_info = (struct omap_sr *) data;
781
782 if (!sr_info) {
783 pr_warning("%s: omap_sr struct for sr_%s not found\n",
784 __func__, sr_info->voltdm->name);
785 return -EINVAL;
786 }
787
788 *val = sr_info->autocomp_active;
789
790 return 0;
791}
792
793static int omap_sr_autocomp_store(void *data, u64 val)
794{
795 struct omap_sr *sr_info = (struct omap_sr *) data;
796
797 if (!sr_info) {
798 pr_warning("%s: omap_sr struct for sr_%s not found\n",
799 __func__, sr_info->voltdm->name);
800 return -EINVAL;
801 }
802
803 /* Sanity check */
804 if (val && (val != 1)) {
805 pr_warning("%s: Invalid argument %lld\n", __func__, val);
806 return -EINVAL;
807 }
808
809 if (!val)
810 sr_stop_vddautocomp(sr_info);
811 else
812 sr_start_vddautocomp(sr_info);
813
814 return 0;
815}
816
817DEFINE_SIMPLE_ATTRIBUTE(pm_sr_fops, omap_sr_autocomp_show,
818 omap_sr_autocomp_store, "%llu\n");
819
820static int __init omap_sr_probe(struct platform_device *pdev)
821{
822 struct omap_sr *sr_info = kzalloc(sizeof(struct omap_sr), GFP_KERNEL);
823 struct omap_sr_data *pdata = pdev->dev.platform_data;
824 struct resource *mem, *irq;
825 struct dentry *vdd_dbg_dir, *dbg_dir, *nvalue_dir;
826 struct omap_volt_data *volt_data;
827 int i, ret = 0;
828
829 if (!sr_info) {
830 dev_err(&pdev->dev, "%s: unable to allocate sr_info\n",
831 __func__);
832 return -ENOMEM;
833 }
834
835 if (!pdata) {
836 dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
837 return -EINVAL;
838 }
839
840 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
841 if (!mem) {
842 dev_err(&pdev->dev, "%s: no mem resource\n", __func__);
843 ret = -ENODEV;
844 goto err_free_devinfo;
845 }
846
847 irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
848
849 pm_runtime_enable(&pdev->dev);
850
851 sr_info->pdev = pdev;
852 sr_info->srid = pdev->id;
853 sr_info->voltdm = pdata->voltdm;
854 sr_info->nvalue_table = pdata->nvalue_table;
855 sr_info->nvalue_count = pdata->nvalue_count;
856 sr_info->senn_mod = pdata->senn_mod;
857 sr_info->senp_mod = pdata->senp_mod;
858 sr_info->autocomp_active = false;
859 sr_info->ip_type = pdata->ip_type;
860 sr_info->base = ioremap(mem->start, resource_size(mem));
861 if (!sr_info->base) {
862 dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
863 ret = -ENOMEM;
864 goto err_release_region;
865 }
866
867 if (irq)
868 sr_info->irq = irq->start;
869
870 sr_set_clk_length(sr_info);
871 sr_set_regfields(sr_info);
872
873 list_add(&sr_info->node, &sr_list);
874
875 /*
876 * Call into late init to do intializations that require
877 * both sr driver and sr class driver to be initiallized.
878 */
879 if (sr_class) {
880 ret = sr_late_init(sr_info);
881 if (ret) {
882 pr_warning("%s: Error in SR late init\n", __func__);
883 return ret;
884 }
885 }
886
887 dev_info(&pdev->dev, "%s: SmartReflex driver initialized\n", __func__);
888
889 /*
890 * If the voltage domain debugfs directory is not created, do
891 * not try to create rest of the debugfs entries.
892 */
893 vdd_dbg_dir = omap_voltage_get_dbgdir(sr_info->voltdm);
894 if (!vdd_dbg_dir)
895 return -EINVAL;
896
897 dbg_dir = debugfs_create_dir("smartreflex", vdd_dbg_dir);
898 if (IS_ERR(dbg_dir)) {
899 dev_err(&pdev->dev, "%s: Unable to create debugfs directory\n",
900 __func__);
901 return PTR_ERR(dbg_dir);
902 }
903
904 (void) debugfs_create_file("autocomp", S_IRUGO | S_IWUGO, dbg_dir,
905 (void *)sr_info, &pm_sr_fops);
906 (void) debugfs_create_x32("errweight", S_IRUGO, dbg_dir,
907 &sr_info->err_weight);
908 (void) debugfs_create_x32("errmaxlimit", S_IRUGO, dbg_dir,
909 &sr_info->err_maxlimit);
910 (void) debugfs_create_x32("errminlimit", S_IRUGO, dbg_dir,
911 &sr_info->err_minlimit);
912
913 nvalue_dir = debugfs_create_dir("nvalue", dbg_dir);
914 if (IS_ERR(nvalue_dir)) {
915 dev_err(&pdev->dev, "%s: Unable to create debugfs directory"
916 "for n-values\n", __func__);
917 return PTR_ERR(nvalue_dir);
918 }
919
920 omap_voltage_get_volttable(sr_info->voltdm, &volt_data);
921 if (!volt_data) {
922 dev_warn(&pdev->dev, "%s: No Voltage table for the"
923 " corresponding vdd vdd_%s. Cannot create debugfs"
924 "entries for n-values\n",
925 __func__, sr_info->voltdm->name);
926 return -ENODATA;
927 }
928
929 for (i = 0; i < sr_info->nvalue_count; i++) {
930 char *name;
931 char volt_name[32];
932
933 name = kzalloc(NVALUE_NAME_LEN + 1, GFP_KERNEL);
934 if (!name) {
935 dev_err(&pdev->dev, "%s: Unable to allocate memory"
936 " for n-value directory name\n", __func__);
937 return -ENOMEM;
938 }
939
940 strcpy(name, "volt_");
941 sprintf(volt_name, "%d", volt_data[i].volt_nominal);
942 strcat(name, volt_name);
943 (void) debugfs_create_x32(name, S_IRUGO | S_IWUGO, nvalue_dir,
944 &(sr_info->nvalue_table[i].nvalue));
945 }
946
947 return ret;
948
949err_release_region:
950 release_mem_region(mem->start, resource_size(mem));
951err_free_devinfo:
952 kfree(sr_info);
953
954 return ret;
955}
956
957static int __devexit omap_sr_remove(struct platform_device *pdev)
958{
959 struct omap_sr_data *pdata = pdev->dev.platform_data;
960 struct omap_sr *sr_info;
961 struct resource *mem;
962
963 if (!pdata) {
964 dev_err(&pdev->dev, "%s: platform data missing\n", __func__);
965 return -EINVAL;
966 }
967
968 sr_info = _sr_lookup(pdata->voltdm);
969 if (!sr_info) {
970 dev_warn(&pdev->dev, "%s: omap_sr struct not found\n",
971 __func__);
972 return -EINVAL;
973 }
974
975 if (sr_info->autocomp_active)
976 sr_stop_vddautocomp(sr_info);
977
978 list_del(&sr_info->node);
979 iounmap(sr_info->base);
980 kfree(sr_info);
981 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
982 release_mem_region(mem->start, resource_size(mem));
983
984 return 0;
985}
986
987static struct platform_driver smartreflex_driver = {
988 .remove = omap_sr_remove,
989 .driver = {
990 .name = "smartreflex",
991 },
992};
993
994static int __init sr_init(void)
995{
996 int ret = 0;
997
998 /*
999 * sr_init is a late init. If by then a pmic specific API is not
1000 * registered either there is no need for anything to be done on
1001 * the PMIC side or somebody has forgotten to register a PMIC
1002 * handler. Warn for the second condition.
1003 */
1004 if (sr_pmic_data && sr_pmic_data->sr_pmic_init)
1005 sr_pmic_data->sr_pmic_init();
1006 else
1007 pr_warning("%s: No PMIC hook to init smartreflex\n", __func__);
1008
1009 ret = platform_driver_probe(&smartreflex_driver, omap_sr_probe);
1010 if (ret) {
1011 pr_err("%s: platform driver register failed for SR\n",
1012 __func__);
1013 return ret;
1014 }
1015
1016 return 0;
1017}
1018
1019static void __exit sr_exit(void)
1020{
1021 platform_driver_unregister(&smartreflex_driver);
1022}
1023late_initcall(sr_init);
1024module_exit(sr_exit);
1025
1026MODULE_DESCRIPTION("OMAP Smartreflex Driver");
1027MODULE_LICENSE("GPL");
1028MODULE_ALIAS("platform:" DRIVER_NAME);
1029MODULE_AUTHOR("Texas Instruments Inc");
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c
new file mode 100644
index 000000000000..786d685c09a9
--- /dev/null
+++ b/arch/arm/mach-omap2/sr_device.c
@@ -0,0 +1,146 @@
1/*
2 * OMAP3/OMAP4 smartreflex device file
3 *
4 * Author: Thara Gopinath <thara@ti.com>
5 *
6 * Based originally on code from smartreflex.c
7 * Copyright (C) 2010 Texas Instruments, Inc.
8 * Thara Gopinath <thara@ti.com>
9 *
10 * Copyright (C) 2008 Nokia Corporation
11 * Kalle Jokiniemi
12 *
13 * Copyright (C) 2007 Texas Instruments, Inc.
14 * Lesly A M <x0080970@ti.com>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2 as
18 * published by the Free Software Foundation.
19 */
20
21#include <linux/err.h>
22#include <linux/slab.h>
23#include <linux/io.h>
24
25#include <plat/omap_device.h>
26#include <plat/smartreflex.h>
27#include <plat/voltage.h>
28
29#include "control.h"
30
31static bool sr_enable_on_init;
32
33static struct omap_device_pm_latency omap_sr_latency[] = {
34 {
35 .deactivate_func = omap_device_idle_hwmods,
36 .activate_func = omap_device_enable_hwmods,
37 .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST
38 },
39};
40
41/* Read EFUSE values from control registers for OMAP3430 */
42static void __init sr_set_nvalues(struct omap_volt_data *volt_data,
43 struct omap_sr_data *sr_data)
44{
45 struct omap_sr_nvalue_table *nvalue_table;
46 int i, count = 0;
47
48 while (volt_data[count].volt_nominal)
49 count++;
50
51 nvalue_table = kzalloc(sizeof(struct omap_sr_nvalue_table)*count,
52 GFP_KERNEL);
53
54 for (i = 0; i < count; i++) {
55 u32 v;
56 /*
57 * In OMAP4 the efuse registers are 24 bit aligned.
58 * A __raw_readl will fail for non-32 bit aligned address
59 * and hence the 8-bit read and shift.
60 */
61 if (cpu_is_omap44xx()) {
62 u16 offset = volt_data[i].sr_efuse_offs;
63
64 v = omap_ctrl_readb(offset) |
65 omap_ctrl_readb(offset + 1) << 8 |
66 omap_ctrl_readb(offset + 2) << 16;
67 } else {
68 v = omap_ctrl_readl(volt_data[i].sr_efuse_offs);
69 }
70
71 nvalue_table[i].efuse_offs = volt_data[i].sr_efuse_offs;
72 nvalue_table[i].nvalue = v;
73 }
74
75 sr_data->nvalue_table = nvalue_table;
76 sr_data->nvalue_count = count;
77}
78
79static int sr_dev_init(struct omap_hwmod *oh, void *user)
80{
81 struct omap_sr_data *sr_data;
82 struct omap_device *od;
83 struct omap_volt_data *volt_data;
84 char *name = "smartreflex";
85 static int i;
86
87 sr_data = kzalloc(sizeof(struct omap_sr_data), GFP_KERNEL);
88 if (!sr_data) {
89 pr_err("%s: Unable to allocate memory for %s sr_data.Error!\n",
90 __func__, oh->name);
91 return -ENOMEM;
92 }
93
94 if (!oh->vdd_name) {
95 pr_err("%s: No voltage domain specified for %s."
96 "Cannot initialize\n", __func__, oh->name);
97 goto exit;
98 }
99
100 sr_data->ip_type = oh->class->rev;
101 sr_data->senn_mod = 0x1;
102 sr_data->senp_mod = 0x1;
103
104 sr_data->voltdm = omap_voltage_domain_lookup(oh->vdd_name);
105 if (IS_ERR(sr_data->voltdm)) {
106 pr_err("%s: Unable to get voltage domain pointer for VDD %s\n",
107 __func__, oh->vdd_name);
108 goto exit;
109 }
110
111 omap_voltage_get_volttable(sr_data->voltdm, &volt_data);
112 if (!volt_data) {
113 pr_warning("%s: No Voltage table registerd fo VDD%d."
114 "Something really wrong\n\n", __func__, i + 1);
115 goto exit;
116 }
117
118 sr_set_nvalues(volt_data, sr_data);
119
120 sr_data->enable_on_init = sr_enable_on_init;
121
122 od = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data),
123 omap_sr_latency,
124 ARRAY_SIZE(omap_sr_latency), 0);
125 if (IS_ERR(od))
126 pr_warning("%s: Could not build omap_device for %s: %s.\n\n",
127 __func__, name, oh->name);
128exit:
129 i++;
130 kfree(sr_data);
131 return 0;
132}
133
134/*
135 * API to be called from board files to enable smartreflex
136 * autocompensation at init.
137 */
138void __init omap_enable_smartreflex_on_init(void)
139{
140 sr_enable_on_init = true;
141}
142
143int __init omap_devinit_smartreflex(void)
144{
145 return omap_hwmod_for_each_by_class("smartreflex", sr_dev_init, NULL);
146}
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
new file mode 100644
index 000000000000..ed6079c94c57
--- /dev/null
+++ b/arch/arm/mach-omap2/voltage.c
@@ -0,0 +1,1571 @@
1/*
2 * OMAP3/OMAP4 Voltage Management Routines
3 *
4 * Author: Thara Gopinath <thara@ti.com>
5 *
6 * Copyright (C) 2007 Texas Instruments, Inc.
7 * Rajendra Nayak <rnayak@ti.com>
8 * Lesly A M <x0080970@ti.com>
9 *
10 * Copyright (C) 2008 Nokia Corporation
11 * Kalle Jokiniemi
12 *
13 * Copyright (C) 2010 Texas Instruments, Inc.
14 * Thara Gopinath <thara@ti.com>
15 *
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License version 2 as
18 * published by the Free Software Foundation.
19 */
20
21#include <linux/delay.h>
22#include <linux/io.h>
23#include <linux/clk.h>
24#include <linux/err.h>
25#include <linux/debugfs.h>
26#include <linux/slab.h>
27
28#include <plat/common.h>
29#include <plat/voltage.h>
30
31#include "prm-regbits-34xx.h"
32#include "prm-regbits-44xx.h"
33#include "prm44xx.h"
34#include "prcm44xx.h"
35#include "prminst44xx.h"
36#include "control.h"
37
38#define VP_IDLE_TIMEOUT 200
39#define VP_TRANXDONE_TIMEOUT 300
40#define VOLTAGE_DIR_SIZE 16
41
42/* Voltage processor register offsets */
43struct vp_reg_offs {
44 u8 vpconfig;
45 u8 vstepmin;
46 u8 vstepmax;
47 u8 vlimitto;
48 u8 vstatus;
49 u8 voltage;
50};
51
52/* Voltage Processor bit field values, shifts and masks */
53struct vp_reg_val {
54 /* PRM module */
55 u16 prm_mod;
56 /* VPx_VPCONFIG */
57 u32 vpconfig_erroroffset;
58 u16 vpconfig_errorgain;
59 u32 vpconfig_errorgain_mask;
60 u8 vpconfig_errorgain_shift;
61 u32 vpconfig_initvoltage_mask;
62 u8 vpconfig_initvoltage_shift;
63 u32 vpconfig_timeouten;
64 u32 vpconfig_initvdd;
65 u32 vpconfig_forceupdate;
66 u32 vpconfig_vpenable;
67 /* VPx_VSTEPMIN */
68 u8 vstepmin_stepmin;
69 u16 vstepmin_smpswaittimemin;
70 u8 vstepmin_stepmin_shift;
71 u8 vstepmin_smpswaittimemin_shift;
72 /* VPx_VSTEPMAX */
73 u8 vstepmax_stepmax;
74 u16 vstepmax_smpswaittimemax;
75 u8 vstepmax_stepmax_shift;
76 u8 vstepmax_smpswaittimemax_shift;
77 /* VPx_VLIMITTO */
78 u8 vlimitto_vddmin;
79 u8 vlimitto_vddmax;
80 u16 vlimitto_timeout;
81 u8 vlimitto_vddmin_shift;
82 u8 vlimitto_vddmax_shift;
83 u8 vlimitto_timeout_shift;
84 /* PRM_IRQSTATUS*/
85 u32 tranxdone_status;
86};
87
88/* Voltage controller registers and offsets */
89struct vc_reg_info {
90 /* PRM module */
91 u16 prm_mod;
92 /* VC register offsets */
93 u8 smps_sa_reg;
94 u8 smps_volra_reg;
95 u8 bypass_val_reg;
96 u8 cmdval_reg;
97 u8 voltsetup_reg;
98 /*VC_SMPS_SA*/
99 u8 smps_sa_shift;
100 u32 smps_sa_mask;
101 /* VC_SMPS_VOL_RA */
102 u8 smps_volra_shift;
103 u32 smps_volra_mask;
104 /* VC_BYPASS_VAL */
105 u8 data_shift;
106 u8 slaveaddr_shift;
107 u8 regaddr_shift;
108 u32 valid;
109 /* VC_CMD_VAL */
110 u8 cmd_on_shift;
111 u8 cmd_onlp_shift;
112 u8 cmd_ret_shift;
113 u8 cmd_off_shift;
114 u32 cmd_on_mask;
115 /* PRM_VOLTSETUP */
116 u8 voltsetup_shift;
117 u32 voltsetup_mask;
118};
119
120/**
121 * omap_vdd_info - Per Voltage Domain info
122 *
123 * @volt_data : voltage table having the distinct voltages supported
124 * by the domain and other associated per voltage data.
125 * @pmic_info : pmic specific parameters which should be populted by
126 * the pmic drivers.
127 * @vp_offs : structure containing the offsets for various
128 * vp registers
129 * @vp_reg : the register values, shifts, masks for various
130 * vp registers
131 * @vc_reg : structure containing various various vc registers,
132 * shifts, masks etc.
133 * @voltdm : pointer to the voltage domain structure
134 * @debug_dir : debug directory for this voltage domain.
135 * @curr_volt : current voltage for this vdd.
136 * @ocp_mod : The prm module for accessing the prm irqstatus reg.
137 * @prm_irqst_reg : prm irqstatus register.
138 * @vp_enabled : flag to keep track of whether vp is enabled or not
139 * @volt_scale : API to scale the voltage of the vdd.
140 */
141struct omap_vdd_info {
142 struct omap_volt_data *volt_data;
143 struct omap_volt_pmic_info *pmic_info;
144 struct vp_reg_offs vp_offs;
145 struct vp_reg_val vp_reg;
146 struct vc_reg_info vc_reg;
147 struct voltagedomain voltdm;
148 struct dentry *debug_dir;
149 u32 curr_volt;
150 u16 ocp_mod;
151 u8 prm_irqst_reg;
152 bool vp_enabled;
153 u32 (*read_reg) (u16 mod, u8 offset);
154 void (*write_reg) (u32 val, u16 mod, u8 offset);
155 int (*volt_scale) (struct omap_vdd_info *vdd,
156 unsigned long target_volt);
157};
158
159static struct omap_vdd_info *vdd_info;
160/*
161 * Number of scalable voltage domains.
162 */
163static int nr_scalable_vdd;
164
165/* OMAP3 VDD sturctures */
166static struct omap_vdd_info omap3_vdd_info[] = {
167 {
168 .vp_offs = {
169 .vpconfig = OMAP3_PRM_VP1_CONFIG_OFFSET,
170 .vstepmin = OMAP3_PRM_VP1_VSTEPMIN_OFFSET,
171 .vstepmax = OMAP3_PRM_VP1_VSTEPMAX_OFFSET,
172 .vlimitto = OMAP3_PRM_VP1_VLIMITTO_OFFSET,
173 .vstatus = OMAP3_PRM_VP1_STATUS_OFFSET,
174 .voltage = OMAP3_PRM_VP1_VOLTAGE_OFFSET,
175 },
176 .voltdm = {
177 .name = "mpu",
178 },
179 },
180 {
181 .vp_offs = {
182 .vpconfig = OMAP3_PRM_VP2_CONFIG_OFFSET,
183 .vstepmin = OMAP3_PRM_VP2_VSTEPMIN_OFFSET,
184 .vstepmax = OMAP3_PRM_VP2_VSTEPMAX_OFFSET,
185 .vlimitto = OMAP3_PRM_VP2_VLIMITTO_OFFSET,
186 .vstatus = OMAP3_PRM_VP2_STATUS_OFFSET,
187 .voltage = OMAP3_PRM_VP2_VOLTAGE_OFFSET,
188 },
189 .voltdm = {
190 .name = "core",
191 },
192 },
193};
194
195#define OMAP3_NR_SCALABLE_VDD ARRAY_SIZE(omap3_vdd_info)
196
197/* OMAP4 VDD sturctures */
198static struct omap_vdd_info omap4_vdd_info[] = {
199 {
200 .vp_offs = {
201 .vpconfig = OMAP4_PRM_VP_MPU_CONFIG_OFFSET,
202 .vstepmin = OMAP4_PRM_VP_MPU_VSTEPMIN_OFFSET,
203 .vstepmax = OMAP4_PRM_VP_MPU_VSTEPMAX_OFFSET,
204 .vlimitto = OMAP4_PRM_VP_MPU_VLIMITTO_OFFSET,
205 .vstatus = OMAP4_PRM_VP_MPU_STATUS_OFFSET,
206 .voltage = OMAP4_PRM_VP_MPU_VOLTAGE_OFFSET,
207 },
208 .voltdm = {
209 .name = "mpu",
210 },
211 },
212 {
213 .vp_offs = {
214 .vpconfig = OMAP4_PRM_VP_IVA_CONFIG_OFFSET,
215 .vstepmin = OMAP4_PRM_VP_IVA_VSTEPMIN_OFFSET,
216 .vstepmax = OMAP4_PRM_VP_IVA_VSTEPMAX_OFFSET,
217 .vlimitto = OMAP4_PRM_VP_IVA_VLIMITTO_OFFSET,
218 .vstatus = OMAP4_PRM_VP_IVA_STATUS_OFFSET,
219 .voltage = OMAP4_PRM_VP_IVA_VOLTAGE_OFFSET,
220 },
221 .voltdm = {
222 .name = "iva",
223 },
224 },
225 {
226 .vp_offs = {
227 .vpconfig = OMAP4_PRM_VP_CORE_CONFIG_OFFSET,
228 .vstepmin = OMAP4_PRM_VP_CORE_VSTEPMIN_OFFSET,
229 .vstepmax = OMAP4_PRM_VP_CORE_VSTEPMAX_OFFSET,
230 .vlimitto = OMAP4_PRM_VP_CORE_VLIMITTO_OFFSET,
231 .vstatus = OMAP4_PRM_VP_CORE_STATUS_OFFSET,
232 .voltage = OMAP4_PRM_VP_CORE_VOLTAGE_OFFSET,
233 },
234 .voltdm = {
235 .name = "core",
236 },
237 },
238};
239
240#define OMAP4_NR_SCALABLE_VDD ARRAY_SIZE(omap4_vdd_info)
241
242/*
243 * Structures containing OMAP3430/OMAP3630 voltage supported and various
244 * voltage dependent data for each VDD.
245 */
246#define VOLT_DATA_DEFINE(_v_nom, _efuse_offs, _errminlimit, _errgain) \
247{ \
248 .volt_nominal = _v_nom, \
249 .sr_efuse_offs = _efuse_offs, \
250 .sr_errminlimit = _errminlimit, \
251 .vp_errgain = _errgain \
252}
253
254/* VDD1 */
255static struct omap_volt_data omap34xx_vddmpu_volt_data[] = {
256 VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP1_UV, OMAP343X_CONTROL_FUSE_OPP1_VDD1, 0xf4, 0x0c),
257 VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP2_UV, OMAP343X_CONTROL_FUSE_OPP2_VDD1, 0xf4, 0x0c),
258 VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP3_UV, OMAP343X_CONTROL_FUSE_OPP3_VDD1, 0xf9, 0x18),
259 VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP4_UV, OMAP343X_CONTROL_FUSE_OPP4_VDD1, 0xf9, 0x18),
260 VOLT_DATA_DEFINE(OMAP3430_VDD_MPU_OPP5_UV, OMAP343X_CONTROL_FUSE_OPP5_VDD1, 0xf9, 0x18),
261 VOLT_DATA_DEFINE(0, 0, 0, 0),
262};
263
264static struct omap_volt_data omap36xx_vddmpu_volt_data[] = {
265 VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP50_UV, OMAP3630_CONTROL_FUSE_OPP50_VDD1, 0xf4, 0x0c),
266 VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD1, 0xf9, 0x16),
267 VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP120_UV, OMAP3630_CONTROL_FUSE_OPP120_VDD1, 0xfa, 0x23),
268 VOLT_DATA_DEFINE(OMAP3630_VDD_MPU_OPP1G_UV, OMAP3630_CONTROL_FUSE_OPP1G_VDD1, 0xfa, 0x27),
269 VOLT_DATA_DEFINE(0, 0, 0, 0),
270};
271
272/* VDD2 */
273static struct omap_volt_data omap34xx_vddcore_volt_data[] = {
274 VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP1_UV, OMAP343X_CONTROL_FUSE_OPP1_VDD2, 0xf4, 0x0c),
275 VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP2_UV, OMAP343X_CONTROL_FUSE_OPP2_VDD2, 0xf4, 0x0c),
276 VOLT_DATA_DEFINE(OMAP3430_VDD_CORE_OPP3_UV, OMAP343X_CONTROL_FUSE_OPP3_VDD2, 0xf9, 0x18),
277 VOLT_DATA_DEFINE(0, 0, 0, 0),
278};
279
280static struct omap_volt_data omap36xx_vddcore_volt_data[] = {
281 VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP50_UV, OMAP3630_CONTROL_FUSE_OPP50_VDD2, 0xf4, 0x0c),
282 VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD2, 0xf9, 0x16),
283 VOLT_DATA_DEFINE(0, 0, 0, 0),
284};
285
286/*
287 * Structures containing OMAP4430 voltage supported and various
288 * voltage dependent data for each VDD.
289 */
290static struct omap_volt_data omap44xx_vdd_mpu_volt_data[] = {
291 VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP50_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP50, 0xf4, 0x0c),
292 VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPP100_UV, OMAP44XX_CONTROL_FUSE_MPU_OPP100, 0xf9, 0x16),
293 VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPTURBO, 0xfa, 0x23),
294 VOLT_DATA_DEFINE(OMAP4430_VDD_MPU_OPPNITRO_UV, OMAP44XX_CONTROL_FUSE_MPU_OPPNITRO, 0xfa, 0x27),
295 VOLT_DATA_DEFINE(0, 0, 0, 0),
296};
297
298static struct omap_volt_data omap44xx_vdd_iva_volt_data[] = {
299 VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP50_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP50, 0xf4, 0x0c),
300 VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPP100_UV, OMAP44XX_CONTROL_FUSE_IVA_OPP100, 0xf9, 0x16),
301 VOLT_DATA_DEFINE(OMAP4430_VDD_IVA_OPPTURBO_UV, OMAP44XX_CONTROL_FUSE_IVA_OPPTURBO, 0xfa, 0x23),
302 VOLT_DATA_DEFINE(0, 0, 0, 0),
303};
304
305static struct omap_volt_data omap44xx_vdd_core_volt_data[] = {
306 VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP50_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP50, 0xf4, 0x0c),
307 VOLT_DATA_DEFINE(OMAP4430_VDD_CORE_OPP100_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100, 0xf9, 0x16),
308 VOLT_DATA_DEFINE(0, 0, 0, 0),
309};
310
311static struct dentry *voltage_dir;
312
313/* Init function pointers */
314static void (*vc_init) (struct omap_vdd_info *vdd);
315static int (*vdd_data_configure) (struct omap_vdd_info *vdd);
316
317static u32 omap3_voltage_read_reg(u16 mod, u8 offset)
318{
319 return omap2_prm_read_mod_reg(mod, offset);
320}
321
322static void omap3_voltage_write_reg(u32 val, u16 mod, u8 offset)
323{
324 omap2_prm_write_mod_reg(val, mod, offset);
325}
326
327static u32 omap4_voltage_read_reg(u16 mod, u8 offset)
328{
329 return omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
330 mod, offset);
331}
332
333static void omap4_voltage_write_reg(u32 val, u16 mod, u8 offset)
334{
335 omap4_prminst_write_inst_reg(val, OMAP4430_PRM_PARTITION, mod, offset);
336}
337
338/* Voltage debugfs support */
339static int vp_volt_debug_get(void *data, u64 *val)
340{
341 struct omap_vdd_info *vdd = (struct omap_vdd_info *) data;
342 u8 vsel;
343
344 if (!vdd) {
345 pr_warning("Wrong paramater passed\n");
346 return -EINVAL;
347 }
348
349 vsel = vdd->read_reg(vdd->vp_reg.prm_mod, vdd->vp_offs.voltage);
350 pr_notice("curr_vsel = %x\n", vsel);
351
352 if (!vdd->pmic_info->vsel_to_uv) {
353 pr_warning("PMIC function to convert vsel to voltage"
354 "in uV not registerd\n");
355 return -EINVAL;
356 }
357
358 *val = vdd->pmic_info->vsel_to_uv(vsel);
359 return 0;
360}
361
362static int nom_volt_debug_get(void *data, u64 *val)
363{
364 struct omap_vdd_info *vdd = (struct omap_vdd_info *) data;
365
366 if (!vdd) {
367 pr_warning("Wrong paramater passed\n");
368 return -EINVAL;
369 }
370
371 *val = omap_voltage_get_nom_volt(&vdd->voltdm);
372
373 return 0;
374}
375
376DEFINE_SIMPLE_ATTRIBUTE(vp_volt_debug_fops, vp_volt_debug_get, NULL, "%llu\n");
377DEFINE_SIMPLE_ATTRIBUTE(nom_volt_debug_fops, nom_volt_debug_get, NULL,
378 "%llu\n");
379static void vp_latch_vsel(struct omap_vdd_info *vdd)
380{
381 u32 vpconfig;
382 u16 mod;
383 unsigned long uvdc;
384 char vsel;
385
386 uvdc = omap_voltage_get_nom_volt(&vdd->voltdm);
387 if (!uvdc) {
388 pr_warning("%s: unable to find current voltage for vdd_%s\n",
389 __func__, vdd->voltdm.name);
390 return;
391 }
392
393 if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) {
394 pr_warning("%s: PMIC function to convert voltage in uV to"
395 " vsel not registered\n", __func__);
396 return;
397 }
398
399 mod = vdd->vp_reg.prm_mod;
400
401 vsel = vdd->pmic_info->uv_to_vsel(uvdc);
402
403 vpconfig = vdd->read_reg(mod, vdd->vp_offs.vpconfig);
404 vpconfig &= ~(vdd->vp_reg.vpconfig_initvoltage_mask |
405 vdd->vp_reg.vpconfig_initvdd);
406 vpconfig |= vsel << vdd->vp_reg.vpconfig_initvoltage_shift;
407
408 vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
409
410 /* Trigger initVDD value copy to voltage processor */
411 vdd->write_reg((vpconfig | vdd->vp_reg.vpconfig_initvdd), mod,
412 vdd->vp_offs.vpconfig);
413
414 /* Clear initVDD copy trigger bit */
415 vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
416}
417
418/* Generic voltage init functions */
419static void __init vp_init(struct omap_vdd_info *vdd)
420{
421 u32 vp_val;
422 u16 mod;
423
424 if (!vdd->read_reg || !vdd->write_reg) {
425 pr_err("%s: No read/write API for accessing vdd_%s regs\n",
426 __func__, vdd->voltdm.name);
427 return;
428 }
429
430 mod = vdd->vp_reg.prm_mod;
431
432 vp_val = vdd->vp_reg.vpconfig_erroroffset |
433 (vdd->vp_reg.vpconfig_errorgain <<
434 vdd->vp_reg.vpconfig_errorgain_shift) |
435 vdd->vp_reg.vpconfig_timeouten;
436 vdd->write_reg(vp_val, mod, vdd->vp_offs.vpconfig);
437
438 vp_val = ((vdd->vp_reg.vstepmin_smpswaittimemin <<
439 vdd->vp_reg.vstepmin_smpswaittimemin_shift) |
440 (vdd->vp_reg.vstepmin_stepmin <<
441 vdd->vp_reg.vstepmin_stepmin_shift));
442 vdd->write_reg(vp_val, mod, vdd->vp_offs.vstepmin);
443
444 vp_val = ((vdd->vp_reg.vstepmax_smpswaittimemax <<
445 vdd->vp_reg.vstepmax_smpswaittimemax_shift) |
446 (vdd->vp_reg.vstepmax_stepmax <<
447 vdd->vp_reg.vstepmax_stepmax_shift));
448 vdd->write_reg(vp_val, mod, vdd->vp_offs.vstepmax);
449
450 vp_val = ((vdd->vp_reg.vlimitto_vddmax <<
451 vdd->vp_reg.vlimitto_vddmax_shift) |
452 (vdd->vp_reg.vlimitto_vddmin <<
453 vdd->vp_reg.vlimitto_vddmin_shift) |
454 (vdd->vp_reg.vlimitto_timeout <<
455 vdd->vp_reg.vlimitto_timeout_shift));
456 vdd->write_reg(vp_val, mod, vdd->vp_offs.vlimitto);
457}
458
459static void __init vdd_debugfs_init(struct omap_vdd_info *vdd)
460{
461 char *name;
462
463 name = kzalloc(VOLTAGE_DIR_SIZE, GFP_KERNEL);
464 if (!name) {
465 pr_warning("%s: Unable to allocate memory for debugfs"
466 " directory name for vdd_%s",
467 __func__, vdd->voltdm.name);
468 return;
469 }
470 strcpy(name, "vdd_");
471 strcat(name, vdd->voltdm.name);
472
473 vdd->debug_dir = debugfs_create_dir(name, voltage_dir);
474 if (IS_ERR(vdd->debug_dir)) {
475 pr_warning("%s: Unable to create debugfs directory for"
476 " vdd_%s\n", __func__, vdd->voltdm.name);
477 vdd->debug_dir = NULL;
478 return;
479 }
480
481 (void) debugfs_create_x16("vp_errorgain", S_IRUGO, vdd->debug_dir,
482 &(vdd->vp_reg.vpconfig_errorgain));
483 (void) debugfs_create_x16("vp_smpswaittimemin", S_IRUGO,
484 vdd->debug_dir,
485 &(vdd->vp_reg.vstepmin_smpswaittimemin));
486 (void) debugfs_create_x8("vp_stepmin", S_IRUGO, vdd->debug_dir,
487 &(vdd->vp_reg.vstepmin_stepmin));
488 (void) debugfs_create_x16("vp_smpswaittimemax", S_IRUGO,
489 vdd->debug_dir,
490 &(vdd->vp_reg.vstepmax_smpswaittimemax));
491 (void) debugfs_create_x8("vp_stepmax", S_IRUGO, vdd->debug_dir,
492 &(vdd->vp_reg.vstepmax_stepmax));
493 (void) debugfs_create_x8("vp_vddmax", S_IRUGO, vdd->debug_dir,
494 &(vdd->vp_reg.vlimitto_vddmax));
495 (void) debugfs_create_x8("vp_vddmin", S_IRUGO, vdd->debug_dir,
496 &(vdd->vp_reg.vlimitto_vddmin));
497 (void) debugfs_create_x16("vp_timeout", S_IRUGO, vdd->debug_dir,
498 &(vdd->vp_reg.vlimitto_timeout));
499 (void) debugfs_create_file("curr_vp_volt", S_IRUGO, vdd->debug_dir,
500 (void *) vdd, &vp_volt_debug_fops);
501 (void) debugfs_create_file("curr_nominal_volt", S_IRUGO,
502 vdd->debug_dir, (void *) vdd,
503 &nom_volt_debug_fops);
504}
505
506/* Voltage scale and accessory APIs */
507static int _pre_volt_scale(struct omap_vdd_info *vdd,
508 unsigned long target_volt, u8 *target_vsel, u8 *current_vsel)
509{
510 struct omap_volt_data *volt_data;
511 u32 vc_cmdval, vp_errgain_val;
512 u16 vp_mod, vc_mod;
513
514 /* Check if suffiecient pmic info is available for this vdd */
515 if (!vdd->pmic_info) {
516 pr_err("%s: Insufficient pmic info to scale the vdd_%s\n",
517 __func__, vdd->voltdm.name);
518 return -EINVAL;
519 }
520
521 if (!vdd->pmic_info->uv_to_vsel) {
522 pr_err("%s: PMIC function to convert voltage in uV to"
523 "vsel not registered. Hence unable to scale voltage"
524 "for vdd_%s\n", __func__, vdd->voltdm.name);
525 return -ENODATA;
526 }
527
528 if (!vdd->read_reg || !vdd->write_reg) {
529 pr_err("%s: No read/write API for accessing vdd_%s regs\n",
530 __func__, vdd->voltdm.name);
531 return -EINVAL;
532 }
533
534 vp_mod = vdd->vp_reg.prm_mod;
535 vc_mod = vdd->vc_reg.prm_mod;
536
537 /* Get volt_data corresponding to target_volt */
538 volt_data = omap_voltage_get_voltdata(&vdd->voltdm, target_volt);
539 if (IS_ERR(volt_data))
540 volt_data = NULL;
541
542 *target_vsel = vdd->pmic_info->uv_to_vsel(target_volt);
543 *current_vsel = vdd->read_reg(vp_mod, vdd->vp_offs.voltage);
544
545 /* Setting the ON voltage to the new target voltage */
546 vc_cmdval = vdd->read_reg(vc_mod, vdd->vc_reg.cmdval_reg);
547 vc_cmdval &= ~vdd->vc_reg.cmd_on_mask;
548 vc_cmdval |= (*target_vsel << vdd->vc_reg.cmd_on_shift);
549 vdd->write_reg(vc_cmdval, vc_mod, vdd->vc_reg.cmdval_reg);
550
551 /* Setting vp errorgain based on the voltage */
552 if (volt_data) {
553 vp_errgain_val = vdd->read_reg(vp_mod,
554 vdd->vp_offs.vpconfig);
555 vdd->vp_reg.vpconfig_errorgain = volt_data->vp_errgain;
556 vp_errgain_val &= ~vdd->vp_reg.vpconfig_errorgain_mask;
557 vp_errgain_val |= vdd->vp_reg.vpconfig_errorgain <<
558 vdd->vp_reg.vpconfig_errorgain_shift;
559 vdd->write_reg(vp_errgain_val, vp_mod,
560 vdd->vp_offs.vpconfig);
561 }
562
563 return 0;
564}
565
566static void _post_volt_scale(struct omap_vdd_info *vdd,
567 unsigned long target_volt, u8 target_vsel, u8 current_vsel)
568{
569 u32 smps_steps = 0, smps_delay = 0;
570
571 smps_steps = abs(target_vsel - current_vsel);
572 /* SMPS slew rate / step size. 2us added as buffer. */
573 smps_delay = ((smps_steps * vdd->pmic_info->step_size) /
574 vdd->pmic_info->slew_rate) + 2;
575 udelay(smps_delay);
576
577 vdd->curr_volt = target_volt;
578}
579
580/* vc_bypass_scale_voltage - VC bypass method of voltage scaling */
581static int vc_bypass_scale_voltage(struct omap_vdd_info *vdd,
582 unsigned long target_volt)
583{
584 u32 loop_cnt = 0, retries_cnt = 0;
585 u32 vc_valid, vc_bypass_val_reg, vc_bypass_value;
586 u16 mod;
587 u8 target_vsel, current_vsel;
588 int ret;
589
590 ret = _pre_volt_scale(vdd, target_volt, &target_vsel, &current_vsel);
591 if (ret)
592 return ret;
593
594 mod = vdd->vc_reg.prm_mod;
595
596 vc_valid = vdd->vc_reg.valid;
597 vc_bypass_val_reg = vdd->vc_reg.bypass_val_reg;
598 vc_bypass_value = (target_vsel << vdd->vc_reg.data_shift) |
599 (vdd->pmic_info->pmic_reg <<
600 vdd->vc_reg.regaddr_shift) |
601 (vdd->pmic_info->i2c_slave_addr <<
602 vdd->vc_reg.slaveaddr_shift);
603
604 vdd->write_reg(vc_bypass_value, mod, vc_bypass_val_reg);
605 vdd->write_reg(vc_bypass_value | vc_valid, mod, vc_bypass_val_reg);
606
607 vc_bypass_value = vdd->read_reg(mod, vc_bypass_val_reg);
608 /*
609 * Loop till the bypass command is acknowledged from the SMPS.
610 * NOTE: This is legacy code. The loop count and retry count needs
611 * to be revisited.
612 */
613 while (!(vc_bypass_value & vc_valid)) {
614 loop_cnt++;
615
616 if (retries_cnt > 10) {
617 pr_warning("%s: Retry count exceeded\n", __func__);
618 return -ETIMEDOUT;
619 }
620
621 if (loop_cnt > 50) {
622 retries_cnt++;
623 loop_cnt = 0;
624 udelay(10);
625 }
626 vc_bypass_value = vdd->read_reg(mod, vc_bypass_val_reg);
627 }
628
629 _post_volt_scale(vdd, target_volt, target_vsel, current_vsel);
630 return 0;
631}
632
633/* VP force update method of voltage scaling */
634static int vp_forceupdate_scale_voltage(struct omap_vdd_info *vdd,
635 unsigned long target_volt)
636{
637 u32 vpconfig;
638 u16 mod, ocp_mod;
639 u8 target_vsel, current_vsel, prm_irqst_reg;
640 int ret, timeout = 0;
641
642 ret = _pre_volt_scale(vdd, target_volt, &target_vsel, &current_vsel);
643 if (ret)
644 return ret;
645
646 mod = vdd->vp_reg.prm_mod;
647 ocp_mod = vdd->ocp_mod;
648 prm_irqst_reg = vdd->prm_irqst_reg;
649
650 /*
651 * Clear all pending TransactionDone interrupt/status. Typical latency
652 * is <3us
653 */
654 while (timeout++ < VP_TRANXDONE_TIMEOUT) {
655 vdd->write_reg(vdd->vp_reg.tranxdone_status,
656 ocp_mod, prm_irqst_reg);
657 if (!(vdd->read_reg(ocp_mod, prm_irqst_reg) &
658 vdd->vp_reg.tranxdone_status))
659 break;
660 udelay(1);
661 }
662 if (timeout >= VP_TRANXDONE_TIMEOUT) {
663 pr_warning("%s: vdd_%s TRANXDONE timeout exceeded."
664 "Voltage change aborted", __func__, vdd->voltdm.name);
665 return -ETIMEDOUT;
666 }
667
668 /* Configure for VP-Force Update */
669 vpconfig = vdd->read_reg(mod, vdd->vp_offs.vpconfig);
670 vpconfig &= ~(vdd->vp_reg.vpconfig_initvdd |
671 vdd->vp_reg.vpconfig_forceupdate |
672 vdd->vp_reg.vpconfig_initvoltage_mask);
673 vpconfig |= ((target_vsel <<
674 vdd->vp_reg.vpconfig_initvoltage_shift));
675 vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
676
677 /* Trigger initVDD value copy to voltage processor */
678 vpconfig |= vdd->vp_reg.vpconfig_initvdd;
679 vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
680
681 /* Force update of voltage */
682 vpconfig |= vdd->vp_reg.vpconfig_forceupdate;
683 vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
684
685 /*
686 * Wait for TransactionDone. Typical latency is <200us.
687 * Depends on SMPSWAITTIMEMIN/MAX and voltage change
688 */
689 timeout = 0;
690 omap_test_timeout((vdd->read_reg(ocp_mod, prm_irqst_reg) &
691 vdd->vp_reg.tranxdone_status),
692 VP_TRANXDONE_TIMEOUT, timeout);
693 if (timeout >= VP_TRANXDONE_TIMEOUT)
694 pr_err("%s: vdd_%s TRANXDONE timeout exceeded."
695 "TRANXDONE never got set after the voltage update\n",
696 __func__, vdd->voltdm.name);
697
698 _post_volt_scale(vdd, target_volt, target_vsel, current_vsel);
699
700 /*
701 * Disable TransactionDone interrupt , clear all status, clear
702 * control registers
703 */
704 timeout = 0;
705 while (timeout++ < VP_TRANXDONE_TIMEOUT) {
706 vdd->write_reg(vdd->vp_reg.tranxdone_status,
707 ocp_mod, prm_irqst_reg);
708 if (!(vdd->read_reg(ocp_mod, prm_irqst_reg) &
709 vdd->vp_reg.tranxdone_status))
710 break;
711 udelay(1);
712 }
713
714 if (timeout >= VP_TRANXDONE_TIMEOUT)
715 pr_warning("%s: vdd_%s TRANXDONE timeout exceeded while trying"
716 "to clear the TRANXDONE status\n",
717 __func__, vdd->voltdm.name);
718
719 vpconfig = vdd->read_reg(mod, vdd->vp_offs.vpconfig);
720 /* Clear initVDD copy trigger bit */
721 vpconfig &= ~vdd->vp_reg.vpconfig_initvdd;;
722 vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
723 /* Clear force bit */
724 vpconfig &= ~vdd->vp_reg.vpconfig_forceupdate;
725 vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
726
727 return 0;
728}
729
730/* OMAP3 specific voltage init functions */
731
732/*
733 * Intializes the voltage controller registers with the PMIC and board
734 * specific parameters and voltage setup times for OMAP3.
735 */
736static void __init omap3_vc_init(struct omap_vdd_info *vdd)
737{
738 u32 vc_val;
739 u16 mod;
740 u8 on_vsel, onlp_vsel, ret_vsel, off_vsel;
741 static bool is_initialized;
742
743 if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) {
744 pr_err("%s: PMIC info requried to configure vc for"
745 "vdd_%s not populated.Hence cannot initialize vc\n",
746 __func__, vdd->voltdm.name);
747 return;
748 }
749
750 if (!vdd->read_reg || !vdd->write_reg) {
751 pr_err("%s: No read/write API for accessing vdd_%s regs\n",
752 __func__, vdd->voltdm.name);
753 return;
754 }
755
756 mod = vdd->vc_reg.prm_mod;
757
758 /* Set up the SMPS_SA(i2c slave address in VC */
759 vc_val = vdd->read_reg(mod, vdd->vc_reg.smps_sa_reg);
760 vc_val &= ~vdd->vc_reg.smps_sa_mask;
761 vc_val |= vdd->pmic_info->i2c_slave_addr << vdd->vc_reg.smps_sa_shift;
762 vdd->write_reg(vc_val, mod, vdd->vc_reg.smps_sa_reg);
763
764 /* Setup the VOLRA(pmic reg addr) in VC */
765 vc_val = vdd->read_reg(mod, vdd->vc_reg.smps_volra_reg);
766 vc_val &= ~vdd->vc_reg.smps_volra_mask;
767 vc_val |= vdd->pmic_info->pmic_reg << vdd->vc_reg.smps_volra_shift;
768 vdd->write_reg(vc_val, mod, vdd->vc_reg.smps_volra_reg);
769
770 /*Configure the setup times */
771 vc_val = vdd->read_reg(mod, vdd->vc_reg.voltsetup_reg);
772 vc_val &= ~vdd->vc_reg.voltsetup_mask;
773 vc_val |= vdd->pmic_info->volt_setup_time <<
774 vdd->vc_reg.voltsetup_shift;
775 vdd->write_reg(vc_val, mod, vdd->vc_reg.voltsetup_reg);
776
777 /* Set up the on, inactive, retention and off voltage */
778 on_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->on_volt);
779 onlp_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->onlp_volt);
780 ret_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->ret_volt);
781 off_vsel = vdd->pmic_info->uv_to_vsel(vdd->pmic_info->off_volt);
782 vc_val = ((on_vsel << vdd->vc_reg.cmd_on_shift) |
783 (onlp_vsel << vdd->vc_reg.cmd_onlp_shift) |
784 (ret_vsel << vdd->vc_reg.cmd_ret_shift) |
785 (off_vsel << vdd->vc_reg.cmd_off_shift));
786 vdd->write_reg(vc_val, mod, vdd->vc_reg.cmdval_reg);
787
788 if (is_initialized)
789 return;
790
791 /* Generic VC parameters init */
792 vdd->write_reg(OMAP3430_CMD1_MASK | OMAP3430_RAV1_MASK, mod,
793 OMAP3_PRM_VC_CH_CONF_OFFSET);
794 vdd->write_reg(OMAP3430_MCODE_SHIFT | OMAP3430_HSEN_MASK, mod,
795 OMAP3_PRM_VC_I2C_CFG_OFFSET);
796 vdd->write_reg(OMAP3_CLKSETUP, mod, OMAP3_PRM_CLKSETUP_OFFSET);
797 vdd->write_reg(OMAP3_VOLTOFFSET, mod, OMAP3_PRM_VOLTOFFSET_OFFSET);
798 vdd->write_reg(OMAP3_VOLTSETUP2, mod, OMAP3_PRM_VOLTSETUP2_OFFSET);
799 is_initialized = true;
800}
801
802/* Sets up all the VDD related info for OMAP3 */
803static int __init omap3_vdd_data_configure(struct omap_vdd_info *vdd)
804{
805 struct clk *sys_ck;
806 u32 sys_clk_speed, timeout_val, waittime;
807
808 if (!vdd->pmic_info) {
809 pr_err("%s: PMIC info requried to configure vdd_%s not"
810 "populated.Hence cannot initialize vdd_%s\n",
811 __func__, vdd->voltdm.name, vdd->voltdm.name);
812 return -EINVAL;
813 }
814
815 if (!strcmp(vdd->voltdm.name, "mpu")) {
816 if (cpu_is_omap3630())
817 vdd->volt_data = omap36xx_vddmpu_volt_data;
818 else
819 vdd->volt_data = omap34xx_vddmpu_volt_data;
820
821 vdd->vp_reg.tranxdone_status = OMAP3430_VP1_TRANXDONE_ST_MASK;
822 vdd->vc_reg.cmdval_reg = OMAP3_PRM_VC_CMD_VAL_0_OFFSET;
823 vdd->vc_reg.smps_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA0_SHIFT;
824 vdd->vc_reg.smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA0_MASK;
825 vdd->vc_reg.smps_volra_shift = OMAP3430_VOLRA0_SHIFT;
826 vdd->vc_reg.smps_volra_mask = OMAP3430_VOLRA0_MASK;
827 vdd->vc_reg.voltsetup_shift = OMAP3430_SETUP_TIME1_SHIFT;
828 vdd->vc_reg.voltsetup_mask = OMAP3430_SETUP_TIME1_MASK;
829 } else if (!strcmp(vdd->voltdm.name, "core")) {
830 if (cpu_is_omap3630())
831 vdd->volt_data = omap36xx_vddcore_volt_data;
832 else
833 vdd->volt_data = omap34xx_vddcore_volt_data;
834
835 vdd->vp_reg.tranxdone_status = OMAP3430_VP2_TRANXDONE_ST_MASK;
836 vdd->vc_reg.cmdval_reg = OMAP3_PRM_VC_CMD_VAL_1_OFFSET;
837 vdd->vc_reg.smps_sa_shift = OMAP3430_PRM_VC_SMPS_SA_SA1_SHIFT;
838 vdd->vc_reg.smps_sa_mask = OMAP3430_PRM_VC_SMPS_SA_SA1_MASK;
839 vdd->vc_reg.smps_volra_shift = OMAP3430_VOLRA1_SHIFT;
840 vdd->vc_reg.smps_volra_mask = OMAP3430_VOLRA1_MASK;
841 vdd->vc_reg.voltsetup_shift = OMAP3430_SETUP_TIME2_SHIFT;
842 vdd->vc_reg.voltsetup_mask = OMAP3430_SETUP_TIME2_MASK;
843 } else {
844 pr_warning("%s: vdd_%s does not exisit in OMAP3\n",
845 __func__, vdd->voltdm.name);
846 return -EINVAL;
847 }
848
849 /*
850 * Sys clk rate is require to calculate vp timeout value and
851 * smpswaittimemin and smpswaittimemax.
852 */
853 sys_ck = clk_get(NULL, "sys_ck");
854 if (IS_ERR(sys_ck)) {
855 pr_warning("%s: Could not get the sys clk to calculate"
856 "various vdd_%s params\n", __func__, vdd->voltdm.name);
857 return -EINVAL;
858 }
859 sys_clk_speed = clk_get_rate(sys_ck);
860 clk_put(sys_ck);
861 /* Divide to avoid overflow */
862 sys_clk_speed /= 1000;
863
864 /* Generic voltage parameters */
865 vdd->curr_volt = 1200000;
866 vdd->ocp_mod = OCP_MOD;
867 vdd->prm_irqst_reg = OMAP3_PRM_IRQSTATUS_MPU_OFFSET;
868 vdd->read_reg = omap3_voltage_read_reg;
869 vdd->write_reg = omap3_voltage_write_reg;
870 vdd->volt_scale = vp_forceupdate_scale_voltage;
871 vdd->vp_enabled = false;
872
873 /* VC parameters */
874 vdd->vc_reg.prm_mod = OMAP3430_GR_MOD;
875 vdd->vc_reg.smps_sa_reg = OMAP3_PRM_VC_SMPS_SA_OFFSET;
876 vdd->vc_reg.smps_volra_reg = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET;
877 vdd->vc_reg.bypass_val_reg = OMAP3_PRM_VC_BYPASS_VAL_OFFSET;
878 vdd->vc_reg.voltsetup_reg = OMAP3_PRM_VOLTSETUP1_OFFSET;
879 vdd->vc_reg.data_shift = OMAP3430_DATA_SHIFT;
880 vdd->vc_reg.slaveaddr_shift = OMAP3430_SLAVEADDR_SHIFT;
881 vdd->vc_reg.regaddr_shift = OMAP3430_REGADDR_SHIFT;
882 vdd->vc_reg.valid = OMAP3430_VALID_MASK;
883 vdd->vc_reg.cmd_on_shift = OMAP3430_VC_CMD_ON_SHIFT;
884 vdd->vc_reg.cmd_on_mask = OMAP3430_VC_CMD_ON_MASK;
885 vdd->vc_reg.cmd_onlp_shift = OMAP3430_VC_CMD_ONLP_SHIFT;
886 vdd->vc_reg.cmd_ret_shift = OMAP3430_VC_CMD_RET_SHIFT;
887 vdd->vc_reg.cmd_off_shift = OMAP3430_VC_CMD_OFF_SHIFT;
888
889 vdd->vp_reg.prm_mod = OMAP3430_GR_MOD;
890
891 /* VPCONFIG bit fields */
892 vdd->vp_reg.vpconfig_erroroffset = (vdd->pmic_info->vp_erroroffset <<
893 OMAP3430_ERROROFFSET_SHIFT);
894 vdd->vp_reg.vpconfig_errorgain_mask = OMAP3430_ERRORGAIN_MASK;
895 vdd->vp_reg.vpconfig_errorgain_shift = OMAP3430_ERRORGAIN_SHIFT;
896 vdd->vp_reg.vpconfig_initvoltage_shift = OMAP3430_INITVOLTAGE_SHIFT;
897 vdd->vp_reg.vpconfig_initvoltage_mask = OMAP3430_INITVOLTAGE_MASK;
898 vdd->vp_reg.vpconfig_timeouten = OMAP3430_TIMEOUTEN_MASK;
899 vdd->vp_reg.vpconfig_initvdd = OMAP3430_INITVDD_MASK;
900 vdd->vp_reg.vpconfig_forceupdate = OMAP3430_FORCEUPDATE_MASK;
901 vdd->vp_reg.vpconfig_vpenable = OMAP3430_VPENABLE_MASK;
902
903 /* VSTEPMIN VSTEPMAX bit fields */
904 waittime = ((vdd->pmic_info->step_size / vdd->pmic_info->slew_rate) *
905 sys_clk_speed) / 1000;
906 vdd->vp_reg.vstepmin_smpswaittimemin = waittime;
907 vdd->vp_reg.vstepmax_smpswaittimemax = waittime;
908 vdd->vp_reg.vstepmin_stepmin = vdd->pmic_info->vp_vstepmin;
909 vdd->vp_reg.vstepmax_stepmax = vdd->pmic_info->vp_vstepmax;
910 vdd->vp_reg.vstepmin_smpswaittimemin_shift =
911 OMAP3430_SMPSWAITTIMEMIN_SHIFT;
912 vdd->vp_reg.vstepmax_smpswaittimemax_shift =
913 OMAP3430_SMPSWAITTIMEMAX_SHIFT;
914 vdd->vp_reg.vstepmin_stepmin_shift = OMAP3430_VSTEPMIN_SHIFT;
915 vdd->vp_reg.vstepmax_stepmax_shift = OMAP3430_VSTEPMAX_SHIFT;
916
917 /* VLIMITTO bit fields */
918 timeout_val = (sys_clk_speed * vdd->pmic_info->vp_timeout_us) / 1000;
919 vdd->vp_reg.vlimitto_timeout = timeout_val;
920 vdd->vp_reg.vlimitto_vddmin = vdd->pmic_info->vp_vddmin;
921 vdd->vp_reg.vlimitto_vddmax = vdd->pmic_info->vp_vddmax;
922 vdd->vp_reg.vlimitto_vddmin_shift = OMAP3430_VDDMIN_SHIFT;
923 vdd->vp_reg.vlimitto_vddmax_shift = OMAP3430_VDDMAX_SHIFT;
924 vdd->vp_reg.vlimitto_timeout_shift = OMAP3430_TIMEOUT_SHIFT;
925
926 return 0;
927}
928
929/* OMAP4 specific voltage init functions */
930static void __init omap4_vc_init(struct omap_vdd_info *vdd)
931{
932 u32 vc_val;
933 u16 mod;
934 static bool is_initialized;
935
936 if (!vdd->pmic_info || !vdd->pmic_info->uv_to_vsel) {
937 pr_err("%s: PMIC info requried to configure vc for"
938 "vdd_%s not populated.Hence cannot initialize vc\n",
939 __func__, vdd->voltdm.name);
940 return;
941 }
942
943 if (!vdd->read_reg || !vdd->write_reg) {
944 pr_err("%s: No read/write API for accessing vdd_%s regs\n",
945 __func__, vdd->voltdm.name);
946 return;
947 }
948
949 mod = vdd->vc_reg.prm_mod;
950
951 /* Set up the SMPS_SA(i2c slave address in VC */
952 vc_val = vdd->read_reg(mod, vdd->vc_reg.smps_sa_reg);
953 vc_val &= ~vdd->vc_reg.smps_sa_mask;
954 vc_val |= vdd->pmic_info->i2c_slave_addr << vdd->vc_reg.smps_sa_shift;
955 vdd->write_reg(vc_val, mod, vdd->vc_reg.smps_sa_reg);
956
957 /* Setup the VOLRA(pmic reg addr) in VC */
958 vc_val = vdd->read_reg(mod, vdd->vc_reg.smps_volra_reg);
959 vc_val &= ~vdd->vc_reg.smps_volra_mask;
960 vc_val |= vdd->pmic_info->pmic_reg << vdd->vc_reg.smps_volra_shift;
961 vdd->write_reg(vc_val, mod, vdd->vc_reg.smps_volra_reg);
962
963 /* TODO: Configure setup times and CMD_VAL values*/
964
965 if (is_initialized)
966 return;
967
968 /* Generic VC parameters init */
969 vc_val = (OMAP4430_RAV_VDD_MPU_L_MASK | OMAP4430_CMD_VDD_MPU_L_MASK |
970 OMAP4430_RAV_VDD_IVA_L_MASK | OMAP4430_CMD_VDD_IVA_L_MASK |
971 OMAP4430_RAV_VDD_CORE_L_MASK | OMAP4430_CMD_VDD_CORE_L_MASK);
972 vdd->write_reg(vc_val, mod, OMAP4_PRM_VC_CFG_CHANNEL_OFFSET);
973
974 vc_val = (0x60 << OMAP4430_SCLL_SHIFT | 0x26 << OMAP4430_SCLH_SHIFT);
975 vdd->write_reg(vc_val, mod, OMAP4_PRM_VC_CFG_I2C_CLK_OFFSET);
976
977 is_initialized = true;
978}
979
980/* Sets up all the VDD related info for OMAP4 */
981static int __init omap4_vdd_data_configure(struct omap_vdd_info *vdd)
982{
983 struct clk *sys_ck;
984 u32 sys_clk_speed, timeout_val, waittime;
985
986 if (!vdd->pmic_info) {
987 pr_err("%s: PMIC info requried to configure vdd_%s not"
988 "populated.Hence cannot initialize vdd_%s\n",
989 __func__, vdd->voltdm.name, vdd->voltdm.name);
990 return -EINVAL;
991 }
992
993 if (!strcmp(vdd->voltdm.name, "mpu")) {
994 vdd->volt_data = omap44xx_vdd_mpu_volt_data;
995 vdd->vp_reg.tranxdone_status =
996 OMAP4430_VP_MPU_TRANXDONE_ST_MASK;
997 vdd->vc_reg.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_MPU_L_OFFSET;
998 vdd->vc_reg.smps_sa_shift =
999 OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_SHIFT;
1000 vdd->vc_reg.smps_sa_mask =
1001 OMAP4430_SA_VDD_MPU_L_PRM_VC_SMPS_SA_MASK;
1002 vdd->vc_reg.smps_volra_shift = OMAP4430_VOLRA_VDD_MPU_L_SHIFT;
1003 vdd->vc_reg.smps_volra_mask = OMAP4430_VOLRA_VDD_MPU_L_MASK;
1004 vdd->vc_reg.voltsetup_reg =
1005 OMAP4_PRM_VOLTSETUP_MPU_RET_SLEEP_OFFSET;
1006 vdd->prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET;
1007 } else if (!strcmp(vdd->voltdm.name, "core")) {
1008 vdd->volt_data = omap44xx_vdd_core_volt_data;
1009 vdd->vp_reg.tranxdone_status =
1010 OMAP4430_VP_CORE_TRANXDONE_ST_MASK;
1011 vdd->vc_reg.cmdval_reg =
1012 OMAP4_PRM_VC_VAL_CMD_VDD_CORE_L_OFFSET;
1013 vdd->vc_reg.smps_sa_shift = OMAP4430_SA_VDD_CORE_L_0_6_SHIFT;
1014 vdd->vc_reg.smps_sa_mask = OMAP4430_SA_VDD_CORE_L_0_6_MASK;
1015 vdd->vc_reg.smps_volra_shift = OMAP4430_VOLRA_VDD_CORE_L_SHIFT;
1016 vdd->vc_reg.smps_volra_mask = OMAP4430_VOLRA_VDD_CORE_L_MASK;
1017 vdd->vc_reg.voltsetup_reg =
1018 OMAP4_PRM_VOLTSETUP_CORE_RET_SLEEP_OFFSET;
1019 vdd->prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_OFFSET;
1020 } else if (!strcmp(vdd->voltdm.name, "iva")) {
1021 vdd->volt_data = omap44xx_vdd_iva_volt_data;
1022 vdd->vp_reg.tranxdone_status =
1023 OMAP4430_VP_IVA_TRANXDONE_ST_MASK;
1024 vdd->vc_reg.cmdval_reg = OMAP4_PRM_VC_VAL_CMD_VDD_IVA_L_OFFSET;
1025 vdd->vc_reg.smps_sa_shift =
1026 OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_SHIFT;
1027 vdd->vc_reg.smps_sa_mask =
1028 OMAP4430_SA_VDD_IVA_L_PRM_VC_SMPS_SA_MASK;
1029 vdd->vc_reg.smps_volra_shift = OMAP4430_VOLRA_VDD_IVA_L_SHIFT;
1030 vdd->vc_reg.smps_volra_mask = OMAP4430_VOLRA_VDD_IVA_L_MASK;
1031 vdd->vc_reg.voltsetup_reg =
1032 OMAP4_PRM_VOLTSETUP_IVA_RET_SLEEP_OFFSET;
1033 vdd->prm_irqst_reg = OMAP4_PRM_IRQSTATUS_MPU_OFFSET;
1034 } else {
1035 pr_warning("%s: vdd_%s does not exisit in OMAP4\n",
1036 __func__, vdd->voltdm.name);
1037 return -EINVAL;
1038 }
1039
1040 /*
1041 * Sys clk rate is require to calculate vp timeout value and
1042 * smpswaittimemin and smpswaittimemax.
1043 */
1044 sys_ck = clk_get(NULL, "sys_clkin_ck");
1045 if (IS_ERR(sys_ck)) {
1046 pr_warning("%s: Could not get the sys clk to calculate"
1047 "various vdd_%s params\n", __func__, vdd->voltdm.name);
1048 return -EINVAL;
1049 }
1050 sys_clk_speed = clk_get_rate(sys_ck);
1051 clk_put(sys_ck);
1052 /* Divide to avoid overflow */
1053 sys_clk_speed /= 1000;
1054
1055 /* Generic voltage parameters */
1056 vdd->curr_volt = 1200000;
1057 vdd->ocp_mod = OMAP4430_PRM_OCP_SOCKET_INST;
1058 vdd->read_reg = omap4_voltage_read_reg;
1059 vdd->write_reg = omap4_voltage_write_reg;
1060 vdd->volt_scale = vp_forceupdate_scale_voltage;
1061 vdd->vp_enabled = false;
1062
1063 /* VC parameters */
1064 vdd->vc_reg.prm_mod = OMAP4430_PRM_DEVICE_INST;
1065 vdd->vc_reg.smps_sa_reg = OMAP4_PRM_VC_SMPS_SA_OFFSET;
1066 vdd->vc_reg.smps_volra_reg = OMAP4_PRM_VC_VAL_SMPS_RA_VOL_OFFSET;
1067 vdd->vc_reg.bypass_val_reg = OMAP4_PRM_VC_VAL_BYPASS_OFFSET;
1068 vdd->vc_reg.data_shift = OMAP4430_DATA_SHIFT;
1069 vdd->vc_reg.slaveaddr_shift = OMAP4430_SLAVEADDR_SHIFT;
1070 vdd->vc_reg.regaddr_shift = OMAP4430_REGADDR_SHIFT;
1071 vdd->vc_reg.valid = OMAP4430_VALID_MASK;
1072 vdd->vc_reg.cmd_on_shift = OMAP4430_ON_SHIFT;
1073 vdd->vc_reg.cmd_on_mask = OMAP4430_ON_MASK;
1074 vdd->vc_reg.cmd_onlp_shift = OMAP4430_ONLP_SHIFT;
1075 vdd->vc_reg.cmd_ret_shift = OMAP4430_RET_SHIFT;
1076 vdd->vc_reg.cmd_off_shift = OMAP4430_OFF_SHIFT;
1077
1078 vdd->vp_reg.prm_mod = OMAP4430_PRM_DEVICE_INST;
1079
1080 /* VPCONFIG bit fields */
1081 vdd->vp_reg.vpconfig_erroroffset = (vdd->pmic_info->vp_erroroffset <<
1082 OMAP4430_ERROROFFSET_SHIFT);
1083 vdd->vp_reg.vpconfig_errorgain_mask = OMAP4430_ERRORGAIN_MASK;
1084 vdd->vp_reg.vpconfig_errorgain_shift = OMAP4430_ERRORGAIN_SHIFT;
1085 vdd->vp_reg.vpconfig_initvoltage_shift = OMAP4430_INITVOLTAGE_SHIFT;
1086 vdd->vp_reg.vpconfig_initvoltage_mask = OMAP4430_INITVOLTAGE_MASK;
1087 vdd->vp_reg.vpconfig_timeouten = OMAP4430_TIMEOUTEN_MASK;
1088 vdd->vp_reg.vpconfig_initvdd = OMAP4430_INITVDD_MASK;
1089 vdd->vp_reg.vpconfig_forceupdate = OMAP4430_FORCEUPDATE_MASK;
1090 vdd->vp_reg.vpconfig_vpenable = OMAP4430_VPENABLE_MASK;
1091
1092 /* VSTEPMIN VSTEPMAX bit fields */
1093 waittime = ((vdd->pmic_info->step_size / vdd->pmic_info->slew_rate) *
1094 sys_clk_speed) / 1000;
1095 vdd->vp_reg.vstepmin_smpswaittimemin = waittime;
1096 vdd->vp_reg.vstepmax_smpswaittimemax = waittime;
1097 vdd->vp_reg.vstepmin_stepmin = vdd->pmic_info->vp_vstepmin;
1098 vdd->vp_reg.vstepmax_stepmax = vdd->pmic_info->vp_vstepmax;
1099 vdd->vp_reg.vstepmin_smpswaittimemin_shift =
1100 OMAP4430_SMPSWAITTIMEMIN_SHIFT;
1101 vdd->vp_reg.vstepmax_smpswaittimemax_shift =
1102 OMAP4430_SMPSWAITTIMEMAX_SHIFT;
1103 vdd->vp_reg.vstepmin_stepmin_shift = OMAP4430_VSTEPMIN_SHIFT;
1104 vdd->vp_reg.vstepmax_stepmax_shift = OMAP4430_VSTEPMAX_SHIFT;
1105
1106 /* VLIMITTO bit fields */
1107 timeout_val = (sys_clk_speed * vdd->pmic_info->vp_timeout_us) / 1000;
1108 vdd->vp_reg.vlimitto_timeout = timeout_val;
1109 vdd->vp_reg.vlimitto_vddmin = vdd->pmic_info->vp_vddmin;
1110 vdd->vp_reg.vlimitto_vddmax = vdd->pmic_info->vp_vddmax;
1111 vdd->vp_reg.vlimitto_vddmin_shift = OMAP4430_VDDMIN_SHIFT;
1112 vdd->vp_reg.vlimitto_vddmax_shift = OMAP4430_VDDMAX_SHIFT;
1113 vdd->vp_reg.vlimitto_timeout_shift = OMAP4430_TIMEOUT_SHIFT;
1114
1115 return 0;
1116}
1117
1118/* Public functions */
1119/**
1120 * omap_voltage_get_nom_volt() - Gets the current non-auto-compensated voltage
1121 * @voltdm: pointer to the VDD for which current voltage info is needed
1122 *
1123 * API to get the current non-auto-compensated voltage for a VDD.
1124 * Returns 0 in case of error else returns the current voltage for the VDD.
1125 */
1126unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm)
1127{
1128 struct omap_vdd_info *vdd;
1129
1130 if (!voltdm || IS_ERR(voltdm)) {
1131 pr_warning("%s: VDD specified does not exist!\n", __func__);
1132 return 0;
1133 }
1134
1135 vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
1136
1137 return vdd->curr_volt;
1138}
1139
1140/**
1141 * omap_vp_get_curr_volt() - API to get the current vp voltage.
1142 * @voltdm: pointer to the VDD.
1143 *
1144 * This API returns the current voltage for the specified voltage processor
1145 */
1146unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm)
1147{
1148 struct omap_vdd_info *vdd;
1149 u8 curr_vsel;
1150
1151 if (!voltdm || IS_ERR(voltdm)) {
1152 pr_warning("%s: VDD specified does not exist!\n", __func__);
1153 return 0;
1154 }
1155
1156 vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
1157 if (!vdd->read_reg) {
1158 pr_err("%s: No read API for reading vdd_%s regs\n",
1159 __func__, voltdm->name);
1160 return 0;
1161 }
1162
1163 curr_vsel = vdd->read_reg(vdd->vp_reg.prm_mod,
1164 vdd->vp_offs.voltage);
1165
1166 if (!vdd->pmic_info || !vdd->pmic_info->vsel_to_uv) {
1167 pr_warning("%s: PMIC function to convert vsel to voltage"
1168 "in uV not registerd\n", __func__);
1169 return 0;
1170 }
1171
1172 return vdd->pmic_info->vsel_to_uv(curr_vsel);
1173}
1174
1175/**
1176 * omap_vp_enable() - API to enable a particular VP
1177 * @voltdm: pointer to the VDD whose VP is to be enabled.
1178 *
1179 * This API enables a particular voltage processor. Needed by the smartreflex
1180 * class drivers.
1181 */
1182void omap_vp_enable(struct voltagedomain *voltdm)
1183{
1184 struct omap_vdd_info *vdd;
1185 u32 vpconfig;
1186 u16 mod;
1187
1188 if (!voltdm || IS_ERR(voltdm)) {
1189 pr_warning("%s: VDD specified does not exist!\n", __func__);
1190 return;
1191 }
1192
1193 vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
1194 if (!vdd->read_reg || !vdd->write_reg) {
1195 pr_err("%s: No read/write API for accessing vdd_%s regs\n",
1196 __func__, voltdm->name);
1197 return;
1198 }
1199
1200 mod = vdd->vp_reg.prm_mod;
1201
1202 /* If VP is already enabled, do nothing. Return */
1203 if (vdd->vp_enabled)
1204 return;
1205
1206 vp_latch_vsel(vdd);
1207
1208 /* Enable VP */
1209 vpconfig = vdd->read_reg(mod, vdd->vp_offs.vpconfig);
1210 vpconfig |= vdd->vp_reg.vpconfig_vpenable;
1211 vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
1212 vdd->vp_enabled = true;
1213}
1214
1215/**
1216 * omap_vp_disable() - API to disable a particular VP
1217 * @voltdm: pointer to the VDD whose VP is to be disabled.
1218 *
1219 * This API disables a particular voltage processor. Needed by the smartreflex
1220 * class drivers.
1221 */
1222void omap_vp_disable(struct voltagedomain *voltdm)
1223{
1224 struct omap_vdd_info *vdd;
1225 u32 vpconfig;
1226 u16 mod;
1227 int timeout;
1228
1229 if (!voltdm || IS_ERR(voltdm)) {
1230 pr_warning("%s: VDD specified does not exist!\n", __func__);
1231 return;
1232 }
1233
1234 vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
1235 if (!vdd->read_reg || !vdd->write_reg) {
1236 pr_err("%s: No read/write API for accessing vdd_%s regs\n",
1237 __func__, voltdm->name);
1238 return;
1239 }
1240
1241 mod = vdd->vp_reg.prm_mod;
1242
1243 /* If VP is already disabled, do nothing. Return */
1244 if (!vdd->vp_enabled) {
1245 pr_warning("%s: Trying to disable VP for vdd_%s when"
1246 "it is already disabled\n", __func__, voltdm->name);
1247 return;
1248 }
1249
1250 /* Disable VP */
1251 vpconfig = vdd->read_reg(mod, vdd->vp_offs.vpconfig);
1252 vpconfig &= ~vdd->vp_reg.vpconfig_vpenable;
1253 vdd->write_reg(vpconfig, mod, vdd->vp_offs.vpconfig);
1254
1255 /*
1256 * Wait for VP idle Typical latency is <2us. Maximum latency is ~100us
1257 */
1258 omap_test_timeout((vdd->read_reg(mod, vdd->vp_offs.vstatus)),
1259 VP_IDLE_TIMEOUT, timeout);
1260
1261 if (timeout >= VP_IDLE_TIMEOUT)
1262 pr_warning("%s: vdd_%s idle timedout\n",
1263 __func__, voltdm->name);
1264
1265 vdd->vp_enabled = false;
1266
1267 return;
1268}
1269
1270/**
1271 * omap_voltage_scale_vdd() - API to scale voltage of a particular
1272 * voltage domain.
1273 * @voltdm: pointer to the VDD which is to be scaled.
1274 * @target_volt: The target voltage of the voltage domain
1275 *
1276 * This API should be called by the kernel to do the voltage scaling
1277 * for a particular voltage domain during dvfs or any other situation.
1278 */
1279int omap_voltage_scale_vdd(struct voltagedomain *voltdm,
1280 unsigned long target_volt)
1281{
1282 struct omap_vdd_info *vdd;
1283
1284 if (!voltdm || IS_ERR(voltdm)) {
1285 pr_warning("%s: VDD specified does not exist!\n", __func__);
1286 return -EINVAL;
1287 }
1288
1289 vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
1290
1291 if (!vdd->volt_scale) {
1292 pr_err("%s: No voltage scale API registered for vdd_%s\n",
1293 __func__, voltdm->name);
1294 return -ENODATA;
1295 }
1296
1297 return vdd->volt_scale(vdd, target_volt);
1298}
1299
1300/**
1301 * omap_voltage_reset() - Resets the voltage of a particular voltage domain
1302 * to that of the current OPP.
1303 * @voltdm: pointer to the VDD whose voltage is to be reset.
1304 *
1305 * This API finds out the correct voltage the voltage domain is supposed
1306 * to be at and resets the voltage to that level. Should be used expecially
1307 * while disabling any voltage compensation modules.
1308 */
1309void omap_voltage_reset(struct voltagedomain *voltdm)
1310{
1311 unsigned long target_uvdc;
1312
1313 if (!voltdm || IS_ERR(voltdm)) {
1314 pr_warning("%s: VDD specified does not exist!\n", __func__);
1315 return;
1316 }
1317
1318 target_uvdc = omap_voltage_get_nom_volt(voltdm);
1319 if (!target_uvdc) {
1320 pr_err("%s: unable to find current voltage for vdd_%s\n",
1321 __func__, voltdm->name);
1322 return;
1323 }
1324
1325 omap_voltage_scale_vdd(voltdm, target_uvdc);
1326}
1327
1328/**
1329 * omap_voltage_get_volttable() - API to get the voltage table associated with a
1330 * particular voltage domain.
1331 * @voltdm: pointer to the VDD for which the voltage table is required
1332 * @volt_data: the voltage table for the particular vdd which is to be
1333 * populated by this API
1334 *
1335 * This API populates the voltage table associated with a VDD into the
1336 * passed parameter pointer. Returns the count of distinct voltages
1337 * supported by this vdd.
1338 *
1339 */
1340void omap_voltage_get_volttable(struct voltagedomain *voltdm,
1341 struct omap_volt_data **volt_data)
1342{
1343 struct omap_vdd_info *vdd;
1344
1345 if (!voltdm || IS_ERR(voltdm)) {
1346 pr_warning("%s: VDD specified does not exist!\n", __func__);
1347 return;
1348 }
1349
1350 vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
1351
1352 *volt_data = vdd->volt_data;
1353}
1354
1355/**
1356 * omap_voltage_get_voltdata() - API to get the voltage table entry for a
1357 * particular voltage
1358 * @voltdm: pointer to the VDD whose voltage table has to be searched
1359 * @volt: the voltage to be searched in the voltage table
1360 *
1361 * This API searches through the voltage table for the required voltage
1362 * domain and tries to find a matching entry for the passed voltage volt.
1363 * If a matching entry is found volt_data is populated with that entry.
1364 * This API searches only through the non-compensated voltages int the
1365 * voltage table.
1366 * Returns pointer to the voltage table entry corresponding to volt on
1367 * sucess. Returns -ENODATA if no voltage table exisits for the passed voltage
1368 * domain or if there is no matching entry.
1369 */
1370struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
1371 unsigned long volt)
1372{
1373 struct omap_vdd_info *vdd;
1374 int i;
1375
1376 if (!voltdm || IS_ERR(voltdm)) {
1377 pr_warning("%s: VDD specified does not exist!\n", __func__);
1378 return ERR_PTR(-EINVAL);
1379 }
1380
1381 vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
1382
1383 if (!vdd->volt_data) {
1384 pr_warning("%s: voltage table does not exist for vdd_%s\n",
1385 __func__, voltdm->name);
1386 return ERR_PTR(-ENODATA);
1387 }
1388
1389 for (i = 0; vdd->volt_data[i].volt_nominal != 0; i++) {
1390 if (vdd->volt_data[i].volt_nominal == volt)
1391 return &vdd->volt_data[i];
1392 }
1393
1394 pr_notice("%s: Unable to match the current voltage with the voltage"
1395 "table for vdd_%s\n", __func__, voltdm->name);
1396
1397 return ERR_PTR(-ENODATA);
1398}
1399
1400/**
1401 * omap_voltage_register_pmic() - API to register PMIC specific data
1402 * @voltdm: pointer to the VDD for which the PMIC specific data is
1403 * to be registered
1404 * @pmic_info: the structure containing pmic info
1405 *
1406 * This API is to be called by the SOC/PMIC file to specify the
1407 * pmic specific info as present in omap_volt_pmic_info structure.
1408 */
1409int omap_voltage_register_pmic(struct voltagedomain *voltdm,
1410 struct omap_volt_pmic_info *pmic_info)
1411{
1412 struct omap_vdd_info *vdd;
1413
1414 if (!voltdm || IS_ERR(voltdm)) {
1415 pr_warning("%s: VDD specified does not exist!\n", __func__);
1416 return -EINVAL;
1417 }
1418
1419 vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
1420
1421 vdd->pmic_info = pmic_info;
1422
1423 return 0;
1424}
1425
1426/**
1427 * omap_voltage_get_dbgdir() - API to get pointer to the debugfs directory
1428 * corresponding to a voltage domain.
1429 *
1430 * @voltdm: pointer to the VDD whose debug directory is required.
1431 *
1432 * This API returns pointer to the debugfs directory corresponding
1433 * to the voltage domain. Should be used by drivers requiring to
1434 * add any debug entry for a particular voltage domain. Returns NULL
1435 * in case of error.
1436 */
1437struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm)
1438{
1439 struct omap_vdd_info *vdd;
1440
1441 if (!voltdm || IS_ERR(voltdm)) {
1442 pr_warning("%s: VDD specified does not exist!\n", __func__);
1443 return NULL;
1444 }
1445
1446 vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
1447
1448 return vdd->debug_dir;
1449}
1450
1451/**
1452 * omap_change_voltscale_method() - API to change the voltage scaling method.
1453 * @voltdm: pointer to the VDD whose voltage scaling method
1454 * has to be changed.
1455 * @voltscale_method: the method to be used for voltage scaling.
1456 *
1457 * This API can be used by the board files to change the method of voltage
1458 * scaling between vpforceupdate and vcbypass. The parameter values are
1459 * defined in voltage.h
1460 */
1461void omap_change_voltscale_method(struct voltagedomain *voltdm,
1462 int voltscale_method)
1463{
1464 struct omap_vdd_info *vdd;
1465
1466 if (!voltdm || IS_ERR(voltdm)) {
1467 pr_warning("%s: VDD specified does not exist!\n", __func__);
1468 return;
1469 }
1470
1471 vdd = container_of(voltdm, struct omap_vdd_info, voltdm);
1472
1473 switch (voltscale_method) {
1474 case VOLTSCALE_VPFORCEUPDATE:
1475 vdd->volt_scale = vp_forceupdate_scale_voltage;
1476 return;
1477 case VOLTSCALE_VCBYPASS:
1478 vdd->volt_scale = vc_bypass_scale_voltage;
1479 return;
1480 default:
1481 pr_warning("%s: Trying to change the method of voltage scaling"
1482 "to an unsupported one!\n", __func__);
1483 }
1484}
1485
1486/**
1487 * omap_voltage_domain_lookup() - API to get the voltage domain pointer
1488 * @name: Name of the voltage domain
1489 *
1490 * This API looks up in the global vdd_info struct for the
1491 * existence of voltage domain <name>. If it exists, the API returns
1492 * a pointer to the voltage domain structure corresponding to the
1493 * VDD<name>. Else retuns error pointer.
1494 */
1495struct voltagedomain *omap_voltage_domain_lookup(char *name)
1496{
1497 int i;
1498
1499 if (!vdd_info) {
1500 pr_err("%s: Voltage driver init not yet happened.Faulting!\n",
1501 __func__);
1502 return ERR_PTR(-EINVAL);
1503 }
1504
1505 if (!name) {
1506 pr_err("%s: No name to get the votage domain!\n", __func__);
1507 return ERR_PTR(-EINVAL);
1508 }
1509
1510 for (i = 0; i < nr_scalable_vdd; i++) {
1511 if (!(strcmp(name, vdd_info[i].voltdm.name)))
1512 return &vdd_info[i].voltdm;
1513 }
1514
1515 return ERR_PTR(-EINVAL);
1516}
1517
1518/**
1519 * omap_voltage_late_init() - Init the various voltage parameters
1520 *
1521 * This API is to be called in the later stages of the
1522 * system boot to init the voltage controller and
1523 * voltage processors.
1524 */
1525int __init omap_voltage_late_init(void)
1526{
1527 int i;
1528
1529 if (!vdd_info) {
1530 pr_err("%s: Voltage driver support not added\n",
1531 __func__);
1532 return -EINVAL;
1533 }
1534
1535 voltage_dir = debugfs_create_dir("voltage", NULL);
1536 if (IS_ERR(voltage_dir))
1537 pr_err("%s: Unable to create voltage debugfs main dir\n",
1538 __func__);
1539 for (i = 0; i < nr_scalable_vdd; i++) {
1540 if (vdd_data_configure(&vdd_info[i]))
1541 continue;
1542 vc_init(&vdd_info[i]);
1543 vp_init(&vdd_info[i]);
1544 vdd_debugfs_init(&vdd_info[i]);
1545 }
1546
1547 return 0;
1548}
1549
1550/**
1551 * omap_voltage_early_init()- Volatage driver early init
1552 */
1553static int __init omap_voltage_early_init(void)
1554{
1555 if (cpu_is_omap34xx()) {
1556 vdd_info = omap3_vdd_info;
1557 nr_scalable_vdd = OMAP3_NR_SCALABLE_VDD;
1558 vc_init = omap3_vc_init;
1559 vdd_data_configure = omap3_vdd_data_configure;
1560 } else if (cpu_is_omap44xx()) {
1561 vdd_info = omap4_vdd_info;
1562 nr_scalable_vdd = OMAP4_NR_SCALABLE_VDD;
1563 vc_init = omap4_vc_init;
1564 vdd_data_configure = omap4_vdd_data_configure;
1565 } else {
1566 pr_warning("%s: voltage driver support not added\n", __func__);
1567 }
1568
1569 return 0;
1570}
1571core_initcall(omap_voltage_early_init);
diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig
index 5e63e5069e0d..11bf9f991509 100644
--- a/arch/arm/plat-omap/Kconfig
+++ b/arch/arm/plat-omap/Kconfig
@@ -35,6 +35,37 @@ config OMAP_DEBUG_LEDS
35 depends on OMAP_DEBUG_DEVICES 35 depends on OMAP_DEBUG_DEVICES
36 default y if LEDS_CLASS 36 default y if LEDS_CLASS
37 37
38config OMAP_SMARTREFLEX
39 bool "SmartReflex support"
40 depends on (ARCH_OMAP3 || ARCH_OMAP4) && PM
41 help
42 Say Y if you want to enable SmartReflex.
43
44 SmartReflex can perform continuous dynamic voltage
45 scaling around the nominal operating point voltage
46 according to silicon characteristics and operating
47 conditions. Enabling SmartReflex reduces power
48 consumption.
49
50 Please note, that by default SmartReflex is only
51 initialized. To enable the automatic voltage
52 compensation for vdd mpu and vdd core from user space,
53 user must write 1 to
54 /debug/voltage/vdd_<X>/smartreflex/autocomp,
55 where X is mpu or core for OMAP3.
56 Optionallly autocompensation can be enabled in the kernel
57 by default during system init via the enable_on_init flag
58 which an be passed as platform data to the smartreflex driver.
59
60config OMAP_SMARTREFLEX_CLASS3
61 bool "Class 3 mode of Smartreflex Implementation"
62 depends on OMAP_SMARTREFLEX && TWL4030_CORE
63 help
64 Say Y to enable Class 3 implementation of Smartreflex
65
66 Class 3 implementation of Smartreflex employs continuous hardware
67 voltage calibration.
68
38config OMAP_RESET_CLOCKS 69config OMAP_RESET_CLOCKS
39 bool "Reset unused clocks during boot" 70 bool "Reset unused clocks during boot"
40 depends on ARCH_OMAP 71 depends on ARCH_OMAP
diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h
index 2825b456da0e..b219a88cac2c 100644
--- a/arch/arm/plat-omap/include/plat/omap_hwmod.h
+++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h
@@ -34,6 +34,7 @@
34#include <linux/ioport.h> 34#include <linux/ioport.h>
35#include <linux/spinlock.h> 35#include <linux/spinlock.h>
36#include <plat/cpu.h> 36#include <plat/cpu.h>
37#include <plat/voltage.h>
37 38
38struct omap_device; 39struct omap_device;
39 40
@@ -452,6 +453,8 @@ struct omap_hwmod_class {
452 * @main_clk: main clock: OMAP clock name 453 * @main_clk: main clock: OMAP clock name
453 * @_clk: pointer to the main struct clk (filled in at runtime) 454 * @_clk: pointer to the main struct clk (filled in at runtime)
454 * @opt_clks: other device clocks that drivers can request (0..*) 455 * @opt_clks: other device clocks that drivers can request (0..*)
456 * @vdd_name: voltage domain name
457 * @voltdm: pointer to voltage domain (filled in at runtime)
455 * @masters: ptr to array of OCP ifs that this hwmod can initiate on 458 * @masters: ptr to array of OCP ifs that this hwmod can initiate on
456 * @slaves: ptr to array of OCP ifs that this hwmod can respond on 459 * @slaves: ptr to array of OCP ifs that this hwmod can respond on
457 * @dev_attr: arbitrary device attributes that can be passed to the driver 460 * @dev_attr: arbitrary device attributes that can be passed to the driver
@@ -494,6 +497,8 @@ struct omap_hwmod {
494 const char *main_clk; 497 const char *main_clk;
495 struct clk *_clk; 498 struct clk *_clk;
496 struct omap_hwmod_opt_clk *opt_clks; 499 struct omap_hwmod_opt_clk *opt_clks;
500 char *vdd_name;
501 struct voltagedomain *voltdm;
497 struct omap_hwmod_ocp_if **masters; /* connect to *_IA */ 502 struct omap_hwmod_ocp_if **masters; /* connect to *_IA */
498 struct omap_hwmod_ocp_if **slaves; /* connect to *_TA */ 503 struct omap_hwmod_ocp_if **slaves; /* connect to *_TA */
499 void *dev_attr; 504 void *dev_attr;
diff --git a/arch/arm/plat-omap/include/plat/smartreflex.h b/arch/arm/plat-omap/include/plat/smartreflex.h
new file mode 100644
index 000000000000..6568c885f37a
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/smartreflex.h
@@ -0,0 +1,245 @@
1/*
2 * OMAP Smartreflex Defines and Routines
3 *
4 * Author: Thara Gopinath <thara@ti.com>
5 *
6 * Copyright (C) 2010 Texas Instruments, Inc.
7 * Thara Gopinath <thara@ti.com>
8 *
9 * Copyright (C) 2008 Nokia Corporation
10 * Kalle Jokiniemi
11 *
12 * Copyright (C) 2007 Texas Instruments, Inc.
13 * Lesly A M <x0080970@ti.com>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License version 2 as
17 * published by the Free Software Foundation.
18 */
19
20#ifndef __ASM_ARM_OMAP_SMARTREFLEX_H
21#define __ASM_ARM_OMAP_SMARTREFLEX_H
22
23#include <linux/platform_device.h>
24#include <plat/voltage.h>
25
26/*
27 * Different Smartreflex IPs version. The v1 is the 65nm version used in
28 * OMAP3430. The v2 is the update for the 45nm version of the IP
29 * used in OMAP3630 and OMAP4430
30 */
31#define SR_TYPE_V1 1
32#define SR_TYPE_V2 2
33
34/* SMART REFLEX REG ADDRESS OFFSET */
35#define SRCONFIG 0x00
36#define SRSTATUS 0x04
37#define SENVAL 0x08
38#define SENMIN 0x0C
39#define SENMAX 0x10
40#define SENAVG 0x14
41#define AVGWEIGHT 0x18
42#define NVALUERECIPROCAL 0x1c
43#define SENERROR_V1 0x20
44#define ERRCONFIG_V1 0x24
45#define IRQ_EOI 0x20
46#define IRQSTATUS_RAW 0x24
47#define IRQSTATUS 0x28
48#define IRQENABLE_SET 0x2C
49#define IRQENABLE_CLR 0x30
50#define SENERROR_V2 0x34
51#define ERRCONFIG_V2 0x38
52
53/* Bit/Shift Positions */
54
55/* SRCONFIG */
56#define SRCONFIG_ACCUMDATA_SHIFT 22
57#define SRCONFIG_SRCLKLENGTH_SHIFT 12
58#define SRCONFIG_SENNENABLE_V1_SHIFT 5
59#define SRCONFIG_SENPENABLE_V1_SHIFT 3
60#define SRCONFIG_SENNENABLE_V2_SHIFT 1
61#define SRCONFIG_SENPENABLE_V2_SHIFT 0
62#define SRCONFIG_CLKCTRL_SHIFT 0
63
64#define SRCONFIG_ACCUMDATA_MASK (0x3ff << 22)
65
66#define SRCONFIG_SRENABLE BIT(11)
67#define SRCONFIG_SENENABLE BIT(10)
68#define SRCONFIG_ERRGEN_EN BIT(9)
69#define SRCONFIG_MINMAXAVG_EN BIT(8)
70#define SRCONFIG_DELAYCTRL BIT(2)
71
72/* AVGWEIGHT */
73#define AVGWEIGHT_SENPAVGWEIGHT_SHIFT 2
74#define AVGWEIGHT_SENNAVGWEIGHT_SHIFT 0
75
76/* NVALUERECIPROCAL */
77#define NVALUERECIPROCAL_SENPGAIN_SHIFT 20
78#define NVALUERECIPROCAL_SENNGAIN_SHIFT 16
79#define NVALUERECIPROCAL_RNSENP_SHIFT 8
80#define NVALUERECIPROCAL_RNSENN_SHIFT 0
81
82/* ERRCONFIG */
83#define ERRCONFIG_ERRWEIGHT_SHIFT 16
84#define ERRCONFIG_ERRMAXLIMIT_SHIFT 8
85#define ERRCONFIG_ERRMINLIMIT_SHIFT 0
86
87#define SR_ERRWEIGHT_MASK (0x07 << 16)
88#define SR_ERRMAXLIMIT_MASK (0xff << 8)
89#define SR_ERRMINLIMIT_MASK (0xff << 0)
90
91#define ERRCONFIG_VPBOUNDINTEN_V1 BIT(31)
92#define ERRCONFIG_VPBOUNDINTST_V1 BIT(30)
93#define ERRCONFIG_MCUACCUMINTEN BIT(29)
94#define ERRCONFIG_MCUACCUMINTST BIT(28)
95#define ERRCONFIG_MCUVALIDINTEN BIT(27)
96#define ERRCONFIG_MCUVALIDINTST BIT(26)
97#define ERRCONFIG_MCUBOUNDINTEN BIT(25)
98#define ERRCONFIG_MCUBOUNDINTST BIT(24)
99#define ERRCONFIG_MCUDISACKINTEN BIT(23)
100#define ERRCONFIG_VPBOUNDINTST_V2 BIT(23)
101#define ERRCONFIG_MCUDISACKINTST BIT(22)
102#define ERRCONFIG_VPBOUNDINTEN_V2 BIT(22)
103
104#define ERRCONFIG_STATUS_V1_MASK (ERRCONFIG_VPBOUNDINTST_V1 | \
105 ERRCONFIG_MCUACCUMINTST | \
106 ERRCONFIG_MCUVALIDINTST | \
107 ERRCONFIG_MCUBOUNDINTST | \
108 ERRCONFIG_MCUDISACKINTST)
109/* IRQSTATUS */
110#define IRQSTATUS_MCUACCUMINT BIT(3)
111#define IRQSTATUS_MCVALIDINT BIT(2)
112#define IRQSTATUS_MCBOUNDSINT BIT(1)
113#define IRQSTATUS_MCUDISABLEACKINT BIT(0)
114
115/* IRQENABLE_SET and IRQENABLE_CLEAR */
116#define IRQENABLE_MCUACCUMINT BIT(3)
117#define IRQENABLE_MCUVALIDINT BIT(2)
118#define IRQENABLE_MCUBOUNDSINT BIT(1)
119#define IRQENABLE_MCUDISABLEACKINT BIT(0)
120
121/* Common Bit values */
122
123#define SRCLKLENGTH_12MHZ_SYSCLK 0x3c
124#define SRCLKLENGTH_13MHZ_SYSCLK 0x41
125#define SRCLKLENGTH_19MHZ_SYSCLK 0x60
126#define SRCLKLENGTH_26MHZ_SYSCLK 0x82
127#define SRCLKLENGTH_38MHZ_SYSCLK 0xC0
128
129/*
130 * 3430 specific values. Maybe these should be passed from board file or
131 * pmic structures.
132 */
133#define OMAP3430_SR_ACCUMDATA 0x1f4
134
135#define OMAP3430_SR1_SENPAVGWEIGHT 0x03
136#define OMAP3430_SR1_SENNAVGWEIGHT 0x03
137
138#define OMAP3430_SR2_SENPAVGWEIGHT 0x01
139#define OMAP3430_SR2_SENNAVGWEIGHT 0x01
140
141#define OMAP3430_SR_ERRWEIGHT 0x04
142#define OMAP3430_SR_ERRMAXLIMIT 0x02
143
144/**
145 * struct omap_sr_pmic_data - Strucutre to be populated by pmic code to pass
146 * pmic specific info to smartreflex driver
147 *
148 * @sr_pmic_init: API to initialize smartreflex on the PMIC side.
149 */
150struct omap_sr_pmic_data {
151 void (*sr_pmic_init) (void);
152};
153
154#ifdef CONFIG_OMAP_SMARTREFLEX
155/*
156 * The smart reflex driver supports CLASS1 CLASS2 and CLASS3 SR.
157 * The smartreflex class driver should pass the class type.
158 * Should be used to populate the class_type field of the
159 * omap_smartreflex_class_data structure.
160 */
161#define SR_CLASS1 0x1
162#define SR_CLASS2 0x2
163#define SR_CLASS3 0x3
164
165/**
166 * struct omap_sr_class_data - Smartreflex class driver info
167 *
168 * @enable: API to enable a particular class smaartreflex.
169 * @disable: API to disable a particular class smartreflex.
170 * @configure: API to configure a particular class smartreflex.
171 * @notify: API to notify the class driver about an event in SR.
172 * Not needed for class3.
173 * @notify_flags: specify the events to be notified to the class driver
174 * @class_type: specify which smartreflex class.
175 * Can be used by the SR driver to take any class
176 * based decisions.
177 */
178struct omap_sr_class_data {
179 int (*enable)(struct voltagedomain *voltdm);
180 int (*disable)(struct voltagedomain *voltdm, int is_volt_reset);
181 int (*configure)(struct voltagedomain *voltdm);
182 int (*notify)(struct voltagedomain *voltdm, u32 status);
183 u8 notify_flags;
184 u8 class_type;
185};
186
187/**
188 * struct omap_sr_nvalue_table - Smartreflex n-target value info
189 *
190 * @efuse_offs: The offset of the efuse where n-target values are stored.
191 * @nvalue: The n-target value.
192 */
193struct omap_sr_nvalue_table {
194 u32 efuse_offs;
195 u32 nvalue;
196};
197
198/**
199 * struct omap_sr_data - Smartreflex platform data.
200 *
201 * @ip_type: Smartreflex IP type.
202 * @senp_mod: SENPENABLE value for the sr
203 * @senn_mod: SENNENABLE value for sr
204 * @nvalue_count: Number of distinct nvalues in the nvalue table
205 * @enable_on_init: whether this sr module needs to enabled at
206 * boot up or not.
207 * @nvalue_table: table containing the efuse offsets and nvalues
208 * corresponding to them.
209 * @voltdm: Pointer to the voltage domain associated with the SR
210 */
211struct omap_sr_data {
212 int ip_type;
213 u32 senp_mod;
214 u32 senn_mod;
215 int nvalue_count;
216 bool enable_on_init;
217 struct omap_sr_nvalue_table *nvalue_table;
218 struct voltagedomain *voltdm;
219};
220
221/* Smartreflex module enable/disable interface */
222void omap_sr_enable(struct voltagedomain *voltdm);
223void omap_sr_disable(struct voltagedomain *voltdm);
224void omap_sr_disable_reset_volt(struct voltagedomain *voltdm);
225
226/* API to register the pmic specific data with the smartreflex driver. */
227void omap_sr_register_pmic(struct omap_sr_pmic_data *pmic_data);
228
229/* Smartreflex driver hooks to be called from Smartreflex class driver */
230int sr_enable(struct voltagedomain *voltdm, unsigned long volt);
231void sr_disable(struct voltagedomain *voltdm);
232int sr_configure_errgen(struct voltagedomain *voltdm);
233int sr_configure_minmax(struct voltagedomain *voltdm);
234
235/* API to register the smartreflex class driver with the smartreflex driver */
236int sr_register_class(struct omap_sr_class_data *class_data);
237#else
238static inline void omap_sr_enable(struct voltagedomain *voltdm) {}
239static inline void omap_sr_disable(struct voltagedomain *voltdm) {}
240static inline void omap_sr_disable_reset_volt(
241 struct voltagedomain *voltdm) {}
242static inline void omap_sr_register_pmic(
243 struct omap_sr_pmic_data *pmic_data) {}
244#endif
245#endif
diff --git a/arch/arm/plat-omap/include/plat/voltage.h b/arch/arm/plat-omap/include/plat/voltage.h
new file mode 100644
index 000000000000..0ff123399f3b
--- /dev/null
+++ b/arch/arm/plat-omap/include/plat/voltage.h
@@ -0,0 +1,146 @@
1/*
2 * OMAP Voltage Management Routines
3 *
4 * Author: Thara Gopinath <thara@ti.com>
5 *
6 * Copyright (C) 2009 Texas Instruments, Inc.
7 * Thara Gopinath <thara@ti.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 */
13
14#ifndef __ARCH_ARM_MACH_OMAP2_VOLTAGE_H
15#define __ARCH_ARM_MACH_OMAP2_VOLTAGE_H
16
17#define VOLTSCALE_VPFORCEUPDATE 1
18#define VOLTSCALE_VCBYPASS 2
19
20/*
21 * OMAP3 GENERIC setup times. Revisit to see if these needs to be
22 * passed from board or PMIC file
23 */
24#define OMAP3_CLKSETUP 0xff
25#define OMAP3_VOLTOFFSET 0xff
26#define OMAP3_VOLTSETUP2 0xff
27
28/* Voltage value defines */
29#define OMAP3430_VDD_MPU_OPP1_UV 975000
30#define OMAP3430_VDD_MPU_OPP2_UV 1075000
31#define OMAP3430_VDD_MPU_OPP3_UV 1200000
32#define OMAP3430_VDD_MPU_OPP4_UV 1270000
33#define OMAP3430_VDD_MPU_OPP5_UV 1350000
34
35#define OMAP3430_VDD_CORE_OPP1_UV 975000
36#define OMAP3430_VDD_CORE_OPP2_UV 1050000
37#define OMAP3430_VDD_CORE_OPP3_UV 1150000
38
39#define OMAP3630_VDD_MPU_OPP50_UV 1012500
40#define OMAP3630_VDD_MPU_OPP100_UV 1200000
41#define OMAP3630_VDD_MPU_OPP120_UV 1325000
42#define OMAP3630_VDD_MPU_OPP1G_UV 1375000
43
44#define OMAP3630_VDD_CORE_OPP50_UV 1000000
45#define OMAP3630_VDD_CORE_OPP100_UV 1200000
46
47#define OMAP4430_VDD_MPU_OPP50_UV 930000
48#define OMAP4430_VDD_MPU_OPP100_UV 1100000
49#define OMAP4430_VDD_MPU_OPPTURBO_UV 1260000
50#define OMAP4430_VDD_MPU_OPPNITRO_UV 1350000
51
52#define OMAP4430_VDD_IVA_OPP50_UV 930000
53#define OMAP4430_VDD_IVA_OPP100_UV 1100000
54#define OMAP4430_VDD_IVA_OPPTURBO_UV 1260000
55
56#define OMAP4430_VDD_CORE_OPP50_UV 930000
57#define OMAP4430_VDD_CORE_OPP100_UV 1100000
58
59/**
60 * struct voltagedomain - omap voltage domain global structure.
61 * @name: Name of the voltage domain which can be used as a unique
62 * identifier.
63 */
64struct voltagedomain {
65 char *name;
66};
67
68/* API to get the voltagedomain pointer */
69struct voltagedomain *omap_voltage_domain_lookup(char *name);
70
71/**
72 * struct omap_volt_data - Omap voltage specific data.
73 * @voltage_nominal: The possible voltage value in uV
74 * @sr_efuse_offs: The offset of the efuse register(from system
75 * control module base address) from where to read
76 * the n-target value for the smartreflex module.
77 * @sr_errminlimit: Error min limit value for smartreflex. This value
78 * differs at differnet opp and thus is linked
79 * with voltage.
80 * @vp_errorgain: Error gain value for the voltage processor. This
81 * field also differs according to the voltage/opp.
82 */
83struct omap_volt_data {
84 u32 volt_nominal;
85 u32 sr_efuse_offs;
86 u8 sr_errminlimit;
87 u8 vp_errgain;
88};
89
90/**
91 * struct omap_volt_pmic_info - PMIC specific data required by voltage driver.
92 * @slew_rate: PMIC slew rate (in uv/us)
93 * @step_size: PMIC voltage step size (in uv)
94 * @vsel_to_uv: PMIC API to convert vsel value to actual voltage in uV.
95 * @uv_to_vsel: PMIC API to convert voltage in uV to vsel value.
96 */
97struct omap_volt_pmic_info {
98 int slew_rate;
99 int step_size;
100 u32 on_volt;
101 u32 onlp_volt;
102 u32 ret_volt;
103 u32 off_volt;
104 u16 volt_setup_time;
105 u8 vp_erroroffset;
106 u8 vp_vstepmin;
107 u8 vp_vstepmax;
108 u8 vp_vddmin;
109 u8 vp_vddmax;
110 u8 vp_timeout_us;
111 u8 i2c_slave_addr;
112 u8 pmic_reg;
113 unsigned long (*vsel_to_uv) (const u8 vsel);
114 u8 (*uv_to_vsel) (unsigned long uV);
115};
116
117unsigned long omap_vp_get_curr_volt(struct voltagedomain *voltdm);
118void omap_vp_enable(struct voltagedomain *voltdm);
119void omap_vp_disable(struct voltagedomain *voltdm);
120int omap_voltage_scale_vdd(struct voltagedomain *voltdm,
121 unsigned long target_volt);
122void omap_voltage_reset(struct voltagedomain *voltdm);
123void omap_voltage_get_volttable(struct voltagedomain *voltdm,
124 struct omap_volt_data **volt_data);
125struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
126 unsigned long volt);
127unsigned long omap_voltage_get_nom_volt(struct voltagedomain *voltdm);
128struct dentry *omap_voltage_get_dbgdir(struct voltagedomain *voltdm);
129#ifdef CONFIG_PM
130int omap_voltage_register_pmic(struct voltagedomain *voltdm,
131 struct omap_volt_pmic_info *pmic_info);
132void omap_change_voltscale_method(struct voltagedomain *voltdm,
133 int voltscale_method);
134int omap_voltage_late_init(void);
135#else
136static inline int omap_voltage_register_pmic(struct voltagedomain *voltdm,
137 struct omap_volt_pmic_info *pmic_info) {}
138static inline void omap_change_voltscale_method(struct voltagedomain *voltdm,
139 int voltscale_method) {}
140static inline int omap_voltage_late_init(void)
141{
142 return -EINVAL;
143}
144#endif
145
146#endif