Skip to content

Commit 93b2371

Browse files
committed
Merge tag 'omap-devel-d2-for-3.9' of git://git.kernel.org/pub/scm/linux/kernel/git/pjw/omap-pending into omap-for-v3.9/pm-omap4
Some OMAP4 power management fixes and audio device integration patches. This pull request contains a fix for an issue discovered during branch integration. Basic test logs are available at: http://www.pwsan.com/omap/testlogs/omap4_prcm_devel_a_3.9/20130210112717/
2 parents 88b62b9 + a5a8c31 commit 93b2371

File tree

8 files changed

+208
-17
lines changed

8 files changed

+208
-17
lines changed

arch/arm/mach-omap2/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ obj-y := id.o io.o control.o mux.o devices.o fb.o serial.o gpmc.o timer.o pm.o \
88
omap_device.o sram.o
99

1010
omap-2-3-common= irq.o
11-
hwmod-common= omap_hwmod.o \
11+
hwmod-common= omap_hwmod.o omap_hwmod_reset.o \
1212
omap_hwmod_common_data.o
1313
clock-common= clock.o clock_common_data.o \
1414
clkt_dpll.o clkt_clksel.o

arch/arm/mach-omap2/omap_hwmod.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2052,6 +2052,23 @@ static int _omap4_get_context_lost(struct omap_hwmod *oh)
20522052
return oh->prcm.omap4.context_lost_counter;
20532053
}
20542054

