Commit ebcfe0fa authored by Olof Johansson's avatar Olof Johansson

Merge tag 'omap-for-v3.9/pm-omap4-signed' of...

Merge tag 'omap-for-v3.9/pm-omap4-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into late/omap

From Tony Lindgren:
omap4 pm changes via Paul Walmsley <paul@pwsan.com>:

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/

* tag 'omap-for-v3.9/pm-omap4-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap:
  ARM: OMAP4: hwmod data: Enable AESS hwmod device
  ARM: OMAP4: hwmod data: Update AESS data with memory bank area
  ARM: OMAP4+: AESS: enable internal auto-gating during initial setup
  ASoC: TI AESS: add autogating-enable function, callable from architecture code
  ARM: OMAP2+: hwmod: add enable_preprogram hook
  ARM: OMAP2+: PM: Fix the dt return condition in pm_late_init()
  ARM: OMAP4: PM: Warn users about usage of older bootloaders
parents 488c77c9 93b23711
......@@ -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 \
omap_device.o sram.o
omap-2-3-common = irq.o
hwmod-common = omap_hwmod.o \
hwmod-common = omap_hwmod.o omap_hwmod_reset.o \
omap_hwmod_common_data.o
clock-common = clock.o clock_common_data.o \
clkt_dpll.o clkt_clksel.o
......
......@@ -2054,6 +2054,23 @@ static int _omap4_get_context_lost(struct omap_hwmod *oh)
return oh->prcm.omap4.context_lost_counter;
}
/**
* _enable_preprogram - Pre-program an IP block during the _enable() process
* @oh: struct omap_hwmod *
*
* Some IP blocks (such as AESS) require some additional programming
* after enable before they can enter idle. If a function pointer to
* do so is present in the hwmod data, then call it and pass along the
* return value; otherwise, return 0.
*/
static int __init _enable_preprogram(struct omap_hwmod *oh)
{
if (!oh->class->enable_preprogram)
return 0;
return oh->class->enable_preprogram(oh);
}
/**
* _enable - enable an omap_hwmod
* @oh: struct omap_hwmod *
......@@ -2160,6 +2177,7 @@ static int _enable(struct omap_hwmod *oh)
_update_sysc_cache(oh);
_enable_sysc(oh);
}
r = _enable_preprogram(oh);
} else {
if (soc_ops.disable_module)
soc_ops.disable_module(oh);
......
......@@ -510,6 +510,7 @@ struct omap_hwmod_omap4_prcm {
* @rev: revision of the IP class
* @pre_shutdown: ptr to fn to be executed immediately prior to device shutdown
* @reset: ptr to fn to be executed in place of the standard hwmod reset fn
* @enable_preprogram: ptr to fn to be executed during device enable
*
* Represent the class of a OMAP hardware "modules" (e.g. timer,
* smartreflex, gpio, uart...)
......@@ -533,6 +534,7 @@ struct omap_hwmod_class {
u32 rev;
int (*pre_shutdown)(struct omap_hwmod *oh);
int (*reset)(struct omap_hwmod *oh);
int (*enable_preprogram)(struct omap_hwmod *oh);
};
/**
......@@ -679,6 +681,12 @@ extern void __init omap_hwmod_init(void);
const char *omap_hwmod_get_main_clk(struct omap_hwmod *oh);
/*
*
*/
extern int omap_hwmod_aess_preprogram(struct omap_hwmod *oh);
/*
* Chip variant-specific hwmod init routines - XXX should be converted
* to use initcalls once the initial boot ordering is straightened out
......
......@@ -322,6 +322,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_aess_sysc = {
static struct omap_hwmod_class omap44xx_aess_hwmod_class = {
.name = "aess",
.sysc = &omap44xx_aess_sysc,
.enable_preprogram = omap_hwmod_aess_preprogram,
};
/* aess */
......@@ -348,7 +349,7 @@ static struct omap_hwmod omap44xx_aess_hwmod = {
.clkdm_name = "abe_clkdm",
.mpu_irqs = omap44xx_aess_irqs,
.sdma_reqs = omap44xx_aess_sdma_reqs,
.main_clk = "aess_fck",
.main_clk = "aess_fclk",
.prcm = {
.omap4 = {
.clkctrl_offs = OMAP4_CM1_ABE_AESS_CLKCTRL_OFFSET,
......@@ -4248,6 +4249,27 @@ static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ocp_wp_noc = {
static struct omap_hwmod_addr_space omap44xx_aess_addrs[] = {
{
.name = "dmem",
.pa_start = 0x40180000,
.pa_end = 0x4018ffff
},
{
.name = "cmem",
.pa_start = 0x401a0000,
.pa_end = 0x401a1fff
},
{
.name = "smem",
.pa_start = 0x401c0000,
.pa_end = 0x401c5fff
},
{
.name = "pmem",
.pa_start = 0x401e0000,
.pa_end = 0x401e1fff
},
{
.name = "mpu",
.pa_start = 0x401f1000,
.pa_end = 0x401f13ff,
.flags = ADDR_TYPE_RT
......@@ -4266,6 +4288,27 @@ static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l4_abe__aess = {
static struct omap_hwmod_addr_space omap44xx_aess_dma_addrs[] = {
{
.name = "dmem_dma",
.pa_start = 0x49080000,
.pa_end = 0x4908ffff
},
{
.name = "cmem_dma",
.pa_start = 0x490a0000,
.pa_end = 0x490a1fff
},
{
.name = "smem_dma",
.pa_start = 0x490c0000,
.pa_end = 0x490c5fff
},
{
.name = "pmem_dma",
.pa_start = 0x490e0000,
.pa_end = 0x490e1fff
},
{
.name = "dma",
.pa_start = 0x490f1000,
.pa_end = 0x490f13ff,
.flags = ADDR_TYPE_RT
......@@ -6281,7 +6324,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
&omap44xx_l3_main_1__l3_main_3,
&omap44xx_l3_main_2__l3_main_3,
&omap44xx_l4_cfg__l3_main_3,
/* &omap44xx_aess__l4_abe, */
&omap44xx_aess__l4_abe,
&omap44xx_dsp__l4_abe,
&omap44xx_l3_main_1__l4_abe,
&omap44xx_mpu__l4_abe,
......@@ -6290,8 +6333,8 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
&omap44xx_l4_cfg__l4_wkup,
&omap44xx_mpu__mpu_private,
&omap44xx_l4_cfg__ocp_wp_noc,
/* &omap44xx_l4_abe__aess, */
/* &omap44xx_l4_abe__aess_dma, */
&omap44xx_l4_abe__aess,
&omap44xx_l4_abe__aess_dma,
&omap44xx_l3_main_2__c2c,
&omap44xx_l4_wkup__counter_32k,
&omap44xx_l4_cfg__ctrl_module_core,
......
/*
* OMAP IP block custom reset and preprogramming stubs
*
* Copyright (C) 2012 Texas Instruments, Inc.
* Paul Walmsley
*
* A small number of IP blocks need custom reset and preprogramming
* functions. The stubs in this file provide a standard way for the
* hwmod code to call these functions, which are to be located under
* drivers/.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#include <linux/kernel.h>
#include <sound/aess.h>
#include "omap_hwmod.h"
/**
* omap_hwmod_aess_preprogram - enable AESS internal autogating
* @oh: struct omap_hwmod *
*
* The AESS will not IdleAck to the PRCM until its internal autogating
* is enabled. Since internal autogating is disabled by default after
* AESS reset, we must enable autogating after the hwmod code resets
* the AESS. Returns 0.
*/
int omap_hwmod_aess_preprogram(struct omap_hwmod *oh)
{
void __iomem *va;
va = omap_hwmod_get_mpu_rt_va(oh);
if (!va)
return -EINVAL;
aess_enable_autogating(va);
return 0;
}
......@@ -282,19 +282,19 @@ int __init omap2_common_pm_late_init(void)
* a completely different mechanism.
* Disable this part if a DT blob is available.
*/
if (of_have_populated_dt())
return 0;
if (!of_have_populated_dt()) {
/* Init the voltage layer */
omap_pmic_late_init();
omap_voltage_late_init();
/* Init the voltage layer */
omap_pmic_late_init();
omap_voltage_late_init();
/* Initialize the voltages */
omap3_init_voltages();
omap4_init_voltages();
/* Initialize the voltages */
omap3_init_voltages();
omap4_init_voltages();
/* Smartreflex device init */
omap_devinit_smartreflex();
/* Smartreflex device init */
omap_devinit_smartreflex();
}
#ifdef CONFIG_SUSPEND
suspend_set_ops(&omap_pm_ops);
......
......@@ -77,10 +77,20 @@ static int omap4_pm_suspend(void)
omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state);
pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->saved_logic_state);
}
if (ret)
if (ret) {
pr_crit("Could not enter target state in pm_suspend\n");
else
/*
* OMAP4 chip PM currently works only with certain (newer)
* versions of bootloaders. This is due to missing code in the
* kernel to properly reset and initialize some devices.
* Warn the user about the bootloader version being one of the
* possible causes.
* http://www.spinics.net/lists/arm-kernel/msg218641.html
*/
pr_warn("A possible cause could be an old bootloader - try u-boot >= v2012.07\n");
} else {
pr_info("Successfully put all powerdomains to target state\n");
}
return 0;
}
......@@ -146,6 +156,13 @@ int __init omap4_pm_init(void)
}
pr_err("Power Management for TI OMAP4.\n");
/*
* OMAP4 chip PM currently works only with certain (newer)
* versions of bootloaders. This is due to missing code in the
* kernel to properly reset and initialize some devices.
* http://www.spinics.net/lists/arm-kernel/msg218641.html
*/
pr_warn("OMAP4 PM: u-boot >= v2012.07 is required for full PM support\n");
ret = pwrdm_for_each(pwrdms_setup, NULL);
if (ret) {
......
/*
* AESS IP block reset
*
* Copyright (C) 2012 Texas Instruments, Inc.
* Paul Walmsley
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any
* kind, whether express or implied; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA
*/
#ifndef __SOUND_AESS_H__
#define __SOUND_AESS_H__
#include <linux/kernel.h>
#include <linux/io.h>
/*
* AESS_AUTO_GATING_ENABLE_OFFSET: offset in bytes of the AESS IP
* block's AESS_AUTO_GATING_ENABLE__1 register from the IP block's
* base address
*/
#define AESS_AUTO_GATING_ENABLE_OFFSET 0x07c
/* Register bitfields in the AESS_AUTO_GATING_ENABLE__1 register */
#define AESS_AUTO_GATING_ENABLE_SHIFT 0
/**
* aess_enable_autogating - enable AESS internal autogating
* @oh: struct omap_hwmod *
*
* Enable internal autogating on the AESS. This allows the AESS to
* indicate that it is idle to the OMAP PRCM. Returns 0.
*/
static inline void aess_enable_autogating(void __iomem *base)
{
u32 v;
/* Set AESS_AUTO_GATING_ENABLE__1.ENABLE to allow idle entry */
v = 1 << AESS_AUTO_GATING_ENABLE_SHIFT;
writel(v, base + AESS_AUTO_GATING_ENABLE_OFFSET);
}
#endif /* __SOUND_AESS_H__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment