mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-19 18:24:14 +08:00
Merge branch 'pull/v3.18/for-omap-soc' of https://github.com/nmenon/linux-2.6-playground into omap-for-v3.18/soc
This commit is contained in:
commit
887782e04f
@ -60,7 +60,7 @@ static inline int omap3_pm_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
|
||||
#if defined(CONFIG_PM) && (defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5))
|
||||
int omap4_pm_init(void);
|
||||
int omap4_pm_init_early(void);
|
||||
#else
|
||||
|
@ -667,6 +667,7 @@ void __init omap5_init_early(void)
|
||||
omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_AON_BASE),
|
||||
OMAP2_L4_IO_ADDRESS(OMAP54XX_CM_CORE_BASE));
|
||||
omap2_set_globals_prcm_mpu(OMAP2_L4_IO_ADDRESS(OMAP54XX_PRCM_MPU_BASE));
|
||||
omap4_pm_init_early();
|
||||
omap_prm_base_init();
|
||||
omap_cm_base_init();
|
||||
omap44xx_prm_init();
|
||||
@ -682,6 +683,8 @@ void __init omap5_init_early(void)
|
||||
void __init omap5_init_late(void)
|
||||
{
|
||||
omap_common_late_init();
|
||||
omap4_pm_init();
|
||||
omap2_clk_enable_autoidle_all();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -56,6 +56,7 @@
|
||||
#include "omap4-sar-layout.h"
|
||||
#include "pm.h"
|
||||
#include "prcm_mpu44xx.h"
|
||||
#include "prcm_mpu54xx.h"
|
||||
#include "prminst44xx.h"
|
||||
#include "prcm44xx.h"
|
||||
#include "prm44xx.h"
|
||||
@ -68,7 +69,6 @@ struct omap4_cpu_pm_info {
|
||||
void __iomem *scu_sar_addr;
|
||||
void __iomem *wkup_sar_addr;
|
||||
void __iomem *l2x0_sar_addr;
|
||||
void (*secondary_startup)(void);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -76,6 +76,7 @@ struct omap4_cpu_pm_info {
|
||||
* @finish_suspend: CPU suspend finisher function pointer
|
||||
* @resume: CPU resume function pointer
|
||||
* @scu_prepare: CPU Snoop Control program function pointer
|
||||
* @hotplug_restart: CPU restart function pointer
|
||||
*
|
||||
* Structure holds functions pointer for CPU low power operations like
|
||||
* suspend, resume and scu programming.
|
||||
@ -84,11 +85,13 @@ struct cpu_pm_ops {
|
||||
int (*finish_suspend)(unsigned long cpu_state);
|
||||
void (*resume)(void);
|
||||
void (*scu_prepare)(unsigned int cpu_id, unsigned int cpu_state);
|
||||
void (*hotplug_restart)(void);
|
||||
};
|
||||
|
||||
static DEFINE_PER_CPU(struct omap4_cpu_pm_info, omap4_pm_info);
|
||||
static struct powerdomain *mpuss_pd;
|
||||
static void __iomem *sar_base;
|
||||
static u32 cpu_context_offset;
|
||||
|
||||
static int default_finish_suspend(unsigned long cpu_state)
|
||||
{
|
||||
@ -106,6 +109,7 @@ struct cpu_pm_ops omap_pm_ops = {
|
||||
.finish_suspend = default_finish_suspend,
|
||||
.resume = dummy_cpu_resume,
|
||||
.scu_prepare = dummy_scu_prepare,
|
||||
.hotplug_restart = dummy_cpu_resume,
|
||||
};
|
||||
|
||||
/*
|
||||
@ -116,7 +120,8 @@ static inline void set_cpu_wakeup_addr(unsigned int cpu_id, u32 addr)
|
||||
{
|
||||
struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
|
||||
|
||||
writel_relaxed(addr, pm_info->wkup_sar_addr);
|
||||
if (pm_info->wkup_sar_addr)
|
||||
writel_relaxed(addr, pm_info->wkup_sar_addr);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -141,7 +146,8 @@ static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state)
|
||||
break;
|
||||
}
|
||||
|
||||
writel_relaxed(scu_pwr_st, pm_info->scu_sar_addr);
|
||||
if (pm_info->scu_sar_addr)
|
||||
writel_relaxed(scu_pwr_st, pm_info->scu_sar_addr);
|
||||
}
|
||||
|
||||
/* Helper functions for MPUSS OSWR */
|
||||
@ -161,14 +167,14 @@ static inline void cpu_clear_prev_logic_pwrst(unsigned int cpu_id)
|
||||
|
||||
if (cpu_id) {
|
||||
reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU1_INST,
|
||||
OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET);
|
||||
cpu_context_offset);
|
||||
omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU1_INST,
|
||||
OMAP4_RM_CPU1_CPU1_CONTEXT_OFFSET);
|
||||
cpu_context_offset);
|
||||
} else {
|
||||
reg = omap4_prcm_mpu_read_inst_reg(OMAP4430_PRCM_MPU_CPU0_INST,
|
||||
OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET);
|
||||
cpu_context_offset);
|
||||
omap4_prcm_mpu_write_inst_reg(reg, OMAP4430_PRCM_MPU_CPU0_INST,
|
||||
OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET);
|
||||
cpu_context_offset);
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,7 +185,8 @@ static void l2x0_pwrst_prepare(unsigned int cpu_id, unsigned int save_state)
|
||||
{
|
||||
struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id);
|
||||
|
||||
writel_relaxed(save_state, pm_info->l2x0_sar_addr);
|
||||
if (pm_info->l2x0_sar_addr)
|
||||
writel_relaxed(save_state, pm_info->l2x0_sar_addr);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -189,10 +196,14 @@ static void l2x0_pwrst_prepare(unsigned int cpu_id, unsigned int save_state)
|
||||
#ifdef CONFIG_CACHE_L2X0
|
||||
static void __init save_l2x0_context(void)
|
||||
{
|
||||
writel_relaxed(l2x0_saved_regs.aux_ctrl,
|
||||
sar_base + L2X0_AUXCTRL_OFFSET);
|
||||
writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
|
||||
sar_base + L2X0_PREFETCH_CTRL_OFFSET);
|
||||
void __iomem *l2x0_base = omap4_get_l2cache_base();
|
||||
|
||||
if (l2x0_base && sar_base) {
|
||||
writel_relaxed(l2x0_saved_regs.aux_ctrl,
|
||||
sar_base + L2X0_AUXCTRL_OFFSET);
|
||||
writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
|
||||
sar_base + L2X0_PREFETCH_CTRL_OFFSET);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void __init save_l2x0_context(void)
|
||||
@ -231,6 +242,10 @@ int omap4_enter_lowpower(unsigned int cpu, unsigned int power_state)
|
||||
save_state = 1;
|
||||
break;
|
||||
case PWRDM_POWER_RET:
|
||||
if (IS_PM44XX_ERRATUM(PM_OMAP4_CPU_OSWR_DISABLE)) {
|
||||
save_state = 0;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
/*
|
||||
* CPUx CSWR is invalid hardware state. Also CPUx OSWR
|
||||
@ -307,7 +322,7 @@ int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
|
||||
|
||||
pwrdm_clear_all_prev_pwrst(pm_info->pwrdm);
|
||||
pwrdm_set_next_pwrst(pm_info->pwrdm, power_state);
|
||||
set_cpu_wakeup_addr(cpu, virt_to_phys(pm_info->secondary_startup));
|
||||
set_cpu_wakeup_addr(cpu, virt_to_phys(omap_pm_ops.hotplug_restart));
|
||||
omap_pm_ops.scu_prepare(cpu, power_state);
|
||||
|
||||
/*
|
||||
@ -322,6 +337,21 @@ int omap4_hotplug_cpu(unsigned int cpu, unsigned int power_state)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Enable Mercury Fast HG retention mode by default.
|
||||
*/
|
||||
static void enable_mercury_retention_mode(void)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = omap4_prcm_mpu_read_inst_reg(OMAP54XX_PRCM_MPU_DEVICE_INST,
|
||||
OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET);
|
||||
/* Enable HG_EN, HG_RAMPUP = fast mode */
|
||||
reg |= BIT(24) | BIT(25);
|
||||
omap4_prcm_mpu_write_inst_reg(reg, OMAP54XX_PRCM_MPU_DEVICE_INST,
|
||||
OMAP54XX_PRCM_MPU_PRM_PSCON_COUNT_OFFSET);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise OMAP4 MPUSS
|
||||
*/
|
||||
@ -334,13 +364,17 @@ int __init omap4_mpuss_init(void)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
sar_base = omap4_get_sar_ram_base();
|
||||
if (cpu_is_omap44xx())
|
||||
sar_base = omap4_get_sar_ram_base();
|
||||
|
||||
/* Initilaise per CPU PM information */
|
||||
pm_info = &per_cpu(omap4_pm_info, 0x0);
|
||||
pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
|
||||
pm_info->wkup_sar_addr = sar_base + CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
|
||||
pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0;
|
||||
if (sar_base) {
|
||||
pm_info->scu_sar_addr = sar_base + SCU_OFFSET0;
|
||||
pm_info->wkup_sar_addr = sar_base +
|
||||
CPU0_WAKEUP_NS_PA_ADDR_OFFSET;
|
||||
pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET0;
|
||||
}
|
||||
pm_info->pwrdm = pwrdm_lookup("cpu0_pwrdm");
|
||||
if (!pm_info->pwrdm) {
|
||||
pr_err("Lookup failed for CPU0 pwrdm\n");
|
||||
@ -355,13 +389,12 @@ int __init omap4_mpuss_init(void)
|
||||
pwrdm_set_next_pwrst(pm_info->pwrdm, PWRDM_POWER_ON);
|
||||
|
||||
pm_info = &per_cpu(omap4_pm_info, 0x1);
|
||||
pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
|
||||
pm_info->wkup_sar_addr = sar_base + CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
|
||||
pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
|
||||
if (cpu_is_omap446x())
|
||||
pm_info->secondary_startup = omap4460_secondary_startup;
|
||||
else
|
||||
pm_info->secondary_startup = omap4_secondary_startup;
|
||||
if (sar_base) {
|
||||
pm_info->scu_sar_addr = sar_base + SCU_OFFSET1;
|
||||
pm_info->wkup_sar_addr = sar_base +
|
||||
CPU1_WAKEUP_NS_PA_ADDR_OFFSET;
|
||||
pm_info->l2x0_sar_addr = sar_base + L2X0_SAVE_OFFSET1;
|
||||
}
|
||||
|
||||
pm_info->pwrdm = pwrdm_lookup("cpu1_pwrdm");
|
||||
if (!pm_info->pwrdm) {
|
||||
@ -384,20 +417,27 @@ int __init omap4_mpuss_init(void)
|
||||
pwrdm_clear_all_prev_pwrst(mpuss_pd);
|
||||
mpuss_clear_prev_logic_pwrst();
|
||||
|
||||
/* Save device type on scratchpad for low level code to use */
|
||||
if (omap_type() != OMAP2_DEVICE_TYPE_GP)
|
||||
writel_relaxed(1, sar_base + OMAP_TYPE_OFFSET);
|
||||
else
|
||||
writel_relaxed(0, sar_base + OMAP_TYPE_OFFSET);
|
||||
|
||||
save_l2x0_context();
|
||||
if (sar_base) {
|
||||
/* Save device type on scratchpad for low level code to use */
|
||||
writel_relaxed((omap_type() != OMAP2_DEVICE_TYPE_GP) ? 1 : 0,
|
||||
sar_base + OMAP_TYPE_OFFSET);
|
||||
save_l2x0_context();
|
||||
}
|
||||
|
||||
if (cpu_is_omap44xx()) {
|
||||
omap_pm_ops.finish_suspend = omap4_finish_suspend;
|
||||
omap_pm_ops.resume = omap4_cpu_resume;
|
||||
omap_pm_ops.scu_prepare = scu_pwrst_prepare;
|
||||
omap_pm_ops.hotplug_restart = omap4_secondary_startup;
|
||||
cpu_context_offset = OMAP4_RM_CPU0_CPU0_CONTEXT_OFFSET;
|
||||
} else if (soc_is_omap54xx() || soc_is_dra7xx()) {
|
||||
cpu_context_offset = OMAP54XX_RM_CPU0_CPU0_CONTEXT_OFFSET;
|
||||
enable_mercury_retention_mode();
|
||||
}
|
||||
|
||||
if (cpu_is_omap446x())
|
||||
omap_pm_ops.hotplug_restart = omap4460_secondary_startup;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,7 @@
|
||||
#define OMAP4_MON_L2X0_PREFETCH_INDEX 0x113
|
||||
|
||||
#define OMAP5_DRA7_MON_SET_CNTFRQ_INDEX 0x109
|
||||
#define OMAP5_MON_AMBA_IF_INDEX 0x108
|
||||
|
||||
/* Secure PPA(Primary Protected Application) APIs */
|
||||
#define OMAP4_PPA_L2_POR_INDEX 0x23
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include "soc.h"
|
||||
#include "omap4-sar-layout.h"
|
||||
#include "common.h"
|
||||
#include "pm.h"
|
||||
|
||||
#define AM43XX_NR_REG_BANKS 7
|
||||
#define AM43XX_IRQS 224
|
||||
@ -381,7 +382,7 @@ static struct notifier_block irq_notifier_block = {
|
||||
static void __init irq_pm_init(void)
|
||||
{
|
||||
/* FIXME: Remove this when MPU OSWR support is added */
|
||||
if (!soc_is_omap54xx())
|
||||
if (!IS_PM44XX_ERRATUM(PM_OMAP4_CPU_OSWR_DISABLE))
|
||||
cpu_pm_register_notifier(&irq_notifier_block);
|
||||
}
|
||||
#else
|
||||
@ -406,6 +407,7 @@ int __init omap_wakeupgen_init(void)
|
||||
{
|
||||
int i;
|
||||
unsigned int boot_cpu = smp_processor_id();
|
||||
u32 val;
|
||||
|
||||
/* Not supported on OMAP4 ES1.0 silicon */
|
||||
if (omap_rev() == OMAP4430_REV_ES1_0) {
|
||||
@ -451,6 +453,22 @@ int __init omap_wakeupgen_init(void)
|
||||
for (i = 0; i < max_irqs; i++)
|
||||
irq_target_cpu[i] = boot_cpu;
|
||||
|
||||
/*
|
||||
* Enables OMAP5 ES2 PM Mode using ES2_PM_MODE in AMBA_IF_MODE
|
||||
* 0x0: ES1 behavior, CPU cores would enter and exit OFF mode together.
|
||||
* 0x1: ES2 behavior, CPU cores are allowed to enter/exit OFF mode
|
||||
* independently.
|
||||
* This needs to be set one time thanks to always ON domain.
|
||||
*
|
||||
* We do not support ES1 behavior anymore. OMAP5 is assumed to be
|
||||
* ES2.0, and the same is applicable for DRA7.
|
||||
*/
|
||||
if (soc_is_omap54xx() || soc_is_dra7xx()) {
|
||||
val = __raw_readl(wakeupgen_base + OMAP_AMBA_IF_MODE);
|
||||
val |= BIT(5);
|
||||
omap_smc1(OMAP5_MON_AMBA_IF_INDEX, val);
|
||||
}
|
||||
|
||||
irq_hotplug_init();
|
||||
irq_pm_init();
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#define OMAP_WKG_ENB_E_1 0x420
|
||||
#define OMAP_AUX_CORE_BOOT_0 0x800
|
||||
#define OMAP_AUX_CORE_BOOT_1 0x804
|
||||
#define OMAP_AMBA_IF_MODE 0x80c
|
||||
#define OMAP_PTMSYNCREQ_MASK 0xc00
|
||||
#define OMAP_PTMSYNCREQ_EN 0xc04
|
||||
#define OMAP_TIMESTAMPCYCLELO 0xc08
|
||||
|
@ -352,6 +352,16 @@ struct of_dev_auxdata omap_auxdata_lookup[] __initdata = {
|
||||
OF_DEV_AUXDATA("ti,omap4-padconf", 0x4a100040, "4a100040.pinmux", &pcs_pdata),
|
||||
OF_DEV_AUXDATA("ti,omap4-padconf", 0x4a31e040, "4a31e040.pinmux", &pcs_pdata),
|
||||
#endif
|
||||
#ifdef CONFIG_SOC_OMAP5
|
||||
OF_DEV_AUXDATA("ti,omap5-padconf", 0x4a002840, "4a002840.pinmux", &pcs_pdata),
|
||||
OF_DEV_AUXDATA("ti,omap5-padconf", 0x4ae0c840, "4ae0c840.pinmux", &pcs_pdata),
|
||||
#endif
|
||||
#ifdef CONFIG_SOC_DRA7XX
|
||||
OF_DEV_AUXDATA("ti,dra7-padconf", 0x4a003400, "4a003400.pinmux", &pcs_pdata),
|
||||
#endif
|
||||
#ifdef CONFIG_SOC_AM43XX
|
||||
OF_DEV_AUXDATA("ti,am437-padconf", 0x44e10800, "44e10800.pinmux", &pcs_pdata),
|
||||
#endif
|
||||
#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
|
||||
OF_DEV_AUXDATA("ti,omap4-iommu", 0x4a066000, "4a066000.mmu",
|
||||
&omap4_iommu_pdata),
|
||||
|
@ -101,6 +101,7 @@ static inline void enable_omap3630_toggle_l2_on_restore(void) { }
|
||||
#endif /* defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) */
|
||||
|
||||
#define PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD (1 << 0)
|
||||
#define PM_OMAP4_CPU_OSWR_DISABLE (1 << 1)
|
||||
|
||||
#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP4)
|
||||
extern u16 pm44xx_errata;
|
||||
|
@ -37,6 +37,8 @@ struct power_state {
|
||||
struct list_head node;
|
||||
};
|
||||
|
||||
static u32 cpu_suspend_state = PWRDM_POWER_OFF;
|
||||
|
||||
static LIST_HEAD(pwrst_list);
|
||||
|
||||
#ifdef CONFIG_SUSPEND
|
||||
@ -67,7 +69,7 @@ static int omap4_pm_suspend(void)
|
||||
* domain CSWR is not supported by hardware.
|
||||
* More details can be found in OMAP4430 TRM section 4.3.4.2.
|
||||
*/
|
||||
omap4_enter_lowpower(cpu_id, PWRDM_POWER_OFF);
|
||||
omap4_enter_lowpower(cpu_id, cpu_suspend_state);
|
||||
|
||||
/* Restore next powerdomain state */
|
||||
list_for_each_entry(pwrst, &pwrst_list, node) {
|
||||
@ -113,8 +115,11 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
|
||||
* through hotplug path and CPU0 explicitly programmed
|
||||
* further down in the code path
|
||||
*/
|
||||
if (!strncmp(pwrdm->name, "cpu", 3))
|
||||
if (!strncmp(pwrdm->name, "cpu", 3)) {
|
||||
if (IS_PM44XX_ERRATUM(PM_OMAP4_CPU_OSWR_DISABLE))
|
||||
cpu_suspend_state = PWRDM_POWER_RET;
|
||||
return 0;
|
||||
}
|
||||
|
||||
pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC);
|
||||
if (!pwrst)
|
||||
@ -207,6 +212,32 @@ static inline int omap4_init_static_deps(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap5_dra7_init_static_deps - Init static clkdm dependencies on OMAP5 and
|
||||
* DRA7
|
||||
*
|
||||
* The dynamic dependency between MPUSS -> EMIF is broken and has
|
||||
* not worked as expected. The hardware recommendation is to
|
||||
* enable static dependencies for these to avoid system
|
||||
* lock ups or random crashes.
|
||||
*/
|
||||
static inline int omap5_dra7_init_static_deps(void)
|
||||
{
|
||||
struct clockdomain *mpuss_clkdm, *emif_clkdm;
|
||||
int ret;
|
||||
|
||||
mpuss_clkdm = clkdm_lookup("mpu_clkdm");
|
||||
emif_clkdm = clkdm_lookup("emif_clkdm");
|
||||
if (!mpuss_clkdm || !emif_clkdm)
|
||||
return -EINVAL;
|
||||
|
||||
ret = clkdm_add_wkdep(mpuss_clkdm, emif_clkdm);
|
||||
if (ret)
|
||||
pr_err("Failed to add MPUSS -> EMIF wakeup dependency\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* omap4_pm_init_early - Does early initialization necessary for OMAP4+ devices
|
||||
*
|
||||
@ -217,6 +248,9 @@ int __init omap4_pm_init_early(void)
|
||||
if (cpu_is_omap446x())
|
||||
pm44xx_errata |= PM_OMAP4_ROM_SMP_BOOT_ERRATUM_GICD;
|
||||
|
||||
if (soc_is_omap54xx() || soc_is_dra7xx())
|
||||
pm44xx_errata |= PM_OMAP4_CPU_OSWR_DISABLE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -244,10 +278,14 @@ int __init omap4_pm_init(void)
|
||||
goto err2;
|
||||
}
|
||||
|
||||
if (cpu_is_omap44xx()) {
|
||||
if (cpu_is_omap44xx())
|
||||
ret = omap4_init_static_deps();
|
||||
if (ret)
|
||||
goto err2;
|
||||
else if (soc_is_omap54xx() || soc_is_dra7xx())
|
||||
ret = omap5_dra7_init_static_deps();
|
||||
|
||||
if (ret) {
|
||||
pr_err("Failed to initialise static dependencies.\n");
|
||||
goto err2;
|
||||
}
|
||||
|
||||
ret = omap4_mpuss_init();
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/of_irq.h>
|
||||
|
||||
#include "soc.h"
|
||||
#include "common.h"
|
||||
@ -649,6 +650,11 @@ int __init omap3xxx_prm_init(void)
|
||||
return prm_register(&omap3xxx_prm_ll_data);
|
||||
}
|
||||
|
||||
static struct of_device_id omap3_prm_dt_match_table[] = {
|
||||
{ .compatible = "ti,omap3-prm" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static int omap3xxx_prm_late_init(void)
|
||||
{
|
||||
int ret;
|
||||
@ -656,6 +662,18 @@ static int omap3xxx_prm_late_init(void)
|
||||
if (!(prm_features & PRM_HAS_IO_WAKEUP))
|
||||
return 0;
|
||||
|
||||
if (of_have_populated_dt()) {
|
||||
struct device_node *np;
|
||||
int irq_num;
|
||||
|
||||
np = of_find_matching_node(NULL, omap3_prm_dt_match_table);
|
||||
if (np) {
|
||||
irq_num = of_irq_get(np, 0);
|
||||
if (irq_num >= 0)
|
||||
omap3_prcm_irq_setup.irq = irq_num;
|
||||
}
|
||||
}
|
||||
|
||||
omap3xxx_prm_enable_io_wakeup();
|
||||
ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
|
||||
if (!ret)
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of_irq.h>
|
||||
|
||||
|
||||
#include "soc.h"
|
||||
@ -32,7 +33,6 @@
|
||||
/* Static data */
|
||||
|
||||
static const struct omap_prcm_irq omap4_prcm_irqs[] = {
|
||||
OMAP_PRCM_IRQ("wkup", 0, 0),
|
||||
OMAP_PRCM_IRQ("io", 9, 1),
|
||||
};
|
||||
|
||||
@ -154,21 +154,36 @@ void omap4_prm_vp_clear_txdone(u8 vp_id)
|
||||
|
||||
u32 omap4_prm_vcvp_read(u8 offset)
|
||||
{
|
||||
s32 inst = omap4_prmst_get_prm_dev_inst();
|
||||
|
||||
if (inst == PRM_INSTANCE_UNKNOWN)
|
||||
return 0;
|
||||
|
||||
return omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
|
||||
OMAP4430_PRM_DEVICE_INST, offset);
|
||||
inst, offset);
|
||||
}
|
||||
|
||||
void omap4_prm_vcvp_write(u32 val, u8 offset)
|
||||
{
|
||||
s32 inst = omap4_prmst_get_prm_dev_inst();
|
||||
|
||||
if (inst == PRM_INSTANCE_UNKNOWN)
|
||||
return;
|
||||
|
||||
omap4_prminst_write_inst_reg(val, OMAP4430_PRM_PARTITION,
|
||||
OMAP4430_PRM_DEVICE_INST, offset);
|
||||
inst, offset);
|
||||
}
|
||||
|
||||
u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset)
|
||||
{
|
||||
s32 inst = omap4_prmst_get_prm_dev_inst();
|
||||
|
||||
if (inst == PRM_INSTANCE_UNKNOWN)
|
||||
return 0;
|
||||
|
||||
return omap4_prminst_rmw_inst_reg_bits(mask, bits,
|
||||
OMAP4430_PRM_PARTITION,
|
||||
OMAP4430_PRM_DEVICE_INST,
|
||||
inst,
|
||||
offset);
|
||||
}
|
||||
|
||||
@ -275,14 +290,18 @@ void omap44xx_prm_restore_irqen(u32 *saved_mask)
|
||||
void omap44xx_prm_reconfigure_io_chain(void)
|
||||
{
|
||||
int i = 0;
|
||||
s32 inst = omap4_prmst_get_prm_dev_inst();
|
||||
|
||||
if (inst == PRM_INSTANCE_UNKNOWN)
|
||||
return;
|
||||
|
||||
/* Trigger WUCLKIN enable */
|
||||
omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK,
|
||||
OMAP4430_WUCLK_CTRL_MASK,
|
||||
OMAP4430_PRM_DEVICE_INST,
|
||||
inst,
|
||||
OMAP4_PRM_IO_PMCTRL_OFFSET);
|
||||
omap_test_timeout(
|
||||
(((omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
|
||||
(((omap4_prm_read_inst_reg(inst,
|
||||
OMAP4_PRM_IO_PMCTRL_OFFSET) &
|
||||
OMAP4430_WUCLK_STATUS_MASK) >>
|
||||
OMAP4430_WUCLK_STATUS_SHIFT) == 1),
|
||||
@ -292,10 +311,10 @@ void omap44xx_prm_reconfigure_io_chain(void)
|
||||
|
||||
/* Trigger WUCLKIN disable */
|
||||
omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, 0x0,
|
||||
OMAP4430_PRM_DEVICE_INST,
|
||||
inst,
|
||||
OMAP4_PRM_IO_PMCTRL_OFFSET);
|
||||
omap_test_timeout(
|
||||
(((omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
|
||||
(((omap4_prm_read_inst_reg(inst,
|
||||
OMAP4_PRM_IO_PMCTRL_OFFSET) &
|
||||
OMAP4430_WUCLK_STATUS_MASK) >>
|
||||
OMAP4430_WUCLK_STATUS_SHIFT) == 0),
|
||||
@ -316,9 +335,14 @@ void omap44xx_prm_reconfigure_io_chain(void)
|
||||
*/
|
||||
static void __init omap44xx_prm_enable_io_wakeup(void)
|
||||
{
|
||||
s32 inst = omap4_prmst_get_prm_dev_inst();
|
||||
|
||||
if (inst == PRM_INSTANCE_UNKNOWN)
|
||||
return;
|
||||
|
||||
omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK,
|
||||
OMAP4430_GLOBAL_WUEN_MASK,
|
||||
OMAP4430_PRM_DEVICE_INST,
|
||||
inst,
|
||||
OMAP4_PRM_IO_PMCTRL_OFFSET);
|
||||
}
|
||||
|
||||
@ -333,8 +357,13 @@ static u32 omap44xx_prm_read_reset_sources(void)
|
||||
struct prm_reset_src_map *p;
|
||||
u32 r = 0;
|
||||
u32 v;
|
||||
s32 inst = omap4_prmst_get_prm_dev_inst();
|
||||
|
||||
v = omap4_prm_read_inst_reg(OMAP4430_PRM_DEVICE_INST,
|
||||
if (inst == PRM_INSTANCE_UNKNOWN)
|
||||
return 0;
|
||||
|
||||
|
||||
v = omap4_prm_read_inst_reg(inst,
|
||||
OMAP4_RM_RSTST);
|
||||
|
||||
p = omap44xx_prm_reset_src_map;
|
||||
@ -664,17 +693,56 @@ static struct prm_ll_data omap44xx_prm_ll_data = {
|
||||
|
||||
int __init omap44xx_prm_init(void)
|
||||
{
|
||||
if (cpu_is_omap44xx())
|
||||
if (cpu_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx())
|
||||
prm_features |= PRM_HAS_IO_WAKEUP;
|
||||
|
||||
return prm_register(&omap44xx_prm_ll_data);
|
||||
}
|
||||
|
||||
static struct of_device_id omap_prm_dt_match_table[] = {
|
||||
{ .compatible = "ti,omap4-prm" },
|
||||
{ .compatible = "ti,omap5-prm" },
|
||||
{ .compatible = "ti,dra7-prm" },
|
||||
{ }
|
||||
};
|
||||
|
||||
static int omap44xx_prm_late_init(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
int irq_num;
|
||||
|
||||
if (!(prm_features & PRM_HAS_IO_WAKEUP))
|
||||
return 0;
|
||||
|
||||
/* OMAP4+ is DT only now */
|
||||
if (!of_have_populated_dt())
|
||||
return 0;
|
||||
|
||||
np = of_find_matching_node(NULL, omap_prm_dt_match_table);
|
||||
|
||||
if (!np) {
|
||||
/* Default loaded up with OMAP4 values */
|
||||
if (!cpu_is_omap44xx())
|
||||
return 0;
|
||||
} else {
|
||||
irq_num = of_irq_get(np, 0);
|
||||
/*
|
||||
* Already have OMAP4 IRQ num. For all other platforms, we need
|
||||
* IRQ numbers from DT
|
||||
*/
|
||||
if (irq_num < 0 && !cpu_is_omap44xx()) {
|
||||
if (irq_num == -EPROBE_DEFER)
|
||||
return irq_num;
|
||||
|
||||
/* Have nothing to do */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Once OMAP4 DT is filled as well */
|
||||
if (irq_num >= 0)
|
||||
omap4_prcm_irq_setup.irq = irq_num;
|
||||
}
|
||||
|
||||
omap44xx_prm_enable_io_wakeup();
|
||||
|
||||
return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup);
|
||||
|
@ -31,6 +31,8 @@
|
||||
|
||||
static void __iomem *_prm_bases[OMAP4_MAX_PRCM_PARTITIONS];
|
||||
|
||||
static s32 prm_dev_inst = PRM_INSTANCE_UNKNOWN;
|
||||
|
||||
/**
|
||||
* omap_prm_base_init - Populates the prm partitions
|
||||
*
|
||||
@ -43,6 +45,24 @@ void omap_prm_base_init(void)
|
||||
_prm_bases[OMAP4430_PRCM_MPU_PARTITION] = prcm_mpu_base;
|
||||
}
|
||||
|
||||
s32 omap4_prmst_get_prm_dev_inst(void)
|
||||
{
|
||||
if (prm_dev_inst != PRM_INSTANCE_UNKNOWN)
|
||||
return prm_dev_inst;
|
||||
|
||||
/* This cannot be done way early at boot.. as things are not setup */
|
||||
if (cpu_is_omap44xx())
|
||||
prm_dev_inst = OMAP4430_PRM_DEVICE_INST;
|
||||
else if (soc_is_omap54xx())
|
||||
prm_dev_inst = OMAP54XX_PRM_DEVICE_INST;
|
||||
else if (soc_is_dra7xx())
|
||||
prm_dev_inst = DRA7XX_PRM_DEVICE_INST;
|
||||
else if (soc_is_am43xx())
|
||||
prm_dev_inst = AM43XX_PRM_DEVICE_INST;
|
||||
|
||||
return prm_dev_inst;
|
||||
}
|
||||
|
||||
/* Read a register in a PRM instance */
|
||||
u32 omap4_prminst_read_inst_reg(u8 part, s16 inst, u16 idx)
|
||||
{
|
||||
@ -169,28 +189,18 @@ int omap4_prminst_deassert_hardreset(u8 shift, u8 part, s16 inst,
|
||||
void omap4_prminst_global_warm_sw_reset(void)
|
||||
{
|
||||
u32 v;
|
||||
s16 dev_inst;
|
||||
s32 inst = omap4_prmst_get_prm_dev_inst();
|
||||
|
||||
if (cpu_is_omap44xx())
|
||||
dev_inst = OMAP4430_PRM_DEVICE_INST;
|
||||
else if (soc_is_omap54xx())
|
||||
dev_inst = OMAP54XX_PRM_DEVICE_INST;
|
||||
else if (soc_is_dra7xx())
|
||||
dev_inst = DRA7XX_PRM_DEVICE_INST;
|
||||
else if (soc_is_am43xx())
|
||||
dev_inst = AM43XX_PRM_DEVICE_INST;
|
||||
else
|
||||
if (inst == PRM_INSTANCE_UNKNOWN)
|
||||
return;
|
||||
|
||||
v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, dev_inst,
|
||||
v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION, inst,
|
||||
OMAP4_PRM_RSTCTRL_OFFSET);
|
||||
v |= OMAP4430_RST_GLOBAL_WARM_SW_MASK;
|
||||
omap4_prminst_write_inst_reg(v, OMAP4430_PRM_PARTITION,
|
||||
dev_inst,
|
||||
OMAP4_PRM_RSTCTRL_OFFSET);
|
||||
inst, OMAP4_PRM_RSTCTRL_OFFSET);
|
||||
|
||||
/* OCP barrier */
|
||||
v = omap4_prminst_read_inst_reg(OMAP4430_PRM_PARTITION,
|
||||
dev_inst,
|
||||
OMAP4_PRM_RSTCTRL_OFFSET);
|
||||
inst, OMAP4_PRM_RSTCTRL_OFFSET);
|
||||
}
|
||||
|
@ -12,6 +12,9 @@
|
||||
#ifndef __ARCH_ASM_MACH_OMAP2_PRMINST44XX_H
|
||||
#define __ARCH_ASM_MACH_OMAP2_PRMINST44XX_H
|
||||
|
||||
#define PRM_INSTANCE_UNKNOWN -1
|
||||
extern s32 omap4_prmst_get_prm_dev_inst(void);
|
||||
|
||||
/*
|
||||
* In an ideal world, we would not export these low-level functions,
|
||||
* but this will probably take some time to fix properly
|
||||
|
Loading…
Reference in New Issue
Block a user