2055+
/**
2056+
* _enable_preprogram - Pre-program an IP block during the _enable() process
2057+
* @oh: struct omap_hwmod *
2058+
*
2059+
* Some IP blocks (such as AESS) require some additional programming
2060+
* after enable before they can enter idle. If a function pointer to
2061+
* do so is present in the hwmod data, then call it and pass along the
2062+
* return value; otherwise, return 0.
2063+
*/
2064+
static int __init _enable_preprogram(struct omap_hwmod *oh)
2065+
{
2066+
if (!oh->class->enable_preprogram)
2067+
return 0;
2068+
2069+
return oh->class->enable_preprogram(oh);
2070+
}
2071+
20552072
/**
20562073
* _enable - enable an omap_hwmod
20572074
* @oh: struct omap_hwmod *
@@ -2156,6 +2173,7 @@ static int _enable(struct omap_hwmod *oh)
21562173
_update_sysc_cache(oh);
21572174
_enable_sysc(oh);
21582175
}
2176+
r = _enable_preprogram(oh);
21592177
} else {
21602178
if (soc_ops.disable_module)
21612179
soc_ops.disable_module(oh);

arch/arm/mach-omap2/omap_hwmod.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,7 @@ struct omap_hwmod_omap4_prcm {
501501
* @rev: revision of the IP class
502502
* @pre_shutdown: ptr to fn to be executed immediately prior to device shutdown
503503
* @reset: ptr to fn to be executed in place of the standard hwmod reset fn
504+
* @enable_preprogram: ptr to fn to be executed during device enable
504505
*
505506
* Represent the class of a OMAP hardware "modules" (e.g. timer,
506507
* smartreflex, gpio, uart...)
@@ -524,6 +525,7 @@ struct omap_hwmod_class {
524525
u32rev;
525526
int(*pre_shutdown)(struct omap_hwmod *oh);
526527
int(*reset)(struct omap_hwmod *oh);
528+
int(*enable_preprogram)(struct omap_hwmod *oh);
527529
};
528530

529531
/**
@@ -670,6 +672,12 @@ extern void __init omap_hwmod_init(void);
670672

671673
const char *omap_hwmod_get_main_clk(struct omap_hwmod *oh);
672674

675+
/*
676+
*
677+
*/
678+
679+
extern int omap_hwmod_aess_preprogram(struct omap_hwmod *oh);
680+
673681
/*
674682
* Chip variant-specific hwmod init routines - XXX should be converted
675683
* to use initcalls once the initial boot ordering is straightened out

arch/arm/mach-omap2/omap_hwmod_44xx_data.c

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_aess_sysc = {
322322
static struct omap_hwmod_class omap44xx_aess_hwmod_class = {
323323
.name= "aess",
324324
.sysc= &omap44xx_aess_sysc,
325+
.enable_preprogram = omap_hwmod_aess_preprogram,
325326
};
326327

327328
/* aess */
@@ -348,7 +349,7 @@ static struct omap_hwmod omap44xx_aess_hwmod = {
348349
.clkdm_name= "abe_clkdm",
349350
.mpu_irqs= omap44xx_aess_irqs,
350351
.sdma_reqs= omap44xx_aess_sdma_reqs,
351-
.main_clk= "aess_fck",
352+
.main_clk= "aess_fclk",
352353
.prcm = {
353354
.omap4 = {
354355
.clkctrl_offs = OMAP4_CM1_ABE_AESS_CLKCTRL_OFFSET,
@@ -4249,6 +4250,27 @@ static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ocp_wp_noc = {
42494250

42504251
static struct omap_hwmod_addr_space omap44xx_aess_addrs[] = {
42514252
{
4253+
.name= "dmem",
4254+
.pa_start= 0x40180000,
4255+
.pa_end= 0x4018ffff
4256+
},
4257+
{
4258+
.name= "cmem",
4259+
.pa_start= 0x401a0000,
4260+
.pa_end= 0x401a1fff
4261+
},
4262+
{
4263+
.name= "smem",
4264+
.pa_start= 0x401c0000,
4265+
.pa_end= 0x401c5fff
4266+
},
4267+
{
4268+
.name= "pmem",
4269+
.pa_start= 0x401e0000,
4270+
.pa_end= 0x401e1fff
4271+
},
4272+
{
4273+
.name= "mpu",
42524274
.pa_start= 0x401f1000,
42534275
.pa_end= 0x401f13ff,
42544276
.flags= ADDR_TYPE_RT
@@ -4267,6 +4289,27 @@ static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l4_abe__aess = {
42674289

42684290
static struct omap_hwmod_addr_space omap44xx_aess_dma_addrs[] = {
42694291
{
4292+
.name= "dmem_dma",
4293+
.pa_start= 0x49080000,
4294+
.pa_end= 0x4908ffff
4295+
},
4296+
{
4297+
.name= "cmem_dma",
4298+
.pa_start= 0x490a0000,
4299+
.pa_end= 0x490a1fff
4300+
},
4301+
{
4302+
.name= "smem_dma",
4303+
.pa_start= 0x490c0000,
4304+
.pa_end= 0x490c5fff
4305+
},
4306+
{
4307+
.name= "pmem_dma",
4308+
.pa_start= 0x490e0000,
4309+
.pa_end= 0x490e1fff
4310+
},
4311+
{
4312+
.name= "dma",
42704313
.pa_start= 0x490f1000,
42714314
.pa_end= 0x490f13ff,
42724315
.flags= ADDR_TYPE_RT
@@ -6282,7 +6325,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
62826325
&omap44xx_l3_main_1__l3_main_3,
62836326
&omap44xx_l3_main_2__l3_main_3,
62846327
&omap44xx_l4_cfg__l3_main_3,
6285-
/* &omap44xx_aess__l4_abe, */
6328+
&omap44xx_aess__l4_abe,
62866329
&omap44xx_dsp__l4_abe,
62876330
&omap44xx_l3_main_1__l4_abe,
62886331
&omap44xx_mpu__l4_abe,
@@ -6291,8 +6334,8 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
62916334
&omap44xx_l4_cfg__l4_wkup,
62926335
&omap44xx_mpu__mpu_private,
62936336
&omap44xx_l4_cfg__ocp_wp_noc,
6294-
/* &omap44xx_l4_abe__aess, */
6295-
/* &omap44xx_l4_abe__aess_dma, */
6337+
&omap44xx_l4_abe__aess,
6338+
&omap44xx_l4_abe__aess_dma,
62966339
&omap44xx_l3_main_2__c2c,
62976340
&omap44xx_l4_wkup__counter_32k,
62986341
&omap44xx_l4_cfg__ctrl_module_core,
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* OMAP IP block custom reset and preprogramming stubs
3+
*
4+
* Copyright (C) 2012 Texas Instruments, Inc.
5+
* Paul Walmsley
6+
*
7+
* A small number of IP blocks need custom reset and preprogramming
8+
* functions. The stubs in this file provide a standard way for the
9+
* hwmod code to call these functions, which are to be located under
10+
* drivers/.
11+
*
12+
* This program is free software; you can redistribute it and/or
13+
* modify it under the terms of the GNU General Public License as
14+
* published by the Free Software Foundation version 2.
15+
*
16+
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
17+
* kind, whether express or implied; without even the implied warranty
18+
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19+
* GNU General Public License for more details.
20+
*
21+
* You should have received a copy of the GNU General Public License
22+
* along with this program; if not, write to the Free Software
23+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24+
* 02110-1301 USA
25+
*/
26+
#include <linux/kernel.h>
27+
28+
#include <sound/aess.h>
29+
30+
#include "omap_hwmod.h"
31+
32+
/**
33+
* omap_hwmod_aess_preprogram - enable AESS internal autogating
34+
* @oh: struct omap_hwmod *
35+
*
36+
* The AESS will not IdleAck to the PRCM until its internal autogating
37+
* is enabled. Since internal autogating is disabled by default after
38+
* AESS reset, we must enable autogating after the hwmod code resets
39+
* the AESS. Returns 0.
40+
*/
41+
int omap_hwmod_aess_preprogram(struct omap_hwmod *oh)
42+
{
43+
void __iomem *va;
44+
45+
va = omap_hwmod_get_mpu_rt_va(oh);
46+
if (!va)
47+
return -EINVAL;
48+
49+
aess_enable_autogating(va);
50+
51+
return 0;
52+
}

arch/arm/mach-omap2/pm.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -345,19 +345,19 @@ int __init omap2_common_pm_late_init(void)
345345
* a completely different mechanism.
346346
* Disable this part if a DT blob is available.
347347
*/
348-
if (of_have_populated_dt())
349-
return 0;
348+
if (!of_have_populated_dt()) {
350349

351-
/* Init the voltage layer */
352-
omap_pmic_late_init();
353-
omap_voltage_late_init();
350+
/* Init the voltage layer */
351+
omap_pmic_late_init();
352+
omap_voltage_late_init();
354353

355-
/* Initialize the voltages */
356-
omap3_init_voltages();
357-
omap4_init_voltages();
354+
/* Initialize the voltages */
355+
omap3_init_voltages();
356+
omap4_init_voltages();
358357

359-
/* Smartreflex device init */
360-
omap_devinit_smartreflex();
358+
/* Smartreflex device init */
359+
omap_devinit_smartreflex();
360+
}
361361

362362
#ifdef CONFIG_SUSPEND
363363
suspend_set_ops(&omap_pm_ops);

arch/arm/mach-omap2/pm44xx.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,20 @@ static int omap4_pm_suspend(void)
7777
omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
7878
pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->saved_logic_state);
7979
}
80-
if (ret)
80+
if (ret) {
8181
pr_crit("Could not enter target state in pm_suspend\n");
82-
else
82+
/*
83+
* OMAP4 chip PM currently works only with certain (newer)
84+
* versions of bootloaders. This is due to missing code in the
85+
* kernel to properly reset and initialize some devices.
86+
* Warn the user about the bootloader version being one of the
87+
* possible causes.
88+
* http://www.spinics.net/lists/arm-kernel/msg218641.html
89+
*/
90+
pr_warn("A possible cause could be an old bootloader - try u-boot >= v2012.07\n");
91+
} else {
8392
pr_info("Successfully put all powerdomains to target state\n");
93+
}
8494

8595
return 0;
8696
}
@@ -146,6 +156,13 @@ int __init omap4_pm_init(void)
146156
}
147157

148158
pr_err("Power Management for TI OMAP4.\n");
159+
/*
160+
* OMAP4 chip PM currently works only with certain (newer)
161+
* versions of bootloaders. This is due to missing code in the
162+
* kernel to properly reset and initialize some devices.
163+
* http://www.spinics.net/lists/arm-kernel/msg218641.html
164+
*/
165+
pr_warn("OMAP4 PM: u-boot >= v2012.07 is required for full PM support\n");
149166

150167
ret = pwrdm_for_each(pwrdms_setup, NULL);
151168
if (ret) {

include/sound/aess.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* AESS IP block reset
3+
*
4+
* Copyright (C) 2012 Texas Instruments, Inc.
5+
* Paul Walmsley
6+
*
7+
* This program is free software; you can redistribute it and/or
8+
* modify it under the terms of the GNU General Public License as
9+
* published by the Free Software Foundation version 2.
10+
*
11+
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
12+
* kind, whether express or implied; without even the implied warranty
13+
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+
* GNU General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU General Public License
17+
* along with this program; if not, write to the Free Software
18+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19+
* 02110-1301 USA
20+
*/
21+
#ifndef __SOUND_AESS_H__
22+
#define __SOUND_AESS_H__
23+
24+
#include <linux/kernel.h>
25+
#include <linux/io.h>
26+
27+
/*
28+
* AESS_AUTO_GATING_ENABLE_OFFSET: offset in bytes of the AESS IP
29+
* block's AESS_AUTO_GATING_ENABLE__1 register from the IP block's
30+
* base address
31+
*/
32+
#define AESS_AUTO_GATING_ENABLE_OFFSET0x07c
33+
34+
/* Register bitfields in the AESS_AUTO_GATING_ENABLE__1 register */
35+
#define AESS_AUTO_GATING_ENABLE_SHIFT0
36+
37+
/**
38+
* aess_enable_autogating - enable AESS internal autogating
39+
* @oh: struct omap_hwmod *
40+
*
41+
* Enable internal autogating on the AESS. This allows the AESS to
42+
* indicate that it is idle to the OMAP PRCM. Returns 0.
43+
*/
44+
static inline void aess_enable_autogating(void __iomem *base)
45+
{
46+
u32 v;
47+
48+
/* Set AESS_AUTO_GATING_ENABLE__1.ENABLE to allow idle entry */
49+
v = 1 << AESS_AUTO_GATING_ENABLE_SHIFT;
50+
writel(v, base + AESS_AUTO_GATING_ENABLE_OFFSET);
51+
}
52+
53+
#endif /* __SOUND_AESS_H__ */

0 commit comments

Comments
 (0)