diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-22 09:41:01 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-22 09:41:01 -0700 |
commit | cdd3a354a05b0c33fe33ab11a0fb0838396cad19 (patch) | |
tree | ea2c87bbc2dc5865a97e73e201661d69937b45d5 | |
parent | 813a95e5b4fa936bbde10ef89188932745dcd7f4 (diff) | |
parent | ada2e35defe6c6f0a986ec8147e47726fbd0e7b1 (diff) |
Merge tag 'pm' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull arm-soc power management changes from Olof Johansson:
"Power management changes here are mostly for the omap platform, but
also include cpuidle changes for ux500 and suspend/resume code for
mmp."
* tag 'pm' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (48 commits)
ARM: OMAP2+: WDTIMER integration: fix !PM boot crash, disarm timer after hwmod reset
ARM: OMAP2/3: hwmod data: Add 32k-sync timer data to hwmod database
ARM: OMAP4: hwmod_data: Name the common irq for McBSP ports
ARM: OMAP4: hwmod data: I2C: add flag for context restore
ARM: OMAP3: hwmod_data: Rename the common irq for McBSP ports
ARM: OMAP2xxx: hwmod data: add HDQ/1-wire hwmod
ARM: OMAP3: hwmod data: add HDQ/1-wire hwmod
ARM: OMAP2+: hwmod data: add HDQ/1-wire hwmod shared data
ARM: OMAP2+: HDQ1W: add custom reset function
ARM: OMAP2420: hwmod data: Add MMC hwmod data for 2420
arm: omap3: clockdomain data: Remove superfluous commas from gfx_sgx_3xxx_wkdeps[]
ARM: OMAP2+: powerdomain: Get rid off duplicate pwrdm_clkdm_state_switch() API
ARM: OMAP3: clock data: add clockdomain for HDQ functional clock
ARM: OMAP3+: dpll: Configure autoidle mode only if it's supported
ARM: OMAP2+: dmtimer: cleanup iclk usage
ARM: OMAP4+: Add prm and cm base init function.
ARM: OMAP2/3: Add idle_st bits for ST_32KSYNC timer to prcm-common header
ARM: OMAP3: Fix CM register bit masks
ARM: OMAP: clock: convert AM3517/3505 detection/flags to AM35xx
ARM: OMAP3: clock data: treat all AM35x devices the same
...
57 files changed, 3204 insertions, 176 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 58e2f7865f54..0a2fc01891a9 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -2261,7 +2261,7 @@ source "kernel/power/Kconfig" config ARCH_SUSPEND_POSSIBLE depends on !ARCH_S5PC100 && !ARCH_TEGRA depends on CPU_ARM920T || CPU_ARM926T || CPU_SA1100 || \ - CPU_V6 || CPU_V6K || CPU_V7 || CPU_XSC3 || CPU_XSCALE + CPU_V6 || CPU_V6K || CPU_V7 || CPU_XSC3 || CPU_XSCALE || CPU_MOHAWK def_bool y config ARM_CPU_SUSPEND diff --git a/arch/arm/mach-mmp/Makefile b/arch/arm/mach-mmp/Makefile index b920b9bfbdb6..b786f7e6cd1f 100644 --- a/arch/arm/mach-mmp/Makefile +++ b/arch/arm/mach-mmp/Makefile @@ -9,6 +9,11 @@ obj-$(CONFIG_CPU_PXA168) += pxa168.o obj-$(CONFIG_CPU_PXA910) += pxa910.o obj-$(CONFIG_CPU_MMP2) += mmp2.o sram.o +ifeq ($(CONFIG_PM),y) +obj-$(CONFIG_CPU_PXA910) += pm-pxa910.o +obj-$(CONFIG_CPU_MMP2) += pm-mmp2.o +endif + # board support obj-$(CONFIG_MACH_ASPENITE) += aspenite.o obj-$(CONFIG_MACH_ZYLONITE2) += aspenite.o diff --git a/arch/arm/mach-mmp/include/mach/addr-map.h b/arch/arm/mach-mmp/include/mach/addr-map.h index b1ece08174e8..f88a44c0ef91 100644 --- a/arch/arm/mach-mmp/include/mach/addr-map.h +++ b/arch/arm/mach-mmp/include/mach/addr-map.h @@ -31,4 +31,16 @@ #define SMC_CS1_PHYS_BASE 0x90000000 #define SMC_CS1_PHYS_SIZE 0x10000000 +#define APMU_VIRT_BASE (AXI_VIRT_BASE + 0x82800) +#define APMU_REG(x) (APMU_VIRT_BASE + (x)) + +#define APBC_VIRT_BASE (APB_VIRT_BASE + 0x015000) +#define APBC_REG(x) (APBC_VIRT_BASE + (x)) + +#define MPMU_VIRT_BASE (APB_VIRT_BASE + 0x50000) +#define MPMU_REG(x) (MPMU_VIRT_BASE + (x)) + +#define CIU_VIRT_BASE (AXI_VIRT_BASE + 0x82c00) +#define CIU_REG(x) (CIU_VIRT_BASE + (x)) + #endif /* __ASM_MACH_ADDR_MAP_H */ diff --git a/arch/arm/mach-mmp/include/mach/pm-mmp2.h b/arch/arm/mach-mmp/include/mach/pm-mmp2.h new file mode 100644 index 000000000000..98bd66ce8006 --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/pm-mmp2.h @@ -0,0 +1,61 @@ +/* + * MMP2 Power Management Routines + * + * This software program is licensed subject to the GNU General Public License + * (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html + * + * (C) Copyright 2010 Marvell International Ltd. + * All Rights Reserved + */ + +#ifndef __MMP2_PM_H__ +#define __MMP2_PM_H__ + +#include <mach/addr-map.h> + +#define APMU_PJ_IDLE_CFG APMU_REG(0x018) +#define APMU_PJ_IDLE_CFG_PJ_IDLE (1 << 1) +#define APMU_PJ_IDLE_CFG_PJ_PWRDWN (1 << 5) +#define APMU_PJ_IDLE_CFG_PWR_SW(x) ((x) << 16) +#define APMU_PJ_IDLE_CFG_L2_PWR_SW (1 << 19) +#define APMU_PJ_IDLE_CFG_ISO_MODE_CNTRL_MASK (3 << 28) + +#define APMU_SRAM_PWR_DWN APMU_REG(0x08c) + +#define MPMU_SCCR MPMU_REG(0x038) +#define MPMU_PCR_PJ MPMU_REG(0x1000) +#define MPMU_PCR_PJ_AXISD (1 << 31) +#define MPMU_PCR_PJ_SLPEN (1 << 29) +#define MPMU_PCR_PJ_SPSD (1 << 28) +#define MPMU_PCR_PJ_DDRCORSD (1 << 27) +#define MPMU_PCR_PJ_APBSD (1 << 26) +#define MPMU_PCR_PJ_INTCLR (1 << 24) +#define MPMU_PCR_PJ_SLPWP0 (1 << 23) +#define MPMU_PCR_PJ_SLPWP1 (1 << 22) +#define MPMU_PCR_PJ_SLPWP2 (1 << 21) +#define MPMU_PCR_PJ_SLPWP3 (1 << 20) +#define MPMU_PCR_PJ_VCTCXOSD (1 << 19) +#define MPMU_PCR_PJ_SLPWP4 (1 << 18) +#define MPMU_PCR_PJ_SLPWP5 (1 << 17) +#define MPMU_PCR_PJ_SLPWP6 (1 << 16) +#define MPMU_PCR_PJ_SLPWP7 (1 << 15) + +#define MPMU_PLL2_CTRL1 MPMU_REG(0x0414) +#define MPMU_CGR_PJ MPMU_REG(0x1024) +#define MPMU_WUCRM_PJ MPMU_REG(0x104c) +#define MPMU_WUCRM_PJ_WAKEUP(x) (1 << (x)) +#define MPMU_WUCRM_PJ_RTC_ALARM (1 << 17) + +enum { + POWER_MODE_ACTIVE = 0, + POWER_MODE_CORE_INTIDLE, + POWER_MODE_CORE_EXTIDLE, + POWER_MODE_APPS_IDLE, + POWER_MODE_APPS_SLEEP, + POWER_MODE_CHIP_SLEEP, + POWER_MODE_SYS_SLEEP, +}; + +extern void mmp2_pm_enter_lowpower_mode(int state); +extern int mmp2_set_wake(struct irq_data *d, unsigned int on); +#endif diff --git a/arch/arm/mach-mmp/include/mach/pm-pxa910.h b/arch/arm/mach-mmp/include/mach/pm-pxa910.h new file mode 100644 index 000000000000..8cac8ab5253d --- /dev/null +++ b/arch/arm/mach-mmp/include/mach/pm-pxa910.h @@ -0,0 +1,77 @@ +/* + * PXA910 Power Management Routines + * + * This software program is licensed subject to the GNU General Public License + * (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html + * + * (C) Copyright 2009 Marvell International Ltd. + * All Rights Reserved + */ + +#ifndef __PXA910_PM_H__ +#define __PXA910_PM_H__ + +#define APMU_MOH_IDLE_CFG APMU_REG(0x0018) +#define APMU_MOH_IDLE_CFG_MOH_IDLE (1 << 1) +#define APMU_MOH_IDLE_CFG_MOH_PWRDWN (1 << 5) +#define APMU_MOH_IDLE_CFG_MOH_SRAM_PWRDWN (1 << 6) +#define APMU_MOH_IDLE_CFG_MOH_PWR_SW(x) (((x) & 0x3) << 16) +#define APMU_MOH_IDLE_CFG_MOH_L2_PWR_SW(x) (((x) & 0x3) << 18) +#define APMU_MOH_IDLE_CFG_MOH_DIS_MC_SW_REQ (1 << 21) +#define APMU_MOH_IDLE_CFG_MOH_MC_WAKE_EN (1 << 20) + +#define APMU_SQU_CLK_GATE_CTRL APMU_REG(0x001c) +#define APMU_MC_HW_SLP_TYPE APMU_REG(0x00b0) + +#define MPMU_FCCR MPMU_REG(0x0008) +#define MPMU_APCR MPMU_REG(0x1000) +#define MPMU_APCR_AXISD (1 << 31) +#define MPMU_APCR_DSPSD (1 << 30) +#define MPMU_APCR_SLPEN (1 << 29) +#define MPMU_APCR_DTCMSD (1 << 28) +#define MPMU_APCR_DDRCORSD (1 << 27) +#define MPMU_APCR_APBSD (1 << 26) +#define MPMU_APCR_BBSD (1 << 25) +#define MPMU_APCR_SLPWP0 (1 << 23) +#define MPMU_APCR_SLPWP1 (1 << 22) +#define MPMU_APCR_SLPWP2 (1 << 21) +#define MPMU_APCR_SLPWP3 (1 << 20) +#define MPMU_APCR_VCTCXOSD (1 << 19) +#define MPMU_APCR_SLPWP4 (1 << 18) +#define MPMU_APCR_SLPWP5 (1 << 17) +#define MPMU_APCR_SLPWP6 (1 << 16) +#define MPMU_APCR_SLPWP7 (1 << 15) +#define MPMU_APCR_MSASLPEN (1 << 14) +#define MPMU_APCR_STBYEN (1 << 13) + +#define MPMU_AWUCRM MPMU_REG(0x104c) +#define MPMU_AWUCRM_AP_ASYNC_INT (1 << 25) +#define MPMU_AWUCRM_AP_FULL_IDLE (1 << 24) +#define MPMU_AWUCRM_SDH1 (1 << 23) +#define MPMU_AWUCRM_SDH2 (1 << 22) +#define MPMU_AWUCRM_KEYPRESS (1 << 21) +#define MPMU_AWUCRM_TRACKBALL (1 << 20) +#define MPMU_AWUCRM_NEWROTARY (1 << 19) +#define MPMU_AWUCRM_RTC_ALARM (1 << 17) +#define MPMU_AWUCRM_AP2_TIMER_3 (1 << 13) +#define MPMU_AWUCRM_AP2_TIMER_2 (1 << 12) +#define MPMU_AWUCRM_AP2_TIMER_1 (1 << 11) +#define MPMU_AWUCRM_AP1_TIMER_3 (1 << 10) +#define MPMU_AWUCRM_AP1_TIMER_2 (1 << 9) +#define MPMU_AWUCRM_AP1_TIMER_1 (1 << 8) +#define MPMU_AWUCRM_WAKEUP(x) (1 << ((x) & 0x7)) + +enum { + POWER_MODE_ACTIVE = 0, + POWER_MODE_CORE_INTIDLE, + POWER_MODE_CORE_EXTIDLE, + POWER_MODE_APPS_IDLE, + POWER_MODE_APPS_SLEEP, + POWER_MODE_SYS_SLEEP, + POWER_MODE_HIBERNATE, + POWER_MODE_UDR, +}; + +extern int pxa910_set_wake(struct irq_data *data, unsigned int on); + +#endif diff --git a/arch/arm/mach-mmp/include/mach/regs-apbc.h b/arch/arm/mach-mmp/include/mach/regs-apbc.h index 8a37fb003655..68b0c93ec6a1 100644 --- a/arch/arm/mach-mmp/include/mach/regs-apbc.h +++ b/arch/arm/mach-mmp/include/mach/regs-apbc.h @@ -13,9 +13,6 @@ #include <mach/addr-map.h> -#define APBC_VIRT_BASE (APB_VIRT_BASE + 0x015000) -#define APBC_REG(x) (APBC_VIRT_BASE + (x)) - /* * APB clock register offsets for PXA168 */ diff --git a/arch/arm/mach-mmp/include/mach/regs-apmu.h b/arch/arm/mach-mmp/include/mach/regs-apmu.h index 8447ac63e28f..7af8deb63e83 100644 --- a/arch/arm/mach-mmp/include/mach/regs-apmu.h +++ b/arch/arm/mach-mmp/include/mach/regs-apmu.h @@ -13,9 +13,6 @@ #include <mach/addr-map.h> -#define APMU_VIRT_BASE (AXI_VIRT_BASE + 0x82800) -#define APMU_REG(x) (APMU_VIRT_BASE + (x)) - /* Clock Reset Control */ #define APMU_IRE APMU_REG(0x048) #define APMU_LCD APMU_REG(0x04c) diff --git a/arch/arm/mach-mmp/irq.c b/arch/arm/mach-mmp/irq.c index 3705470c9f1e..fcfe0e3bd701 100644 --- a/arch/arm/mach-mmp/irq.c +++ b/arch/arm/mach-mmp/irq.c @@ -23,6 +23,13 @@ #include <mach/irqs.h> +#ifdef CONFIG_CPU_MMP2 +#include <mach/pm-mmp2.h> +#endif +#ifdef CONFIG_CPU_PXA910 +#include <mach/pm-pxa910.h> +#endif + #include "common.h" #define MAX_ICU_NR 16 @@ -209,6 +216,9 @@ void __init icu_init_irq(void) set_irq_flags(irq, IRQF_VALID); } irq_set_default_host(icu_data[0].domain); +#ifdef CONFIG_CPU_PXA910 + icu_irq_chip.irq_set_wake = pxa910_set_wake; +#endif } /* MMP2 (ARMv7) */ @@ -305,6 +315,9 @@ void __init mmp2_init_icu(void) set_irq_flags(irq, IRQF_VALID); } irq_set_default_host(icu_data[0].domain); +#ifdef CONFIG_CPU_MMP2 + icu_irq_chip.irq_set_wake = mmp2_set_wake; +#endif } #ifdef CONFIG_OF diff --git a/arch/arm/mach-mmp/pm-mmp2.c b/arch/arm/mach-mmp/pm-mmp2.c new file mode 100644 index 000000000000..461a191a32d2 --- /dev/null +++ b/arch/arm/mach-mmp/pm-mmp2.c @@ -0,0 +1,264 @@ +/* + * MMP2 Power Management Routines + * + * This software program is licensed subject to the GNU General Public License + * (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html + * + * (C) Copyright 2012 Marvell International Ltd. + * All Rights Reserved + */ + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/time.h> +#include <linux/delay.h> +#include <linux/suspend.h> +#include <linux/irq.h> +#include <linux/io.h> +#include <linux/interrupt.h> +#include <asm/mach-types.h> +#include <mach/hardware.h> +#include <mach/cputype.h> +#include <mach/addr-map.h> +#include <mach/pm-mmp2.h> +#include <mach/regs-icu.h> +#include <mach/irqs.h> + +int mmp2_set_wake(struct irq_data *d, unsigned int on) +{ + int irq = d->irq; + struct irq_desc *desc = irq_to_desc(irq); + unsigned long data = 0; + + if (unlikely(irq >= nr_irqs)) { + pr_err("IRQ nubmers are out of boundary!\n"); + return -EINVAL; + } + + if (on) { + if (desc->action) + desc->action->flags |= IRQF_NO_SUSPEND; + } else { + if (desc->action) + desc->action->flags &= ~IRQF_NO_SUSPEND; + } + + /* enable wakeup sources */ + switch (irq) { + case IRQ_MMP2_RTC: + case IRQ_MMP2_RTC_ALARM: + data = MPMU_WUCRM_PJ_WAKEUP(4) | MPMU_WUCRM_PJ_RTC_ALARM; + break; + case IRQ_MMP2_PMIC: + data = MPMU_WUCRM_PJ_WAKEUP(7); + break; + case IRQ_MMP2_MMC2: + /* mmc use WAKEUP2, same as GPIO wakeup source */ + data = MPMU_WUCRM_PJ_WAKEUP(2); + break; + } + if (on) { + if (data) { + data |= __raw_readl(MPMU_WUCRM_PJ); + __raw_writel(data, MPMU_WUCRM_PJ); + } + } else { + if (data) { + data = ~data & __raw_readl(MPMU_WUCRM_PJ); + __raw_writel(data, MPMU_WUCRM_PJ); + } + } + return 0; +} + +static void pm_scu_clk_disable(void) +{ + unsigned int val; + + /* close AXI fabric clock gate */ + __raw_writel(0x0, CIU_REG(0x64)); + __raw_writel(0x0, CIU_REG(0x68)); + + /* close MCB master clock gate */ + val = __raw_readl(CIU_REG(0x1c)); + val |= 0xf0; + __raw_writel(val, CIU_REG(0x1c)); + + return ; +} + +static void pm_scu_clk_enable(void) +{ + unsigned int val; + + /* open AXI fabric clock gate */ + __raw_writel(0x03003003, CIU_REG(0x64)); + __raw_writel(0x00303030, CIU_REG(0x68)); + + /* open MCB master clock gate */ + val = __raw_readl(CIU_REG(0x1c)); + val &= ~(0xf0); + __raw_writel(val, CIU_REG(0x1c)); + + return ; +} + +static void pm_mpmu_clk_disable(void) +{ + /* + * disable clocks in MPMU_CGR_PJ register + * except clock for APMU_PLL1, APMU_PLL1_2 and AP_26M + */ + __raw_writel(0x0000a010, MPMU_CGR_PJ); +} + +static void pm_mpmu_clk_enable(void) +{ + unsigned int val; + + __raw_writel(0xdffefffe, MPMU_CGR_PJ); + val = __raw_readl(MPMU_PLL2_CTRL1); + val |= (1 << 29); + __raw_writel(val, MPMU_PLL2_CTRL1); + + return ; +} + +void mmp2_pm_enter_lowpower_mode(int state) +{ + uint32_t idle_cfg, apcr; + + idle_cfg = __raw_readl(APMU_PJ_IDLE_CFG); + apcr = __raw_readl(MPMU_PCR_PJ); + apcr &= ~(MPMU_PCR_PJ_SLPEN | MPMU_PCR_PJ_DDRCORSD | MPMU_PCR_PJ_APBSD + | MPMU_PCR_PJ_AXISD | MPMU_PCR_PJ_VCTCXOSD | (1 << 13)); + idle_cfg &= ~APMU_PJ_IDLE_CFG_PJ_IDLE; + + switch (state) { + case POWER_MODE_SYS_SLEEP: + apcr |= MPMU_PCR_PJ_SLPEN; /* set the SLPEN bit */ + apcr |= MPMU_PCR_PJ_VCTCXOSD; /* set VCTCXOSD */ + /* fall through */ + case POWER_MODE_CHIP_SLEEP: + apcr |= MPMU_PCR_PJ_SLPEN; + /* fall through */ + case POWER_MODE_APPS_SLEEP: + apcr |= MPMU_PCR_PJ_APBSD; /* set APBSD */ + /* fall through */ + case POWER_MODE_APPS_IDLE: + apcr |= MPMU_PCR_PJ_AXISD; /* set AXISDD bit */ + apcr |= MPMU_PCR_PJ_DDRCORSD; /* set DDRCORSD bit */ + idle_cfg |= APMU_PJ_IDLE_CFG_PJ_PWRDWN; /* PJ power down */ + apcr |= MPMU_PCR_PJ_SPSD; + /* fall through */ + case POWER_MODE_CORE_EXTIDLE: + idle_cfg |= APMU_PJ_IDLE_CFG_PJ_IDLE; /* set the IDLE bit */ + idle_cfg &= ~APMU_PJ_IDLE_CFG_ISO_MODE_CNTRL_MASK; + idle_cfg |= APMU_PJ_IDLE_CFG_PWR_SW(3) + | APMU_PJ_IDLE_CFG_L2_PWR_SW; + break; + case POWER_MODE_CORE_INTIDLE: + apcr &= ~MPMU_PCR_PJ_SPSD; + break; + } + + /* set reserve bits */ + apcr |= (1 << 30) | (1 << 25); + + /* finally write the registers back */ + __raw_writel(idle_cfg, APMU_PJ_IDLE_CFG); + __raw_writel(apcr, MPMU_PCR_PJ); /* 0xfe086000 */ +} + +static int mmp2_pm_enter(suspend_state_t state) +{ + int temp; + + temp = __raw_readl(MMP2_ICU_INT4_MASK); + if (temp & (1 << 1)) { + printk(KERN_ERR "%s: PMIC interrupt is handling\n", __func__); + return -EAGAIN; + } + + temp = __raw_readl(APMU_SRAM_PWR_DWN); + temp |= ((1 << 19) | (1 << 18)); + __raw_writel(temp, APMU_SRAM_PWR_DWN); + pm_mpmu_clk_disable(); + pm_scu_clk_disable(); + + printk(KERN_INFO "%s: before suspend\n", __func__); + cpu_do_idle(); + printk(KERN_INFO "%s: after suspend\n", __func__); + + pm_mpmu_clk_enable(); /* enable clocks in MPMU */ + pm_scu_clk_enable(); /* enable clocks in SCU */ + + return 0; +} + +/* + * Called after processes are frozen, but before we shut down devices. + */ +static int mmp2_pm_prepare(void) +{ + mmp2_pm_enter_lowpower_mode(POWER_MODE_SYS_SLEEP); + + return 0; +} + +/* + * Called after devices are re-setup, but before processes are thawed. + */ +static void mmp2_pm_finish(void) +{ + mmp2_pm_enter_lowpower_mode(POWER_MODE_CORE_INTIDLE); +} + +static int mmp2_pm_valid(suspend_state_t state) +{ + return ((state == PM_SUSPEND_STANDBY) || (state == PM_SUSPEND_MEM)); +} + +/* + * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk. + */ +static const struct platform_suspend_ops mmp2_pm_ops = { + .valid = mmp2_pm_valid, + .prepare = mmp2_pm_prepare, + .enter = mmp2_pm_enter, + .finish = mmp2_pm_finish, +}; + +static int __init mmp2_pm_init(void) +{ + uint32_t apcr; + + if (!cpu_is_mmp2()) + return -EIO; + + suspend_set_ops(&mmp2_pm_ops); + + /* + * Set bit 0, Slow clock Select 32K clock input instead of VCXO + * VCXO is chosen by default, which would be disabled in suspend + */ + __raw_writel(0x5, MPMU_SCCR); + + /* + * Clear bit 23 of CIU_CPU_CONF + * direct PJ4 to DDR access through Memory Controller slow queue + * fast queue has issue and cause lcd will flick + */ + __raw_writel(__raw_readl(CIU_REG(0x8)) & ~(0x1 << 23), CIU_REG(0x8)); + + /* Clear default low power control bit */ + apcr = __raw_readl(MPMU_PCR_PJ); + apcr &= ~(MPMU_PCR_PJ_SLPEN | MPMU_PCR_PJ_DDRCORSD + | MPMU_PCR_PJ_APBSD | MPMU_PCR_PJ_AXISD | 1 << 13); + __raw_writel(apcr, MPMU_PCR_PJ); + + return 0; +} + +late_initcall(mmp2_pm_init); diff --git a/arch/arm/mach-mmp/pm-pxa910.c b/arch/arm/mach-mmp/pm-pxa910.c new file mode 100644 index 000000000000..48981ca801a5 --- /dev/null +++ b/arch/arm/mach-mmp/pm-pxa910.c @@ -0,0 +1,285 @@ +/* + * PXA910 Power Management Routines + * + * This software program is licensed subject to the GNU General Public License + * (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html + * + * (C) Copyright 2009 Marvell International Ltd. + * All Rights Reserved + */ + +#include <linux/kernel.h> +#include <linux/errno.h> +#include <linux/err.h> +#include <linux/time.h> +#include <linux/delay.h> +#include <linux/suspend.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/irq.h> +#include <asm/mach-types.h> +#include <mach/hardware.h> +#include <mach/cputype.h> +#include <mach/addr-map.h> +#include <mach/pm-pxa910.h> +#include <mach/regs-icu.h> +#include <mach/irqs.h> + +int pxa910_set_wake(struct irq_data *data, unsigned int on) +{ + int irq = data->irq; + struct irq_desc *desc = irq_to_desc(data->irq); + uint32_t awucrm = 0, apcr = 0; + + if (unlikely(irq >= nr_irqs)) { + pr_err("IRQ nubmers are out of boundary!\n"); + return -EINVAL; + } + + if (on) { + if (desc->action) + desc->action->flags |= IRQF_NO_SUSPEND; + } else { + if (desc->action) + desc->action->flags &= ~IRQF_NO_SUSPEND; + } + + /* setting wakeup sources */ + switch (irq) { + /* wakeup line 2 */ + case IRQ_PXA910_AP_GPIO: + awucrm = MPMU_AWUCRM_WAKEUP(2); + apcr |= MPMU_APCR_SLPWP2; + break; + /* wakeup line 3 */ + case IRQ_PXA910_KEYPAD: + awucrm = MPMU_AWUCRM_WAKEUP(3) | MPMU_AWUCRM_KEYPRESS; + apcr |= MPMU_APCR_SLPWP3; + break; + case IRQ_PXA910_ROTARY: + awucrm = MPMU_AWUCRM_WAKEUP(3) | MPMU_AWUCRM_NEWROTARY; + apcr |= MPMU_APCR_SLPWP3; + break; + case IRQ_PXA910_TRACKBALL: + awucrm = MPMU_AWUCRM_WAKEUP(3) | MPMU_AWUCRM_TRACKBALL; + apcr |= MPMU_APCR_SLPWP3; + break; + /* wakeup line 4 */ + case IRQ_PXA910_AP1_TIMER1: + awucrm = MPMU_AWUCRM_WAKEUP(4) | MPMU_AWUCRM_AP1_TIMER_1; + apcr |= MPMU_APCR_SLPWP4; + break; + case IRQ_PXA910_AP1_TIMER2: + awucrm = MPMU_AWUCRM_WAKEUP(4) | MPMU_AWUCRM_AP1_TIMER_2; + apcr |= MPMU_APCR_SLPWP4; + break; + case IRQ_PXA910_AP1_TIMER3: + awucrm = MPMU_AWUCRM_WAKEUP(4) | MPMU_AWUCRM_AP1_TIMER_3; + apcr |= MPMU_APCR_SLPWP4; + break; + case IRQ_PXA910_AP2_TIMER1: + awucrm = MPMU_AWUCRM_WAKEUP(4) | MPMU_AWUCRM_AP2_TIMER_1; + apcr |= MPMU_APCR_SLPWP4; + break; + case IRQ_PXA910_AP2_TIMER2: + awucrm = MPMU_AWUCRM_WAKEUP(4) | MPMU_AWUCRM_AP2_TIMER_2; + apcr |= MPMU_APCR_SLPWP4; + break; + case IRQ_PXA910_AP2_TIMER3: + awucrm = MPMU_AWUCRM_WAKEUP(4) | MPMU_AWUCRM_AP2_TIMER_3; + apcr |= MPMU_APCR_SLPWP4; + break; + case IRQ_PXA910_RTC_ALARM: + awucrm = MPMU_AWUCRM_WAKEUP(4) | MPMU_AWUCRM_RTC_ALARM; + apcr |= MPMU_APCR_SLPWP4; + break; + /* wakeup line 5 */ + case IRQ_PXA910_USB1: + case IRQ_PXA910_USB2: + awucrm = MPMU_AWUCRM_WAKEUP(5); + apcr |= MPMU_APCR_SLPWP5; + break; + /* wakeup line 6 */ + case IRQ_PXA910_MMC: + awucrm = MPMU_AWUCRM_WAKEUP(6) + | MPMU_AWUCRM_SDH1 + | MPMU_AWUCRM_SDH2; + apcr |= MPMU_APCR_SLPWP6; + break; + /* wakeup line 7 */ + case IRQ_PXA910_PMIC_INT: + awucrm = MPMU_AWUCRM_WAKEUP(7); + apcr |= MPMU_APCR_SLPWP7; + break; + default: + if (irq >= IRQ_GPIO_START && irq < IRQ_BOARD_START) { + awucrm = MPMU_AWUCRM_WAKEUP(2); + apcr |= MPMU_APCR_SLPWP2; + } else + printk(KERN_ERR "Error: no defined wake up source irq: %d\n", + irq); + } + + if (on) { + if (awucrm) { + awucrm |= __raw_readl(MPMU_AWUCRM); + __raw_writel(awucrm, MPMU_AWUCRM); + } + if (apcr) { + apcr = ~apcr & __raw_readl(MPMU_APCR); + __raw_writel(apcr, MPMU_APCR); + } + } else { + if (awucrm) { + awucrm = ~awucrm & __raw_readl(MPMU_AWUCRM); + __raw_writel(awucrm, MPMU_AWUCRM); + } + if (apcr) { + apcr |= __raw_readl(MPMU_APCR); + __raw_writel(apcr, MPMU_APCR); + } + } + return 0; +} + +void pxa910_pm_enter_lowpower_mode(int state) +{ + uint32_t idle_cfg, apcr; + + idle_cfg = __raw_readl(APMU_MOH_IDLE_CFG); + apcr = __raw_readl(MPMU_APCR); + + apcr &= ~(MPMU_APCR_DDRCORSD | MPMU_APCR_APBSD | MPMU_APCR_AXISD + | MPMU_APCR_VCTCXOSD | MPMU_APCR_STBYEN); + idle_cfg &= ~(APMU_MOH_IDLE_CFG_MOH_IDLE + | APMU_MOH_IDLE_CFG_MOH_PWRDWN); + + switch (state) { + case POWER_MODE_UDR: + /* only shutdown APB in UDR */ + apcr |= MPMU_APCR_STBYEN | MPMU_APCR_APBSD; + /* fall through */ + case POWER_MODE_SYS_SLEEP: + apcr |= MPMU_APCR_SLPEN; /* set the SLPEN bit */ + apcr |= MPMU_APCR_VCTCXOSD; /* set VCTCXOSD */ + /* fall through */ + case POWER_MODE_APPS_SLEEP: + apcr |= MPMU_APCR_DDRCORSD; /* set DDRCORSD */ + /* fall through */ + case POWER_MODE_APPS_IDLE: + apcr |= MPMU_APCR_AXISD; /* set AXISDD bit */ + /* fall through */ + case POWER_MODE_CORE_EXTIDLE: + idle_cfg |= APMU_MOH_IDLE_CFG_MOH_IDLE; + idle_cfg |= APMU_MOH_IDLE_CFG_MOH_PWRDWN; + idle_cfg |= APMU_MOH_IDLE_CFG_MOH_PWR_SW(3) + | APMU_MOH_IDLE_CFG_MOH_L2_PWR_SW(3); + /* fall through */ + case POWER_MODE_CORE_INTIDLE: + break; + } + + /* program the memory controller hardware sleep type and auto wakeup */ + idle_cfg |= APMU_MOH_IDLE_CFG_MOH_DIS_MC_SW_REQ; + idle_cfg |= APMU_MOH_IDLE_CFG_MOH_MC_WAKE_EN; + __raw_writel(0x0, APMU_MC_HW_SLP_TYPE); /* auto refresh */ + + /* set DSPSD, DTCMSD, BBSD, MSASLPEN */ + apcr |= MPMU_APCR_DSPSD | MPMU_APCR_DTCMSD | MPMU_APCR_BBSD + | MPMU_APCR_MSASLPEN; + + /*always set SLEPEN bit mainly for MSA*/ + apcr |= MPMU_APCR_SLPEN; + + /* finally write the registers back */ + __raw_writel(idle_cfg, APMU_MOH_IDLE_CFG); + __raw_writel(apcr, MPMU_APCR); + +} + +static int pxa910_pm_enter(suspend_state_t state) +{ + unsigned int idle_cfg, reg = 0; + + /*pmic thread not completed,exit;otherwise system can't be waked up*/ + reg = __raw_readl(ICU_INT_CONF(IRQ_PXA910_PMIC_INT)); + if ((reg & 0x3) == 0) + return -EAGAIN; + + idle_cfg = __raw_readl(APMU_MOH_IDLE_CFG); + idle_cfg |= APMU_MOH_IDLE_CFG_MOH_PWRDWN + | APMU_MOH_IDLE_CFG_MOH_SRAM_PWRDWN; + __raw_writel(idle_cfg, APMU_MOH_IDLE_CFG); + + /* disable L2 */ + outer_disable(); + /* wait for l2 idle */ + while (!(readl(CIU_REG(0x8)) & (1 << 16))) + udelay(1); + + cpu_do_idle(); + + /* enable L2 */ + outer_resume(); + /* wait for l2 idle */ + while (!(readl(CIU_REG(0x8)) & (1 << 16))) + udelay(1); + + idle_cfg = __raw_readl(APMU_MOH_IDLE_CFG); + idle_cfg &= ~(APMU_MOH_IDLE_CFG_MOH_PWRDWN + | APMU_MOH_IDLE_CFG_MOH_SRAM_PWRDWN); + __raw_writel(idle_cfg, APMU_MOH_IDLE_CFG); + + return 0; +} + +/* + * Called after processes are frozen, but before we shut down devices. + */ +static int pxa910_pm_prepare(void) +{ + pxa910_pm_enter_lowpower_mode(POWER_MODE_UDR); + return 0; +} + +/* + * Called after devices are re-setup, but before processes are thawed. + */ +static void pxa910_pm_finish(void) +{ + pxa910_pm_enter_lowpower_mode(POWER_MODE_CORE_INTIDLE); +} + +static int pxa910_pm_valid(suspend_state_t state) +{ + return ((state == PM_SUSPEND_STANDBY) || (state == PM_SUSPEND_MEM)); +} + +static const struct platform_suspend_ops pxa910_pm_ops = { + .valid = pxa910_pm_valid, + .prepare = pxa910_pm_prepare, + .enter = pxa910_pm_enter, + .finish = pxa910_pm_finish, +}; + +static int __init pxa910_pm_init(void) +{ + uint32_t awucrm = 0; + + if (!cpu_is_pxa910()) + return -EIO; + + suspend_set_ops(&pxa910_pm_ops); + + /* Set the following bits for MMP3 playback with VCTXO on */ + __raw_writel(__raw_readl(APMU_SQU_CLK_GATE_CTRL) | (1 << 30), + APMU_SQU_CLK_GATE_CTRL); + __raw_writel(__raw_readl(MPMU_FCCR) | (1 << 28), MPMU_FCCR); + + awucrm |= MPMU_AWUCRM_AP_ASYNC_INT | MPMU_AWUCRM_AP_FULL_IDLE; + __raw_writel(awucrm, MPMU_AWUCRM); + + return 0; +} + +late_initcall(pxa910_pm_init); diff --git a/arch/arm/mach-mmp/ttc_dkb.c b/arch/arm/mach-mmp/ttc_dkb.c index 3fc9ed21f97d..e8cf5ea15263 100644 --- a/arch/arm/mach-mmp/ttc_dkb.c +++ b/arch/arm/mach-mmp/ttc_dkb.c @@ -17,6 +17,7 @@ #include <linux/interrupt.h> #include <linux/i2c/pca953x.h> #include <linux/gpio.h> +#include <linux/mfd/88pm860x.h> #include <asm/mach-types.h> #include <asm/mach/arch.h> @@ -135,8 +136,18 @@ static struct pca953x_platform_data max7312_data[] = { }, }; +static struct pm860x_platform_data ttc_dkb_pm8607_info = { + .irq_base = IRQ_BOARD_START, +}; + static struct i2c_board_info ttc_dkb_i2c_info[] = { { + .type = "88PM860x", + .addr = 0x34, + .platform_data = &ttc_dkb_pm8607_info, + .irq = IRQ_PXA910_PMIC_INT, + }, + { .type = "max7312", .addr = 0x23, .irq = MMP_GPIO_TO_IRQ(80), diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 49f92bc1c311..385c083d24b2 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -4,7 +4,7 @@ # Common support obj-y := id.o io.o control.o mux.o devices.o serial.o gpmc.o timer.o pm.o \ - common.o gpio.o dma.o wd_timer.o display.o i2c.o + common.o gpio.o dma.o wd_timer.o display.o i2c.o hdq1w.o omap-2-3-common = irq.o sdrc.o hwmod-common = omap_hwmod.o \ @@ -118,16 +118,18 @@ obj-$(CONFIG_ARCH_OMAP4) += $(powerdomain-common) \ powerdomains44xx_data.o # PRCM clockdomain control -obj-$(CONFIG_ARCH_OMAP2) += clockdomain.o \ +clockdomain-common += clockdomain.o \ + clockdomains_common_data.o +obj-$(CONFIG_ARCH_OMAP2) += $(clockdomain-common) \ clockdomain2xxx_3xxx.o \ clockdomains2xxx_3xxx_data.o obj-$(CONFIG_SOC_OMAP2420) += clockdomains2420_data.o obj-$(CONFIG_SOC_OMAP2430) += clockdomains2430_data.o -obj-$(CONFIG_ARCH_OMAP3) += clockdomain.o \ +obj-$(CONFIG_ARCH_OMAP3) += $(clockdomain-common) \ clockdomain2xxx_3xxx.o \ clockdomains2xxx_3xxx_data.o \ clockdomains3xxx_data.o -obj-$(CONFIG_ARCH_OMAP4) += clockdomain.o \ +obj-$(CONFIG_ARCH_OMAP4) += $(clockdomain-common) \ clockdomain44xx.o \ clockdomains44xx_data.o @@ -187,6 +189,9 @@ ifneq ($(CONFIG_TIDSPBRIDGE),) obj-y += dsp.o endif +# OMAP2420 MSDI controller integration support ("MMC") +obj-$(CONFIG_SOC_OMAP2420) += msdi.o + # Specific board support obj-$(CONFIG_MACH_OMAP_GENERIC) += board-generic.o obj-$(CONFIG_MACH_OMAP_H4) += board-h4.o diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c index d9f4931513f9..5c4e66542169 100644 --- a/arch/arm/mach-omap2/clock.c +++ b/arch/arm/mach-omap2/clock.c @@ -439,7 +439,7 @@ void omap2_clk_disable_unused(struct clk *clk) clk->ops->disable(clk); } if (clk->clkdm != NULL) - pwrdm_clkdm_state_switch(clk->clkdm); + pwrdm_state_switch(clk->clkdm->pwrdm.ptr); } #endif diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c index f4a626f7c79e..4e1a3b0e8cc8 100644 --- a/arch/arm/mach-omap2/clock3xxx_data.c +++ b/arch/arm/mach-omap2/clock3xxx_data.c @@ -1,7 +1,7 @@ /* * OMAP3 clock data * - * Copyright (C) 2007-2010 Texas Instruments, Inc. + * Copyright (C) 2007-2010, 2012 Texas Instruments, Inc. * Copyright (C) 2007-2011 Nokia Corporation * * Written by Paul Walmsley @@ -1640,6 +1640,7 @@ static struct clk hdq_fck = { .name = "hdq_fck", .ops = &clkops_omap2_dflt_wait, .parent = &core_12m_fck, + .clkdm_name = "core_l4_clkdm", .enable_reg = OMAP_CM_REGADDR(CORE_MOD, CM_FCLKEN1), .enable_bit = OMAP3430_EN_HDQ_SHIFT, .recalc = &followparent_recalc, @@ -3294,8 +3295,8 @@ static struct omap_clk omap3xxx_clks[] = { CLK(NULL, "gfx_l3_ick", &gfx_l3_ick, CK_3430ES1), CLK(NULL, "gfx_cg1_ck", &gfx_cg1_ck, CK_3430ES1), CLK(NULL, "gfx_cg2_ck", &gfx_cg2_ck, CK_3430ES1), - CLK(NULL, "sgx_fck", &sgx_fck, CK_3430ES2PLUS | CK_3517 | CK_36XX), - CLK(NULL, "sgx_ick", &sgx_ick, CK_3430ES2PLUS | CK_3517 | CK_36XX), + CLK(NULL, "sgx_fck", &sgx_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), + CLK(NULL, "sgx_ick", &sgx_ick, CK_3430ES2PLUS | CK_AM35XX | CK_36XX), CLK(NULL, "d2d_26m_fck", &d2d_26m_fck, CK_3430ES1), CLK(NULL, "modem_fck", &modem_fck, CK_34XX | CK_36XX), CLK(NULL, "sad2d_ick", &sad2d_ick, CK_34XX | CK_36XX), @@ -3419,7 +3420,7 @@ static struct omap_clk omap3xxx_clks[] = { CLK(NULL, "per_48m_fck", &per_48m_fck, CK_3XXX), CLK(NULL, "uart3_fck", &uart3_fck, CK_3XXX), CLK(NULL, "uart4_fck", &uart4_fck, CK_36XX), - CLK(NULL, "uart4_fck", &uart4_fck_am35xx, CK_3505 | CK_3517), + CLK(NULL, "uart4_fck", &uart4_fck_am35xx, CK_AM35XX), CLK(NULL, "gpt2_fck", &gpt2_fck, CK_3XXX), CLK(NULL, "gpt3_fck", &gpt3_fck, CK_3XXX), CLK(NULL, "gpt4_fck", &gpt4_fck, CK_3XXX), @@ -3513,21 +3514,9 @@ int __init omap3xxx_clk_init(void) struct omap_clk *c; u32 cpu_clkflg = 0; - /* - * 3505 must be tested before 3517, since 3517 returns true - * for both AM3517 chips and AM3517 family chips, which - * includes 3505. Unfortunately there's no obvious family - * test for 3517/3505 :-( - */ - if (cpu_is_omap3505()) { - cpu_mask = RATE_IN_34XX; - cpu_clkflg = CK_3505; - } else if (cpu_is_omap3517()) { - cpu_mask = RATE_IN_34XX; - cpu_clkflg = CK_3517; - } else if (cpu_is_omap3505()) { + if (cpu_is_omap3517()) { cpu_mask = RATE_IN_34XX; - cpu_clkflg = CK_3505; + cpu_clkflg = CK_AM35XX; } else if (cpu_is_omap3630()) { cpu_mask = (RATE_IN_34XX | RATE_IN_36XX); cpu_clkflg = CK_36XX; diff --git a/arch/arm/mach-omap2/clock44xx_data.c b/arch/arm/mach-omap2/clock44xx_data.c index fa6ea65ad44b..2172f6603848 100644 --- a/arch/arm/mach-omap2/clock44xx_data.c +++ b/arch/arm/mach-omap2/clock44xx_data.c @@ -3355,17 +3355,6 @@ static struct omap_clk omap44xx_clks[] = { CLK(NULL, "auxclk5_ck", &auxclk5_ck, CK_443X), CLK(NULL, "auxclkreq5_ck", &auxclkreq5_ck, CK_443X), CLK(NULL, "gpmc_ck", &dummy_ck, CK_443X), - CLK(NULL, "gpt1_ick", &dummy_ck, CK_443X), - CLK(NULL, "gpt2_ick", &dummy_ck, CK_443X), - CLK(NULL, "gpt3_ick", &dummy_ck, CK_443X), - CLK(NULL, "gpt4_ick", &dummy_ck, CK_443X), - CLK(NULL, "gpt5_ick", &dummy_ck, CK_443X), - CLK(NULL, "gpt6_ick", &dummy_ck, CK_443X), - CLK(NULL, "gpt7_ick", &dummy_ck, CK_443X), - CLK(NULL, "gpt8_ick", &dummy_ck, CK_443X), - CLK(NULL, "gpt9_ick", &dummy_ck, CK_443X), - CLK(NULL, "gpt10_ick", &dummy_ck, CK_443X), - CLK(NULL, "gpt11_ick", &dummy_ck, CK_443X), CLK("omap_i2c.1", "ick", &dummy_ck, CK_443X), CLK("omap_i2c.2", "ick", &dummy_ck, CK_443X), CLK("omap_i2c.3", "ick", &dummy_ck, CK_443X), diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index ad07689e1563..8664f5a8bfb6 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c @@ -840,7 +840,7 @@ void clkdm_allow_idle(struct clockdomain *clkdm) spin_lock_irqsave(&clkdm->lock, flags); clkdm->_flags |= _CLKDM_FLAG_HWSUP_ENABLED; arch_clkdm->clkdm_allow_idle(clkdm); - pwrdm_clkdm_state_switch(clkdm); + pwrdm_state_switch(clkdm->pwrdm.ptr); spin_unlock_irqrestore(&clkdm->lock, flags); } @@ -924,8 +924,7 @@ static int _clkdm_clk_hwmod_enable(struct clockdomain *clkdm) spin_lock_irqsave(&clkdm->lock, flags); arch_clkdm->clkdm_clk_enable(clkdm); - pwrdm_wait_transition(clkdm->pwrdm.ptr); - pwrdm_clkdm_state_switch(clkdm); + pwrdm_state_switch(clkdm->pwrdm.ptr); spin_unlock_irqrestore(&clkdm->lock, flags); pr_debug("clockdomain: clkdm %s: enabled\n", clkdm->name); @@ -950,7 +949,7 @@ static int _clkdm_clk_hwmod_disable(struct clockdomain *clkdm) spin_lock_irqsave(&clkdm->lock, flags); arch_clkdm->clkdm_clk_disable(clkdm); - pwrdm_clkdm_state_switch(clkdm); + pwrdm_state_switch(clkdm->pwrdm.ptr); spin_unlock_irqrestore(&clkdm->lock, flags); pr_debug("clockdomain: clkdm %s: disabled\n", clkdm->name); diff --git a/arch/arm/mach-omap2/clockdomain44xx.c b/arch/arm/mach-omap2/clockdomain44xx.c index 935c7f03dab9..4f04dd11d655 100644 --- a/arch/arm/mach-omap2/clockdomain44xx.c +++ b/arch/arm/mach-omap2/clockdomain44xx.c @@ -51,6 +51,9 @@ static int omap4_clkdm_clear_all_wkup_sleep_deps(struct clockdomain *clkdm) struct clkdm_dep *cd; u32 mask = 0; + if (!clkdm->prcm_partition) + return 0; + for (cd = clkdm->wkdep_srcs; cd && cd->clkdm_name; cd++) { if (!cd->clkdm) continue; /* only happens if data is erroneous */ @@ -103,6 +106,9 @@ static int omap4_clkdm_clk_disable(struct clockdomain *clkdm) { bool hwsup = false; + if (!clkdm->prcm_partition) + return 0; + hwsup = omap4_cminst_is_clkdm_in_hwsup(clkdm->prcm_partition, clkdm->cm_inst, clkdm->clkdm_offs); diff --git a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c index 0a6a04897d89..839145e1cfbe 100644 --- a/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c +++ b/arch/arm/mach-omap2/clockdomains2xxx_3xxx_data.c @@ -89,13 +89,3 @@ struct clockdomain wkup_common_clkdm = { .pwrdm = { .name = "wkup_pwrdm" }, .dep_bit = OMAP_EN_WKUP_SHIFT, }; - -struct clockdomain prm_common_clkdm = { - .name = "prm_clkdm", - .pwrdm = { .name = "wkup_pwrdm" }, -}; - -struct clockdomain cm_common_clkdm = { - .name = "cm_clkdm", - .pwrdm = { .name = "core_pwrdm" }, -}; diff --git a/arch/arm/mach-omap2/clockdomains3xxx_data.c b/arch/arm/mach-omap2/clockdomains3xxx_data.c index b84e138d99c8..6038adb97710 100644 --- a/arch/arm/mach-omap2/clockdomains3xxx_data.c +++ b/arch/arm/mach-omap2/clockdomains3xxx_data.c @@ -53,9 +53,9 @@ * 3430ES2 PM_WKDEP_SGX: adds IVA2, removes CORE */ static struct clkdm_dep gfx_sgx_3xxx_wkdeps[] = { - { .clkdm_name = "iva2_clkdm", }, - { .clkdm_name = "mpu_clkdm", }, - { .clkdm_name = "wkup_clkdm", }, + { .clkdm_name = "iva2_clkdm" }, + { .clkdm_name = "mpu_clkdm" }, + { .clkdm_name = "wkup_clkdm" }, { NULL }, }; diff --git a/arch/arm/mach-omap2/clockdomains44xx_data.c b/arch/arm/mach-omap2/clockdomains44xx_data.c index bd7ed13515cc..c53425847493 100644 --- a/arch/arm/mach-omap2/clockdomains44xx_data.c +++ b/arch/arm/mach-omap2/clockdomains44xx_data.c @@ -430,6 +430,8 @@ static struct clockdomain *clockdomains_omap44xx[] __initdata = { &l4_wkup_44xx_clkdm, &emu_sys_44xx_clkdm, &l3_dma_44xx_clkdm, + &prm_common_clkdm, + &cm_common_clkdm, NULL }; diff --git a/arch/arm/mach-omap2/clockdomains_common_data.c b/arch/arm/mach-omap2/clockdomains_common_data.c new file mode 100644 index 000000000000..615b1f04967d --- /dev/null +++ b/arch/arm/mach-omap2/clockdomains_common_data.c @@ -0,0 +1,24 @@ +/* + * OMAP2+-common clockdomain data + * + * Copyright (C) 2008-2012 Texas Instruments, Inc. + * Copyright (C) 2008-2010 Nokia Corporation + * + * Paul Walmsley, Jouni Högander + */ + +#include <linux/kernel.h> +#include <linux/io.h> + +#include "clockdomain.h" + +/* These are implicit clockdomains - they are never defined as such in TRM */ +struct clockdomain prm_common_clkdm = { + .name = "prm_clkdm", + .pwrdm = { .name = "wkup_pwrdm" }, +}; + +struct clockdomain cm_common_clkdm = { + .name = "cm_clkdm", + .pwrdm = { .name = "core_pwrdm" }, +}; diff --git a/arch/arm/mach-omap2/cm-regbits-34xx.h b/arch/arm/mach-omap2/cm-regbits-34xx.h index b91275908f33..8083a8cdc55f 100644 --- a/arch/arm/mach-omap2/cm-regbits-34xx.h +++ b/arch/arm/mach-omap2/cm-regbits-34xx.h @@ -79,7 +79,7 @@ /* CM_CLKSEL1_PLL_IVA2 */ #define OMAP3430_IVA2_CLK_SRC_SHIFT 19 -#define OMAP3430_IVA2_CLK_SRC_MASK (0x3 << 19) +#define OMAP3430_IVA2_CLK_SRC_MASK (0x7 << 19) #define OMAP3430_IVA2_DPLL_MULT_SHIFT 8 #define OMAP3430_IVA2_DPLL_MULT_MASK (0x7ff << 8) #define OMAP3430_IVA2_DPLL_DIV_SHIFT 0 @@ -124,7 +124,7 @@ /* CM_CLKSEL1_PLL_MPU */ #define OMAP3430_MPU_CLK_SRC_SHIFT 19 -#define OMAP3430_MPU_CLK_SRC_MASK (0x3 << 19) +#define OMAP3430_MPU_CLK_SRC_MASK (0x7 << 19) #define OMAP3430_MPU_DPLL_MULT_SHIFT 8 #define OMAP3430_MPU_DPLL_MULT_MASK (0x7ff << 8) #define OMAP3430_MPU_DPLL_DIV_SHIFT 0 diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c index bd8810c3753f..8c86d294b1a3 100644 --- a/arch/arm/mach-omap2/cminst44xx.c +++ b/arch/arm/mach-omap2/cminst44xx.c @@ -32,6 +32,7 @@ #include "prcm44xx.h" #include "prm44xx.h" #include "prcm_mpu44xx.h" +#include "prcm-common.h" /* * CLKCTRL_IDLEST_*: possible values for the CM_*_CLKCTRL.IDLEST bitfield: @@ -49,14 +50,21 @@ #define CLKCTRL_IDLEST_INTERFACE_IDLE 0x2 #define CLKCTRL_IDLEST_DISABLED 0x3 -static u32 _cm_bases[OMAP4_MAX_PRCM_PARTITIONS] = { - [OMAP4430_INVALID_PRCM_PARTITION] = 0, - [OMAP4430_PRM_PARTITION] = OMAP4430_PRM_BASE, - [OMAP4430_CM1_PARTITION] = OMAP4430_CM1_BASE, - [OMAP4430_CM2_PARTITION] = OMAP4430_CM2_BASE, - [OMAP4430_SCRM_PARTITION] = 0, - [OMAP4430_PRCM_MPU_PARTITION] = OMAP4430_PRCM_MPU_BASE, -}; +static void __iomem *_cm_bases[OMAP4_MAX_PRCM_PARTITIONS]; + +/** + * omap_cm_base_init - Populates the cm partitions + * + * Populates the base addresses of the _cm_bases + * array used for read/write of cm module registers. + */ +void omap_cm_base_init(void) +{ + _cm_bases[OMAP4430_PRM_PARTITION] = prm_base; + _cm_bases[OMAP4430_CM1_PARTITION] = cm_base; + _cm_bases[OMAP4430_CM2_PARTITION] = cm2_base; + _cm_bases[OMAP4430_PRCM_MPU_PARTITION] = prcm_mpu_base; +} /* Private functions */ @@ -106,7 +114,7 @@ u32 omap4_cminst_read_inst_reg(u8 part, s16 inst, u16 idx) BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || part == OMAP4430_INVALID_PRCM_PARTITION || !_cm_bases[part]); - return __raw_readl(OMAP2_L4_IO_ADDRESS(_cm_bases[part] + inst + idx)); + return __raw_readl(_cm_bases[part] + inst + idx); } /* Write into a register in a CM instance */ @@ -115,7 +123,7 @@ void omap4_cminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx) BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || part == OMAP4430_INVALID_PRCM_PARTITION || !_cm_bases[part]); - __raw_writel(val, OMAP2_L4_IO_ADDRESS(_cm_bases[part] + inst + idx)); + __raw_writel(val, _cm_bases[part] + inst + idx); } /* Read-modify-write a register in CM1. Caller must lock */ diff --git a/arch/arm/mach-omap2/common.c b/arch/arm/mach-omap2/common.c index 1549c11000d3..8a6953a34fe2 100644 --- a/arch/arm/mach-omap2/common.c +++ b/arch/arm/mach-omap2/common.c @@ -166,6 +166,7 @@ static struct omap_globals omap4_globals = { .prm = OMAP2_L4_IO_ADDRESS(OMAP4430_PRM_BASE), .cm = OMAP2_L4_IO_ADDRESS(OMAP4430_CM_BASE), .cm2 = OMAP2_L4_IO_ADDRESS(OMAP4430_CM2_BASE), + .prcm_mpu = OMAP2_L4_IO_ADDRESS(OMAP4430_PRCM_MPU_BASE), }; void __init omap2_set_globals_443x(void) diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index f14b3aec58cc..d6c9e6180318 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -112,6 +112,7 @@ struct omap_globals { void __iomem *prm; /* Power and Reset Management */ void __iomem *cm; /* Clock Management */ void __iomem *cm2; + void __iomem *prcm_mpu; }; void omap2_set_globals_242x(void); diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c index fc56745676fa..f0f10beeffe8 100644 --- a/arch/arm/mach-omap2/dpll3xxx.c +++ b/arch/arm/mach-omap2/dpll3xxx.c @@ -142,7 +142,8 @@ static int _omap3_noncore_dpll_lock(struct clk *clk) ai = omap3_dpll_autoidle_read(clk); - omap3_dpll_deny_idle(clk); + if (ai) + omap3_dpll_deny_idle(clk); _omap3_dpll_write_clken(clk, DPLL_LOCKED); @@ -186,8 +187,6 @@ static int _omap3_noncore_dpll_bypass(struct clk *clk) if (ai) omap3_dpll_allow_idle(clk); - else - omap3_dpll_deny_idle(clk); return r; } @@ -216,8 +215,6 @@ static int _omap3_noncore_dpll_stop(struct clk *clk) if (ai) omap3_dpll_allow_idle(clk); - else - omap3_dpll_deny_idle(clk); return 0; } @@ -519,6 +516,9 @@ u32 omap3_dpll_autoidle_read(struct clk *clk) dd = clk->dpll_data; + if (!dd->autoidle_reg) + return -EINVAL; + v = __raw_readl(dd->autoidle_reg); v &= dd->autoidle_mask; v >>= __ffs(dd->autoidle_mask); @@ -545,6 +545,12 @@ void omap3_dpll_allow_idle(struct clk *clk) dd = clk->dpll_data; + if (!dd->autoidle_reg) { + pr_debug("clock: DPLL %s: autoidle not supported\n", + clk->name); + return; + } + /* * REVISIT: CORE DPLL can optionally enter low-power bypass * by writing 0x5 instead of 0x1. Add some mechanism to @@ -554,6 +560,7 @@ void omap3_dpll_allow_idle(struct clk *clk) v &= ~dd->autoidle_mask; v |= DPLL_AUTOIDLE_LOW_POWER_STOP << __ffs(dd->autoidle_mask); __raw_writel(v, dd->autoidle_reg); + } /** @@ -572,6 +579,12 @@ void omap3_dpll_deny_idle(struct clk *clk) dd = clk->dpll_data; + if (!dd->autoidle_reg) { + pr_debug("clock: DPLL %s: autoidle not supported\n", + clk->name); + return; + } + v = __raw_readl(dd->autoidle_reg); v &= ~dd->autoidle_mask; v |= DPLL_AUTOIDLE_DISABLE << __ffs(dd->autoidle_mask); diff --git a/arch/arm/mach-omap2/hdq1w.c b/arch/arm/mach-omap2/hdq1w.c new file mode 100644 index 000000000000..297ebe03f09c --- /dev/null +++ b/arch/arm/mach-omap2/hdq1w.c @@ -0,0 +1,72 @@ +/* + * IP block integration code for the HDQ1W/1-wire IP block + * + * Copyright (C) 2012 Texas Instruments, Inc. + * Paul Walmsley + * + * Based on the I2C reset code in arch/arm/mach-omap2/i2c.c by + * Avinash.H.M <avinashhm@ti.com> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; 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 <plat/omap_hwmod.h> +#include <plat/hdq1w.h> + +#include "common.h" + +/* Maximum microseconds to wait for OMAP module to softreset */ +#define MAX_MODULE_SOFTRESET_WAIT 10000 + +/** + * omap_hdq1w_reset - reset the OMAP HDQ1W module + * @oh: struct omap_hwmod * + * + * OCP soft reset the HDQ1W IP block. Section 20.6.1.4 "HDQ1W/1-Wire + * Software Reset" of the OMAP34xx Technical Reference Manual Revision + * ZR (SWPU223R) does not include the rather important fact that, for + * the reset to succeed, the HDQ1W module's internal clock gate must be + * programmed to allow the clock to propagate to the rest of the + * module. In this sense, it's rather similar to the I2C custom reset + * function. Returns 0. + */ +int omap_hdq1w_reset(struct omap_hwmod *oh) +{ + u32 v; + int c = 0; + + /* Write to the SOFTRESET bit */ + omap_hwmod_softreset(oh); + + /* Enable the module's internal clocks */ + v = omap_hwmod_read(oh, HDQ_CTRL_STATUS_OFFSET); + v |= 1 << HDQ_CTRL_STATUS_CLOCKENABLE_SHIFT; + omap_hwmod_write(v, oh, HDQ_CTRL_STATUS_OFFSET); + + /* Poll on RESETDONE bit */ + omap_test_timeout((omap_hwmod_read(oh, + oh->class->sysc->syss_offs) + & SYSS_RESETDONE_MASK), + MAX_MODULE_SOFTRESET_WAIT, c); + + if (c == MAX_MODULE_SOFTRESET_WAIT) + pr_warning("%s: %s: softreset failed (waited %d usec)\n", + __func__, oh->name, MAX_MODULE_SOFTRESET_WAIT); + else + pr_debug("%s: %s: softreset in %d usec\n", __func__, + oh->name, c); + + return 0; +} diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 2d5a57669a79..4b9491aa36fa 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -364,24 +364,6 @@ static void __init omap_hwmod_init_postsetup(void) #endif omap_hwmod_for_each(_set_hwmod_postsetup_state, &postsetup_state); - /* - * Set the default postsetup state for unusual modules (like - * MPU WDT). - * - * The postsetup_state is not actually used until - * omap_hwmod_late_init(), so boards that desire full watchdog - * coverage of kernel initialization can reprogram the - * postsetup_state between the calls to - * omap2_init_common_infra() and omap_sdrc_init(). - * - * XXX ideally we could detect whether the MPU WDT was currently - * enabled here and make this conditional - */ - postsetup_state = _HWMOD_STATE_DISABLED; - omap_hwmod_for_each_by_class("wd_timer", - _set_hwmod_postsetup_state, - &postsetup_state); - omap_pm_if_early_init(); } diff --git a/arch/arm/mach-omap2/msdi.c b/arch/arm/mach-omap2/msdi.c new file mode 100644 index 000000000000..ef2a6924731a --- /dev/null +++ b/arch/arm/mach-omap2/msdi.c @@ -0,0 +1,88 @@ +/* + * MSDI 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 + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; 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 + * + * XXX What about pad muxing? + */ + +#include <linux/kernel.h> + +#include <plat/omap_hwmod.h> +#include <plat/mmc.h> + +#include "common.h" + +/* + * MSDI_CON_OFFSET: offset in bytes of the MSDI IP block's CON register + * from the IP block's base address + */ +#define MSDI_CON_OFFSET 0x0c + +/* Register bitfields in the CON register */ +#define MSDI_CON_POW_MASK BIT(11) +#define MSDI_CON_CLKD_MASK (0x3f << 0) +#define MSDI_CON_CLKD_SHIFT 0 + +/* Maximum microseconds to wait for OMAP module to softreset */ +#define MAX_MODULE_SOFTRESET_WAIT 10000 + +/* MSDI_TARGET_RESET_CLKD: clock divisor to use throughout the reset */ +#define MSDI_TARGET_RESET_CLKD 0x3ff + +/** + * omap_msdi_reset - reset the MSDI IP block + * @oh: struct omap_hwmod * + * + * The MSDI IP block on OMAP2420 has to have both the POW and CLKD + * fields set inside its CON register for a reset to complete + * successfully. This is not documented in the TRM. For CLKD, we use + * the value that results in the lowest possible clock rate, to attempt + * to avoid disturbing any cards. + */ +int omap_msdi_reset(struct omap_hwmod *oh) +{ + u16 v = 0; + int c = 0; + + /* Write to the SOFTRESET bit */ + omap_hwmod_softreset(oh); + + /* Enable the MSDI core and internal clock */ + v |= MSDI_CON_POW_MASK; + v |= MSDI_TARGET_RESET_CLKD << MSDI_CON_CLKD_SHIFT; + omap_hwmod_write(v, oh, MSDI_CON_OFFSET); + + /* Poll on RESETDONE bit */ + omap_test_timeout((omap_hwmod_read(oh, oh->class->sysc->syss_offs) + & SYSS_RESETDONE_MASK), + MAX_MODULE_SOFTRESET_WAIT, c); + + if (c == MAX_MODULE_SOFTRESET_WAIT) + pr_warning("%s: %s: softreset failed (waited %d usec)\n", + __func__, oh->name, MAX_MODULE_SOFTRESET_WAIT); + else + pr_debug("%s: %s: softreset in %d usec\n", __func__, + oh->name, c); + + /* Disable the MSDI internal clock */ + v &= ~MSDI_CON_CLKD_MASK; + omap_hwmod_write(v, oh, MSDI_CON_OFFSET); + + return 0; +} diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index 2c087ffc6a92..a7640d1b215e 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -23,6 +23,7 @@ #include <plat/dmtimer.h> #include <plat/l3_2xxx.h> #include <plat/l4_2xxx.h> +#include <plat/mmc.h> #include "omap_hwmod_common_data.h" @@ -239,6 +240,67 @@ static struct omap_hwmod omap2420_mcbsp2_hwmod = { }, }; +static struct omap_hwmod_class_sysconfig omap2420_msdi_sysc = { + .rev_offs = 0x3c, + .sysc_offs = 0x64, + .syss_offs = 0x68, + .sysc_flags = (SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap2420_msdi_hwmod_class = { + .name = "msdi", + .sysc = &omap2420_msdi_sysc, + .reset = &omap_msdi_reset, +}; + +/* msdi1 */ +static struct omap_hwmod_irq_info omap2420_msdi1_irqs[] = { + { .irq = 83 }, + { .irq = -1 } +}; + +static struct omap_hwmod_dma_info omap2420_msdi1_sdma_reqs[] = { + { .name = "tx", .dma_req = 61 }, /* OMAP24XX_DMA_MMC1_TX */ + { .name = "rx", .dma_req = 62 }, /* OMAP24XX_DMA_MMC1_RX */ + { .dma_req = -1 } +}; + +static struct omap_hwmod omap2420_msdi1_hwmod = { + .name = "msdi1", + .class = &omap2420_msdi_hwmod_class, + .mpu_irqs = omap2420_msdi1_irqs, + .sdma_reqs = omap2420_msdi1_sdma_reqs, + .main_clk = "mmc_fck", + .prcm = { + .omap2 = { + .prcm_reg_id = 1, + .module_bit = OMAP2420_EN_MMC_SHIFT, + .module_offs = CORE_MOD, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP2420_ST_MMC_SHIFT, + }, + }, + .flags = HWMOD_16BIT_REG, +}; + +/* HDQ1W/1-wire */ +static struct omap_hwmod omap2420_hdq1w_hwmod = { + .name = "hdq1w", + .mpu_irqs = omap2_hdq1w_mpu_irqs, + .main_clk = "hdq_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_HDQ_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_HDQ_SHIFT, + }, + }, + .class = &omap2_hdq1w_class, +}; + /* * interfaces */ @@ -428,6 +490,53 @@ static struct omap_hwmod_ocp_if omap2420_l4_core__mcbsp2 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +static struct omap_hwmod_addr_space omap2420_msdi1_addrs[] = { + { + .pa_start = 0x4809c000, + .pa_end = 0x4809c000 + SZ_128 - 1, + .flags = ADDR_TYPE_RT, + }, + { } +}; + +/* l4_core -> msdi1 */ +static struct omap_hwmod_ocp_if omap2420_l4_core__msdi1 = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2420_msdi1_hwmod, + .clk = "mmc_ick", + .addr = omap2420_msdi1_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_core -> hdq1w interface */ +static struct omap_hwmod_ocp_if omap2420_l4_core__hdq1w = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2420_hdq1w_hwmod, + .clk = "hdq_ick", + .addr = omap2_hdq1w_addr_space, + .user = OCP_USER_MPU | OCP_USER_SDMA, + .flags = OMAP_FIREWALL_L4 | OCPIF_SWSUP_IDLE, +}; + + +/* l4_wkup -> 32ksync_counter */ +static struct omap_hwmod_addr_space omap2420_counter_32k_addrs[] = { + { + .pa_start = 0x48004000, + .pa_end = 0x4800401f, + .flags = ADDR_TYPE_RT + }, + { } +}; + +static struct omap_hwmod_ocp_if omap2420_l4_wkup__counter_32k = { + .master = &omap2xxx_l4_wkup_hwmod, + .slave = &omap2xxx_counter_32k_hwmod, + .clk = "sync_32k_ick", + .addr = omap2420_counter_32k_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + static struct omap_hwmod_ocp_if *omap2420_hwmod_ocp_ifs[] __initdata = { &omap2xxx_l3_main__l4_core, &omap2xxx_mpu__l3_main, @@ -468,6 +577,9 @@ static struct omap_hwmod_ocp_if *omap2420_hwmod_ocp_ifs[] __initdata = { &omap2420_l4_core__mailbox, &omap2420_l4_core__mcbsp1, &omap2420_l4_core__mcbsp2, + &omap2420_l4_core__msdi1, + &omap2420_l4_core__hdq1w, + &omap2420_l4_wkup__counter_32k, NULL, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_2430_data.c b/arch/arm/mach-omap2/omap_hwmod_2430_data.c index 71d9f8824f9d..4d7264981230 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2430_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2430_data.c @@ -528,6 +528,23 @@ static struct omap_hwmod omap2430_mmc2_hwmod = { .class = &omap2430_mmc_class, }; +/* HDQ1W/1-wire */ +static struct omap_hwmod omap2430_hdq1w_hwmod = { + .name = "hdq1w", + .mpu_irqs = omap2_hdq1w_mpu_irqs, + .main_clk = "hdq_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP24XX_EN_HDQ_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_HDQ_SHIFT, + }, + }, + .class = &omap2_hdq1w_class, +}; + /* * interfaces */ @@ -838,6 +855,34 @@ static struct omap_hwmod_ocp_if omap2430_l4_core__mcbsp5 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* l4_core -> hdq1w */ +static struct omap_hwmod_ocp_if omap2430_l4_core__hdq1w = { + .master = &omap2xxx_l4_core_hwmod, + .slave = &omap2430_hdq1w_hwmod, + .clk = "hdq_ick", + .addr = omap2_hdq1w_addr_space, + .user = OCP_USER_MPU | OCP_USER_SDMA, + .flags = OMAP_FIREWALL_L4 | OCPIF_SWSUP_IDLE, +}; + +/* l4_wkup -> 32ksync_counter */ +static struct omap_hwmod_addr_space omap2430_counter_32k_addrs[] = { + { + .pa_start = 0x49020000, + .pa_end = 0x4902001f, + .flags = ADDR_TYPE_RT + }, + { } +}; + +static struct omap_hwmod_ocp_if omap2430_l4_wkup__counter_32k = { + .master = &omap2xxx_l4_wkup_hwmod, + .slave = &omap2xxx_counter_32k_hwmod, + .clk = "sync_32k_ick", + .addr = omap2430_counter_32k_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + static struct omap_hwmod_ocp_if *omap2430_hwmod_ocp_ifs[] __initdata = { &omap2xxx_l3_main__l4_core, &omap2xxx_mpu__l3_main, @@ -886,6 +931,8 @@ static struct omap_hwmod_ocp_if *omap2430_hwmod_ocp_ifs[] __initdata = { &omap2430_l4_core__mcbsp3, &omap2430_l4_core__mcbsp4, &omap2430_l4_core__mcbsp5, + &omap2430_l4_core__hdq1w, + &omap2430_l4_wkup__counter_32k, NULL, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_interconnect_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_interconnect_data.c index 04637fabadd2..cbb4ef6544ad 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_interconnect_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_interconnect_data.c @@ -171,3 +171,12 @@ struct omap_hwmod_addr_space omap2_mcbsp1_addrs[] = { }, { } }; + +struct omap_hwmod_addr_space omap2_hdq1w_addr_space[] = { + { + .pa_start = 0x480b2000, + .pa_end = 0x480b2fff, + .flags = ADDR_TYPE_RT, + }, + { } +}; diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c index f08e442af397..102d76e9e9ea 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_3xxx_ipblock_data.c @@ -2,6 +2,7 @@ * omap_hwmod_2xxx_3xxx_ipblock_data.c - common IP block data for OMAP2/3 * * Copyright (C) 2011 Nokia Corporation + * Copyright (C) 2012 Texas Instruments, Inc. * Paul Walmsley * * This program is free software; you can redistribute it and/or modify @@ -12,6 +13,7 @@ #include <plat/serial.h> #include <plat/dma.h> #include <plat/common.h> +#include <plat/hdq1w.h> #include <mach/irqs.h> @@ -302,3 +304,23 @@ struct omap_hwmod_irq_info omap2_mcspi2_mpu_irqs[] = { { .irq = -1 } }; +struct omap_hwmod_class_sysconfig omap2_hdq1w_sysc = { + .rev_offs = 0x0, + .sysc_offs = 0x14, + .syss_offs = 0x18, + .sysc_flags = (SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE | + SYSS_HAS_RESET_STATUS), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +struct omap_hwmod_class omap2_hdq1w_class = { + .name = "hdq1w", + .sysc = &omap2_hdq1w_sysc, + .reset = &omap_hdq1w_reset, +}; + +struct omap_hwmod_irq_info omap2_hdq1w_mpu_irqs[] = { + { .irq = 58, }, + { .irq = -1 } +}; + diff --git a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c index 45aaa07e3025..83eafd96ecaa 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c @@ -89,7 +89,8 @@ static struct omap_hwmod_class_sysconfig omap2xxx_wd_timer_sysc = { struct omap_hwmod_class omap2xxx_wd_timer_hwmod_class = { .name = "wd_timer", .sysc = &omap2xxx_wd_timer_sysc, - .pre_shutdown = &omap2_wd_timer_disable + .pre_shutdown = &omap2_wd_timer_disable, + .reset = &omap2_wd_timer_reset, }; /* @@ -732,3 +733,23 @@ struct omap_hwmod omap2xxx_mcspi2_hwmod = { .class = &omap2xxx_mcspi_class, .dev_attr = &omap_mcspi2_dev_attr, }; + + +static struct omap_hwmod_class omap2xxx_counter_hwmod_class = { + .name = "counter", +}; + +struct omap_hwmod omap2xxx_counter_32k_hwmod = { + .name = "counter_32k", + .main_clk = "func_32k_ck", + .prcm = { + .omap2 = { + .module_offs = WKUP_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP24XX_ST_32KSYNC_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP24XX_ST_32KSYNC_SHIFT, + }, + }, + .class = &omap2xxx_counter_hwmod_class, +}; diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 0c65079c2b69..fd48797fa95a 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -418,7 +418,8 @@ static struct omap_hwmod_class_sysconfig i2c_sysc = { static struct omap_hwmod_class omap3xxx_wd_timer_hwmod_class = { .name = "wd_timer", .sysc = &omap3xxx_wd_timer_sysc, - .pre_shutdown = &omap2_wd_timer_disable + .pre_shutdown = &omap2_wd_timer_disable, + .reset = &omap2_wd_timer_reset, }; static struct omap_hwmod omap3xxx_wd_timer2_hwmod = { @@ -1075,7 +1076,7 @@ static struct omap_hwmod_class omap3xxx_mcbsp_hwmod_class = { /* mcbsp1 */ static struct omap_hwmod_irq_info omap3xxx_mcbsp1_irqs[] = { - { .name = "irq", .irq = 16 }, + { .name = "common", .irq = 16 }, { .name = "tx", .irq = 59 }, { .name = "rx", .irq = 60 }, { .irq = -1 } @@ -1100,7 +1101,7 @@ static struct omap_hwmod omap3xxx_mcbsp1_hwmod = { /* mcbsp2 */ static struct omap_hwmod_irq_info omap3xxx_mcbsp2_irqs[] = { - { .name = "irq", .irq = 17 }, + { .name = "common", .irq = 17 }, { .name = "tx", .irq = 62 }, { .name = "rx", .irq = 63 }, { .irq = -1 } @@ -1130,7 +1131,7 @@ static struct omap_hwmod omap3xxx_mcbsp2_hwmod = { /* mcbsp3 */ static struct omap_hwmod_irq_info omap3xxx_mcbsp3_irqs[] = { - { .name = "irq", .irq = 22 }, + { .name = "common", .irq = 22 }, { .name = "tx", .irq = 89 }, { .name = "rx", .irq = 90 }, { .irq = -1 } @@ -1160,7 +1161,7 @@ static struct omap_hwmod omap3xxx_mcbsp3_hwmod = { /* mcbsp4 */ static struct omap_hwmod_irq_info omap3xxx_mcbsp4_irqs[] = { - { .name = "irq", .irq = 23 }, + { .name = "common", .irq = 23 }, { .name = "tx", .irq = 54 }, { .name = "rx", .irq = 55 }, { .irq = -1 } @@ -1191,7 +1192,7 @@ static struct omap_hwmod omap3xxx_mcbsp4_hwmod = { /* mcbsp5 */ static struct omap_hwmod_irq_info omap3xxx_mcbsp5_irqs[] = { - { .name = "irq", .irq = 27 }, + { .name = "common", .irq = 27 }, { .name = "tx", .irq = 81 }, { .name = "rx", .irq = 82 }, { .irq = -1 } @@ -1980,6 +1981,56 @@ static struct omap_hwmod omap3xxx_usb_tll_hs_hwmod = { }, }; +static struct omap_hwmod omap3xxx_hdq1w_hwmod = { + .name = "hdq1w", + .mpu_irqs = omap2_hdq1w_mpu_irqs, + .main_clk = "hdq_fck", + .prcm = { + .omap2 = { + .module_offs = CORE_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_EN_HDQ_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_HDQ_SHIFT, + }, + }, + .class = &omap2_hdq1w_class, +}; + +/* + * '32K sync counter' class + * 32-bit ordinary counter, clocked by the falling edge of the 32 khz clock + */ +static struct omap_hwmod_class_sysconfig omap3xxx_counter_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0004, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap3xxx_counter_hwmod_class = { + .name = "counter", + .sysc = &omap3xxx_counter_sysc, +}; + +static struct omap_hwmod omap3xxx_counter_32k_hwmod = { + .name = "counter_32k", + .class = &omap3xxx_counter_hwmod_class, + .clkdm_name = "wkup_clkdm", + .flags = HWMOD_SWSUP_SIDLE, + .main_clk = "wkup_32k_fck", + .prcm = { + .omap2 = { + .module_offs = WKUP_MOD, + .prcm_reg_id = 1, + .module_bit = OMAP3430_ST_32KSYNC_SHIFT, + .idlest_reg_id = 1, + .idlest_idle_bit = OMAP3430_ST_32KSYNC_SHIFT, + }, + }, +}; + /* * interfaces */ @@ -3059,6 +3110,34 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_core__usb_tll_hs = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* l4_core -> hdq1w interface */ +static struct omap_hwmod_ocp_if omap3xxx_l4_core__hdq1w = { + .master = &omap3xxx_l4_core_hwmod, + .slave = &omap3xxx_hdq1w_hwmod, + .clk = "hdq_ick", + .addr = omap2_hdq1w_addr_space, + .user = OCP_USER_MPU | OCP_USER_SDMA, + .flags = OMAP_FIREWALL_L4 | OCPIF_SWSUP_IDLE, +}; + +/* l4_wkup -> 32ksync_counter */ +static struct omap_hwmod_addr_space omap3xxx_counter_32k_addrs[] = { + { + .pa_start = 0x48320000, + .pa_end = 0x4832001f, + .flags = ADDR_TYPE_RT + }, + { } +}; + +static struct omap_hwmod_ocp_if omap3xxx_l4_wkup__counter_32k = { + .master = &omap3xxx_l4_wkup_hwmod, + .slave = &omap3xxx_counter_32k_hwmod, + .clk = "omap_32ksync_ick", + .addr = omap3xxx_counter_32k_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = { &omap3xxx_l3_main__l4_core, &omap3xxx_l3_main__l4_per, @@ -3103,6 +3182,7 @@ static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = { &omap34xx_l4_core__mcspi2, &omap34xx_l4_core__mcspi3, &omap34xx_l4_core__mcspi4, + &omap3xxx_l4_wkup__counter_32k, NULL, }; @@ -3151,6 +3231,7 @@ static struct omap_hwmod_ocp_if *omap34xx_hwmod_ocp_ifs[] __initdata = { &omap34xx_l4_core__sr1, &omap34xx_l4_core__sr2, &omap3xxx_l4_core__mailbox, + &omap3xxx_l4_core__hdq1w, NULL }; @@ -3170,6 +3251,7 @@ static struct omap_hwmod_ocp_if *omap36xx_hwmod_ocp_ifs[] __initdata = { &omap3xxx_l4_core__usb_tll_hs, &omap3xxx_l4_core__es3plus_mmc1, &omap3xxx_l4_core__es3plus_mmc2, + &omap3xxx_l4_core__hdq1w, NULL }; diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 0d91dec5b4bc..950454a3fa31 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -51,6 +51,27 @@ */ /* + * 'c2c_target_fw' class + * instance(s): c2c_target_fw + */ +static struct omap_hwmod_class omap44xx_c2c_target_fw_hwmod_class = { + .name = "c2c_target_fw", +}; + +/* c2c_target_fw */ +static struct omap_hwmod omap44xx_c2c_target_fw_hwmod = { + .name = "c2c_target_fw", + .class = &omap44xx_c2c_target_fw_hwmod_class, + .clkdm_name = "d2d_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_D2D_SAD2D_FW_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_D2D_SAD2D_FW_CONTEXT_OFFSET, + }, + }, +}; + +/* * 'dmm' class * instance(s): dmm */ @@ -242,6 +263,28 @@ static struct omap_hwmod omap44xx_mpu_private_hwmod = { }; /* + * 'ocp_wp_noc' class + * instance(s): ocp_wp_noc + */ +static struct omap_hwmod_class omap44xx_ocp_wp_noc_hwmod_class = { + .name = "ocp_wp_noc", +}; + +/* ocp_wp_noc */ +static struct omap_hwmod omap44xx_ocp_wp_noc_hwmod = { + .name = "ocp_wp_noc", + .class = &omap44xx_ocp_wp_noc_hwmod_class, + .clkdm_name = "l3_instr_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3INSTR_OCP_WP1_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3INSTR_OCP_WP1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* * Modules omap_hwmod structures * * The following IPs are excluded for the moment because: @@ -249,41 +292,7 @@ static struct omap_hwmod omap44xx_mpu_private_hwmod = { * - They still need to be validated with the driver * properly adapted to omap_hwmod / omap_device * - * c2c - * c2c_target_fw - * cm_core - * cm_core_aon - * ctrl_module_core - * ctrl_module_pad_core - * ctrl_module_pad_wkup - * ctrl_module_wkup - * debugss - * efuse_ctrl_cust - * efuse_ctrl_std - * elm - * emif1 - * emif2 - * fdif - * gpmc - * gpu - * hdq1w - * mcasp - * mpu_c0 - * mpu_c1 - * ocmc_ram - * ocp2scp_usb_phy - * ocp_wp_noc - * prcm_mpu - * prm - * scrm - * sl2if - * slimbus1 - * slimbus2 - * usb_host_fs - * usb_host_hs - * usb_phy_cm - * usb_tll_hs - * usim + * usim */ /* @@ -341,6 +350,41 @@ static struct omap_hwmod omap44xx_aess_hwmod = { }; /* + * 'c2c' class + * chip 2 chip interface used to plug the ape soc (omap) with an external modem + * soc + */ + +static struct omap_hwmod_class omap44xx_c2c_hwmod_class = { + .name = "c2c", +}; + +/* c2c */ +static struct omap_hwmod_irq_info omap44xx_c2c_irqs[] = { + { .irq = 88 + OMAP44XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod_dma_info omap44xx_c2c_sdma_reqs[] = { + { .dma_req = 68 + OMAP44XX_DMA_REQ_START }, + { .dma_req = -1 } +}; + +static struct omap_hwmod omap44xx_c2c_hwmod = { + .name = "c2c", + .class = &omap44xx_c2c_hwmod_class, + .clkdm_name = "d2d_clkdm", + .mpu_irqs = omap44xx_c2c_irqs, + .sdma_reqs = omap44xx_c2c_sdma_reqs, + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_D2D_SAD2D_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_D2D_SAD2D_CONTEXT_OFFSET, + }, + }, +}; + +/* * 'counter' class * 32-bit ordinary counter, clocked by the falling edge of the 32 khz clock */ @@ -375,6 +419,83 @@ static struct omap_hwmod omap44xx_counter_32k_hwmod = { }; /* + * 'ctrl_module' class + * attila core control module + core pad control module + wkup pad control + * module + attila wkup control module + */ + +static struct omap_hwmod_class_sysconfig omap44xx_ctrl_module_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap44xx_ctrl_module_hwmod_class = { + .name = "ctrl_module", + .sysc = &omap44xx_ctrl_module_sysc, +}; + +/* ctrl_module_core */ +static struct omap_hwmod_irq_info omap44xx_ctrl_module_core_irqs[] = { + { .irq = 8 + OMAP44XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod omap44xx_ctrl_module_core_hwmod = { + .name = "ctrl_module_core", + .class = &omap44xx_ctrl_module_hwmod_class, + .clkdm_name = "l4_cfg_clkdm", + .mpu_irqs = omap44xx_ctrl_module_core_irqs, +}; + +/* ctrl_module_pad_core */ +static struct omap_hwmod omap44xx_ctrl_module_pad_core_hwmod = { + .name = "ctrl_module_pad_core", + .class = &omap44xx_ctrl_module_hwmod_class, + .clkdm_name = "l4_cfg_clkdm", +}; + +/* ctrl_module_wkup */ +static struct omap_hwmod omap44xx_ctrl_module_wkup_hwmod = { + .name = "ctrl_module_wkup", + .class = &omap44xx_ctrl_module_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", +}; + +/* ctrl_module_pad_wkup */ +static struct omap_hwmod omap44xx_ctrl_module_pad_wkup_hwmod = { + .name = "ctrl_module_pad_wkup", + .class = &omap44xx_ctrl_module_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", +}; + +/* + * 'debugss' class + * debug and emulation sub system + */ + +static struct omap_hwmod_class omap44xx_debugss_hwmod_class = { + .name = "debugss", +}; + +/* debugss */ +static struct omap_hwmod omap44xx_debugss_hwmod = { + .name = "debugss", + .class = &omap44xx_debugss_hwmod_class, + .clkdm_name = "emu_sys_clkdm", + .main_clk = "trace_clk_div_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_EMU_DEBUGSS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_EMU_DEBUGSS_CONTEXT_OFFSET, + }, + }, +}; + +/* * 'dma' class * dma controller for data exchange between memory to memory (i.e. internal or * external memory) and gp peripherals to memory or memory to gp peripherals @@ -816,6 +937,154 @@ static struct omap_hwmod omap44xx_dss_venc_hwmod = { }; /* + * 'elm' class + * bch error location module + */ + +static struct omap_hwmod_class_sysconfig omap44xx_elm_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_elm_hwmod_class = { + .name = "elm", + .sysc = &omap44xx_elm_sysc, +}; + +/* elm */ +static struct omap_hwmod_irq_info omap44xx_elm_irqs[] = { + { .irq = 4 + OMAP44XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod omap44xx_elm_hwmod = { + .name = "elm", + .class = &omap44xx_elm_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .mpu_irqs = omap44xx_elm_irqs, + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_ELM_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_ELM_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'emif' class + * external memory interface no1 + */ + +static struct omap_hwmod_class_sysconfig omap44xx_emif_sysc = { + .rev_offs = 0x0000, +}; + +static struct omap_hwmod_class omap44xx_emif_hwmod_class = { + .name = "emif", + .sysc = &omap44xx_emif_sysc, +}; + +/* emif1 */ +static struct omap_hwmod_irq_info omap44xx_emif1_irqs[] = { + { .irq = 110 + OMAP44XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod omap44xx_emif1_hwmod = { + .name = "emif1", + .class = &omap44xx_emif_hwmod_class, + .clkdm_name = "l3_emif_clkdm", + .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .mpu_irqs = omap44xx_emif1_irqs, + .main_clk = "ddrphy_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_MEMIF_EMIF_1_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_MEMIF_EMIF_1_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* emif2 */ +static struct omap_hwmod_irq_info omap44xx_emif2_irqs[] = { + { .irq = 111 + OMAP44XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod omap44xx_emif2_hwmod = { + .name = "emif2", + .class = &omap44xx_emif_hwmod_class, + .clkdm_name = "l3_emif_clkdm", + .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .mpu_irqs = omap44xx_emif2_irqs, + .main_clk = "ddrphy_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_MEMIF_EMIF_2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_MEMIF_EMIF_2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'fdif' class + * face detection hw accelerator module + */ + +static struct omap_hwmod_class_sysconfig omap44xx_fdif_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + /* + * FDIF needs 100 OCP clk cycles delay after a softreset before + * accessing sysconfig again. + * The lowest frequency at the moment for L3 bus is 100 MHz, so + * 1usec delay is needed. Add an x2 margin to be safe (2 usecs). + * + * TODO: Indicate errata when available. + */ + .srst_udelay = 2, + .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS | + SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap44xx_fdif_hwmod_class = { + .name = "fdif", + .sysc = &omap44xx_fdif_sysc, +}; + +/* fdif */ +static struct omap_hwmod_irq_info omap44xx_fdif_irqs[] = { + { .irq = 69 + OMAP44XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod omap44xx_fdif_hwmod = { + .name = "fdif", + .class = &omap44xx_fdif_hwmod_class, + .clkdm_name = "iss_clkdm", + .mpu_irqs = omap44xx_fdif_irqs, + .main_clk = "fdif_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_CAM_FDIF_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_CAM_FDIF_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* * 'gpio' class * general purpose io module */ @@ -1018,6 +1287,135 @@ static struct omap_hwmod omap44xx_gpio6_hwmod = { }; /* + * 'gpmc' class + * general purpose memory controller + */ + +static struct omap_hwmod_class_sysconfig omap44xx_gpmc_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .syss_offs = 0x0014, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_gpmc_hwmod_class = { + .name = "gpmc", + .sysc = &omap44xx_gpmc_sysc, +}; + +/* gpmc */ +static struct omap_hwmod_irq_info omap44xx_gpmc_irqs[] = { + { .irq = 20 + OMAP44XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod_dma_info omap44xx_gpmc_sdma_reqs[] = { + { .dma_req = 3 + OMAP44XX_DMA_REQ_START }, + { .dma_req = -1 } +}; + +static struct omap_hwmod omap44xx_gpmc_hwmod = { + .name = "gpmc", + .class = &omap44xx_gpmc_hwmod_class, + .clkdm_name = "l3_2_clkdm", + .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET, + .mpu_irqs = omap44xx_gpmc_irqs, + .sdma_reqs = omap44xx_gpmc_sdma_reqs, + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3_2_GPMC_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3_2_GPMC_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'gpu' class + * 2d/3d graphics accelerator + */ + +static struct omap_hwmod_class_sysconfig omap44xx_gpu_sysc = { + .rev_offs = 0x1fc00, + .sysc_offs = 0x1fc10, + .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO | + MSTANDBY_SMART | MSTANDBY_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap44xx_gpu_hwmod_class = { + .name = "gpu", + .sysc = &omap44xx_gpu_sysc, +}; + +/* gpu */ +static struct omap_hwmod_irq_info omap44xx_gpu_irqs[] = { + { .irq = 21 + OMAP44XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod omap44xx_gpu_hwmod = { + .name = "gpu", + .class = &omap44xx_gpu_hwmod_class, + .clkdm_name = "l3_gfx_clkdm", + .mpu_irqs = omap44xx_gpu_irqs, + .main_clk = "gpu_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_GFX_GFX_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_GFX_GFX_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* + * 'hdq1w' class + * hdq / 1-wire serial interface controller + */ + +static struct omap_hwmod_class_sysconfig omap44xx_hdq1w_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0014, + .syss_offs = 0x0018, + .sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SOFTRESET | + SYSS_HAS_RESET_STATUS), + .sysc_fields = &omap_hwmod_sysc_type1, +}; + +static struct omap_hwmod_class omap44xx_hdq1w_hwmod_class = { + .name = "hdq1w", + .sysc = &omap44xx_hdq1w_sysc, +}; + +/* hdq1w */ +static struct omap_hwmod_irq_info omap44xx_hdq1w_irqs[] = { + { .irq = 58 + OMAP44XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod omap44xx_hdq1w_hwmod = { + .name = "hdq1w", + .class = &omap44xx_hdq1w_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .flags = HWMOD_INIT_NO_RESET, /* XXX temporary */ + .mpu_irqs = omap44xx_hdq1w_irqs, + .main_clk = "hdq1w_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_HDQ1W_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_HDQ1W_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* * 'hsi' class * mipi high-speed synchronous serial interface (multichannel and full-duplex * serial if) @@ -1089,7 +1487,8 @@ static struct omap_hwmod_class omap44xx_i2c_hwmod_class = { }; static struct omap_i2c_dev_attr i2c_dev_attr = { - .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE, + .flags = OMAP_I2C_FLAG_BUS_SHIFT_NONE | + OMAP_I2C_FLAG_RESET_REGS_POSTIDLE, }; /* i2c1 */ @@ -1441,6 +1840,58 @@ static struct omap_hwmod omap44xx_mailbox_hwmod = { }; /* + * 'mcasp' class + * multi-channel audio serial port controller + */ + +/* The IP is not compliant to type1 / type2 scheme */ +static struct omap_hwmod_sysc_fields omap_hwmod_sysc_type_mcasp = { + .sidle_shift = 0, +}; + +static struct omap_hwmod_class_sysconfig omap44xx_mcasp_sysc = { + .sysc_offs = 0x0004, + .sysc_flags = SYSC_HAS_SIDLEMODE, + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type_mcasp, +}; + +static struct omap_hwmod_class omap44xx_mcasp_hwmod_class = { + .name = "mcasp", + .sysc = &omap44xx_mcasp_sysc, +}; + +/* mcasp */ +static struct omap_hwmod_irq_info omap44xx_mcasp_irqs[] = { + { .name = "arevt", .irq = 108 + OMAP44XX_IRQ_GIC_START }, + { .name = "axevt", .irq = 109 + OMAP44XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod_dma_info omap44xx_mcasp_sdma_reqs[] = { + { .name = "axevt", .dma_req = 7 + OMAP44XX_DMA_REQ_START }, + { .name = "arevt", .dma_req = 10 + OMAP44XX_DMA_REQ_START }, + { .dma_req = -1 } +}; + +static struct omap_hwmod omap44xx_mcasp_hwmod = { + .name = "mcasp", + .class = &omap44xx_mcasp_hwmod_class, + .clkdm_name = "abe_clkdm", + .mpu_irqs = omap44xx_mcasp_irqs, + .sdma_reqs = omap44xx_mcasp_sdma_reqs, + .main_clk = "mcasp_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM1_ABE_MCASP_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_MCASP_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* * 'mcbsp' class * multi channel buffered serial port controller */ @@ -1461,7 +1912,7 @@ static struct omap_hwmod_class omap44xx_mcbsp_hwmod_class = { /* mcbsp1 */ static struct omap_hwmod_irq_info omap44xx_mcbsp1_irqs[] = { - { .irq = 17 + OMAP44XX_IRQ_GIC_START }, + { .name = "common", .irq = 17 + OMAP44XX_IRQ_GIC_START }, { .irq = -1 } }; @@ -1496,7 +1947,7 @@ static struct omap_hwmod omap44xx_mcbsp1_hwmod = { /* mcbsp2 */ static struct omap_hwmod_irq_info omap44xx_mcbsp2_irqs[] = { - { .irq = 22 + OMAP44XX_IRQ_GIC_START }, + { .name = "common", .irq = 22 + OMAP44XX_IRQ_GIC_START }, { .irq = -1 } }; @@ -1531,7 +1982,7 @@ static struct omap_hwmod omap44xx_mcbsp2_hwmod = { /* mcbsp3 */ static struct omap_hwmod_irq_info omap44xx_mcbsp3_irqs[] = { - { .irq = 23 + OMAP44XX_IRQ_GIC_START }, + { .name = "common", .irq = 23 + OMAP44XX_IRQ_GIC_START }, { .irq = -1 } }; @@ -1566,7 +2017,7 @@ static struct omap_hwmod omap44xx_mcbsp3_hwmod = { /* mcbsp4 */ static struct omap_hwmod_irq_info omap44xx_mcbsp4_irqs[] = { - { .irq = 16 + OMAP44XX_IRQ_GIC_START }, + { .name = "common", .irq = 16 + OMAP44XX_IRQ_GIC_START }, { .irq = -1 } }; @@ -2017,6 +2468,252 @@ static struct omap_hwmod omap44xx_mpu_hwmod = { }; /* + * 'ocmc_ram' class + * top-level core on-chip ram + */ + +static struct omap_hwmod_class omap44xx_ocmc_ram_hwmod_class = { + .name = "ocmc_ram", +}; + +/* ocmc_ram */ +static struct omap_hwmod omap44xx_ocmc_ram_hwmod = { + .name = "ocmc_ram", + .class = &omap44xx_ocmc_ram_hwmod_class, + .clkdm_name = "l3_2_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3_2_OCMC_RAM_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3_2_OCMC_RAM_CONTEXT_OFFSET, + }, + }, +}; + +/* + * 'ocp2scp' class + * bridge to transform ocp interface protocol to scp (serial control port) + * protocol + */ + +static struct omap_hwmod_class omap44xx_ocp2scp_hwmod_class = { + .name = "ocp2scp", +}; + +/* ocp2scp_usb_phy */ +static struct omap_hwmod_opt_clk ocp2scp_usb_phy_opt_clks[] = { + { .role = "phy_48m", .clk = "ocp2scp_usb_phy_phy_48m" }, +}; + +static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = { + .name = "ocp2scp_usb_phy", + .class = &omap44xx_ocp2scp_hwmod_class, + .clkdm_name = "l3_init_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3INIT_USBPHYOCP2SCP_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, + .opt_clks = ocp2scp_usb_phy_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(ocp2scp_usb_phy_opt_clks), +}; + +/* + * 'prcm' class + * power and reset manager (part of the prcm infrastructure) + clock manager 2 + * + clock manager 1 (in always on power domain) + local prm in mpu + */ + +static struct omap_hwmod_class omap44xx_prcm_hwmod_class = { + .name = "prcm", +}; + +/* prcm_mpu */ +static struct omap_hwmod omap44xx_prcm_mpu_hwmod = { + .name = "prcm_mpu", + .class = &omap44xx_prcm_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", +}; + +/* cm_core_aon */ +static struct omap_hwmod omap44xx_cm_core_aon_hwmod = { + .name = "cm_core_aon", + .class = &omap44xx_prcm_hwmod_class, + .clkdm_name = "cm_clkdm", +}; + +/* cm_core */ +static struct omap_hwmod omap44xx_cm_core_hwmod = { + .name = "cm_core", + .class = &omap44xx_prcm_hwmod_class, + .clkdm_name = "cm_clkdm", +}; + +/* prm */ +static struct omap_hwmod_irq_info omap44xx_prm_irqs[] = { + { .irq = 11 + OMAP44XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod_rst_info omap44xx_prm_resets[] = { + { .name = "rst_global_warm_sw", .rst_shift = 0 }, + { .name = "rst_global_cold_sw", .rst_shift = 1 }, +}; + +static struct omap_hwmod omap44xx_prm_hwmod = { + .name = "prm", + .class = &omap44xx_prcm_hwmod_class, + .clkdm_name = "prm_clkdm", + .mpu_irqs = omap44xx_prm_irqs, + .rst_lines = omap44xx_prm_resets, + .rst_lines_cnt = ARRAY_SIZE(omap44xx_prm_resets), +}; + +/* + * 'scrm' class + * system clock and reset manager + */ + +static struct omap_hwmod_class omap44xx_scrm_hwmod_class = { + .name = "scrm", +}; + +/* scrm */ +static struct omap_hwmod omap44xx_scrm_hwmod = { + .name = "scrm", + .class = &omap44xx_scrm_hwmod_class, + .clkdm_name = "l4_wkup_clkdm", +}; + +/* + * 'sl2if' class + * shared level 2 memory interface + */ + +static struct omap_hwmod_class omap44xx_sl2if_hwmod_class = { + .name = "sl2if", +}; + +/* sl2if */ +static struct omap_hwmod omap44xx_sl2if_hwmod = { + .name = "sl2if", + .class = &omap44xx_sl2if_hwmod_class, + .clkdm_name = "ivahd_clkdm", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_IVAHD_SL2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_IVAHD_SL2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_HWCTRL, + }, + }, +}; + +/* + * 'slimbus' class + * bidirectional, multi-drop, multi-channel two-line serial interface between + * the device and external components + */ + +static struct omap_hwmod_class_sysconfig omap44xx_slimbus_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0010, + .sysc_flags = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type2, +}; + +static struct omap_hwmod_class omap44xx_slimbus_hwmod_class = { + .name = "slimbus", + .sysc = &omap44xx_slimbus_sysc, +}; + +/* slimbus1 */ +static struct omap_hwmod_irq_info omap44xx_slimbus1_irqs[] = { + { .irq = 97 + OMAP44XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod_dma_info omap44xx_slimbus1_sdma_reqs[] = { + { .name = "tx0", .dma_req = 84 + OMAP44XX_DMA_REQ_START }, + { .name = "tx1", .dma_req = 85 + OMAP44XX_DMA_REQ_START }, + { .name = "tx2", .dma_req = 86 + OMAP44XX_DMA_REQ_START }, + { .name = "tx3", .dma_req = 87 + OMAP44XX_DMA_REQ_START }, + { .name = "rx0", .dma_req = 88 + OMAP44XX_DMA_REQ_START }, + { .name = "rx1", .dma_req = 89 + OMAP44XX_DMA_REQ_START }, + { .name = "rx2", .dma_req = 90 + OMAP44XX_DMA_REQ_START }, + { .name = "rx3", .dma_req = 91 + OMAP44XX_DMA_REQ_START }, + { .dma_req = -1 } +}; + +static struct omap_hwmod_opt_clk slimbus1_opt_clks[] = { + { .role = "fclk_1", .clk = "slimbus1_fclk_1" }, + { .role = "fclk_0", .clk = "slimbus1_fclk_0" }, + { .role = "fclk_2", .clk = "slimbus1_fclk_2" }, + { .role = "slimbus_clk", .clk = "slimbus1_slimbus_clk" }, +}; + +static struct omap_hwmod omap44xx_slimbus1_hwmod = { + .name = "slimbus1", + .class = &omap44xx_slimbus_hwmod_class, + .clkdm_name = "abe_clkdm", + .mpu_irqs = omap44xx_slimbus1_irqs, + .sdma_reqs = omap44xx_slimbus1_sdma_reqs, + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM1_ABE_SLIMBUS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_ABE_SLIMBUS_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = slimbus1_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(slimbus1_opt_clks), +}; + +/* slimbus2 */ +static struct omap_hwmod_irq_info omap44xx_slimbus2_irqs[] = { + { .irq = 98 + OMAP44XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod_dma_info omap44xx_slimbus2_sdma_reqs[] = { + { .name = "tx0", .dma_req = 92 + OMAP44XX_DMA_REQ_START }, + { .name = "tx1", .dma_req = 93 + OMAP44XX_DMA_REQ_START }, + { .name = "tx2", .dma_req = 94 + OMAP44XX_DMA_REQ_START }, + { .name = "tx3", .dma_req = 95 + OMAP44XX_DMA_REQ_START }, + { .name = "rx0", .dma_req = 96 + OMAP44XX_DMA_REQ_START }, + { .name = "rx1", .dma_req = 97 + OMAP44XX_DMA_REQ_START }, + { .name = "rx2", .dma_req = 98 + OMAP44XX_DMA_REQ_START }, + { .name = "rx3", .dma_req = 99 + OMAP44XX_DMA_REQ_START }, + { .dma_req = -1 } +}; + +static struct omap_hwmod_opt_clk slimbus2_opt_clks[] = { + { .role = "fclk_1", .clk = "slimbus2_fclk_1" }, + { .role = "fclk_0", .clk = "slimbus2_fclk_0" }, + { .role = "slimbus_clk", .clk = "slimbus2_slimbus_clk" }, +}; + +static struct omap_hwmod omap44xx_slimbus2_hwmod = { + .name = "slimbus2", + .class = &omap44xx_slimbus_hwmod_class, + .clkdm_name = "l4_per_clkdm", + .mpu_irqs = omap44xx_slimbus2_irqs, + .sdma_reqs = omap44xx_slimbus2_sdma_reqs, + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4PER_SLIMBUS2_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4PER_SLIMBUS2_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, + .opt_clks = slimbus2_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(slimbus2_opt_clks), +}; + +/* * 'smartreflex' class * smartreflex module (monitor silicon performance and outputs a measure of * performance error) @@ -2584,6 +3281,55 @@ static struct omap_hwmod omap44xx_uart4_hwmod = { }; /* + * 'usb_host_fs' class + * full-speed usb host controller + */ + +/* The IP is not compliant to type1 / type2 scheme */ +static struct omap_hwmod_sysc_fields omap_hwmod_sysc_type_usb_host_fs = { + .midle_shift = 4, + .sidle_shift = 2, + .srst_shift = 1, +}; + +static struct omap_hwmod_class_sysconfig omap44xx_usb_host_fs_sysc = { + .rev_offs = 0x0000, + .sysc_offs = 0x0210, + .sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE | + SYSC_HAS_SOFTRESET), + .idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART | + SIDLE_SMART_WKUP), + .sysc_fields = &omap_hwmod_sysc_type_usb_host_fs, +}; + +static struct omap_hwmod_class omap44xx_usb_host_fs_hwmod_class = { + .name = "usb_host_fs", + .sysc = &omap44xx_usb_host_fs_sysc, +}; + +/* usb_host_fs */ +static struct omap_hwmod_irq_info omap44xx_usb_host_fs_irqs[] = { + { .name = "std", .irq = 89 + OMAP44XX_IRQ_GIC_START }, + { .name = "smi", .irq = 90 + OMAP44XX_IRQ_GIC_START }, + { .irq = -1 } +}; + +static struct omap_hwmod omap44xx_usb_host_fs_hwmod = { + .name = "usb_host_fs", + .class = &omap44xx_usb_host_fs_hwmod_class, + .clkdm_name = "l3_init_clkdm", + .mpu_irqs = omap44xx_usb_host_fs_irqs, + .main_clk = "usb_host_fs_fck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L3INIT_USB_HOST_FS_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L3INIT_USB_HOST_FS_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* * 'usb_host_hs' class * high-speed multi-port usb host controller */ @@ -2789,6 +3535,7 @@ static struct omap_hwmod_class omap44xx_wd_timer_hwmod_class = { .name = "wd_timer", .sysc = &omap44xx_wd_timer_sysc, .pre_shutdown = &omap2_wd_timer_disable, + .reset = &omap2_wd_timer_reset, }; /* wd_timer2 */ @@ -2838,6 +3585,32 @@ static struct omap_hwmod omap44xx_wd_timer3_hwmod = { * interfaces */ +static struct omap_hwmod_addr_space omap44xx_c2c_target_fw_addrs[] = { + { + .pa_start = 0x4a204000, + .pa_end = 0x4a2040ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* c2c -> c2c_target_fw */ +static struct omap_hwmod_ocp_if omap44xx_c2c__c2c_target_fw = { + .master = &omap44xx_c2c_hwmod, + .slave = &omap44xx_c2c_target_fw_hwmod, + .clk = "div_core_ck", + .addr = omap44xx_c2c_target_fw_addrs, + .user = OCP_USER_MPU, +}; + +/* l4_cfg -> c2c_target_fw */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__c2c_target_fw = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_c2c_target_fw_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* l3_main_1 -> dmm */ static struct omap_hwmod_ocp_if omap44xx_l3_main_1__dmm = { .master = &omap44xx_l3_main_1_hwmod, @@ -2864,6 +3637,14 @@ static struct omap_hwmod_ocp_if omap44xx_mpu__dmm = { .user = OCP_USER_MPU, }; +/* c2c -> emif_fw */ +static struct omap_hwmod_ocp_if omap44xx_c2c__emif_fw = { + .master = &omap44xx_c2c_hwmod, + .slave = &omap44xx_emif_fw_hwmod, + .clk = "div_core_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* dmm -> emif_fw */ static struct omap_hwmod_ocp_if omap44xx_dmm__emif_fw = { .master = &omap44xx_dmm_hwmod, @@ -2906,6 +3687,14 @@ static struct omap_hwmod_ocp_if omap44xx_l3_main_3__l3_instr = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* ocp_wp_noc -> l3_instr */ +static struct omap_hwmod_ocp_if omap44xx_ocp_wp_noc__l3_instr = { + .master = &omap44xx_ocp_wp_noc_hwmod, + .slave = &omap44xx_l3_instr_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* dsp -> l3_main_1 */ static struct omap_hwmod_ocp_if omap44xx_dsp__l3_main_1 = { .master = &omap44xx_dsp_hwmod, @@ -2972,6 +3761,22 @@ static struct omap_hwmod_ocp_if omap44xx_mpu__l3_main_1 = { .user = OCP_USER_MPU, }; +/* c2c_target_fw -> l3_main_2 */ +static struct omap_hwmod_ocp_if omap44xx_c2c_target_fw__l3_main_2 = { + .master = &omap44xx_c2c_target_fw_hwmod, + .slave = &omap44xx_l3_main_2_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* debugss -> l3_main_2 */ +static struct omap_hwmod_ocp_if omap44xx_debugss__l3_main_2 = { + .master = &omap44xx_debugss_hwmod, + .slave = &omap44xx_l3_main_2_hwmod, + .clk = "dbgclk_mux_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* dma_system -> l3_main_2 */ static struct omap_hwmod_ocp_if omap44xx_dma_system__l3_main_2 = { .master = &omap44xx_dma_system_hwmod, @@ -2980,6 +3785,22 @@ static struct omap_hwmod_ocp_if omap44xx_dma_system__l3_main_2 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* fdif -> l3_main_2 */ +static struct omap_hwmod_ocp_if omap44xx_fdif__l3_main_2 = { + .master = &omap44xx_fdif_hwmod, + .slave = &omap44xx_l3_main_2_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* gpu -> l3_main_2 */ +static struct omap_hwmod_ocp_if omap44xx_gpu__l3_main_2 = { + .master = &omap44xx_gpu_hwmod, + .slave = &omap44xx_l3_main_2_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* hsi -> l3_main_2 */ static struct omap_hwmod_ocp_if omap44xx_hsi__l3_main_2 = { .master = &omap44xx_hsi_hwmod, @@ -3038,6 +3859,14 @@ static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_2 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* usb_host_fs -> l3_main_2 */ +static struct omap_hwmod_ocp_if omap44xx_usb_host_fs__l3_main_2 = { + .master = &omap44xx_usb_host_fs_hwmod, + .slave = &omap44xx_l3_main_2_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* usb_host_hs -> l3_main_2 */ static struct omap_hwmod_ocp_if omap44xx_usb_host_hs__l3_main_2 = { .master = &omap44xx_usb_host_hs_hwmod, @@ -3152,6 +3981,24 @@ static struct omap_hwmod_ocp_if omap44xx_mpu__mpu_private = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +static struct omap_hwmod_addr_space omap44xx_ocp_wp_noc_addrs[] = { + { + .pa_start = 0x4a102000, + .pa_end = 0x4a10207f, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> ocp_wp_noc */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ocp_wp_noc = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_ocp_wp_noc_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_ocp_wp_noc_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + static struct omap_hwmod_addr_space omap44xx_aess_addrs[] = { { .pa_start = 0x401f1000, @@ -3188,6 +4035,14 @@ static struct omap_hwmod_ocp_if omap44xx_l4_abe__aess_dma = { .user = OCP_USER_SDMA, }; +/* l3_main_2 -> c2c */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__c2c = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_c2c_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + static struct omap_hwmod_addr_space omap44xx_counter_32k_addrs[] = { { .pa_start = 0x4a304000, @@ -3206,6 +4061,96 @@ static struct omap_hwmod_ocp_if omap44xx_l4_wkup__counter_32k = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +static struct omap_hwmod_addr_space omap44xx_ctrl_module_core_addrs[] = { + { + .pa_start = 0x4a002000, + .pa_end = 0x4a0027ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> ctrl_module_core */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ctrl_module_core = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_ctrl_module_core_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_ctrl_module_core_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_ctrl_module_pad_core_addrs[] = { + { + .pa_start = 0x4a100000, + .pa_end = 0x4a1007ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> ctrl_module_pad_core */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ctrl_module_pad_core = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_ctrl_module_pad_core_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_ctrl_module_pad_core_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_ctrl_module_wkup_addrs[] = { + { + .pa_start = 0x4a30c000, + .pa_end = 0x4a30c7ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_wkup -> ctrl_module_wkup */ +static struct omap_hwmod_ocp_if omap44xx_l4_wkup__ctrl_module_wkup = { + .master = &omap44xx_l4_wkup_hwmod, + .slave = &omap44xx_ctrl_module_wkup_hwmod, + .clk = "l4_wkup_clk_mux_ck", + .addr = omap44xx_ctrl_module_wkup_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_ctrl_module_pad_wkup_addrs[] = { + { + .pa_start = 0x4a31e000, + .pa_end = 0x4a31e7ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_wkup -> ctrl_module_pad_wkup */ +static struct omap_hwmod_ocp_if omap44xx_l4_wkup__ctrl_module_pad_wkup = { + .master = &omap44xx_l4_wkup_hwmod, + .slave = &omap44xx_ctrl_module_pad_wkup_hwmod, + .clk = "l4_wkup_clk_mux_ck", + .addr = omap44xx_ctrl_module_pad_wkup_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_debugss_addrs[] = { + { + .pa_start = 0x54160000, + .pa_end = 0x54167fff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l3_instr -> debugss */ +static struct omap_hwmod_ocp_if omap44xx_l3_instr__debugss = { + .master = &omap44xx_l3_instr_hwmod, + .slave = &omap44xx_debugss_hwmod, + .clk = "l3_div_ck", + .addr = omap44xx_debugss_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + static struct omap_hwmod_addr_space omap44xx_dma_system_addrs[] = { { .pa_start = 0x4a056000, @@ -3270,6 +4215,14 @@ static struct omap_hwmod_ocp_if omap44xx_dsp__iva = { .user = OCP_USER_DSP, }; +/* dsp -> sl2if */ +static struct omap_hwmod_ocp_if omap44xx_dsp__sl2if = { + .master = &omap44xx_dsp_hwmod, + .slave = &omap44xx_sl2if_hwmod, + .clk = "dpll_iva_m5x2_ck", + .user = OCP_USER_DSP, +}; + /* l4_cfg -> dsp */ static struct omap_hwmod_ocp_if omap44xx_l4_cfg__dsp = { .master = &omap44xx_l4_cfg_hwmod, @@ -3530,6 +4483,78 @@ static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_venc = { .user = OCP_USER_MPU, }; +static struct omap_hwmod_addr_space omap44xx_elm_addrs[] = { + { + .pa_start = 0x48078000, + .pa_end = 0x48078fff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> elm */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__elm = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_elm_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_elm_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_emif1_addrs[] = { + { + .pa_start = 0x4c000000, + .pa_end = 0x4c0000ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* emif_fw -> emif1 */ +static struct omap_hwmod_ocp_if omap44xx_emif_fw__emif1 = { + .master = &omap44xx_emif_fw_hwmod, + .slave = &omap44xx_emif1_hwmod, + .clk = "l3_div_ck", + .addr = omap44xx_emif1_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_emif2_addrs[] = { + { + .pa_start = 0x4d000000, + .pa_end = 0x4d0000ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* emif_fw -> emif2 */ +static struct omap_hwmod_ocp_if omap44xx_emif_fw__emif2 = { + .master = &omap44xx_emif_fw_hwmod, + .slave = &omap44xx_emif2_hwmod, + .clk = "l3_div_ck", + .addr = omap44xx_emif2_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_fdif_addrs[] = { + { + .pa_start = 0x4a10a000, + .pa_end = 0x4a10a1ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> fdif */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__fdif = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_fdif_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_fdif_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + static struct omap_hwmod_addr_space omap44xx_gpio1_addrs[] = { { .pa_start = 0x4a310000, @@ -3638,6 +4663,60 @@ static struct omap_hwmod_ocp_if omap44xx_l4_per__gpio6 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +static struct omap_hwmod_addr_space omap44xx_gpmc_addrs[] = { + { + .pa_start = 0x50000000, + .pa_end = 0x500003ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l3_main_2 -> gpmc */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__gpmc = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_gpmc_hwmod, + .clk = "l3_div_ck", + .addr = omap44xx_gpmc_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_gpu_addrs[] = { + { + .pa_start = 0x56000000, + .pa_end = 0x5600ffff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l3_main_2 -> gpu */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__gpu = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_gpu_hwmod, + .clk = "l3_div_ck", + .addr = omap44xx_gpu_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_hdq1w_addrs[] = { + { + .pa_start = 0x480b2000, + .pa_end = 0x480b201f, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> hdq1w */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__hdq1w = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_hdq1w_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_hdq1w_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + static struct omap_hwmod_addr_space omap44xx_hsi_addrs[] = { { .pa_start = 0x4a058000, @@ -3754,6 +4833,14 @@ static struct omap_hwmod_ocp_if omap44xx_l3_main_2__iss = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* iva -> sl2if */ +static struct omap_hwmod_ocp_if omap44xx_iva__sl2if = { + .master = &omap44xx_iva_hwmod, + .slave = &omap44xx_sl2if_hwmod, + .clk = "dpll_iva_m5x2_ck", + .user = OCP_USER_IVA, +}; + static struct omap_hwmod_addr_space omap44xx_iva_addrs[] = { { .pa_start = 0x5a000000, @@ -3808,6 +4895,42 @@ static struct omap_hwmod_ocp_if omap44xx_l4_cfg__mailbox = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +static struct omap_hwmod_addr_space omap44xx_mcasp_addrs[] = { + { + .pa_start = 0x40128000, + .pa_end = 0x401283ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_abe -> mcasp */ +static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcasp = { + .master = &omap44xx_l4_abe_hwmod, + .slave = &omap44xx_mcasp_hwmod, + .clk = "ocp_abe_iclk", + .addr = omap44xx_mcasp_addrs, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap44xx_mcasp_dma_addrs[] = { + { + .pa_start = 0x49028000, + .pa_end = 0x490283ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_abe -> mcasp (dma) */ +static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcasp_dma = { + .master = &omap44xx_l4_abe_hwmod, + .slave = &omap44xx_mcasp_hwmod, + .clk = "ocp_abe_iclk", + .addr = omap44xx_mcasp_dma_addrs, + .user = OCP_USER_SDMA, +}; + static struct omap_hwmod_addr_space omap44xx_mcbsp1_addrs[] = { { .name = "mpu", @@ -4138,6 +5261,174 @@ static struct omap_hwmod_ocp_if omap44xx_l4_per__mmc5 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +/* l3_main_2 -> ocmc_ram */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__ocmc_ram = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_ocmc_ram_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l4_cfg -> ocp2scp_usb_phy */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ocp2scp_usb_phy = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_ocp2scp_usb_phy_hwmod, + .clk = "l4_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_prcm_mpu_addrs[] = { + { + .pa_start = 0x48243000, + .pa_end = 0x48243fff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* mpu_private -> prcm_mpu */ +static struct omap_hwmod_ocp_if omap44xx_mpu_private__prcm_mpu = { + .master = &omap44xx_mpu_private_hwmod, + .slave = &omap44xx_prcm_mpu_hwmod, + .clk = "l3_div_ck", + .addr = omap44xx_prcm_mpu_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_cm_core_aon_addrs[] = { + { + .pa_start = 0x4a004000, + .pa_end = 0x4a004fff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_wkup -> cm_core_aon */ +static struct omap_hwmod_ocp_if omap44xx_l4_wkup__cm_core_aon = { + .master = &omap44xx_l4_wkup_hwmod, + .slave = &omap44xx_cm_core_aon_hwmod, + .clk = "l4_wkup_clk_mux_ck", + .addr = omap44xx_cm_core_aon_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_cm_core_addrs[] = { + { + .pa_start = 0x4a008000, + .pa_end = 0x4a009fff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> cm_core */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__cm_core = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_cm_core_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_cm_core_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_prm_addrs[] = { + { + .pa_start = 0x4a306000, + .pa_end = 0x4a307fff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_wkup -> prm */ +static struct omap_hwmod_ocp_if omap44xx_l4_wkup__prm = { + .master = &omap44xx_l4_wkup_hwmod, + .slave = &omap44xx_prm_hwmod, + .clk = "l4_wkup_clk_mux_ck", + .addr = omap44xx_prm_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_scrm_addrs[] = { + { + .pa_start = 0x4a30a000, + .pa_end = 0x4a30a7ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_wkup -> scrm */ +static struct omap_hwmod_ocp_if omap44xx_l4_wkup__scrm = { + .master = &omap44xx_l4_wkup_hwmod, + .slave = &omap44xx_scrm_hwmod, + .clk = "l4_wkup_clk_mux_ck", + .addr = omap44xx_scrm_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* l3_main_2 -> sl2if */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__sl2if = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_sl2if_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_slimbus1_addrs[] = { + { + .pa_start = 0x4012c000, + .pa_end = 0x4012c3ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_abe -> slimbus1 */ +static struct omap_hwmod_ocp_if omap44xx_l4_abe__slimbus1 = { + .master = &omap44xx_l4_abe_hwmod, + .slave = &omap44xx_slimbus1_hwmod, + .clk = "ocp_abe_iclk", + .addr = omap44xx_slimbus1_addrs, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space omap44xx_slimbus1_dma_addrs[] = { + { + .pa_start = 0x4902c000, + .pa_end = 0x4902c3ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_abe -> slimbus1 (dma) */ +static struct omap_hwmod_ocp_if omap44xx_l4_abe__slimbus1_dma = { + .master = &omap44xx_l4_abe_hwmod, + .slave = &omap44xx_slimbus1_hwmod, + .clk = "ocp_abe_iclk", + .addr = omap44xx_slimbus1_dma_addrs, + .user = OCP_USER_SDMA, +}; + +static struct omap_hwmod_addr_space omap44xx_slimbus2_addrs[] = { + { + .pa_start = 0x48076000, + .pa_end = 0x480763ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_per -> slimbus2 */ +static struct omap_hwmod_ocp_if omap44xx_l4_per__slimbus2 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_slimbus2_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_slimbus2_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + static struct omap_hwmod_addr_space omap44xx_smartreflex_core_addrs[] = { { .pa_start = 0x4a0dd000, @@ -4552,6 +5843,24 @@ static struct omap_hwmod_ocp_if omap44xx_l4_per__uart4 = { .user = OCP_USER_MPU | OCP_USER_SDMA, }; +static struct omap_hwmod_addr_space omap44xx_usb_host_fs_addrs[] = { + { + .pa_start = 0x4a0a9000, + .pa_end = 0x4a0a93ff, + .flags = ADDR_TYPE_RT + }, + { } +}; + +/* l4_cfg -> usb_host_fs */ +static struct omap_hwmod_ocp_if omap44xx_l4_cfg__usb_host_fs = { + .master = &omap44xx_l4_cfg_hwmod, + .slave = &omap44xx_usb_host_fs_hwmod, + .clk = "l4_div_ck", + .addr = omap44xx_usb_host_fs_addrs, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + static struct omap_hwmod_addr_space omap44xx_usb_host_hs_addrs[] = { { .name = "uhh", @@ -4673,12 +5982,16 @@ static struct omap_hwmod_ocp_if omap44xx_l4_abe__wd_timer3_dma = { }; static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { + &omap44xx_c2c__c2c_target_fw, + &omap44xx_l4_cfg__c2c_target_fw, &omap44xx_l3_main_1__dmm, &omap44xx_mpu__dmm, + &omap44xx_c2c__emif_fw, &omap44xx_dmm__emif_fw, &omap44xx_l4_cfg__emif_fw, &omap44xx_iva__l3_instr, &omap44xx_l3_main_3__l3_instr, + &omap44xx_ocp_wp_noc__l3_instr, &omap44xx_dsp__l3_main_1, &omap44xx_dss__l3_main_1, &omap44xx_l3_main_2__l3_main_1, @@ -4686,13 +5999,18 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_mmc1__l3_main_1, &omap44xx_mmc2__l3_main_1, &omap44xx_mpu__l3_main_1, + &omap44xx_c2c_target_fw__l3_main_2, + &omap44xx_debugss__l3_main_2, &omap44xx_dma_system__l3_main_2, + &omap44xx_fdif__l3_main_2, + &omap44xx_gpu__l3_main_2, &omap44xx_hsi__l3_main_2, &omap44xx_ipu__l3_main_2, &omap44xx_iss__l3_main_2, &omap44xx_iva__l3_main_2, &omap44xx_l3_main_1__l3_main_2, &omap44xx_l4_cfg__l3_main_2, + &omap44xx_usb_host_fs__l3_main_2, &omap44xx_usb_host_hs__l3_main_2, &omap44xx_usb_otg_hs__l3_main_2, &omap44xx_l3_main_1__l3_main_3, @@ -4706,13 +6024,21 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_l3_main_2__l4_per, &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_l3_main_2__c2c, &omap44xx_l4_wkup__counter_32k, + &omap44xx_l4_cfg__ctrl_module_core, + &omap44xx_l4_cfg__ctrl_module_pad_core, + &omap44xx_l4_wkup__ctrl_module_wkup, + &omap44xx_l4_wkup__ctrl_module_pad_wkup, + &omap44xx_l3_instr__debugss, &omap44xx_l4_cfg__dma_system, &omap44xx_l4_abe__dmic, &omap44xx_l4_abe__dmic_dma, &omap44xx_dsp__iva, + &omap44xx_dsp__sl2if, &omap44xx_l4_cfg__dsp, &omap44xx_l3_main_2__dss, &omap44xx_l4_per__dss, @@ -4728,12 +6054,19 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_l4_per__dss_rfbi, &omap44xx_l3_main_2__dss_venc, &omap44xx_l4_per__dss_venc, + &omap44xx_l4_per__elm, + &omap44xx_emif_fw__emif1, + &omap44xx_emif_fw__emif2, + &omap44xx_l4_cfg__fdif, &omap44xx_l4_wkup__gpio1, &omap44xx_l4_per__gpio2, &omap44xx_l4_per__gpio3, &omap44xx_l4_per__gpio4, &omap44xx_l4_per__gpio5, &omap44xx_l4_per__gpio6, + &omap44xx_l3_main_2__gpmc, + &omap44xx_l3_main_2__gpu, + &omap44xx_l4_per__hdq1w, &omap44xx_l4_cfg__hsi, &omap44xx_l4_per__i2c1, &omap44xx_l4_per__i2c2, @@ -4741,9 +6074,12 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_l4_per__i2c4, &omap44xx_l3_main_2__ipu, &omap44xx_l3_main_2__iss, + &omap44xx_iva__sl2if, &omap44xx_l3_main_2__iva, &omap44xx_l4_wkup__kbd, &omap44xx_l4_cfg__mailbox, + &omap44xx_l4_abe__mcasp, + &omap44xx_l4_abe__mcasp_dma, &omap44xx_l4_abe__mcbsp1, &omap44xx_l4_abe__mcbsp1_dma, &omap44xx_l4_abe__mcbsp2, @@ -4762,6 +6098,17 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_l4_per__mmc3, &omap44xx_l4_per__mmc4, &omap44xx_l4_per__mmc5, + &omap44xx_l3_main_2__ocmc_ram, + &omap44xx_l4_cfg__ocp2scp_usb_phy, + &omap44xx_mpu_private__prcm_mpu, + &omap44xx_l4_wkup__cm_core_aon, + &omap44xx_l4_cfg__cm_core, + &omap44xx_l4_wkup__prm, + &omap44xx_l4_wkup__scrm, + &omap44xx_l3_main_2__sl2if, + &omap44xx_l4_abe__slimbus1, + &omap44xx_l4_abe__slimbus1_dma, + &omap44xx_l4_per__slimbus2, &omap44xx_l4_cfg__smartreflex_core, &omap44xx_l4_cfg__smartreflex_iva, &omap44xx_l4_cfg__smartreflex_mpu, @@ -4785,6 +6132,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_l4_per__uart2, &omap44xx_l4_per__uart3, &omap44xx_l4_per__uart4, + &omap44xx_l4_cfg__usb_host_fs, &omap44xx_l4_cfg__usb_host_hs, &omap44xx_l4_cfg__usb_otg_hs, &omap44xx_l4_cfg__usb_tll_hs, diff --git a/arch/arm/mach-omap2/omap_hwmod_common_data.h b/arch/arm/mach-omap2/omap_hwmod_common_data.h index 7aa9156d50ab..e7e8eeae95e5 100644 --- a/arch/arm/mach-omap2/omap_hwmod_common_data.h +++ b/arch/arm/mach-omap2/omap_hwmod_common_data.h @@ -38,6 +38,7 @@ extern struct omap_hwmod_addr_space omap2430_mcspi3_addr_space[]; extern struct omap_hwmod_addr_space omap2_dma_system_addrs[]; extern struct omap_hwmod_addr_space omap2_mailbox_addrs[]; extern struct omap_hwmod_addr_space omap2_mcbsp1_addrs[]; +extern struct omap_hwmod_addr_space omap2_hdq1w_addr_space[]; /* Common IP block data across OMAP2xxx */ extern struct omap_hwmod_irq_info omap2xxx_timer12_mpu_irqs[]; @@ -74,6 +75,7 @@ extern struct omap_hwmod omap2xxx_gpio3_hwmod; extern struct omap_hwmod omap2xxx_gpio4_hwmod; extern struct omap_hwmod omap2xxx_mcspi1_hwmod; extern struct omap_hwmod omap2xxx_mcspi2_hwmod; +extern struct omap_hwmod omap2xxx_counter_32k_hwmod; /* Common interface data across OMAP2xxx */ extern struct omap_hwmod_ocp_if omap2xxx_l3_main__l4_core; @@ -141,6 +143,7 @@ extern struct omap_hwmod_irq_info omap2_dma_system_irqs[]; extern struct omap_hwmod_irq_info omap2_mcspi1_mpu_irqs[]; extern struct omap_hwmod_irq_info omap2_mcspi2_mpu_irqs[]; extern struct omap_hwmod_addr_space omap2xxx_timer12_addrs[]; +extern struct omap_hwmod_irq_info omap2_hdq1w_mpu_irqs[]; /* OMAP hwmod classes - forward declarations */ extern struct omap_hwmod_class l3_hwmod_class; @@ -152,6 +155,8 @@ extern struct omap_hwmod_class omap2_dss_hwmod_class; extern struct omap_hwmod_class omap2_dispc_hwmod_class; extern struct omap_hwmod_class omap2_rfbi_hwmod_class; extern struct omap_hwmod_class omap2_venc_hwmod_class; +extern struct omap_hwmod_class_sysconfig omap2_hdq1w_sysc; +extern struct omap_hwmod_class omap2_hdq1w_class; extern struct omap_hwmod_class omap2xxx_timer_hwmod_class; extern struct omap_hwmod_class omap2xxx_wd_timer_hwmod_class; diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 96ad3dbeac34..96114901b932 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c @@ -981,16 +981,6 @@ int pwrdm_state_switch(struct powerdomain *pwrdm) return ret; } -int pwrdm_clkdm_state_switch(struct clockdomain *clkdm) -{ - if (clkdm != NULL && clkdm->pwrdm.ptr != NULL) { - pwrdm_wait_transition(clkdm->pwrdm.ptr); - return pwrdm_state_switch(clkdm->pwrdm.ptr); - } - - return -EINVAL; -} - int pwrdm_pre_transition(void) { pwrdm_for_each(_pwrdm_pre_transition_cb, NULL); diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h index 0d72a8a8ce4d..8f88d65c46ea 100644 --- a/arch/arm/mach-omap2/powerdomain.h +++ b/arch/arm/mach-omap2/powerdomain.h @@ -213,7 +213,6 @@ bool pwrdm_has_hdwr_sar(struct powerdomain *pwrdm); int pwrdm_wait_transition(struct powerdomain *pwrdm); int pwrdm_state_switch(struct powerdomain *pwrdm); -int pwrdm_clkdm_state_switch(struct clockdomain *clkdm); int pwrdm_pre_transition(void); int pwrdm_post_transition(void); int pwrdm_set_lowpwrstchange(struct powerdomain *pwrdm); diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index 5aa5435e3ff1..6da3ba483ad1 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h @@ -177,6 +177,8 @@ /* PM_WKST_WKUP, CM_IDLEST_WKUP shared bits */ #define OMAP24XX_ST_GPIOS_SHIFT 2 #define OMAP24XX_ST_GPIOS_MASK (1 << 2) +#define OMAP24XX_ST_32KSYNC_SHIFT 1 +#define OMAP24XX_ST_32KSYNC_MASK (1 << 1) #define OMAP24XX_ST_GPT1_SHIFT 0 #define OMAP24XX_ST_GPT1_MASK (1 << 0) @@ -307,6 +309,8 @@ #define OMAP3430_ST_SR1_MASK (1 << 6) #define OMAP3430_ST_GPIO1_SHIFT 3 #define OMAP3430_ST_GPIO1_MASK (1 << 3) +#define OMAP3430_ST_32KSYNC_SHIFT 2 +#define OMAP3430_ST_32KSYNC_MASK (1 << 2) #define OMAP3430_ST_GPT12_SHIFT 1 #define OMAP3430_ST_GPT12_MASK (1 << 1) #define OMAP3430_ST_GPT1_SHIFT 0 @@ -410,6 +414,19 @@ extern void __iomem *prm_base; extern void __iomem *cm_base; extern void __iomem *cm2_base; +extern void __iomem *prcm_mpu_base; + +#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_ARCH_OMAP5) +extern void omap_prm_base_init(void); +extern void omap_cm_base_init(void); +#else +static inline void omap_prm_base_init(void) +{ +} +static inline void omap_cm_base_init(void) +{ +} +#endif /** * struct omap_prcm_irq - describes a PRCM interrupt bit diff --git a/arch/arm/mach-omap2/prcm.c b/arch/arm/mach-omap2/prcm.c index 626acfad7190..480f40a5ee42 100644 --- a/arch/arm/mach-omap2/prcm.c +++ b/arch/arm/mach-omap2/prcm.c @@ -42,6 +42,7 @@ void __iomem *prm_base; void __iomem *cm_base; void __iomem *cm2_base; +void __iomem *prcm_mpu_base; #define MAX_MODULE_ENABLE_WAIT 100000 @@ -155,4 +156,11 @@ void __init omap2_set_globals_prcm(struct omap_globals *omap2_globals) cm_base = omap2_globals->cm; if (omap2_globals->cm2) cm2_base = omap2_globals->cm2; + if (omap2_globals->prcm_mpu) + prcm_mpu_base = omap2_globals->prcm_mpu; + + if (cpu_is_omap44xx()) { + omap_prm_base_init(); + omap_cm_base_init(); + } } diff --git a/arch/arm/mach-omap2/prminst44xx.c b/arch/arm/mach-omap2/prminst44xx.c index 9b3898a3ac9b..c12320c0ae95 100644 --- a/arch/arm/mach-omap2/prminst44xx.c +++ b/arch/arm/mach-omap2/prminst44xx.c @@ -18,20 +18,26 @@ #include "iomap.h" #include "common.h" +#include "prcm-common.h" #include "prm44xx.h" #include "prminst44xx.h" #include "prm-regbits-44xx.h" #include "prcm44xx.h" #include "prcm_mpu44xx.h" -static u32 _prm_bases[OMAP4_MAX_PRCM_PARTITIONS] = { - [OMAP4430_INVALID_PRCM_PARTITION] = 0, - [OMAP4430_PRM_PARTITION] = OMAP4430_PRM_BASE, - [OMAP4430_CM1_PARTITION] = 0, - [OMAP4430_CM2_PARTITION] = 0, - [OMAP4430_SCRM_PARTITION] = 0, - [OMAP4430_PRCM_MPU_PARTITION] = OMAP4430_PRCM_MPU_BASE, -}; +static void __iomem *_prm_bases[OMAP4_MAX_PRCM_PARTITIONS]; + +/** + * omap_prm_base_init - Populates the prm partitions + * + * Populates the base addresses of the _prm_bases + * array used for read/write of prm module registers. + */ +void omap_prm_base_init(void) +{ + _prm_bases[OMAP4430_PRM_PARTITION] = prm_base; + _prm_bases[OMAP4430_PRCM_MPU_PARTITION] = prcm_mpu_base; +} /* Read a register in a PRM instance */ u32 omap4_prminst_read_inst_reg(u8 part, s16 inst, u16 idx) @@ -39,8 +45,7 @@ u32 omap4_prminst_read_inst_reg(u8 part, s16 inst, u16 idx) BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || part == OMAP4430_INVALID_PRCM_PARTITION || !_prm_bases[part]); - return __raw_readl(OMAP2_L4_IO_ADDRESS(_prm_bases[part] + inst + - idx)); + return __raw_readl(_prm_bases[part] + inst + idx); } /* Write into a register in a PRM instance */ @@ -49,7 +54,7 @@ void omap4_prminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx) BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || part == OMAP4430_INVALID_PRCM_PARTITION || !_prm_bases[part]); - __raw_writel(val, OMAP2_L4_IO_ADDRESS(_prm_bases[part] + inst + idx)); + __raw_writel(val, _prm_bases[part] + inst + idx); } /* Read-modify-write a register in PRM. Caller must lock */ diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index ecec873e78cd..1b7835865c83 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -178,13 +178,6 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, if (IS_ERR(timer->fclk)) return -ENODEV; - sprintf(name, "gpt%d_ick", gptimer_id); - timer->iclk = clk_get(NULL, name); - if (IS_ERR(timer->iclk)) { - clk_put(timer->fclk); - return -ENODEV; - } - omap_hwmod_enable(oh); sys_timer_reserved |= (1 << (gptimer_id - 1)); diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c index 7a7b89304c48..ee6596b45214 100644 --- a/arch/arm/mach-omap2/twl-common.c +++ b/arch/arm/mach-omap2/twl-common.c @@ -31,6 +31,7 @@ #include "twl-common.h" #include "pm.h" +#include "voltage.h" static struct i2c_board_info __initdata pmic_i2c_board_info = { .addr = 0x48, @@ -47,6 +48,18 @@ static struct i2c_board_info __initdata omap4_i2c1_board_info[] = { }, }; +static int twl_set_voltage(void *data, int target_uV) +{ + struct voltagedomain *voltdm = (struct voltagedomain *)data; + return voltdm_scale(voltdm, target_uV); +} + +static int twl_get_voltage(void *data) +{ + struct voltagedomain *voltdm = (struct voltagedomain *)data; + return voltdm_get_voltage(voltdm); +} + void __init omap_pmic_init(int bus, u32 clkrate, const char *pmic_type, int pmic_irq, struct twl4030_platform_data *pmic_data) @@ -153,6 +166,48 @@ static struct regulator_init_data omap3_vpll2_idata = { .consumer_supplies = omap3_vpll2_supplies, }; +static struct regulator_consumer_supply omap3_vdd1_supply[] = { + REGULATOR_SUPPLY("vcc", "mpu.0"), +}; + +static struct regulator_consumer_supply omap3_vdd2_supply[] = { + REGULATOR_SUPPLY("vcc", "l3_main.0"), +}; + +static struct regulator_init_data omap3_vdd1 = { + .constraints = { + .name = "vdd_mpu_iva", + .min_uV = 600000, + .max_uV = 1450000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + }, + .num_consumer_supplies = ARRAY_SIZE(omap3_vdd1_supply), + .consumer_supplies = omap3_vdd1_supply, +}; + +static struct regulator_init_data omap3_vdd2 = { + .constraints = { + .name = "vdd_core", + .min_uV = 600000, + .max_uV = 1450000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + }, + .num_consumer_supplies = ARRAY_SIZE(omap3_vdd2_supply), + .consumer_supplies = omap3_vdd2_supply, +}; + +static struct twl_regulator_driver_data omap3_vdd1_drvdata = { + .get_voltage = twl_get_voltage, + .set_voltage = twl_set_voltage, +}; + +static struct twl_regulator_driver_data omap3_vdd2_drvdata = { + .get_voltage = twl_get_voltage, + .set_voltage = twl_set_voltage, +}; + void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data, u32 pdata_flags, u32 regulators_flags) { @@ -160,6 +215,16 @@ void __init omap3_pmic_get_config(struct twl4030_platform_data *pmic_data, pmic_data->irq_base = TWL4030_IRQ_BASE; if (!pmic_data->irq_end) pmic_data->irq_end = TWL4030_IRQ_END; + if (!pmic_data->vdd1) { + omap3_vdd1.driver_data = &omap3_vdd1_drvdata; + omap3_vdd1_drvdata.data = voltdm_lookup("mpu_iva"); + pmic_data->vdd1 = &omap3_vdd1; + } + if (!pmic_data->vdd2) { + omap3_vdd2.driver_data = &omap3_vdd2_drvdata; + omap3_vdd2_drvdata.data = voltdm_lookup("core"); + pmic_data->vdd2 = &omap3_vdd2; + } /* Common platform data configurations */ if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb) @@ -310,6 +375,70 @@ static struct regulator_init_data omap4_clk32kg_idata = { }, }; +static struct regulator_consumer_supply omap4_vdd1_supply[] = { + REGULATOR_SUPPLY("vcc", "mpu.0"), +}; + +static struct regulator_consumer_supply omap4_vdd2_supply[] = { + REGULATOR_SUPPLY("vcc", "iva.0"), +}; + +static struct regulator_consumer_supply omap4_vdd3_supply[] = { + REGULATOR_SUPPLY("vcc", "l3_main.0"), +}; + +static struct regulator_init_data omap4_vdd1 = { + .constraints = { + .name = "vdd_mpu", + .min_uV = 500000, + .max_uV = 1500000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + }, + .num_consumer_supplies = ARRAY_SIZE(omap4_vdd1_supply), + .consumer_supplies = omap4_vdd1_supply, +}; + +static struct regulator_init_data omap4_vdd2 = { + .constraints = { + .name = "vdd_iva", + .min_uV = 500000, + .max_uV = 1500000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + }, + .num_consumer_supplies = ARRAY_SIZE(omap4_vdd2_supply), + .consumer_supplies = omap4_vdd2_supply, +}; + +static struct regulator_init_data omap4_vdd3 = { + .constraints = { + .name = "vdd_core", + .min_uV = 500000, + .max_uV = 1500000, + .valid_modes_mask = REGULATOR_MODE_NORMAL, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE, + }, + .num_consumer_supplies = ARRAY_SIZE(omap4_vdd3_supply), + .consumer_supplies = omap4_vdd3_supply, +}; + + +static struct twl_regulator_driver_data omap4_vdd1_drvdata = { + .get_voltage = twl_get_voltage, + .set_voltage = twl_set_voltage, +}; + +static struct twl_regulator_driver_data omap4_vdd2_drvdata = { + .get_voltage = twl_get_voltage, + .set_voltage = twl_set_voltage, +}; + +static struct twl_regulator_driver_data omap4_vdd3_drvdata = { + .get_voltage = twl_get_voltage, + .set_voltage = twl_set_voltage, +}; + void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data, u32 pdata_flags, u32 regulators_flags) { @@ -318,6 +447,24 @@ void __init omap4_pmic_get_config(struct twl4030_platform_data *pmic_data, if (!pmic_data->irq_end) pmic_data->irq_end = TWL6030_IRQ_END; + if (!pmic_data->vdd1) { + omap4_vdd1.driver_data = &omap4_vdd1_drvdata; + omap4_vdd1_drvdata.data = voltdm_lookup("mpu"); + pmic_data->vdd1 = &omap4_vdd1; + } + + if (!pmic_data->vdd2) { + omap4_vdd2.driver_data = &omap4_vdd2_drvdata; + omap4_vdd2_drvdata.data = voltdm_lookup("iva"); + pmic_data->vdd2 = &omap4_vdd2; + } + + if (!pmic_data->vdd3) { + omap4_vdd3.driver_data = &omap4_vdd3_drvdata; + omap4_vdd3_drvdata.data = voltdm_lookup("core"); + pmic_data->vdd3 = &omap4_vdd3; + } + /* Common platform data configurations */ if (pdata_flags & TWL_COMMON_PDATA_USB && !pmic_data->usb) pmic_data->usb = &omap4_usb_pdata; diff --git a/arch/arm/mach-omap2/vc3xxx_data.c b/arch/arm/mach-omap2/vc3xxx_data.c index a5ec7f8f2ea8..5d8eaf31569c 100644 --- a/arch/arm/mach-omap2/vc3xxx_data.c +++ b/arch/arm/mach-omap2/vc3xxx_data.c @@ -46,6 +46,7 @@ static struct omap_vc_common omap3_vc_common = { }; struct omap_vc_channel omap3_vc_mpu = { + .flags = OMAP_VC_CHANNEL_DEFAULT, .common = &omap3_vc_common, .smps_sa_reg = OMAP3_PRM_VC_SMPS_SA_OFFSET, .smps_volra_reg = OMAP3_PRM_VC_SMPS_VOL_RA_OFFSET, diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c index 8a36342e60d2..4dc60e83e00d 100644 --- a/arch/arm/mach-omap2/voltage.c +++ b/arch/arm/mach-omap2/voltage.c @@ -73,7 +73,8 @@ unsigned long voltdm_get_voltage(struct voltagedomain *voltdm) int voltdm_scale(struct voltagedomain *voltdm, unsigned long target_volt) { - int ret; + int ret, i; + unsigned long volt = 0; if (!voltdm || IS_ERR(voltdm)) { pr_warning("%s: VDD specified does not exist!\n", __func__); @@ -86,9 +87,23 @@ int voltdm_scale(struct voltagedomain *voltdm, return -ENODATA; } - ret = voltdm->scale(voltdm, target_volt); + /* Adjust voltage to the exact voltage from the OPP table */ + for (i = 0; voltdm->volt_data[i].volt_nominal != 0; i++) { + if (voltdm->volt_data[i].volt_nominal >= target_volt) { + volt = voltdm->volt_data[i].volt_nominal; + break; + } + } + + if (!volt) { + pr_warning("%s: not scaling. OPP voltage for %lu, not found.\n", + __func__, target_volt); + return -EINVAL; + } + + ret = voltdm->scale(voltdm, volt); if (!ret) - voltdm->nominal_volt = target_volt; + voltdm->nominal_volt = volt; return ret; } diff --git a/arch/arm/mach-omap2/wd_timer.c b/arch/arm/mach-omap2/wd_timer.c index 4067669d96c4..b2f1c67043a2 100644 --- a/arch/arm/mach-omap2/wd_timer.c +++ b/arch/arm/mach-omap2/wd_timer.c @@ -14,6 +14,7 @@ #include <plat/omap_hwmod.h> #include "wd_timer.h" +#include "common.h" /* * In order to avoid any assumptions from bootloader regarding WDT @@ -25,6 +26,8 @@ #define OMAP_WDT_WPS 0x34 #define OMAP_WDT_SPR 0x48 +/* Maximum microseconds to wait for OMAP module to softreset */ +#define MAX_MODULE_SOFTRESET_WAIT 10000 int omap2_wd_timer_disable(struct omap_hwmod *oh) { @@ -54,3 +57,45 @@ int omap2_wd_timer_disable(struct omap_hwmod *oh) return 0; } +/** + * omap2_wdtimer_reset - reset and disable the WDTIMER IP block + * @oh: struct omap_hwmod * + * + * After the WDTIMER IP blocks are reset on OMAP2/3, we must also take + * care to execute the special watchdog disable sequence. This is + * because the watchdog is re-armed upon OCP softreset. (On OMAP4, + * this behavior was apparently changed and the watchdog is no longer + * re-armed after an OCP soft-reset.) Returns -ETIMEDOUT if the reset + * did not complete, or 0 upon success. + * + * XXX Most of this code should be moved to the omap_hwmod.c layer + * during a normal merge window. omap_hwmod_softreset() should be + * renamed to omap_hwmod_set_ocp_softreset(), and omap_hwmod_softreset() + * should call the hwmod _ocp_softreset() code. + */ +int omap2_wd_timer_reset(struct omap_hwmod *oh) +{ + int c = 0; + + /* Write to the SOFTRESET bit */ + omap_hwmod_softreset(oh); + + /* Poll on RESETDONE bit */ + omap_test_timeout((omap_hwmod_read(oh, + oh->class->sysc->syss_offs) + & SYSS_RESETDONE_MASK), + MAX_MODULE_SOFTRESET_WAIT, c); + + if (oh->class->sysc->srst_udelay) + udelay(oh->class->sysc->srst_udelay); + + if (c == MAX_MODULE_SOFTRESET_WAIT) + pr_warning("%s: %s: softreset failed (waited %d usec)\n", + __func__, oh->name, MAX_MODULE_SOFTRESET_WAIT); + else + pr_debug("%s: %s: softreset in %d usec\n", __func__, + oh->name, c); + + return (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : + omap2_wd_timer_disable(oh); +} diff --git a/arch/arm/mach-omap2/wd_timer.h b/arch/arm/mach-omap2/wd_timer.h index e0054a2d5505..f6bbba73b535 100644 --- a/arch/arm/mach-omap2/wd_timer.h +++ b/arch/arm/mach-omap2/wd_timer.h @@ -13,5 +13,6 @@ #include <plat/omap_hwmod.h> extern int omap2_wd_timer_disable(struct omap_hwmod *oh); +extern int omap2_wd_timer_reset(struct omap_hwmod *oh); #endif diff --git a/arch/arm/mach-ux500/Makefile b/arch/arm/mach-ux500/Makefile index 041c35885981..026086ff9e6c 100644 --- a/arch/arm/mach-ux500/Makefile +++ b/arch/arm/mach-ux500/Makefile @@ -4,6 +4,7 @@ obj-y := clock.o cpu.o devices.o devices-common.o \ id.o usb.o timer.o +obj-$(CONFIG_CPU_IDLE) += cpuidle.o obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o obj-$(CONFIG_UX500_SOC_DB8500) += cpu-db8500.o devices-db8500.o obj-$(CONFIG_MACH_MOP500) += board-mop500.o board-mop500-sdi.o \ diff --git a/arch/arm/mach-ux500/cpuidle.c b/arch/arm/mach-ux500/cpuidle.c new file mode 100644 index 000000000000..b54884bd2549 --- /dev/null +++ b/arch/arm/mach-ux500/cpuidle.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2012 Linaro : Daniel Lezcano <daniel.lezcano@linaro.org> (IBM) + * + * Based on the work of Rickard Andersson <rickard.andersson@stericsson.com> + * and Jonas Aaberg <jonas.aberg@stericsson.com>. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include <linux/module.h> +#include <linux/cpuidle.h> +#include <linux/clockchips.h> +#include <linux/spinlock.h> +#include <linux/atomic.h> +#include <linux/smp.h> +#include <linux/mfd/dbx500-prcmu.h> + +#include <asm/cpuidle.h> +#include <asm/proc-fns.h> + +static atomic_t master = ATOMIC_INIT(0); +static DEFINE_SPINLOCK(master_lock); +static DEFINE_PER_CPU(struct cpuidle_device, ux500_cpuidle_device); + +static inline int ux500_enter_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, int index) +{ + int this_cpu = smp_processor_id(); + bool recouple = false; + + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &this_cpu); + + if (atomic_inc_return(&master) == num_online_cpus()) { + + /* With this lock, we prevent the other cpu to exit and enter + * this function again and become the master */ + if (!spin_trylock(&master_lock)) + goto wfi; + + /* decouple the gic from the A9 cores */ + if (prcmu_gic_decouple()) + goto out; + + /* If an error occur, we will have to recouple the gic + * manually */ + recouple = true; + + /* At this state, as the gic is decoupled, if the other + * cpu is in WFI, we have the guarantee it won't be wake + * up, so we can safely go to retention */ + if (!prcmu_is_cpu_in_wfi(this_cpu ? 0 : 1)) + goto out; + + /* The prcmu will be in charge of watching the interrupts + * and wake up the cpus */ + if (prcmu_copy_gic_settings()) + goto out; + + /* Check in the meantime an interrupt did + * not occur on the gic ... */ + if (prcmu_gic_pending_irq()) + goto out; + + /* ... and the prcmu */ + if (prcmu_pending_irq()) + goto out; + + /* Go to the retention state, the prcmu will wait for the + * cpu to go WFI and this is what happens after exiting this + * 'master' critical section */ + if (prcmu_set_power_state(PRCMU_AP_IDLE, true, true)) + goto out; + + /* When we switch to retention, the prcmu is in charge + * of recoupling the gic automatically */ + recouple = false; + + spin_unlock(&master_lock); + } +wfi: + cpu_do_idle(); +out: + atomic_dec(&master); + + if (recouple) { + prcmu_gic_recouple(); + spin_unlock(&master_lock); + } + + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &this_cpu); + + return index; +} + +static struct cpuidle_driver ux500_idle_driver = { + .name = "ux500_idle", + .owner = THIS_MODULE, + .en_core_tk_irqen = 1, + .states = { + ARM_CPUIDLE_WFI_STATE, + { + .enter = ux500_enter_idle, + .exit_latency = 70, + .target_residency = 260, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "ApIdle", + .desc = "ARM Retention", + }, + }, + .safe_state_index = 0, + .state_count = 2, +}; + +/* + * For each cpu, setup the broadcast timer because we will + * need to migrate the timers for the states >= ApIdle. + */ +static void ux500_setup_broadcast_timer(void *arg) +{ + int cpu = smp_processor_id(); + clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu); +} + +int __init ux500_idle_init(void) +{ + int ret, cpu; + struct cpuidle_device *device; + + /* Configure wake up reasons */ + prcmu_enable_wakeups(PRCMU_WAKEUP(ARM) | PRCMU_WAKEUP(RTC) | + PRCMU_WAKEUP(ABB)); + + /* + * Configure the timer broadcast for each cpu, that must + * be done from the cpu context, so we use a smp cross + * call with 'on_each_cpu'. + */ + on_each_cpu(ux500_setup_broadcast_timer, NULL, 1); + + ret = cpuidle_register_driver(&ux500_idle_driver); + if (ret) { + printk(KERN_ERR "failed to register ux500 idle driver\n"); + return ret; + } + + for_each_online_cpu(cpu) { + device = &per_cpu(ux500_cpuidle_device, cpu); + device->cpu = cpu; + ret = cpuidle_register_device(device); + if (ret) { + printk(KERN_ERR "Failed to register cpuidle " + "device for cpu%d\n", cpu); + goto out_unregister; + } + } +out: + return ret; + +out_unregister: + for_each_online_cpu(cpu) { + device = &per_cpu(ux500_cpuidle_device, cpu); + cpuidle_unregister_device(device); + } + + cpuidle_unregister_driver(&ux500_idle_driver); + goto out; +} + +device_initcall(ux500_idle_init); diff --git a/arch/arm/mm/cache-tauros2.c b/arch/arm/mm/cache-tauros2.c index 1fbca05fe906..23a7643e9a87 100644 --- a/arch/arm/mm/cache-tauros2.c +++ b/arch/arm/mm/cache-tauros2.c @@ -108,6 +108,26 @@ static void tauros2_flush_range(unsigned long start, unsigned long end) dsb(); } + +static void tauros2_disable(void) +{ + __asm__ __volatile__ ( + "mcr p15, 1, %0, c7, c11, 0 @L2 Cache Clean All\n\t" + "mrc p15, 0, %0, c1, c0, 0\n\t" + "bic %0, %0, #(1 << 26)\n\t" + "mcr p15, 0, %0, c1, c0, 0 @Disable L2 Cache\n\t" + : : "r" (0x0)); +} + +static void tauros2_resume(void) +{ + __asm__ __volatile__ ( + "mcr p15, 1, %0, c7, c7, 0 @L2 Cache Invalidate All\n\t" + "mrc p15, 0, %0, c1, c0, 0\n\t" + "orr %0, %0, #(1 << 26)\n\t" + "mcr p15, 0, %0, c1, c0, 0 @Enable L2 Cache\n\t" + : : "r" (0x0)); +} #endif static inline u32 __init read_extra_features(void) @@ -194,6 +214,8 @@ void __init tauros2_init(void) outer_cache.inv_range = tauros2_inv_range; outer_cache.clean_range = tauros2_clean_range; outer_cache.flush_range = tauros2_flush_range; + outer_cache.disable = tauros2_disable; + outer_cache.resume = tauros2_resume; } #endif @@ -219,6 +241,8 @@ void __init tauros2_init(void) outer_cache.inv_range = tauros2_inv_range; outer_cache.clean_range = tauros2_clean_range; outer_cache.flush_range = tauros2_flush_range; + outer_cache.disable = tauros2_disable; + outer_cache.resume = tauros2_resume; } #endif diff --git a/arch/arm/mm/proc-mohawk.S b/arch/arm/mm/proc-mohawk.S index b0475468c711..fbb2124a547d 100644 --- a/arch/arm/mm/proc-mohawk.S +++ b/arch/arm/mm/proc-mohawk.S @@ -345,6 +345,41 @@ ENTRY(cpu_mohawk_set_pte_ext) mcr p15, 0, r0, c7, c10, 4 @ drain WB mov pc, lr +.globl cpu_mohawk_suspend_size +.equ cpu_mohawk_suspend_size, 4 * 6 +#ifdef CONFIG_PM_SLEEP +ENTRY(cpu_mohawk_do_suspend) + stmfd sp!, {r4 - r9, lr} + mrc p14, 0, r4, c6, c0, 0 @ clock configuration, for turbo mode + mrc p15, 0, r5, c15, c1, 0 @ CP access reg + mrc p15, 0, r6, c13, c0, 0 @ PID + mrc p15, 0, r7, c3, c0, 0 @ domain ID + mrc p15, 0, r8, c1, c0, 1 @ auxiliary control reg + mrc p15, 0, r9, c1, c0, 0 @ control reg + bic r4, r4, #2 @ clear frequency change bit + stmia r0, {r4 - r9} @ store cp regs + ldmia sp!, {r4 - r9, pc} +ENDPROC(cpu_mohawk_do_suspend) + +ENTRY(cpu_mohawk_do_resume) + ldmia r0, {r4 - r9} @ load cp regs + mov ip, #0 + mcr p15, 0, ip, c7, c7, 0 @ invalidate I & D caches, BTB + mcr p15, 0, ip, c7, c10, 4 @ drain write (&fill) buffer + mcr p15, 0, ip, c7, c5, 4 @ flush prefetch buffer + mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs + mcr p14, 0, r4, c6, c0, 0 @ clock configuration, turbo mode. + mcr p15, 0, r5, c15, c1, 0 @ CP access reg + mcr p15, 0, r6, c13, c0, 0 @ PID + mcr p15, 0, r7, c3, c0, 0 @ domain ID + orr r1, r1, #0x18 @ cache the page table in L2 + mcr p15, 0, r1, c2, c0, 0 @ translation table base addr + mcr p15, 0, r8, c1, c0, 1 @ auxiliary control reg + mov r0, r9 @ control register + b cpu_resume_mmu +ENDPROC(cpu_mohawk_do_resume) +#endif + __CPUINIT .type __mohawk_setup, #function diff --git a/arch/arm/plat-omap/include/plat/clkdev_omap.h b/arch/arm/plat-omap/include/plat/clkdev_omap.h index b299b8d201c8..d0ed8c443a63 100644 --- a/arch/arm/plat-omap/include/plat/clkdev_omap.h +++ b/arch/arm/plat-omap/include/plat/clkdev_omap.h @@ -34,8 +34,7 @@ struct omap_clk { #define CK_243X (1 << 5) /* 243x, 253x */ #define CK_3430ES1 (1 << 6) /* 34xxES1 only */ #define CK_3430ES2PLUS (1 << 7) /* 34xxES2, ES3, non-Sitara 35xx only */ -#define CK_3505 (1 << 8) -#define CK_3517 (1 << 9) +#define CK_AM35XX (1 << 9) /* Sitara AM35xx */ #define CK_36XX (1 << 10) /* 36xx/37xx-specific clocks */ #define CK_443X (1 << 11) #define CK_TI816X (1 << 12) @@ -44,7 +43,6 @@ struct omap_clk { #define CK_34XX (CK_3430ES1 | CK_3430ES2PLUS) -#define CK_AM35XX (CK_3505 | CK_3517) /* all Sitara AM35xx */ #define CK_3XXX (CK_34XX | CK_AM35XX | CK_36XX) diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h index 230ff91be491..bdf871a84d62 100644 --- a/arch/arm/plat-omap/include/plat/dmtimer.h +++ b/arch/arm/plat-omap/include/plat/dmtimer.h @@ -259,7 +259,7 @@ struct omap_dm_timer { unsigned long phys_base; int id; int irq; - struct clk *iclk, *fclk; + struct clk *fclk; void __iomem *io_base; void __iomem *sys_stat; /* TISTAT timer status */ diff --git a/arch/arm/plat-omap/include/plat/hdq1w.h b/arch/arm/plat-omap/include/plat/hdq1w.h new file mode 100644 index 000000000000..0c1efc846d8d --- /dev/null +++ b/arch/arm/plat-omap/include/plat/hdq1w.h @@ -0,0 +1,36 @@ +/* + * Shared macros and function prototypes for the HDQ1W/1-wire IP block + * + * 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 + * version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; 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 ARCH_ARM_MACH_OMAP2_HDQ1W_H +#define ARCH_ARM_MACH_OMAP2_HDQ1W_H + +#include <plat/omap_hwmod.h> + +/* + * XXX A future cleanup patch should modify + * drivers/w1/masters/omap_hdq.c to use these macros + */ +#define HDQ_CTRL_STATUS_OFFSET 0x0c +#define HDQ_CTRL_STATUS_CLOCKENABLE_SHIFT 5 + + +extern int omap_hdq1w_reset(struct omap_hwmod *oh); + +#endif diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h index 7a38750c0079..3e7ae0f0215f 100644 --- a/arch/arm/plat-omap/include/plat/mmc.h +++ b/arch/arm/plat-omap/include/plat/mmc.h @@ -16,6 +16,7 @@ #include <linux/mmc/host.h> #include <plat/board.h> +#include <plat/omap_hwmod.h> #define OMAP15XX_NR_MMC 1 #define OMAP16XX_NR_MMC 2 @@ -195,4 +196,7 @@ static inline int omap_mmc_add(const char *name, int id, unsigned long base, } #endif + +extern int omap_msdi_reset(struct omap_hwmod *oh); + #endif diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 14dde32cd406..c835b7194ff5 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -214,6 +214,7 @@ struct omap_hwmod_addr_space { #define OCP_USER_MPU (1 << 0) #define OCP_USER_SDMA (1 << 1) #define OCP_USER_DSP (1 << 2) +#define OCP_USER_IVA (1 << 3) /* omap_hwmod_ocp_if.flags bits */ #define OCPIF_SWSUP_IDLE (1 << 0) |