aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-omap2/Kconfig4
-rw-r--r--arch/arm/mach-omap2/Makefile7
-rw-r--r--arch/arm/mach-omap2/io.c3
-rw-r--r--arch/arm/mach-omap2/omap_opp_data.h72
-rw-r--r--arch/arm/mach-omap2/opp.c93
-rw-r--r--arch/arm/mach-omap2/opp3xxx_data.c107
-rw-r--r--arch/arm/mach-omap2/opp4xxx_data.c57
-rw-r--r--arch/arm/mach-omap2/pm.h14
-rw-r--r--arch/arm/plat-omap/include/plat/omap-pm.h31
-rw-r--r--arch/arm/plat-omap/omap-pm-noop.c11
10 files changed, 366 insertions, 33 deletions
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 92b004ba5a10..3e8c9e859f98 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -35,6 +35,8 @@ config ARCH_OMAP3
35 select CPU_V7 35 select CPU_V7
36 select USB_ARCH_HAS_EHCI 36 select USB_ARCH_HAS_EHCI
37 select ARM_L1_CACHE_SHIFT_6 if !ARCH_OMAP4 37 select ARM_L1_CACHE_SHIFT_6 if !ARCH_OMAP4
38 select ARCH_HAS_OPP
39 select PM_OPP if PM
38 40
39config ARCH_OMAP4 41config ARCH_OMAP4
40 bool "TI OMAP4" 42 bool "TI OMAP4"
@@ -44,6 +46,8 @@ config ARCH_OMAP4
44 select ARM_GIC 46 select ARM_GIC
45 select PL310_ERRATA_588369 47 select PL310_ERRATA_588369
46 select ARM_ERRATA_720789 48 select ARM_ERRATA_720789
49 select ARCH_HAS_OPP
50 select PM_OPP if PM
47 51
48comment "OMAP Core Type" 52comment "OMAP Core Type"
49 depends on ARCH_OMAP2 53 depends on ARCH_OMAP2
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index cdfb5faaec9d..1b699d3c6cb8 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -49,6 +49,13 @@ obj-$(CONFIG_ARCH_OMAP4) += mux44xx.o
49obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o 49obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o
50# obj-$(CONFIG_ARCH_OMAP3) += sdrc3xxx.o 50# obj-$(CONFIG_ARCH_OMAP3) += sdrc3xxx.o
51 51
52# OPP table initialization
53ifeq ($(CONFIG_PM_OPP),y)
54obj-y += opp.o
55obj-$(CONFIG_ARCH_OMAP3) += opp3xxx_data.o
56obj-$(CONFIG_ARCH_OMAP4) += opp4xxx_data.o
57endif
58
52# Power Management 59# Power Management
53ifeq ($(CONFIG_PM),y) 60ifeq ($(CONFIG_PM),y)
54obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o 61obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index 4605d5073a9b..5577ab2faad2 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -347,8 +347,7 @@ void __init omap2_init_common_hw(struct omap_sdrc_params *sdrc_cs0,
347 else if (cpu_is_omap44xx()) 347 else if (cpu_is_omap44xx())
348 omap44xx_hwmod_init(); 348 omap44xx_hwmod_init();
349 349
350 /* The OPP tables have to be registered before a clk init */ 350 omap_pm_if_early_init();
351 omap_pm_if_early_init(mpu_opps, dsp_opps, l3_opps);
352 351
353 if (cpu_is_omap2420()) 352 if (cpu_is_omap2420())
354 omap2420_clk_init(); 353 omap2420_clk_init();
diff --git a/arch/arm/mach-omap2/omap_opp_data.h b/arch/arm/mach-omap2/omap_opp_data.h
new file mode 100644
index 000000000000..46ac27dd6c84
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_opp_data.h
@@ -0,0 +1,72 @@
1/*
2 * OMAP SoC specific OPP Data helpers
3 *
4 * Copyright (C) 2009-2010 Texas Instruments Incorporated - http://www.ti.com/
5 * Nishanth Menon
6 * Kevin Hilman
7 * Copyright (C) 2010 Nokia Corporation.
8 * Eduardo Valentin
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
15 * kind, whether express or implied; without even the implied warranty
16 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19#ifndef __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H
20#define __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H
21
22#include <plat/omap_hwmod.h>
23
24/*
25 * *BIG FAT WARNING*:
26 * USE the following ONLY in opp data initialization common to an SoC.
27 * DO NOT USE these in board files/pm core etc.
28 */
29
30/**
31 * struct omap_opp_def - OMAP OPP Definition
32 * @hwmod_name: Name of the hwmod for this domain
33 * @freq: Frequency in hertz corresponding to this OPP
34 * @u_volt: Nominal voltage in microvolts corresponding to this OPP
35 * @default_available: True/false - is this OPP available by default
36 *
37 * OMAP SOCs have a standard set of tuples consisting of frequency and voltage
38 * pairs that the device will support per voltage domain. This is called
39 * Operating Points or OPP. The actual definitions of OMAP Operating Points
40 * varies over silicon within the same family of devices. For a specific
41 * domain, you can have a set of {frequency, voltage} pairs and this is denoted
42 * by an array of omap_opp_def. As the kernel boots and more information is
43 * available, a set of these are activated based on the precise nature of
44 * device the kernel boots up on. It is interesting to remember that each IP
45 * which belongs to a voltage domain may define their own set of OPPs on top
46 * of this - but this is handled by the appropriate driver.
47 */
48struct omap_opp_def {
49 char *hwmod_name;
50
51 unsigned long freq;
52 unsigned long u_volt;
53
54 bool default_available;
55};
56
57/*
58 * Initialization wrapper used to define an OPP for OMAP variants.
59 */
60#define OPP_INITIALIZER(_hwmod_name, _enabled, _freq, _uv) \
61{ \
62 .hwmod_name = _hwmod_name, \
63 .default_available = _enabled, \
64 .freq = _freq, \
65 .u_volt = _uv, \
66}
67
68/* Use this to initialize the default table */
69extern int __init omap_init_opp_table(struct omap_opp_def *opp_def,
70 u32 opp_def_size);
71
72#endif /* __ARCH_ARM_MACH_OMAP2_OMAP_OPP_DATA_H */
diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c
new file mode 100644
index 000000000000..ab8b35b780b5
--- /dev/null
+++ b/arch/arm/mach-omap2/opp.c
@@ -0,0 +1,93 @@
1/*
2 * OMAP SoC specific OPP wrapper function
3 *
4 * Copyright (C) 2009-2010 Texas Instruments Incorporated - http://www.ti.com/
5 * Nishanth Menon
6 * Kevin Hilman
7 * Copyright (C) 2010 Nokia Corporation.
8 * Eduardo Valentin
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
15 * kind, whether express or implied; without even the implied warranty
16 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19#include <linux/module.h>
20#include <linux/opp.h>
21
22#include <plat/omap_device.h>
23
24#include "omap_opp_data.h"
25
26/* Temp variable to allow multiple calls */
27static u8 __initdata omap_table_init;
28
29/**
30 * omap_init_opp_table() - Initialize opp table as per the CPU type
31 * @opp_def: opp default list for this silicon
32 * @opp_def_size: number of opp entries for this silicon
33 *
34 * Register the initial OPP table with the OPP library based on the CPU
35 * type. This is meant to be used only by SoC specific registration.
36 */
37int __init omap_init_opp_table(struct omap_opp_def *opp_def,
38 u32 opp_def_size)
39{
40 int i, r;
41
42 if (!opp_def || !opp_def_size) {
43 pr_err("%s: invalid params!\n", __func__);
44 return -EINVAL;
45 }
46
47 /*
48 * Initialize only if not already initialized even if the previous
49 * call failed, because, no reason we'd succeed again.
50 */
51 if (omap_table_init)
52 return -EEXIST;
53 omap_table_init = 1;
54
55 /* Lets now register with OPP library */
56 for (i = 0; i < opp_def_size; i++) {
57 struct omap_hwmod *oh;
58 struct device *dev;
59
60 if (!opp_def->hwmod_name) {
61 pr_err("%s: NULL name of omap_hwmod, failing [%d].\n",
62 __func__, i);
63 return -EINVAL;
64 }
65 oh = omap_hwmod_lookup(opp_def->hwmod_name);
66 if (!oh || !oh->od) {
67 pr_warn("%s: no hwmod or odev for %s, [%d] "
68 "cannot add OPPs.\n", __func__,
69 opp_def->hwmod_name, i);
70 return -EINVAL;
71 }
72 dev = &oh->od->pdev.dev;
73
74 r = opp_add(dev, opp_def->freq, opp_def->u_volt);
75 if (r) {
76 dev_err(dev, "%s: add OPP %ld failed for %s [%d] "
77 "result=%d\n",
78 __func__, opp_def->freq,
79 opp_def->hwmod_name, i, r);
80 } else {
81 if (!opp_def->default_available)
82 r = opp_disable(dev, opp_def->freq);
83 if (r)
84 dev_err(dev, "%s: disable %ld failed for %s "
85 "[%d] result=%d\n",
86 __func__, opp_def->freq,
87 opp_def->hwmod_name, i, r);
88 }
89 opp_def++;
90 }
91
92 return 0;
93}
diff --git a/arch/arm/mach-omap2/opp3xxx_data.c b/arch/arm/mach-omap2/opp3xxx_data.c
new file mode 100644
index 000000000000..0486fce8a92c
--- /dev/null
+++ b/arch/arm/mach-omap2/opp3xxx_data.c
@@ -0,0 +1,107 @@
1/*
2 * OMAP3 OPP table definitions.
3 *
4 * Copyright (C) 2009-2010 Texas Instruments Incorporated - http://www.ti.com/
5 * Nishanth Menon
6 * Kevin Hilman
7 * Copyright (C) 2010 Nokia Corporation.
8 * Eduardo Valentin
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
15 * kind, whether express or implied; without even the implied warranty
16 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19#include <linux/module.h>
20
21#include <plat/cpu.h>
22
23#include "omap_opp_data.h"
24
25static struct omap_opp_def __initdata omap34xx_opp_def_list[] = {
26 /* MPU OPP1 */
27 OPP_INITIALIZER("mpu", true, 125000000, 975000),
28 /* MPU OPP2 */
29 OPP_INITIALIZER("mpu", true, 250000000, 1075000),
30 /* MPU OPP3 */
31 OPP_INITIALIZER("mpu", true, 500000000, 1200000),
32 /* MPU OPP4 */
33 OPP_INITIALIZER("mpu", true, 550000000, 1270000),
34 /* MPU OPP5 */
35 OPP_INITIALIZER("mpu", true, 600000000, 1350000),
36
37 /*
38 * L3 OPP1 - 41.5 MHz is disabled because: The voltage for that OPP is
39 * almost the same than the one at 83MHz thus providing very little
40 * gain for the power point of view. In term of energy it will even
41 * increase the consumption due to the very negative performance
42 * impact that frequency will do to the MPU and the whole system in
43 * general.
44 */
45 OPP_INITIALIZER("l3_main", false, 41500000, 975000),
46 /* L3 OPP2 */
47 OPP_INITIALIZER("l3_main", true, 83000000, 1050000),
48 /* L3 OPP3 */
49 OPP_INITIALIZER("l3_main", true, 166000000, 1150000),
50
51 /* DSP OPP1 */
52 OPP_INITIALIZER("iva", true, 90000000, 975000),
53 /* DSP OPP2 */
54 OPP_INITIALIZER("iva", true, 180000000, 1075000),
55 /* DSP OPP3 */
56 OPP_INITIALIZER("iva", true, 360000000, 1200000),
57 /* DSP OPP4 */
58 OPP_INITIALIZER("iva", true, 400000000, 1270000),
59 /* DSP OPP5 */
60 OPP_INITIALIZER("iva", true, 430000000, 1350000),
61};
62
63static struct omap_opp_def __initdata omap36xx_opp_def_list[] = {
64 /* MPU OPP1 - OPP50 */
65 OPP_INITIALIZER("mpu", true, 300000000, 1012500),
66 /* MPU OPP2 - OPP100 */
67 OPP_INITIALIZER("mpu", true, 600000000, 1200000),
68 /* MPU OPP3 - OPP-Turbo */
69 OPP_INITIALIZER("mpu", false, 800000000, 1325000),
70 /* MPU OPP4 - OPP-SB */
71 OPP_INITIALIZER("mpu", false, 1000000000, 1375000),
72
73 /* L3 OPP1 - OPP50 */
74 OPP_INITIALIZER("l3_main", true, 100000000, 1000000),
75 /* L3 OPP2 - OPP100, OPP-Turbo, OPP-SB */
76 OPP_INITIALIZER("l3_main", true, 200000000, 1200000),
77
78 /* DSP OPP1 - OPP50 */
79 OPP_INITIALIZER("iva", true, 260000000, 1012500),
80 /* DSP OPP2 - OPP100 */
81 OPP_INITIALIZER("iva", true, 520000000, 1200000),
82 /* DSP OPP3 - OPP-Turbo */
83 OPP_INITIALIZER("iva", false, 660000000, 1325000),
84 /* DSP OPP4 - OPP-SB */
85 OPP_INITIALIZER("iva", false, 800000000, 1375000),
86};
87
88/**
89 * omap3_opp_init() - initialize omap3 opp table
90 */
91static int __init omap3_opp_init(void)
92{
93 int r = -ENODEV;
94
95 if (!cpu_is_omap34xx())
96 return r;
97
98 if (cpu_is_omap3630())
99 r = omap_init_opp_table(omap36xx_opp_def_list,
100 ARRAY_SIZE(omap36xx_opp_def_list));
101 else
102 r = omap_init_opp_table(omap34xx_opp_def_list,
103 ARRAY_SIZE(omap34xx_opp_def_list));
104
105 return r;
106}
107device_initcall(omap3_opp_init);
diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-omap2/opp4xxx_data.c
new file mode 100644
index 000000000000..a11fa566d8ee
--- /dev/null
+++ b/arch/arm/mach-omap2/opp4xxx_data.c
@@ -0,0 +1,57 @@
1/*
2 * OMAP4 OPP table definitions.
3 *
4 * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
5 * Nishanth Menon
6 * Kevin Hilman
7 * Thara Gopinath
8 * Copyright (C) 2010 Nokia Corporation.
9 * Eduardo Valentin
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 * This program is distributed "as is" WITHOUT ANY WARRANTY of any
16 * kind, whether express or implied; without even the implied warranty
17 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 */
20#include <linux/module.h>
21
22#include <plat/cpu.h>
23
24#include "omap_opp_data.h"
25
26static struct omap_opp_def __initdata omap44xx_opp_def_list[] = {
27 /* MPU OPP1 - OPP50 */
28 OPP_INITIALIZER("mpu", true, 300000000, 1100000),
29 /* MPU OPP2 - OPP100 */
30 OPP_INITIALIZER("mpu", true, 600000000, 1200000),
31 /* MPU OPP3 - OPP-Turbo */
32 OPP_INITIALIZER("mpu", false, 800000000, 1260000),
33 /* MPU OPP4 - OPP-SB */
34 OPP_INITIALIZER("mpu", false, 1008000000, 1350000),
35 /* L3 OPP1 - OPP50 */
36 OPP_INITIALIZER("l3_main_1", true, 100000000, 930000),
37 /* L3 OPP2 - OPP100, OPP-Turbo, OPP-SB */
38 OPP_INITIALIZER("l3_main_1", true, 200000000, 1100000),
39 /* TODO: add IVA, DSP, aess, fdif, gpu */
40};
41
42/**
43 * omap4_opp_init() - initialize omap4 opp table
44 */
45static int __init omap4_opp_init(void)
46{
47 int r = -ENODEV;
48
49 if (!cpu_is_omap44xx())
50 return r;
51
52 r = omap_init_opp_table(omap44xx_opp_def_list,
53 ARRAY_SIZE(omap44xx_opp_def_list));
54
55 return r;
56}
57device_initcall(omap4_opp_init);
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index c04f7b50e26f..8b4f45eba1b5 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -20,6 +20,20 @@ extern int omap3_can_sleep(void);
20extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state); 20extern int omap_set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
21extern int omap3_idle_init(void); 21extern int omap3_idle_init(void);
22 22
23#if defined(CONFIG_PM_OPP)
24extern int omap3_opp_init(void);
25extern int omap4_opp_init(void);
26#else
27static inline int omap3_opp_init(void)
28{
29 return -EINVAL;
30}
31static inline int omap4_opp_init(void)
32{
33 return -EINVAL;
34}
35#endif
36
23struct cpuidle_params { 37struct cpuidle_params {
24 u8 valid; 38 u8 valid;
25 u32 sleep_latency; 39 u32 sleep_latency;
diff --git a/arch/arm/plat-omap/include/plat/omap-pm.h b/arch/arm/plat-omap/include/plat/omap-pm.h
index 728fbb9dd549..62c3fe918ab2 100644
--- a/arch/arm/plat-omap/include/plat/omap-pm.h
+++ b/arch/arm/plat-omap/include/plat/omap-pm.h
@@ -17,27 +17,10 @@
17#include <linux/device.h> 17#include <linux/device.h>
18#include <linux/cpufreq.h> 18#include <linux/cpufreq.h>
19#include <linux/clk.h> 19#include <linux/clk.h>
20#include <linux/opp.h>
20 21
21#include "powerdomain.h" 22#include "powerdomain.h"
22 23
23/**
24 * struct omap_opp - clock frequency-to-OPP ID table for DSP, MPU
25 * @rate: target clock rate
26 * @opp_id: OPP ID
27 * @min_vdd: minimum VDD1 voltage (in millivolts) for this OPP
28 *
29 * Operating performance point data. Can vary by OMAP chip and board.
30 */
31struct omap_opp {
32 unsigned long rate;
33 u8 opp_id;
34 u16 min_vdd;
35};
36
37extern struct omap_opp *mpu_opps;
38extern struct omap_opp *dsp_opps;
39extern struct omap_opp *l3_opps;
40
41/* 24/*
42 * agent_id values for use with omap_pm_set_min_bus_tput(): 25 * agent_id values for use with omap_pm_set_min_bus_tput():
43 * 26 *
@@ -59,9 +42,11 @@ extern struct omap_opp *l3_opps;
59 * framework starts. The "_if_" is to avoid name collisions with the 42 * framework starts. The "_if_" is to avoid name collisions with the
60 * PM idle-loop code. 43 * PM idle-loop code.
61 */ 44 */
62int __init omap_pm_if_early_init(struct omap_opp *mpu_opp_table, 45#ifdef CONFIG_OMAP_PM_NONE
63 struct omap_opp *dsp_opp_table, 46#define omap_pm_if_early_init() 0
64 struct omap_opp *l3_opp_table); 47#else
48int __init omap_pm_if_early_init(void);
49#endif
65 50
66/** 51/**
67 * omap_pm_if_init - OMAP PM init code called after clock fw init 52 * omap_pm_if_init - OMAP PM init code called after clock fw init
@@ -69,7 +54,11 @@ int __init omap_pm_if_early_init(struct omap_opp *mpu_opp_table,
69 * The main initialization code. OPP tables are passed in here. The 54 * The main initialization code. OPP tables are passed in here. The
70 * "_if_" is to avoid name collisions with the PM idle-loop code. 55 * "_if_" is to avoid name collisions with the PM idle-loop code.
71 */ 56 */
57#ifdef CONFIG_OMAP_PM_NONE
58#define omap_pm_if_init() 0
59#else
72int __init omap_pm_if_init(void); 60int __init omap_pm_if_init(void);
61#endif
73 62
74/** 63/**
75 * omap_pm_if_exit - OMAP PM exit code 64 * omap_pm_if_exit - OMAP PM exit code
diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c
index e129ce80c53b..ca75abb18068 100644
--- a/arch/arm/plat-omap/omap-pm-noop.c
+++ b/arch/arm/plat-omap/omap-pm-noop.c
@@ -26,10 +26,6 @@
26 26
27#include <plat/powerdomain.h> 27#include <plat/powerdomain.h>
28 28
29struct omap_opp *dsp_opps;
30struct omap_opp *mpu_opps;
31struct omap_opp *l3_opps;
32
33/* 29/*
34 * Device-driver-originated constraints (via board-*.c files) 30 * Device-driver-originated constraints (via board-*.c files)
35 */ 31 */
@@ -308,13 +304,8 @@ int omap_pm_get_dev_context_loss_count(struct device *dev)
308 304
309 305
310/* Should be called before clk framework init */ 306/* Should be called before clk framework init */
311int __init omap_pm_if_early_init(struct omap_opp *mpu_opp_table, 307int __init omap_pm_if_early_init(void)
312 struct omap_opp *dsp_opp_table,
313 struct omap_opp *l3_opp_table)
314{ 308{
315 mpu_opps = mpu_opp_table;
316 dsp_opps = dsp_opp_table;
317 l3_opps = l3_opp_table;
318 return 0; 309 return 0;
319} 310}
320 311