From 7b2e1277598e4187c9be3e61fd9b0f0423f97986 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 10 Nov 2012 12:04:15 +0100 Subject: ARM: OMAP3: clock: Back-propagate rate change from cam_mclk to dpll4_m5 The cam_mclk clock is generated through the following clocks chain: dpll4 -> dpll4_m5 -> dpll4_m5x2 -> cam_mclk As dpll4_m5 and dpll4_m5x2 do not driver any clock other than cam_mclk, back-propagate the cam_clk rate changes up to dpll4_m5. Signed-off-by: Laurent Pinchart Reviewed-by: Mike Turquette Acked-by: Sakari Ailus Tested-by: Sakari Ailus diff --git a/arch/arm/mach-omap2/cclock3xxx_data.c b/arch/arm/mach-omap2/cclock3xxx_data.c index 6ef8758..4579c3c 100644 --- a/arch/arm/mach-omap2/cclock3xxx_data.c +++ b/arch/arm/mach-omap2/cclock3xxx_data.c @@ -426,6 +426,7 @@ static struct clk dpll4_m5x2_ck_3630 = { .parent_names = dpll4_m5x2_ck_parent_names, .num_parents = ARRAY_SIZE(dpll4_m5x2_ck_parent_names), .ops = &dpll4_m5x2_ck_3630_ops, + .flags = CLK_SET_RATE_PARENT, }; static struct clk cam_mclk; @@ -443,7 +444,14 @@ static struct clk_hw_omap cam_mclk_hw = { .clkdm_name = "cam_clkdm", }; -DEFINE_STRUCT_CLK(cam_mclk, cam_mclk_parent_names, aes2_ick_ops); +static struct clk cam_mclk = { + .name = "cam_mclk", + .hw = &cam_mclk_hw.hw, + .parent_names = cam_mclk_parent_names, + .num_parents = ARRAY_SIZE(cam_mclk_parent_names), + .ops = &aes2_ick_ops, + .flags = CLK_SET_RATE_PARENT, +}; static const struct clksel_rate clkout2_src_core_rates[] = { { .div = 1, .val = 0, .flags = RATE_IN_3XXX }, -- cgit v0.10.2 From 6d1aa02f10497b138e01ebe6eafabd6071729334 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Sat, 10 Nov 2012 12:06:25 +0100 Subject: omap3isp: Set cam_mclk rate directly Now that the cam_mclk rate changes are back-propagated to dpll4_m5_ck we can set the cam_mclk rate directly instead of manually setting the rate of the parent clock. Signed-off-by: Laurent Pinchart Reviewed-by: Mike Turquette Acked-by: Sakari Ailus Tested-by: Sakari Ailus diff --git a/drivers/media/platform/omap3isp/isp.c b/drivers/media/platform/omap3isp/isp.c index e4aaee9..e7f5da0 100644 --- a/drivers/media/platform/omap3isp/isp.c +++ b/drivers/media/platform/omap3isp/isp.c @@ -1338,28 +1338,15 @@ static int isp_enable_clocks(struct isp_device *isp) { int r; unsigned long rate; - int divisor; - - /* - * cam_mclk clock chain: - * dpll4 -> dpll4_m5 -> dpll4_m5x2 -> cam_mclk - * - * In OMAP3630 dpll4_m5x2 != 2 x dpll4_m5 but both are - * set to the same value. Hence the rate set for dpll4_m5 - * has to be twice of what is set on OMAP3430 to get - * the required value for cam_mclk - */ - divisor = isp->revision == ISP_REVISION_15_0 ? 1 : 2; r = clk_prepare_enable(isp->clock[ISP_CLK_CAM_ICK]); if (r) { dev_err(isp->dev, "failed to enable cam_ick clock\n"); goto out_clk_enable_ick; } - r = clk_set_rate(isp->clock[ISP_CLK_DPLL4_M5_CK], - CM_CAM_MCLK_HZ/divisor); + r = clk_set_rate(isp->clock[ISP_CLK_CAM_MCLK], CM_CAM_MCLK_HZ); if (r) { - dev_err(isp->dev, "clk_set_rate for dpll4_m5_ck failed\n"); + dev_err(isp->dev, "clk_set_rate for cam_mclk failed\n"); goto out_clk_enable_mclk; } r = clk_prepare_enable(isp->clock[ISP_CLK_CAM_MCLK]); @@ -1401,7 +1388,6 @@ static void isp_disable_clocks(struct isp_device *isp) static const char *isp_clocks[] = { "cam_ick", "cam_mclk", - "dpll4_m5_ck", "csi2_96m_fck", "l3_ick", }; diff --git a/drivers/media/platform/omap3isp/isp.h b/drivers/media/platform/omap3isp/isp.h index 517d348..c77e1f2 100644 --- a/drivers/media/platform/omap3isp/isp.h +++ b/drivers/media/platform/omap3isp/isp.h @@ -147,7 +147,6 @@ struct isp_platform_callback { * @ref_count: Reference count for handling multiple ISP requests. * @cam_ick: Pointer to camera interface clock structure. * @cam_mclk: Pointer to camera functional clock structure. - * @dpll4_m5_ck: Pointer to DPLL4 M5 clock structure. * @csi2_fck: Pointer to camera CSI2 complexIO clock structure. * @l3_ick: Pointer to OMAP3 L3 bus interface clock. * @irq: Currently attached ISP ISR callbacks information structure. @@ -189,10 +188,9 @@ struct isp_device { u32 xclk_divisor[2]; /* Two clocks, a and b. */ #define ISP_CLK_CAM_ICK 0 #define ISP_CLK_CAM_MCLK 1 -#define ISP_CLK_DPLL4_M5_CK 2 -#define ISP_CLK_CSI2_FCK 3 -#define ISP_CLK_L3_ICK 4 - struct clk *clock[5]; +#define ISP_CLK_CSI2_FCK 2 +#define ISP_CLK_L3_ICK 3 + struct clk *clock[4]; /* ISP modules */ struct ispstat isp_af; -- cgit v0.10.2 From bb0b7320a72ec899e27b5a852851607ab1305541 Mon Sep 17 00:00:00 2001 From: Afzal Mohammed Date: Thu, 31 Jan 2013 09:24:52 -0700 Subject: ARM: OMAP2+: dpll: am335x - avoid freqsel am335x does not have freqsel, avoid it. Signed-off-by: Afzal Mohammed Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c index 0a02aab..3aed4b0 100644 --- a/arch/arm/mach-omap2/dpll3xxx.c +++ b/arch/arm/mach-omap2/dpll3xxx.c @@ -500,8 +500,9 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate, if (dd->last_rounded_rate == 0) return -EINVAL; - /* No freqsel on OMAP4 and OMAP3630 */ - if (!cpu_is_omap44xx() && !cpu_is_omap3630()) { + /* No freqsel on AM335x, OMAP4 and OMAP3630 */ + if (!soc_is_am33xx() && !cpu_is_omap44xx() && + !cpu_is_omap3630()) { freqsel = _omap3_dpll_compute_freqsel(clk, dd->last_rounded_n); WARN_ON(!freqsel); -- cgit v0.10.2 From 601155b04c2e93c00644003811f59444a9e356e2 Mon Sep 17 00:00:00 2001 From: Afzal Mohammed Date: Wed, 23 Jan 2013 17:12:05 +0530 Subject: ARM: OMAP2+: clock data: add DEFINE_STRUCT_CLK_FLAGS helper DEFINE_STRUCT_CLK does not have the capability to set flags, define DEFINE_STRUCT_CLK_FLAGS to handle flags. This is needed to add SET_RATE_PARENT flag in statically defined lcd clock in am335x. Signed-off-by: Afzal Mohammed Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h index b402048..60ddd86 100644 --- a/arch/arm/mach-omap2/clock.h +++ b/arch/arm/mach-omap2/clock.h @@ -65,6 +65,17 @@ struct clockdomain; .ops = &_clkops_name, \ }; +#define DEFINE_STRUCT_CLK_FLAGS(_name, _parent_array_name, \ + _clkops_name, _flags) \ + static struct clk _name = { \ + .name = #_name, \ + .hw = &_name##_hw.hw, \ + .parent_names = _parent_array_name, \ + .num_parents = ARRAY_SIZE(_parent_array_name), \ + .ops = &_clkops_name, \ + .flags = _flags, \ + }; + #define DEFINE_STRUCT_CLK_HW_OMAP(_name, _clkdm_name) \ static struct clk_hw_omap _name##_hw = { \ .hw = { \ -- cgit v0.10.2 From 0c3c22f9c53e2fc282d0fb221a6e8c9cf9eeafe8 Mon Sep 17 00:00:00 2001 From: Afzal Mohammed Date: Wed, 23 Jan 2013 17:12:11 +0530 Subject: ARM: OMAP AM33XX: clock data: SET_RATE_PARENT in lcd path LCDC clock node is a one that does not have set rate capability. It just passes on the rate that is sent downstream by it's parent. While lcdc clock parent and it's grand parent - dpll_disp_m2_ck and dpll_disp_ck has the capability to configure rate. And the default rates provided by LCDC clock's ancestors are not sufficient to obtain pixel clock for current LCDC use cases, hence currently display would not work on AM335x SoC's (with driver modifications in platfrom independent way). Hence inform clock framework to propogate set rate for LCDC clock as well as it's parent - dpll_disp_m2_ck. With this change, set rate on LCDC clock would get propogated till dpll_disp_ck via dpll_disp_m2_ck, hence allowing the driver (same driver is used in DaVinci too) to set rates using LCDC clock without worrying about platform dependent clock details. Signed-off-by: Afzal Mohammed Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/cclock33xx_data.c b/arch/arm/mach-omap2/cclock33xx_data.c index ea64ad6..476b820 100644 --- a/arch/arm/mach-omap2/cclock33xx_data.c +++ b/arch/arm/mach-omap2/cclock33xx_data.c @@ -284,9 +284,10 @@ DEFINE_STRUCT_CLK(dpll_disp_ck, dpll_core_ck_parents, dpll_ddr_ck_ops); * TODO: Add clksel here (sys_clkin, CORE_CLKOUTM6, PER_CLKOUTM2 * and ALT_CLK1/2) */ -DEFINE_CLK_DIVIDER(dpll_disp_m2_ck, "dpll_disp_ck", &dpll_disp_ck, 0x0, - AM33XX_CM_DIV_M2_DPLL_DISP, AM33XX_DPLL_CLKOUT_DIV_SHIFT, - AM33XX_DPLL_CLKOUT_DIV_WIDTH, CLK_DIVIDER_ONE_BASED, NULL); +DEFINE_CLK_DIVIDER(dpll_disp_m2_ck, "dpll_disp_ck", &dpll_disp_ck, + CLK_SET_RATE_PARENT, AM33XX_CM_DIV_M2_DPLL_DISP, + AM33XX_DPLL_CLKOUT_DIV_SHIFT, AM33XX_DPLL_CLKOUT_DIV_WIDTH, + CLK_DIVIDER_ONE_BASED, NULL); /* DPLL_PER */ static struct dpll_data dpll_per_dd = { @@ -723,7 +724,8 @@ static struct clk_hw_omap lcd_gclk_hw = { .clksel_mask = AM33XX_CLKSEL_0_1_MASK, }; -DEFINE_STRUCT_CLK(lcd_gclk, lcd_ck_parents, gpio_fck_ops); +DEFINE_STRUCT_CLK_FLAGS(lcd_gclk, lcd_ck_parents, + gpio_fck_ops, CLK_SET_RATE_PARENT); DEFINE_CLK_FIXED_FACTOR(mmc_clk, "dpll_per_m2_ck", &dpll_per_m2_ck, 0x0, 1, 2); -- cgit v0.10.2 From 14e067c1a5280fe6fe5d3348a0bae87bc4da16db Mon Sep 17 00:00:00 2001 From: "Jean-Sebastien A. Beaudry" Date: Wed, 23 Jan 2013 16:02:40 -0500 Subject: ARM: OMAP2+: AM33xx: Add SoC specific restart hook Add restart hook so that DTS based AM33xx builds can restart the platform. Tested-by: Nishanth Menon Signed-off-by: Jean-Sebastien A. Beaudry Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 947cafe..d1156cf 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -53,6 +53,7 @@ AFLAGS_sram34xx.o :=-Wa,-march=armv7-a # Restart code (OMAP4/5 currently in omap4-common.c) obj-$(CONFIG_SOC_OMAP2420) += omap2-restart.o obj-$(CONFIG_SOC_OMAP2430) += omap2-restart.o +obj-$(CONFIG_SOC_AM33XX) += am33xx-restart.o obj-$(CONFIG_ARCH_OMAP3) += omap3-restart.o # Pin multiplexing diff --git a/arch/arm/mach-omap2/am33xx-restart.c b/arch/arm/mach-omap2/am33xx-restart.c new file mode 100644 index 0000000..88e4fa8 --- /dev/null +++ b/arch/arm/mach-omap2/am33xx-restart.c @@ -0,0 +1,34 @@ +/* + * am33xx-restart.c - Code common to all AM33xx machines. + * + * 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 + +#include "common.h" +#include "prm-regbits-33xx.h" +#include "prm33xx.h" + +/** + * am3xx_restart - trigger a software restart of the SoC + * @mode: the "reboot mode", see arch/arm/kernel/{setup,process}.c + * @cmd: passed from the userspace program rebooting the system (if provided) + * + * Resets the SoC. For @cmd, see the 'reboot' syscall in + * kernel/sys.c. No return value. + */ +void am33xx_restart(char mode, const char *cmd) +{ + /* TODO: Handle mode and cmd if necessary */ + + am33xx_prm_rmw_reg_bits(AM33XX_GLOBAL_WARM_SW_RST_MASK, + AM33XX_GLOBAL_WARM_SW_RST_MASK, + AM33XX_PRM_DEVICE_MOD, + AM33XX_PRM_RSTCTRL_OFFSET); + + /* OCP barrier */ + (void)am33xx_prm_read_reg(AM33XX_PRM_DEVICE_MOD, + AM33XX_PRM_RSTCTRL_OFFSET); +} diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 53cb380b..fac00f0 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -141,6 +141,7 @@ DT_MACHINE_START(AM33XX_DT, "Generic AM33XX (Flattened Device Tree)") .init_machine = omap_generic_init, .timer = &omap3_am33xx_timer, .dt_compat = am33xx_boards_compat, + .restart = am33xx_restart, MACHINE_END #endif diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index 948bcaa..0c3a991 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -119,6 +119,14 @@ static inline void omap2xxx_restart(char mode, const char *cmd) } #endif +#ifdef CONFIG_SOC_AM33XX +void am33xx_restart(char mode, const char *cmd); +#else +static inline void am33xx_restart(char mode, const char *cmd) +{ +} +#endif + #ifdef CONFIG_ARCH_OMAP3 void omap3xxx_restart(char mode, const char *cmd); #else -- cgit v0.10.2 From 8f0de0d62f29e47f5142737dad7561f108f69e92 Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Thu, 31 Jan 2013 21:02:00 +0530 Subject: ARM: OMAP2+: Get rid of custom OMAP_32K_TIMER_HZ The timekeeping doesn't depend on HZ value in presence of fine grained clocksource and hence there should not be any time drift because of HZ value which was chosen to be divisor of 32768. OMAP has been using HZ = 128 value to avoid any time drift issues because of 32768 HZ clock. But with various measurements performed with HZ = 100, no time drift is observed and it also proves the point about HZ not having impact on time keeping on OMAP. Very informative thread on this topic is here: https://lkml.org/lkml/2013/1/29/435 Special thanks to John Stulz, Arnd Bergmann and Russell King for their valuable suggestions. Cc: Arnd Bergmann Cc: Russell King Cc: John Stultz Cc: Tony Lindgren Signed-off-by: Santosh Shilimkar Tested-by: Lokesh Vutla Signed-off-by: Tony Lindgren diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 67874b8..c407edb 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -1650,7 +1650,6 @@ config HZ int default 200 if ARCH_EBSA110 || ARCH_S3C24XX || ARCH_S5P64X0 || \ ARCH_S5PV210 || ARCH_EXYNOS4 - default OMAP_32K_TIMER_HZ if ARCH_OMAP && OMAP_32K_TIMER default AT91_TIMER_HZ if ARCH_AT91 default SHMOBILE_TIMER_HZ if ARCH_SHMOBILE default 100 diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index 665870d..1fbac36 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -177,15 +177,6 @@ config OMAP3_L2_AUX_SECURE_SERVICE_SET_ID help PPA routine service ID for setting L2 auxiliary control register. -config OMAP_32K_TIMER_HZ - int "Kernel internal timer frequency for 32KHz timer" - range 32 1024 - depends on OMAP_32K_TIMER - default "128" - help - Kernel internal timer frequency should be a divisor of 32768, - such as 64 or 128. - config OMAP_DM_TIMER bool "Use dual-mode timer" depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS diff --git a/arch/arm/plat-omap/include/plat/timex.h b/arch/arm/plat-omap/include/plat/timex.h index 6d35767..e27d2da 100644 --- a/arch/arm/plat-omap/include/plat/timex.h +++ b/arch/arm/plat-omap/include/plat/timex.h @@ -28,14 +28,6 @@ #if !defined(__ASM_ARCH_OMAP_TIMEX_H) #define __ASM_ARCH_OMAP_TIMEX_H -/* - * OMAP 32KHz timer updates time one jiffie at a time from a secondary timer, - * and that's why the CLOCK_TICK_RATE is not 32768. - */ -#ifdef CONFIG_OMAP_32K_TIMER -#define CLOCK_TICK_RATE (CONFIG_OMAP_32K_TIMER_HZ) -#else #define CLOCK_TICK_RATE (HZ * 100000UL) -#endif #endif /* __ASM_ARCH_OMAP_TIMEX_H */ -- cgit v0.10.2 From 5af044f472501c8e9bd6bb274fb3d71d07a038cd Mon Sep 17 00:00:00 2001 From: AnilKumar Ch Date: Fri, 1 Feb 2013 15:58:22 +0530 Subject: ARM: OMAP2: AM33XX: id: Add support for AM335x PG2.0 Add support for chip id recognition of AM335x PG2.0 silicon. By default omap3xxx_check_revision() recognizes PG1.0, which is extended by adding PG2.0 support Signed-off-by: AnilKumar Ch Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 45cc7ed4..8a68f1e 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c @@ -399,8 +399,18 @@ void __init omap3xxx_check_revision(void) } break; case 0xb944: - omap_revision = AM335X_REV_ES1_0; - cpu_rev = "1.0"; + switch (rev) { + case 0: + omap_revision = AM335X_REV_ES1_0; + cpu_rev = "1.0"; + break; + case 1: + /* FALLTHROUGH */ + default: + omap_revision = AM335X_REV_ES2_0; + cpu_rev = "2.0"; + break; + } break; case 0xb8f2: switch (rev) { diff --git a/arch/arm/mach-omap2/soc.h b/arch/arm/mach-omap2/soc.h index f31d907..15e9591 100644 --- a/arch/arm/mach-omap2/soc.h +++ b/arch/arm/mach-omap2/soc.h @@ -387,6 +387,7 @@ IS_OMAP_TYPE(3430, 0x3430) #define AM335X_CLASS 0x33500033 #define AM335X_REV_ES1_0 AM335X_CLASS +#define AM335X_REV_ES2_0 (AM335X_CLASS | (0x1 << 8)) #define OMAP443X_CLASS 0x44300044 #define OMAP4430_REV_ES1_0 (OMAP443X_CLASS | (0x10 << 8)) -- cgit v0.10.2 From 088e8806c411f76216002a8b37c7eb8563614822 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Sun, 30 Dec 2012 10:15:48 -0700 Subject: ARM: OMAP2xxx: PM: enter WFI via inline asm if CORE stays active There shouldn't be any need to jump to SRAM code if the OMAP CORE clockdomain (and consequently the SDRAM controller and CORE PLL) stays active during MPU WFI. The SRAM code should only be needed when the RAM enters self-refresh. So in the case where CORE stays active, just call WFI directly from the mach-omap2/pm24xx.c code. This removes some unnecessary SRAM code. This second version replaces the inline WFI with the corresponding coprocessor register call, using tlbflush.h as an example. This is because the assembler doesn't recognize WFI as a valid ARMv6 instruction. Signed-off-by: Paul Walmsley Cc: Richard Woodruff Cc: Kevin Hilman diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index c333fa6..8914b9e 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -54,7 +54,6 @@ #include "powerdomain.h" #include "clockdomain.h" -static void (*omap2_sram_idle)(void); static void (*omap2_sram_suspend)(u32 dllctrl, void __iomem *sdrc_dlla_ctrl, void __iomem *sdrc_power); @@ -172,6 +171,8 @@ static int omap2_allow_mpu_retention(void) static void omap2_enter_mpu_retention(void) { + const int zero = 0; + /* Putting MPU into the WFI state while a transfer is active * seems to cause the I2C block to timeout. Why? Good question. */ if (omap2_i2c_active()) @@ -196,7 +197,8 @@ static void omap2_enter_mpu_retention(void) OMAP2_PM_PWSTCTRL); } - omap2_sram_idle(); + /* WFI */ + asm("mcr p15, 0, %0, c7, c0, 4" : : "r" (zero) : "memory", "cc"); } static int omap2_can_sleep(void) @@ -356,11 +358,9 @@ int __init omap2_pm_init(void) /* * We copy the assembler sleep/wakeup routines to SRAM. * These routines need to be in SRAM as that's the only - * memory the MPU can see when it wakes up. + * memory the MPU can see when it wakes up after the entire + * chip enters idle. */ - omap2_sram_idle = omap_sram_push(omap24xx_idle_loop_suspend, - omap24xx_idle_loop_suspend_sz); - omap2_sram_suspend = omap_sram_push(omap24xx_cpu_suspend, omap24xx_cpu_suspend_sz); diff --git a/arch/arm/mach-omap2/sleep24xx.S b/arch/arm/mach-omap2/sleep24xx.S index ce0ccd2..1d3cb25 100644 --- a/arch/arm/mach-omap2/sleep24xx.S +++ b/arch/arm/mach-omap2/sleep24xx.S @@ -37,25 +37,6 @@ .text /* - * Forces OMAP into idle state - * - * omap24xx_idle_loop_suspend() - This bit of code just executes the WFI - * for normal idles. - * - * Note: This code get's copied to internal SRAM at boot. When the OMAP - * wakes up it continues execution at the point it went to sleep. - */ - .align 3 -ENTRY(omap24xx_idle_loop_suspend) - stmfd sp!, {r0, lr} @ save registers on stack - mov r0, #0 @ clear for mcr setup - mcr p15, 0, r0, c7, c0, 4 @ wait for interrupt - ldmfd sp!, {r0, pc} @ restore regs and return - -ENTRY(omap24xx_idle_loop_suspend_sz) - .word . - omap24xx_idle_loop_suspend - -/* * omap24xx_cpu_suspend() - Forces OMAP into deep sleep state by completing * SDRC shutdown then ARM shutdown. Upon wake MPU is back on so just restore * SDRC. -- cgit v0.10.2 From db27c0c0d05cafc0eb0bed4d58daea65ed5e6839 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Sun, 30 Dec 2012 10:22:25 -0700 Subject: ARM: OMAP2+: hwmod: add support for blocking WFI when a device is active Apparently, on some OMAPs, the MPU can't be allowed to enter WFI while certain peripherals are active. It's not clear why, and it's likely that there is simply some other bug in the driver or integration code. But since the likelihood that anyone will have the time to track these problems down in the future seems quite small, we'll provide a flag, HWMOD_BLOCK_WFI, to mark these issues in the hwmod data. Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 4653efb..6804d47 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -139,6 +139,8 @@ #include #include +#include + #include "clock.h" #include "omap_hwmod.h" @@ -2134,6 +2136,8 @@ static int _enable(struct omap_hwmod *oh) _enable_clocks(oh); if (soc_ops.enable_module) soc_ops.enable_module(oh); + if (oh->flags & HWMOD_BLOCK_WFI) + disable_hlt(); if (soc_ops.update_context_lost) soc_ops.update_context_lost(oh); @@ -2195,6 +2199,8 @@ static int _idle(struct omap_hwmod *oh) _idle_sysc(oh); _del_initiator_dep(oh, mpu_oh); + if (oh->flags & HWMOD_BLOCK_WFI) + enable_hlt(); if (soc_ops.disable_module) soc_ops.disable_module(oh); @@ -2303,6 +2309,8 @@ static int _shutdown(struct omap_hwmod *oh) if (oh->_state == _HWMOD_STATE_ENABLED) { _del_initiator_dep(oh, mpu_oh); /* XXX what about the other system initiators here? dma, dsp */ + if (oh->flags & HWMOD_BLOCK_WFI) + enable_hlt(); if (soc_ops.disable_module) soc_ops.disable_module(oh); _disable_clocks(oh); diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h index 3ae852a..80c00e7 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h @@ -451,6 +451,14 @@ struct omap_hwmod_omap4_prcm { * enabled. This prevents the hwmod code from being able to * enable and reset the IP block early. XXX Eventually it should * be possible to query the clock framework for this information. + * HWMOD_BLOCK_WFI: Some OMAP peripherals apparently don't work + * correctly if the MPU is allowed to go idle while the + * peripherals are active. This is apparently true for the I2C on + * OMAP2420, and also the EMAC on AM3517/3505. It's unlikely that + * this is really true -- we're probably not configuring something + * correctly, or this is being abused to deal with some PM latency + * issues -- but we're currently suffering from a shortage of + * folks who are able to track these issues down properly. */ #define HWMOD_SWSUP_SIDLE (1 << 0) #define HWMOD_SWSUP_MSTANDBY (1 << 1) @@ -462,6 +470,7 @@ struct omap_hwmod_omap4_prcm { #define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7) #define HWMOD_16BIT_REG (1 << 8) #define HWMOD_EXT_OPT_MAIN_CLK (1 << 9) +#define HWMOD_BLOCK_WFI (1 << 10) /* * omap_hwmod._int_flags definitions -- cgit v0.10.2 From 1e3d8fe771881de323396aaa1efd20243fa974cb Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Sun, 30 Dec 2012 10:31:52 -0700 Subject: ARM: OMAP2420: hwmod data/PM: use hwmod to block WFI when I2C active Use the HWMOD_BLOCK_WFI flag in the hwmod data to prevent the MPU from entering WFI when the I2C devices are active. No idea why this is needed; this could certainly bear further investigation if anyone is interested. The objective here is to remove some custom code from the OMAP24xx PM code. Signed-off-by: Paul Walmsley Cc: Kevin Hilman diff --git a/arch/arm/mach-omap2/omap_hwmod_2420_data.c b/arch/arm/mach-omap2/omap_hwmod_2420_data.c index b5efe58..6a764af 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2420_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2420_data.c @@ -121,7 +121,12 @@ static struct omap_hwmod omap2420_i2c1_hwmod = { }, .class = &i2c_class, .dev_attr = &i2c_dev_attr, - .flags = HWMOD_16BIT_REG, + /* + * From mach-omap2/pm24xx.c: "Putting MPU into the WFI state + * while a transfer is active seems to cause the I2C block to + * timeout. Why? Good question." + */ + .flags = (HWMOD_16BIT_REG | HWMOD_BLOCK_WFI), }; /* I2C2 */ diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index 8914b9e..bc44bcd 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -139,14 +139,6 @@ no_sleep: return 0; } -static int omap2_i2c_active(void) -{ - u32 l; - - l = omap2_cm_read_mod_reg(CORE_MOD, CM_FCLKEN1); - return l & (OMAP2420_EN_I2C2_MASK | OMAP2420_EN_I2C1_MASK); -} - static int sti_console_enabled; static int omap2_allow_mpu_retention(void) @@ -173,11 +165,6 @@ static void omap2_enter_mpu_retention(void) { const int zero = 0; - /* Putting MPU into the WFI state while a transfer is active - * seems to cause the I2C block to timeout. Why? Good question. */ - if (omap2_i2c_active()) - return; - /* The peripherals seem not to be able to wake up the MPU when * it is in retention mode. */ if (omap2_allow_mpu_retention()) { -- cgit v0.10.2 From 814a18a5d026464f56b3616704b985f9942b29a6 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Wed, 6 Feb 2013 13:48:56 -0700 Subject: ARM: OMAP AM3517/05: hwmod data: block WFI when EMAC active According to Mark Greer, on OMAP AM3517/3505 chips, the EMAC is unable to wake the ARM up from WFI: http://www.spinics.net/lists/arm-kernel/msg174734.html Further troubleshooting was unable to narrow the problem down. So we don't have much choice other than to block WFI when the EMAC is active with the HWMOD_BLOCK_WFI flag. Based on Mark's original patch. We're removing the omap_device-based pm_lats code, so a different approach was needed. This third version contains some corrections thanks to Mark's review. Signed-off-by: Paul Walmsley Cc: Mark A. Greer Acked-by: Mark A. Greer diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 8bb2628..ac7e03e 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -3493,7 +3493,12 @@ static struct omap_hwmod am35xx_emac_hwmod = { .name = "davinci_emac", .mpu_irqs = am35xx_emac_mpu_irqs, .class = &am35xx_emac_class, - .flags = HWMOD_NO_IDLEST, + /* + * According to Mark Greer, the MPU will not return from WFI + * when the EMAC signals an interrupt. + * http://www.spinics.net/lists/arm-kernel/msg174734.html + */ + .flags = (HWMOD_NO_IDLEST | HWMOD_BLOCK_WFI), }; /* l3_core -> davinci emac interface */ -- cgit v0.10.2 From 6048009818047297c510e300c6e8e6f623d4eac9 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Mon, 4 Feb 2013 17:54:43 +0530 Subject: ARM: OMAP4: PM: Warn users about usage of older bootloaders OMAP4 CHIP level PM works only with newer bootloaders. The dependency on the bootloader comes from the fact that the kernel is missing reset and initialization code for some devices. While the right thing to do is to add reset and init code in the kernel, for some co-processor IP blocks like DSP and IVA it means downloading firmware into each one of them to execute idle instructions. While a feasible solution is worked upon on how such IP blocks can be better handled in the kernel, in the interim, to avoid any further frustration to users testing PM on OMAP4 and finding it broken, warn them about the bootloader being a possible cause. Signed-off-by: Rajendra Nayak Cc: Tero Kristo Cc: Santosh Shilimkar Cc: R Sricharan [paul@pwsan.com: tweaked warning messages and comments slightly] Acked-by: Kevin Hilman [paul@pwsan.com: fixed checkpatch warning] Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index aa6fd98..ea62e75 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -77,10 +77,20 @@ static int omap4_pm_suspend(void) omap_set_pwrdm_state(pwrst->pwrdm, pwrst->saved_state); pwrdm_set_logic_retst(pwrst->pwrdm, pwrst->saved_logic_state); } - if (ret) + if (ret) { pr_crit("Could not enter target state in pm_suspend\n"); - else + /* + * OMAP4 chip PM currently works only with certain (newer) + * versions of bootloaders. This is due to missing code in the + * kernel to properly reset and initialize some devices. + * Warn the user about the bootloader version being one of the + * possible causes. + * http://www.spinics.net/lists/arm-kernel/msg218641.html + */ + pr_warn("A possible cause could be an old bootloader - try u-boot >= v2012.07\n"); + } else { pr_info("Successfully put all powerdomains to target state\n"); + } return 0; } @@ -146,6 +156,13 @@ int __init omap4_pm_init(void) } pr_err("Power Management for TI OMAP4.\n"); + /* + * OMAP4 chip PM currently works only with certain (newer) + * versions of bootloaders. This is due to missing code in the + * kernel to properly reset and initialize some devices. + * http://www.spinics.net/lists/arm-kernel/msg218641.html + */ + pr_warn("OMAP4 PM: u-boot >= v2012.07 is required for full PM support\n"); ret = pwrdm_for_each(pwrdms_setup, NULL); if (ret) { -- cgit v0.10.2 From 941a98ae290f1671c7ec615154ec678da70b3395 Mon Sep 17 00:00:00 2001 From: Vaibhav Bedia Date: Tue, 29 Jan 2013 16:45:00 +0530 Subject: ARM: OMAP2+: AM33XX: CM: Get rid of unnecessary header inclusions cm33xx.h unnecessarily includes a lot of header files. Get rid of these and directly include "iomap.h" which is needed to keep things compiling. Signed-off-by: Vaibhav Bedia Acked-by: Santosh Shilimkar Acked-by: Peter Korsgaard Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/cm33xx.h b/arch/arm/mach-omap2/cm33xx.h index 5fa0b62..8009e13 100644 --- a/arch/arm/mach-omap2/cm33xx.h +++ b/arch/arm/mach-omap2/cm33xx.h @@ -17,16 +17,11 @@ #ifndef __ARCH_ARM_MACH_OMAP2_CM_33XX_H #define __ARCH_ARM_MACH_OMAP2_CM_33XX_H -#include -#include -#include -#include - #include "common.h" #include "cm.h" #include "cm-regbits-33xx.h" -#include "cm33xx.h" +#include "iomap.h" /* CM base address */ #define AM33XX_CM_BASE 0x44e00000 -- cgit v0.10.2 From 1a7cb4d9c37143ca75567ee4dc10608059c610dc Mon Sep 17 00:00:00 2001 From: Vaibhav Bedia Date: Tue, 29 Jan 2013 16:45:01 +0530 Subject: ARM: OMAP2+: AM33XX: CM/PRM: Use __ASSEMBLER__ macros in header files This is necessary to ensure that macros declared here can be reused from assembly files. Signed-off-by: Vaibhav Bedia Acked-by: Santosh Shilimkar Acked-by: Peter Korsgaard Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/cm33xx.h b/arch/arm/mach-omap2/cm33xx.h index 8009e13..64f4baf 100644 --- a/arch/arm/mach-omap2/cm33xx.h +++ b/arch/arm/mach-omap2/cm33xx.h @@ -376,6 +376,7 @@ #define AM33XX_CM_CEFUSE_CEFUSE_CLKCTRL AM33XX_CM_REGADDR(AM33XX_CM_CEFUSE_MOD, 0x0020) +#ifndef __ASSEMBLER__ extern bool am33xx_cm_is_clkdm_in_hwsup(s16 inst, u16 cdoffs); extern void am33xx_cm_clkdm_enable_hwsup(s16 inst, u16 cdoffs); extern void am33xx_cm_clkdm_disable_hwsup(s16 inst, u16 cdoffs); @@ -412,4 +413,5 @@ static inline int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, } #endif +#endif /* ASSEMBLER */ #endif diff --git a/arch/arm/mach-omap2/prm33xx.h b/arch/arm/mach-omap2/prm33xx.h index 3f25c56..1c40373 100644 --- a/arch/arm/mach-omap2/prm33xx.h +++ b/arch/arm/mach-omap2/prm33xx.h @@ -117,6 +117,7 @@ #define AM33XX_PM_CEFUSE_PWRSTST_OFFSET 0x0004 #define AM33XX_PM_CEFUSE_PWRSTST AM33XX_PRM_REGADDR(AM33XX_PRM_CEFUSE_MOD, 0x0004) +#ifndef __ASSEMBLER__ extern u32 am33xx_prm_read_reg(s16 inst, u16 idx); extern void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx); extern u32 am33xx_prm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx); @@ -126,4 +127,5 @@ extern int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst, extern int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs); extern int am33xx_prm_deassert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs, u16 rstst_offs); +#endif /* ASSEMBLER */ #endif -- cgit v0.10.2 From ca903b6f98281d694b2ae8deec1330d4f392a67d Mon Sep 17 00:00:00 2001 From: Vaibhav Bedia Date: Tue, 29 Jan 2013 16:45:02 +0530 Subject: ARM: OMAP2+: AM33XX: hwmod: Register OCMC RAM hwmod OCMC RAM lies in the PER power domain and this memory support retention. Signed-off-by: Vaibhav Bedia Acked-by: Santosh Shilimkar Acked-by: Peter Korsgaard Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index 646c14d..8280f11 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -414,7 +414,6 @@ static struct omap_hwmod am33xx_adc_tsc_hwmod = { * - cEFUSE (doesn't fall under any ocp_if) * - clkdiv32k * - debugss - * - ocmc ram * - ocp watch point * - aes0 * - sha0 @@ -481,25 +480,6 @@ static struct omap_hwmod am33xx_debugss_hwmod = { }, }; -/* ocmcram */ -static struct omap_hwmod_class am33xx_ocmcram_hwmod_class = { - .name = "ocmcram", -}; - -static struct omap_hwmod am33xx_ocmcram_hwmod = { - .name = "ocmcram", - .class = &am33xx_ocmcram_hwmod_class, - .clkdm_name = "l3_clkdm", - .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), - .main_clk = "l3_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, -}; - /* ocpwp */ static struct omap_hwmod_class am33xx_ocpwp_hwmod_class = { .name = "ocpwp", @@ -570,6 +550,25 @@ static struct omap_hwmod am33xx_sha0_hwmod = { #endif +/* ocmcram */ +static struct omap_hwmod_class am33xx_ocmcram_hwmod_class = { + .name = "ocmcram", +}; + +static struct omap_hwmod am33xx_ocmcram_hwmod = { + .name = "ocmcram", + .class = &am33xx_ocmcram_hwmod_class, + .clkdm_name = "l3_clkdm", + .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET), + .main_clk = "l3_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM33XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + /* 'smartreflex' class */ static struct omap_hwmod_class am33xx_smartreflex_hwmod_class = { .name = "smartreflex", @@ -3328,6 +3327,13 @@ static struct omap_hwmod_ocp_if am33xx_l3_s__usbss = { .flags = OCPIF_SWSUP_IDLE, }; +/* l3 main -> ocmc */ +static struct omap_hwmod_ocp_if am33xx_l3_main__ocmc = { + .master = &am33xx_l3_main_hwmod, + .slave = &am33xx_ocmcram_hwmod, + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = { &am33xx_l4_fw__emif_fw, &am33xx_l3_main__emif, @@ -3398,6 +3404,7 @@ static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = { &am33xx_l3_main__tptc0, &am33xx_l3_main__tptc1, &am33xx_l3_main__tptc2, + &am33xx_l3_main__ocmc, &am33xx_l3_s__usbss, &am33xx_l4_hs__cpgmac0, &am33xx_cpgmac0__mdio, -- cgit v0.10.2 From 0bfbbded8dbd82ec252be2ea0a9e221a1b22e8ba Mon Sep 17 00:00:00 2001 From: Vaibhav Bedia Date: Tue, 29 Jan 2013 16:45:03 +0530 Subject: ARM: OMAP2+: AM33XX: hwmod: Update TPTC0 hwmod with the right flags Third Party Transfer Controller (TPTC0) needs to be idled and put to standby under SW control. Add the appropriate flags in the TPTC0 hwmod entry. Signed-off-by: Vaibhav Bedia Acked-by: Santosh Shilimkar Acked-by: Peter Korsgaard Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index 8280f11..94254e8 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -1823,6 +1823,7 @@ static struct omap_hwmod am33xx_tptc0_hwmod = { .class = &am33xx_tptc_hwmod_class, .clkdm_name = "l3_clkdm", .mpu_irqs = am33xx_tptc0_irqs, + .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, .main_clk = "l3_gclk", .prcm = { .omap4 = { -- cgit v0.10.2 From f13966608f9f65dd635eb400cc93f856a595531a Mon Sep 17 00:00:00 2001 From: Vaibhav Bedia Date: Tue, 29 Jan 2013 16:45:04 +0530 Subject: ARM: OMAP2+: AM33XX: hwmod: Fixup cpgmac0 hwmod entry The current HWMOD code expects the memory region with the IP's SYSCONFIG register to be marked with ADDR_TYPE_RT flag. CPGMAC0 hwmod entry specifies two memory regions and marks both with the flag ADDR_TYPE_RT although only the 2nd region has the SYSCONFIG register. This leads to the HWMOD code accessing the wrong memory address for idle and standby operations. Fix this by removing the ADDR_TYPE_RT flag from the 1st memory region in CPGMAC0 hwmod entry. Signed-off-by: Vaibhav Bedia Acked-by: Peter Korsgaard Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index 94254e8..40bfde3 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -2496,7 +2496,6 @@ static struct omap_hwmod_addr_space am33xx_cpgmac0_addr_space[] = { { .pa_start = 0x4a100000, .pa_end = 0x4a100000 + SZ_2K - 1, - .flags = ADDR_TYPE_RT, }, /* cpsw wr */ { -- cgit v0.10.2 From 3077fe69d7055b2ab118b299613394e13f4983a8 Mon Sep 17 00:00:00 2001 From: Vaibhav Bedia Date: Tue, 29 Jan 2013 16:45:05 +0530 Subject: ARM: OMAP2+: AM33XX: hwmod: Update the WKUP-M3 hwmod with reset status bit WKUP-M3 has a reset status bit (RM_WKUP_STST.WKUP_M3_LRST) Update the WKUP-M3 hwmod data to reflect the same. Signed-off-by: Vaibhav Bedia Acked-by: Peter Korsgaard Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index 40bfde3..9e34d4c 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -269,6 +269,7 @@ static struct omap_hwmod am33xx_wkup_m3_hwmod = { .omap4 = { .clkctrl_offs = AM33XX_CM_WKUP_WKUP_M3_CLKCTRL_OFFSET, .rstctrl_offs = AM33XX_RM_WKUP_RSTCTRL_OFFSET, + .rstst_offs = AM33XX_RM_WKUP_RSTST_OFFSET, .modulemode = MODULEMODE_SWCTRL, }, }, -- cgit v0.10.2 From 3c06f1b8c3ca74669b77c0aaee428b5c46d3e552 Mon Sep 17 00:00:00 2001 From: Vaibhav Bedia Date: Tue, 29 Jan 2013 16:45:06 +0530 Subject: ARM: OMAP2+: AM33XX: Update the hardreset API WKUP-M3 has a reset status bit (RM_WKUP_STST.WKUP_M3_LRST) Update the hardreset API to ensure that the reset line properly deasserted. Signed-off-by: Vaibhav Bedia Acked-by: Santosh Shilimkar Acked-by: Peter Korsgaard Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 4653efb..6549439 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -3041,11 +3041,8 @@ static int _am33xx_assert_hardreset(struct omap_hwmod *oh, static int _am33xx_deassert_hardreset(struct omap_hwmod *oh, struct omap_hwmod_rst_info *ohri) { - if (ohri->st_shift) - pr_err("omap_hwmod: %s: %s: hwmod data error: OMAP4 does not support st_shift\n", - oh->name, ohri->name); - return am33xx_prm_deassert_hardreset(ohri->rst_shift, + ohri->st_shift, oh->clkdm->pwrdm.ptr->prcm_offs, oh->prcm.omap4.rstctrl_offs, oh->prcm.omap4.rstst_offs); diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c index 1ac7388..44c0d72 100644 --- a/arch/arm/mach-omap2/prm33xx.c +++ b/arch/arm/mach-omap2/prm33xx.c @@ -110,11 +110,11 @@ int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs) * -EINVAL upon an argument error, -EEXIST if the submodule was already out * of reset, or -EBUSY if the submodule did not exit reset promptly. */ -int am33xx_prm_deassert_hardreset(u8 shift, s16 inst, +int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, s16 inst, u16 rstctrl_offs, u16 rstst_offs) { int c; - u32 mask = 1 << shift; + u32 mask = 1 << st_shift; /* Check the current status to avoid de-asserting the line twice */ if (am33xx_prm_is_hardreset_asserted(shift, inst, rstctrl_offs) == 0) @@ -122,11 +122,14 @@ int am33xx_prm_deassert_hardreset(u8 shift, s16 inst, /* Clear the reset status by writing 1 to the status bit */ am33xx_prm_rmw_reg_bits(0xffffffff, mask, inst, rstst_offs); + /* de-assert the reset control line */ + mask = 1 << shift; + am33xx_prm_rmw_reg_bits(mask, 0, inst, rstctrl_offs); - /* wait the status to be set */ - omap_test_timeout(am33xx_prm_is_hardreset_asserted(shift, inst, + /* wait the status to be set */ + omap_test_timeout(am33xx_prm_is_hardreset_asserted(st_shift, inst, rstst_offs), MAX_MODULE_HARDRESET_WAIT, c); diff --git a/arch/arm/mach-omap2/prm33xx.h b/arch/arm/mach-omap2/prm33xx.h index 1c40373..9b9918d 100644 --- a/arch/arm/mach-omap2/prm33xx.h +++ b/arch/arm/mach-omap2/prm33xx.h @@ -125,7 +125,7 @@ extern void am33xx_prm_global_warm_sw_reset(void); extern int am33xx_prm_is_hardreset_asserted(u8 shift, s16 inst, u16 rstctrl_offs); extern int am33xx_prm_assert_hardreset(u8 shift, s16 inst, u16 rstctrl_offs); -extern int am33xx_prm_deassert_hardreset(u8 shift, s16 inst, +extern int am33xx_prm_deassert_hardreset(u8 shift, u8 st_shift, s16 inst, u16 rstctrl_offs, u16 rstst_offs); #endif /* ASSEMBLER */ #endif -- cgit v0.10.2 From f6575c90f6fc637697f130ea4a05892296c9a473 Mon Sep 17 00:00:00 2001 From: Vaibhav Bedia Date: Tue, 29 Jan 2013 16:45:07 +0530 Subject: ARM: DTS: AM33XX: Add nodes for OCMC RAM and WKUP-M3 Since AM33XX supports only DT-boot, this is needed for the appropriate device nodes to be created. Note: OCMC RAM is part of the PER power domain and supports retention. The assembly code for low power entry/exit will run from OCMC RAM. To ensure that the OMAP PM code does not attempt to disable the clock to OCMC RAM as part of the suspend process add the no_idle_on_suspend flag. Signed-off-by: Vaibhav Bedia Acked-by: Santosh Shilimkar Acked-by: Peter Korsgaard Signed-off-by: Paul Walmsley diff --git a/arch/arm/boot/dts/am33xx.dtsi b/arch/arm/boot/dts/am33xx.dtsi index c2f14e8..0957645 100644 --- a/arch/arm/boot/dts/am33xx.dtsi +++ b/arch/arm/boot/dts/am33xx.dtsi @@ -385,5 +385,19 @@ mac-address = [ 00 00 00 00 00 00 ]; }; }; + + ocmcram: ocmcram@40300000 { + compatible = "ti,am3352-ocmcram"; + reg = <0x40300000 0x10000>; + ti,hwmods = "ocmcram"; + ti,no_idle_on_suspend; + }; + + wkup_m3: wkup_m3@44d00000 { + compatible = "ti,am3353-wkup-m3"; + reg = <0x44d00000 0x4000 /* M3 UMEM */ + 0x44d80000 0x2000>; /* M3 DMEM */ + ti,hwmods = "wkup_m3"; + }; }; }; -- cgit v0.10.2 From bee76659e268ab9165e4dceee5b5410f3b22cd1c Mon Sep 17 00:00:00 2001 From: Philip Avinash Date: Wed, 2 Jan 2013 18:54:48 +0530 Subject: ARM: OMAP: AM33xx hwmod: Corrects PWM subsystem HWMOD entries EQEP IP block integration data is not present in HWMOD data. Also address ranges specified for EACP & EHRPWM are not correct & HWMOD flags of ADDR_TYPE_RT are added to PWM subsystem register address space. This patch: 1. Corrects register address mapping for ECAP & EHRPWM 2. Removes HWMOD flags in PWM submodule register address space. 3. Adds EQEP HWMOD entries. Signed-off-by: Philip Avinash [paul@pwsan.com: tweaked patch description] Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index 9e34d4c..4b1cc4d 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -784,7 +784,7 @@ static struct omap_hwmod am33xx_elm_hwmod = { }; /* - * 'epwmss' class: ecap0,1,2, ehrpwm0,1,2 + * 'epwmss' class: ehrpwm0,1,2 eqep0,1,2 ecap0,1,2 */ static struct omap_hwmod_class_sysconfig am33xx_epwmss_sysc = { .rev_offs = 0x0, @@ -864,6 +864,66 @@ static struct omap_hwmod am33xx_ehrpwm2_hwmod = { }, }; +/* eqep0 */ +static struct omap_hwmod_irq_info am33xx_eqep0_irqs[] = { + { .irq = 79 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod am33xx_eqep0_hwmod = { + .name = "eqep0", + .class = &am33xx_epwmss_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .mpu_irqs = am33xx_eqep0_irqs, + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM33XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* eqep1 */ +static struct omap_hwmod_irq_info am33xx_eqep1_irqs[] = { + { .irq = 88 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod am33xx_eqep1_hwmod = { + .name = "eqep1", + .class = &am33xx_epwmss_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .mpu_irqs = am33xx_eqep1_irqs, + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM33XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +/* eqep2 */ +static struct omap_hwmod_irq_info am33xx_eqep2_irqs[] = { + { .irq = 89 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod am33xx_eqep2_hwmod = { + .name = "eqep2", + .class = &am33xx_epwmss_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .mpu_irqs = am33xx_eqep2_irqs, + .main_clk = "l4ls_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + /* ecap0 */ static struct omap_hwmod_irq_info am33xx_ecap0_irqs[] = { { .irq = 31 + OMAP_INTC_START, }, @@ -2559,8 +2619,7 @@ static struct omap_hwmod_addr_space am33xx_ehrpwm0_addr_space[] = { }, { .pa_start = 0x48300200, - .pa_end = 0x48300200 + SZ_256 - 1, - .flags = ADDR_TYPE_RT + .pa_end = 0x48300200 + SZ_128 - 1, }, { } }; @@ -2585,8 +2644,7 @@ static struct omap_hwmod_addr_space am33xx_ehrpwm1_addr_space[] = { }, { .pa_start = 0x48302200, - .pa_end = 0x48302200 + SZ_256 - 1, - .flags = ADDR_TYPE_RT + .pa_end = 0x48302200 + SZ_128 - 1, }, { } }; @@ -2611,8 +2669,7 @@ static struct omap_hwmod_addr_space am33xx_ehrpwm2_addr_space[] = { }, { .pa_start = 0x48304200, - .pa_end = 0x48304200 + SZ_256 - 1, - .flags = ADDR_TYPE_RT + .pa_end = 0x48304200 + SZ_128 - 1, }, { } }; @@ -2629,6 +2686,81 @@ static struct omap_hwmod_ocp_if am33xx_l4_ls__ehrpwm2 = { * Splitting the resources to handle access of PWMSS config space * and module specific part independently */ +static struct omap_hwmod_addr_space am33xx_eqep0_addr_space[] = { + { + .pa_start = 0x48300000, + .pa_end = 0x48300000 + SZ_16 - 1, + .flags = ADDR_TYPE_RT + }, + { + .pa_start = 0x48300180, + .pa_end = 0x48300180 + SZ_128 - 1, + }, + { } +}; + +static struct omap_hwmod_ocp_if am33xx_l4_ls__eqep0 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_eqep0_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_eqep0_addr_space, + .user = OCP_USER_MPU, +}; + +/* + * Splitting the resources to handle access of PWMSS config space + * and module specific part independently + */ +static struct omap_hwmod_addr_space am33xx_eqep1_addr_space[] = { + { + .pa_start = 0x48302000, + .pa_end = 0x48302000 + SZ_16 - 1, + .flags = ADDR_TYPE_RT + }, + { + .pa_start = 0x48302180, + .pa_end = 0x48302180 + SZ_128 - 1, + }, + { } +}; + +static struct omap_hwmod_ocp_if am33xx_l4_ls__eqep1 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_eqep1_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_eqep1_addr_space, + .user = OCP_USER_MPU, +}; + +/* + * Splitting the resources to handle access of PWMSS config space + * and module specific part independently + */ +static struct omap_hwmod_addr_space am33xx_eqep2_addr_space[] = { + { + .pa_start = 0x48304000, + .pa_end = 0x48304000 + SZ_16 - 1, + .flags = ADDR_TYPE_RT + }, + { + .pa_start = 0x48304180, + .pa_end = 0x48304180 + SZ_128 - 1, + }, + { } +}; + +static struct omap_hwmod_ocp_if am33xx_l4_ls__eqep2 = { + .master = &am33xx_l4_ls_hwmod, + .slave = &am33xx_eqep2_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_eqep2_addr_space, + .user = OCP_USER_MPU, +}; + +/* + * Splitting the resources to handle access of PWMSS config space + * and module specific part independently + */ static struct omap_hwmod_addr_space am33xx_ecap0_addr_space[] = { { .pa_start = 0x48300000, @@ -2637,8 +2769,7 @@ static struct omap_hwmod_addr_space am33xx_ecap0_addr_space[] = { }, { .pa_start = 0x48300100, - .pa_end = 0x48300100 + SZ_256 - 1, - .flags = ADDR_TYPE_RT + .pa_end = 0x48300100 + SZ_128 - 1, }, { } }; @@ -2663,8 +2794,7 @@ static struct omap_hwmod_addr_space am33xx_ecap1_addr_space[] = { }, { .pa_start = 0x48302100, - .pa_end = 0x48302100 + SZ_256 - 1, - .flags = ADDR_TYPE_RT + .pa_end = 0x48302100 + SZ_128 - 1, }, { } }; @@ -2689,8 +2819,7 @@ static struct omap_hwmod_addr_space am33xx_ecap2_addr_space[] = { }, { .pa_start = 0x48304100, - .pa_end = 0x48304100 + SZ_256 - 1, - .flags = ADDR_TYPE_RT + .pa_end = 0x48304100 + SZ_128 - 1, }, { } }; @@ -3395,6 +3524,9 @@ static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = { &am33xx_l4_ls__ehrpwm0, &am33xx_l4_ls__ehrpwm1, &am33xx_l4_ls__ehrpwm2, + &am33xx_l4_ls__eqep0, + &am33xx_l4_ls__eqep1, + &am33xx_l4_ls__eqep2, &am33xx_l4_ls__ecap0, &am33xx_l4_ls__ecap1, &am33xx_l4_ls__ecap2, -- cgit v0.10.2 From 9652d19afc23b80509e23f1d7c3f37786e50e401 Mon Sep 17 00:00:00 2001 From: Philip Avinash Date: Wed, 2 Jan 2013 18:54:49 +0530 Subject: ARM: OMAP: AM33xx hwmod: Add parent-child relationship for PWM subsystem As part of PWM subsystem integration, PWM subsystem are sharing resources like clock across submodules (ECAP, EQEP & EHRPWM). To handle resource sharing & IP integration rework on parent child relation between PWMSS and ECAP, EQEP & EHRPWM child devices to support runtime PM. Signed-off-by: Philip Avinash Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index 4b1cc4d..8441538 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -783,9 +783,7 @@ static struct omap_hwmod am33xx_elm_hwmod = { }, }; -/* - * 'epwmss' class: ehrpwm0,1,2 eqep0,1,2 ecap0,1,2 - */ +/* pwmss */ static struct omap_hwmod_class_sysconfig am33xx_epwmss_sysc = { .rev_offs = 0x0, .sysc_offs = 0x4, @@ -801,67 +799,44 @@ static struct omap_hwmod_class am33xx_epwmss_hwmod_class = { .sysc = &am33xx_epwmss_sysc, }; -/* ehrpwm0 */ -static struct omap_hwmod_irq_info am33xx_ehrpwm0_irqs[] = { - { .name = "int", .irq = 86 + OMAP_INTC_START, }, - { .name = "tzint", .irq = 58 + OMAP_INTC_START, }, - { .irq = -1 }, +static struct omap_hwmod_class am33xx_ecap_hwmod_class = { + .name = "ecap", }; -static struct omap_hwmod am33xx_ehrpwm0_hwmod = { - .name = "ehrpwm0", - .class = &am33xx_epwmss_hwmod_class, - .clkdm_name = "l4ls_clkdm", - .mpu_irqs = am33xx_ehrpwm0_irqs, - .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, +static struct omap_hwmod_class am33xx_eqep_hwmod_class = { + .name = "eqep", }; -/* ehrpwm1 */ -static struct omap_hwmod_irq_info am33xx_ehrpwm1_irqs[] = { - { .name = "int", .irq = 87 + OMAP_INTC_START, }, - { .name = "tzint", .irq = 59 + OMAP_INTC_START, }, - { .irq = -1 }, +static struct omap_hwmod_class am33xx_ehrpwm_hwmod_class = { + .name = "ehrpwm", }; -static struct omap_hwmod am33xx_ehrpwm1_hwmod = { - .name = "ehrpwm1", +/* epwmss0 */ +static struct omap_hwmod am33xx_epwmss0_hwmod = { + .name = "epwmss0", .class = &am33xx_epwmss_hwmod_class, .clkdm_name = "l4ls_clkdm", - .mpu_irqs = am33xx_ehrpwm1_irqs, .main_clk = "l4ls_gclk", .prcm = { .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET, + .clkctrl_offs = AM33XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET, .modulemode = MODULEMODE_SWCTRL, }, }, }; -/* ehrpwm2 */ -static struct omap_hwmod_irq_info am33xx_ehrpwm2_irqs[] = { - { .name = "int", .irq = 39 + OMAP_INTC_START, }, - { .name = "tzint", .irq = 60 + OMAP_INTC_START, }, +/* ecap0 */ +static struct omap_hwmod_irq_info am33xx_ecap0_irqs[] = { + { .irq = 31 + OMAP_INTC_START, }, { .irq = -1 }, }; -static struct omap_hwmod am33xx_ehrpwm2_hwmod = { - .name = "ehrpwm2", - .class = &am33xx_epwmss_hwmod_class, +static struct omap_hwmod am33xx_ecap0_hwmod = { + .name = "ecap0", + .class = &am33xx_ecap_hwmod_class, .clkdm_name = "l4ls_clkdm", - .mpu_irqs = am33xx_ehrpwm2_irqs, + .mpu_irqs = am33xx_ecap0_irqs, .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, }; /* eqep0 */ @@ -872,29 +847,32 @@ static struct omap_hwmod_irq_info am33xx_eqep0_irqs[] = { static struct omap_hwmod am33xx_eqep0_hwmod = { .name = "eqep0", - .class = &am33xx_epwmss_hwmod_class, + .class = &am33xx_eqep_hwmod_class, .clkdm_name = "l4ls_clkdm", .mpu_irqs = am33xx_eqep0_irqs, .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, }; -/* eqep1 */ -static struct omap_hwmod_irq_info am33xx_eqep1_irqs[] = { - { .irq = 88 + OMAP_INTC_START, }, +/* ehrpwm0 */ +static struct omap_hwmod_irq_info am33xx_ehrpwm0_irqs[] = { + { .name = "int", .irq = 86 + OMAP_INTC_START, }, + { .name = "tzint", .irq = 58 + OMAP_INTC_START, }, { .irq = -1 }, }; -static struct omap_hwmod am33xx_eqep1_hwmod = { - .name = "eqep1", +static struct omap_hwmod am33xx_ehrpwm0_hwmod = { + .name = "ehrpwm0", + .class = &am33xx_ehrpwm_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .mpu_irqs = am33xx_ehrpwm0_irqs, + .main_clk = "l4ls_gclk", +}; + +/* epwmss1 */ +static struct omap_hwmod am33xx_epwmss1_hwmod = { + .name = "epwmss1", .class = &am33xx_epwmss_hwmod_class, .clkdm_name = "l4ls_clkdm", - .mpu_irqs = am33xx_eqep1_irqs, .main_clk = "l4ls_gclk", .prcm = { .omap4 = { @@ -904,61 +882,58 @@ static struct omap_hwmod am33xx_eqep1_hwmod = { }, }; -/* eqep2 */ -static struct omap_hwmod_irq_info am33xx_eqep2_irqs[] = { - { .irq = 89 + OMAP_INTC_START, }, +/* ecap1 */ +static struct omap_hwmod_irq_info am33xx_ecap1_irqs[] = { + { .irq = 47 + OMAP_INTC_START, }, { .irq = -1 }, }; -static struct omap_hwmod am33xx_eqep2_hwmod = { - .name = "eqep2", - .class = &am33xx_epwmss_hwmod_class, +static struct omap_hwmod am33xx_ecap1_hwmod = { + .name = "ecap1", + .class = &am33xx_ecap_hwmod_class, .clkdm_name = "l4ls_clkdm", - .mpu_irqs = am33xx_eqep2_irqs, + .mpu_irqs = am33xx_ecap1_irqs, .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, }; -/* ecap0 */ -static struct omap_hwmod_irq_info am33xx_ecap0_irqs[] = { - { .irq = 31 + OMAP_INTC_START, }, +/* eqep1 */ +static struct omap_hwmod_irq_info am33xx_eqep1_irqs[] = { + { .irq = 88 + OMAP_INTC_START, }, { .irq = -1 }, }; -static struct omap_hwmod am33xx_ecap0_hwmod = { - .name = "ecap0", - .class = &am33xx_epwmss_hwmod_class, +static struct omap_hwmod am33xx_eqep1_hwmod = { + .name = "eqep1", + .class = &am33xx_eqep_hwmod_class, .clkdm_name = "l4ls_clkdm", - .mpu_irqs = am33xx_ecap0_irqs, + .mpu_irqs = am33xx_eqep1_irqs, .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, }; -/* ecap1 */ -static struct omap_hwmod_irq_info am33xx_ecap1_irqs[] = { - { .irq = 47 + OMAP_INTC_START, }, +/* ehrpwm1 */ +static struct omap_hwmod_irq_info am33xx_ehrpwm1_irqs[] = { + { .name = "int", .irq = 87 + OMAP_INTC_START, }, + { .name = "tzint", .irq = 59 + OMAP_INTC_START, }, { .irq = -1 }, }; -static struct omap_hwmod am33xx_ecap1_hwmod = { - .name = "ecap1", +static struct omap_hwmod am33xx_ehrpwm1_hwmod = { + .name = "ehrpwm1", + .class = &am33xx_ehrpwm_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .mpu_irqs = am33xx_ehrpwm1_irqs, + .main_clk = "l4ls_gclk", +}; + +/* epwmss2 */ +static struct omap_hwmod am33xx_epwmss2_hwmod = { + .name = "epwmss2", .class = &am33xx_epwmss_hwmod_class, .clkdm_name = "l4ls_clkdm", - .mpu_irqs = am33xx_ecap1_irqs, .main_clk = "l4ls_gclk", .prcm = { .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET, + .clkctrl_offs = AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET, .modulemode = MODULEMODE_SWCTRL, }, }, @@ -972,16 +947,39 @@ static struct omap_hwmod_irq_info am33xx_ecap2_irqs[] = { static struct omap_hwmod am33xx_ecap2_hwmod = { .name = "ecap2", + .class = &am33xx_ecap_hwmod_class, + .clkdm_name = "l4ls_clkdm", .mpu_irqs = am33xx_ecap2_irqs, - .class = &am33xx_epwmss_hwmod_class, + .main_clk = "l4ls_gclk", +}; + +/* eqep2 */ +static struct omap_hwmod_irq_info am33xx_eqep2_irqs[] = { + { .irq = 89 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod am33xx_eqep2_hwmod = { + .name = "eqep2", + .class = &am33xx_eqep_hwmod_class, .clkdm_name = "l4ls_clkdm", + .mpu_irqs = am33xx_eqep2_irqs, + .main_clk = "l4ls_gclk", +}; + +/* ehrpwm2 */ +static struct omap_hwmod_irq_info am33xx_ehrpwm2_irqs[] = { + { .name = "int", .irq = 39 + OMAP_INTC_START, }, + { .name = "tzint", .irq = 60 + OMAP_INTC_START, }, + { .irq = -1 }, +}; + +static struct omap_hwmod am33xx_ehrpwm2_hwmod = { + .name = "ehrpwm2", + .class = &am33xx_ehrpwm_hwmod_class, + .clkdm_name = "l4ls_clkdm", + .mpu_irqs = am33xx_ehrpwm2_irqs, .main_clk = "l4ls_gclk", - .prcm = { - .omap4 = { - .clkctrl_offs = AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET, - .modulemode = MODULEMODE_SWCTRL, - }, - }, }; /* @@ -2607,116 +2605,106 @@ static struct omap_hwmod_ocp_if am33xx_l4_ls__elm = { .user = OCP_USER_MPU, }; -/* - * Splitting the resources to handle access of PWMSS config space - * and module specific part independently - */ -static struct omap_hwmod_addr_space am33xx_ehrpwm0_addr_space[] = { +static struct omap_hwmod_addr_space am33xx_epwmss0_addr_space[] = { { .pa_start = 0x48300000, .pa_end = 0x48300000 + SZ_16 - 1, .flags = ADDR_TYPE_RT }, - { - .pa_start = 0x48300200, - .pa_end = 0x48300200 + SZ_128 - 1, - }, { } }; -static struct omap_hwmod_ocp_if am33xx_l4_ls__ehrpwm0 = { +static struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss0 = { .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_ehrpwm0_hwmod, + .slave = &am33xx_epwmss0_hwmod, .clk = "l4ls_gclk", - .addr = am33xx_ehrpwm0_addr_space, + .addr = am33xx_epwmss0_addr_space, .user = OCP_USER_MPU, }; -/* - * Splitting the resources to handle access of PWMSS config space - * and module specific part independently - */ -static struct omap_hwmod_addr_space am33xx_ehrpwm1_addr_space[] = { - { - .pa_start = 0x48302000, - .pa_end = 0x48302000 + SZ_16 - 1, - .flags = ADDR_TYPE_RT - }, +static struct omap_hwmod_addr_space am33xx_ecap0_addr_space[] = { { - .pa_start = 0x48302200, - .pa_end = 0x48302200 + SZ_128 - 1, + .pa_start = 0x48300100, + .pa_end = 0x48300100 + SZ_128 - 1, }, { } }; -static struct omap_hwmod_ocp_if am33xx_l4_ls__ehrpwm1 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_ehrpwm1_hwmod, +static struct omap_hwmod_ocp_if am33xx_epwmss0__ecap0 = { + .master = &am33xx_epwmss0_hwmod, + .slave = &am33xx_ecap0_hwmod, .clk = "l4ls_gclk", - .addr = am33xx_ehrpwm1_addr_space, + .addr = am33xx_ecap0_addr_space, .user = OCP_USER_MPU, }; -/* - * Splitting the resources to handle access of PWMSS config space - * and module specific part independently - */ -static struct omap_hwmod_addr_space am33xx_ehrpwm2_addr_space[] = { +static struct omap_hwmod_addr_space am33xx_eqep0_addr_space[] = { { - .pa_start = 0x48304000, - .pa_end = 0x48304000 + SZ_16 - 1, - .flags = ADDR_TYPE_RT + .pa_start = 0x48300180, + .pa_end = 0x48300180 + SZ_128 - 1, }, + { } +}; + +static struct omap_hwmod_ocp_if am33xx_epwmss0__eqep0 = { + .master = &am33xx_epwmss0_hwmod, + .slave = &am33xx_eqep0_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_eqep0_addr_space, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space am33xx_ehrpwm0_addr_space[] = { { - .pa_start = 0x48304200, - .pa_end = 0x48304200 + SZ_128 - 1, + .pa_start = 0x48300200, + .pa_end = 0x48300200 + SZ_128 - 1, }, { } }; -static struct omap_hwmod_ocp_if am33xx_l4_ls__ehrpwm2 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_ehrpwm2_hwmod, +static struct omap_hwmod_ocp_if am33xx_epwmss0__ehrpwm0 = { + .master = &am33xx_epwmss0_hwmod, + .slave = &am33xx_ehrpwm0_hwmod, .clk = "l4ls_gclk", - .addr = am33xx_ehrpwm2_addr_space, + .addr = am33xx_ehrpwm0_addr_space, .user = OCP_USER_MPU, }; -/* - * Splitting the resources to handle access of PWMSS config space - * and module specific part independently - */ -static struct omap_hwmod_addr_space am33xx_eqep0_addr_space[] = { + +static struct omap_hwmod_addr_space am33xx_epwmss1_addr_space[] = { { - .pa_start = 0x48300000, - .pa_end = 0x48300000 + SZ_16 - 1, + .pa_start = 0x48302000, + .pa_end = 0x48302000 + SZ_16 - 1, .flags = ADDR_TYPE_RT }, - { - .pa_start = 0x48300180, - .pa_end = 0x48300180 + SZ_128 - 1, - }, { } }; -static struct omap_hwmod_ocp_if am33xx_l4_ls__eqep0 = { +static struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss1 = { .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_eqep0_hwmod, + .slave = &am33xx_epwmss1_hwmod, .clk = "l4ls_gclk", - .addr = am33xx_eqep0_addr_space, + .addr = am33xx_epwmss1_addr_space, .user = OCP_USER_MPU, }; -/* - * Splitting the resources to handle access of PWMSS config space - * and module specific part independently - */ -static struct omap_hwmod_addr_space am33xx_eqep1_addr_space[] = { +static struct omap_hwmod_addr_space am33xx_ecap1_addr_space[] = { { - .pa_start = 0x48302000, - .pa_end = 0x48302000 + SZ_16 - 1, - .flags = ADDR_TYPE_RT + .pa_start = 0x48302100, + .pa_end = 0x48302100 + SZ_128 - 1, }, + { } +}; + +static struct omap_hwmod_ocp_if am33xx_epwmss1__ecap1 = { + .master = &am33xx_epwmss1_hwmod, + .slave = &am33xx_ecap1_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_ecap1_addr_space, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space am33xx_eqep1_addr_space[] = { { .pa_start = 0x48302180, .pa_end = 0x48302180 + SZ_128 - 1, @@ -2724,111 +2712,92 @@ static struct omap_hwmod_addr_space am33xx_eqep1_addr_space[] = { { } }; -static struct omap_hwmod_ocp_if am33xx_l4_ls__eqep1 = { - .master = &am33xx_l4_ls_hwmod, +static struct omap_hwmod_ocp_if am33xx_epwmss1__eqep1 = { + .master = &am33xx_epwmss1_hwmod, .slave = &am33xx_eqep1_hwmod, .clk = "l4ls_gclk", .addr = am33xx_eqep1_addr_space, .user = OCP_USER_MPU, }; -/* - * Splitting the resources to handle access of PWMSS config space - * and module specific part independently - */ -static struct omap_hwmod_addr_space am33xx_eqep2_addr_space[] = { - { - .pa_start = 0x48304000, - .pa_end = 0x48304000 + SZ_16 - 1, - .flags = ADDR_TYPE_RT - }, +static struct omap_hwmod_addr_space am33xx_ehrpwm1_addr_space[] = { { - .pa_start = 0x48304180, - .pa_end = 0x48304180 + SZ_128 - 1, + .pa_start = 0x48302200, + .pa_end = 0x48302200 + SZ_128 - 1, }, { } }; -static struct omap_hwmod_ocp_if am33xx_l4_ls__eqep2 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_eqep2_hwmod, +static struct omap_hwmod_ocp_if am33xx_epwmss1__ehrpwm1 = { + .master = &am33xx_epwmss1_hwmod, + .slave = &am33xx_ehrpwm1_hwmod, .clk = "l4ls_gclk", - .addr = am33xx_eqep2_addr_space, + .addr = am33xx_ehrpwm1_addr_space, .user = OCP_USER_MPU, }; -/* - * Splitting the resources to handle access of PWMSS config space - * and module specific part independently - */ -static struct omap_hwmod_addr_space am33xx_ecap0_addr_space[] = { +static struct omap_hwmod_addr_space am33xx_epwmss2_addr_space[] = { { - .pa_start = 0x48300000, - .pa_end = 0x48300000 + SZ_16 - 1, + .pa_start = 0x48304000, + .pa_end = 0x48304000 + SZ_16 - 1, .flags = ADDR_TYPE_RT }, - { - .pa_start = 0x48300100, - .pa_end = 0x48300100 + SZ_128 - 1, - }, { } }; -static struct omap_hwmod_ocp_if am33xx_l4_ls__ecap0 = { +static struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss2 = { .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_ecap0_hwmod, + .slave = &am33xx_epwmss2_hwmod, .clk = "l4ls_gclk", - .addr = am33xx_ecap0_addr_space, + .addr = am33xx_epwmss2_addr_space, .user = OCP_USER_MPU, }; -/* - * Splitting the resources to handle access of PWMSS config space - * and module specific part independently - */ -static struct omap_hwmod_addr_space am33xx_ecap1_addr_space[] = { - { - .pa_start = 0x48302000, - .pa_end = 0x48302000 + SZ_16 - 1, - .flags = ADDR_TYPE_RT - }, +static struct omap_hwmod_addr_space am33xx_ecap2_addr_space[] = { { - .pa_start = 0x48302100, - .pa_end = 0x48302100 + SZ_128 - 1, + .pa_start = 0x48304100, + .pa_end = 0x48304100 + SZ_128 - 1, }, { } }; -static struct omap_hwmod_ocp_if am33xx_l4_ls__ecap1 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_ecap1_hwmod, +static struct omap_hwmod_ocp_if am33xx_epwmss2__ecap2 = { + .master = &am33xx_epwmss2_hwmod, + .slave = &am33xx_ecap2_hwmod, .clk = "l4ls_gclk", - .addr = am33xx_ecap1_addr_space, + .addr = am33xx_ecap2_addr_space, .user = OCP_USER_MPU, }; -/* - * Splitting the resources to handle access of PWMSS config space - * and module specific part independently - */ -static struct omap_hwmod_addr_space am33xx_ecap2_addr_space[] = { +static struct omap_hwmod_addr_space am33xx_eqep2_addr_space[] = { { - .pa_start = 0x48304000, - .pa_end = 0x48304000 + SZ_16 - 1, - .flags = ADDR_TYPE_RT + .pa_start = 0x48304180, + .pa_end = 0x48304180 + SZ_128 - 1, }, + { } +}; + +static struct omap_hwmod_ocp_if am33xx_epwmss2__eqep2 = { + .master = &am33xx_epwmss2_hwmod, + .slave = &am33xx_eqep2_hwmod, + .clk = "l4ls_gclk", + .addr = am33xx_eqep2_addr_space, + .user = OCP_USER_MPU, +}; + +static struct omap_hwmod_addr_space am33xx_ehrpwm2_addr_space[] = { { - .pa_start = 0x48304100, - .pa_end = 0x48304100 + SZ_128 - 1, + .pa_start = 0x48304200, + .pa_end = 0x48304200 + SZ_128 - 1, }, { } }; -static struct omap_hwmod_ocp_if am33xx_l4_ls__ecap2 = { - .master = &am33xx_l4_ls_hwmod, - .slave = &am33xx_ecap2_hwmod, +static struct omap_hwmod_ocp_if am33xx_epwmss2__ehrpwm2 = { + .master = &am33xx_epwmss2_hwmod, + .slave = &am33xx_ehrpwm2_hwmod, .clk = "l4ls_gclk", - .addr = am33xx_ecap2_addr_space, + .addr = am33xx_ehrpwm2_addr_space, .user = OCP_USER_MPU, }; @@ -3521,15 +3490,18 @@ static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = { &am33xx_l4_ls__uart6, &am33xx_l4_ls__spinlock, &am33xx_l4_ls__elm, - &am33xx_l4_ls__ehrpwm0, - &am33xx_l4_ls__ehrpwm1, - &am33xx_l4_ls__ehrpwm2, - &am33xx_l4_ls__eqep0, - &am33xx_l4_ls__eqep1, - &am33xx_l4_ls__eqep2, - &am33xx_l4_ls__ecap0, - &am33xx_l4_ls__ecap1, - &am33xx_l4_ls__ecap2, + &am33xx_l4_ls__epwmss0, + &am33xx_epwmss0__ecap0, + &am33xx_epwmss0__eqep0, + &am33xx_epwmss0__ehrpwm0, + &am33xx_l4_ls__epwmss1, + &am33xx_epwmss1__ecap1, + &am33xx_epwmss1__eqep1, + &am33xx_epwmss1__ehrpwm1, + &am33xx_l4_ls__epwmss2, + &am33xx_epwmss2__ecap2, + &am33xx_epwmss2__eqep2, + &am33xx_epwmss2__ehrpwm2, &am33xx_l3_s__gpmc, &am33xx_l3_main__lcdc, &am33xx_l4_ls__mcspi0, -- cgit v0.10.2 From 092bda62772dd0018bf48f2554f8f16348f16410 Mon Sep 17 00:00:00 2001 From: Hebbar Gururaja Date: Fri, 8 Feb 2013 08:21:10 -0700 Subject: ARM: OMAP2+: AM33xx: hwmod: add missing HWMOD_NO_IDLEST flags struct omap_hwmod records belonging to wkup m3 domain is missing HWMOD_NO_IDLEST flags; add them. This patch is a prerequisite for a subsequent patch, 'ARM: OMAP2: am33xx-hwmod: Fix "register offset NULL check" bug'. That patch would otherwise attempt to read from reserved bits. Signed-off-by: Hebbar Gururaja [paul@pwsan.com: add some more explanation in the patch description] Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c index 8441538..26eee4a 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_data.c @@ -262,7 +262,8 @@ static struct omap_hwmod am33xx_wkup_m3_hwmod = { .name = "wkup_m3", .class = &am33xx_wkup_m3_hwmod_class, .clkdm_name = "l4_wkup_aon_clkdm", - .flags = HWMOD_INIT_NO_RESET, /* Keep hardreset asserted */ + /* Keep hardreset asserted */ + .flags = HWMOD_INIT_NO_RESET | HWMOD_NO_IDLEST, .mpu_irqs = am33xx_wkup_m3_irqs, .main_clk = "dpll_core_m4_div2_ck", .prcm = { -- cgit v0.10.2 From 169c82a294e3722eb1e82b7dac58b35fe2119b80 Mon Sep 17 00:00:00 2001 From: Hebbar Gururaja Date: Fri, 8 Feb 2013 08:21:13 -0700 Subject: ARM: OMAP2: am33xx-hwmod: Fix "register offset NULL check" bug am33xx_cm_wait_module_ready() checks if register offset is NULL. int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, u16 clkctrl_offs) { int i = 0; if (!clkctrl_offs) return 0; In case of AM33xx, CLKCTRL register offset for different clock domains are not uniformly placed. An example of this would be the RTC clock domain with CLKCTRL offset at 0x00. In such cases the module ready check is skipped which leads to a data abort during boot-up when RTC registers is accessed. Remove this check here to avoid checking module readiness for modules with clkctrl register offset at 0x00. Koen Kooi notes that this patch fixes a crash on boot with CONFIG_RTC_DRV_OMAP=y with v3.8-rc5. Signed-off-by: Hebbar Gururaja Cc: Koen Kooi [paul@pwsan.com: noted Koen's test in the patch description] Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c index 058ce3c..325a515 100644 --- a/arch/arm/mach-omap2/cm33xx.c +++ b/arch/arm/mach-omap2/cm33xx.c @@ -241,9 +241,6 @@ int am33xx_cm_wait_module_ready(u16 inst, s16 cdoffs, u16 clkctrl_offs) { int i = 0; - if (!clkctrl_offs) - return 0; - omap_test_timeout(_is_module_ready(inst, cdoffs, clkctrl_offs), MAX_MODULE_READY_TIME, i); -- cgit v0.10.2 From cd19010c03cc9cce2366d5065720a3ab546833dd Mon Sep 17 00:00:00 2001 From: Santosh Shilimkar Date: Fri, 8 Feb 2013 20:41:44 +0530 Subject: ARM: OMAP2+: PM: Fix the dt return condition in pm_late_init() Commit 1416408d {ARM: OMAP2+: PM: share some suspend-related functions across OMAP2, 3, 4} moved suspend code to common place but now with that change, for DT build on OMAP4, suspend hooks are not getting registered which results in no suspend support. The DT return condition is limited to PMIC and smartreflex initialization and hence restrict it so that suspend ops gets registered. Cc: Paul Walmsley Cc: Kevin Hilman Signed-off-by: Santosh Shilimkar Reviewed-by: Felipe Balbi Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index f4b3143..1ec4299 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -345,19 +345,19 @@ int __init omap2_common_pm_late_init(void) * a completely different mechanism. * Disable this part if a DT blob is available. */ - if (of_have_populated_dt()) - return 0; + if (!of_have_populated_dt()) { - /* Init the voltage layer */ - omap_pmic_late_init(); - omap_voltage_late_init(); + /* Init the voltage layer */ + omap_pmic_late_init(); + omap_voltage_late_init(); - /* Initialize the voltages */ - omap3_init_voltages(); - omap4_init_voltages(); + /* Initialize the voltages */ + omap3_init_voltages(); + omap4_init_voltages(); - /* Smartreflex device init */ - omap_devinit_smartreflex(); + /* Smartreflex device init */ + omap_devinit_smartreflex(); + } #ifdef CONFIG_SUSPEND suspend_set_ops(&omap_pm_ops); -- cgit v0.10.2 From d0758237eeadde80ca36856345016bbc05b0e2b4 Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Fri, 8 Feb 2013 08:35:14 -0700 Subject: ARM: OMAP4: clock data: Add missing clkdm association for dpll_usb dpll_usb needs the clkdm association so the clkdm can be turned on before a relock. All other dplls for omap4 belong to the ALWON (always on) domain. The association was present as part of the older data file (clock44xx_data.c) but looks like got accidently dropped with the common clk convertion. More details of the patch which fixed this up in the older data file can be dound here.. http://www.spinics.net/lists/linux-omap/msg63076.html Adding the .clkdm_name as part of the clk_hw_omap struct also means a new .init needs to be part of the clk_ops for dpll_usb to initialise the clkdm. Signed-off-by: Rajendra Nayak Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/cclock44xx_data.c b/arch/arm/mach-omap2/cclock44xx_data.c index a2cc046..e71a19c 100644 --- a/arch/arm/mach-omap2/cclock44xx_data.c +++ b/arch/arm/mach-omap2/cclock44xx_data.c @@ -595,15 +595,26 @@ static const char *dpll_usb_ck_parents[] = { static struct clk dpll_usb_ck; +static const struct clk_ops dpll_usb_ck_ops = { + .enable = &omap3_noncore_dpll_enable, + .disable = &omap3_noncore_dpll_disable, + .recalc_rate = &omap3_dpll_recalc, + .round_rate = &omap2_dpll_round_rate, + .set_rate = &omap3_noncore_dpll_set_rate, + .get_parent = &omap2_init_dpll_parent, + .init = &omap2_init_clk_clkdm, +}; + static struct clk_hw_omap dpll_usb_ck_hw = { .hw = { .clk = &dpll_usb_ck, }, .dpll_data = &dpll_usb_dd, + .clkdm_name = "l3_init_clkdm", .ops = &clkhwops_omap3_dpll, }; -DEFINE_STRUCT_CLK(dpll_usb_ck, dpll_usb_ck_parents, dpll_ck_ops); +DEFINE_STRUCT_CLK(dpll_usb_ck, dpll_usb_ck_parents, dpll_usb_ck_ops); static const char *dpll_usb_clkdcoldo_ck_parents[] = { "dpll_usb_ck", -- cgit v0.10.2 From 6d266f63a11bce427504d203834df3c0bb9be9a5 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Sun, 10 Feb 2013 11:22:22 -0700 Subject: ARM: OMAP2+: hwmod: add enable_preprogram hook MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After setup/enable, some IP blocks need some additional setting to indicate the PRCM that they are inactive until they are configured. Some examples on OMAP4 include the AESS and FSUSB IP blocks. To fix this cleanly, this patch adds another optional function pointer, enable_preprogram, to the IP block's hwmod data. The function that is pointed to is called by the hwmod code immediately after the IP block is reset. This version of the patch includes a patch description fix from Felipe. Signed-off-by: Paul Walmsley Signed-off-by: Sebastien Guiriec Cc: Benoît Cousson Cc: Péter Ujfalusi Cc: Felipe Balbi diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 4653efb..f37d22c 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -2053,6 +2053,23 @@ static int _omap4_get_context_lost(struct omap_hwmod *oh) } /** + * _enable_preprogram - Pre-program an IP block during the _enable() process + * @oh: struct omap_hwmod * + * + * Some IP blocks (such as AESS) require some additional programming + * after enable before they can enter idle. If a function pointer to + * do so is present in the hwmod data, then call it and pass along the + * return value; otherwise, return 0. + */ +static int __init _enable_preprogram(struct omap_hwmod *oh) +{ + if (!oh->class->enable_preprogram) + return 0; + + return oh->class->enable_preprogram(oh); +} + +/** * _enable - enable an omap_hwmod * @oh: struct omap_hwmod * * @@ -2156,6 +2173,7 @@ static int _enable(struct omap_hwmod *oh) _update_sysc_cache(oh); _enable_sysc(oh); } + r = _enable_preprogram(oh); } else { if (soc_ops.disable_module) soc_ops.disable_module(oh); diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h index 3ae852a..41066b4 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h @@ -501,6 +501,7 @@ struct omap_hwmod_omap4_prcm { * @rev: revision of the IP class * @pre_shutdown: ptr to fn to be executed immediately prior to device shutdown * @reset: ptr to fn to be executed in place of the standard hwmod reset fn + * @enable_preprogram: ptr to fn to be executed during device enable * * Represent the class of a OMAP hardware "modules" (e.g. timer, * smartreflex, gpio, uart...) @@ -524,6 +525,7 @@ struct omap_hwmod_class { u32 rev; int (*pre_shutdown)(struct omap_hwmod *oh); int (*reset)(struct omap_hwmod *oh); + int (*enable_preprogram)(struct omap_hwmod *oh); }; /** -- cgit v0.10.2 From cf8ba17154b0977e9195b160aef6c934270a08c1 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Sun, 10 Feb 2013 11:22:23 -0700 Subject: ASoC: TI AESS: add autogating-enable function, callable from architecture code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a basic header file for the TI AESS IP block, located in the OMAP4 Audio Back-End subsystem. Currently, this header file only contains a function to enable the AESS internal clock auto-gating. This will be used by a subsequent patch to ensure that the AESS won't block the entire chip low-power-idle mode. We wish to be able to place the AESS into idle even when no AESS driver has been compiled in. Signed-off-by: Paul Walmsley Cc: Liam Girdwood Cc: Mark Brown Cc: Péter Ujfalusi Cc: Tony Lindgren Acked-by: Mark Brown diff --git a/include/sound/aess.h b/include/sound/aess.h new file mode 100644 index 0000000..cee0d09 --- /dev/null +++ b/include/sound/aess.h @@ -0,0 +1,53 @@ +/* + * AESS IP block reset + * + * Copyright (C) 2012 Texas Instruments, Inc. + * Paul Walmsley + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#ifndef __SOUND_AESS_H__ +#define __SOUND_AESS_H__ + +#include +#include + +/* + * AESS_AUTO_GATING_ENABLE_OFFSET: offset in bytes of the AESS IP + * block's AESS_AUTO_GATING_ENABLE__1 register from the IP block's + * base address + */ +#define AESS_AUTO_GATING_ENABLE_OFFSET 0x07c + +/* Register bitfields in the AESS_AUTO_GATING_ENABLE__1 register */ +#define AESS_AUTO_GATING_ENABLE_SHIFT 0 + +/** + * aess_enable_autogating - enable AESS internal autogating + * @oh: struct omap_hwmod * + * + * Enable internal autogating on the AESS. This allows the AESS to + * indicate that it is idle to the OMAP PRCM. Returns 0. + */ +static inline void aess_enable_autogating(void __iomem *base) +{ + u32 v; + + /* Set AESS_AUTO_GATING_ENABLE__1.ENABLE to allow idle entry */ + v = 1 << AESS_AUTO_GATING_ENABLE_SHIFT; + writel(v, base + AESS_AUTO_GATING_ENABLE_OFFSET); +} + +#endif /* __SOUND_AESS_H__ */ -- cgit v0.10.2 From c02060d869247215c2ea15fd650c333d30f5b210 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Sun, 10 Feb 2013 11:22:23 -0700 Subject: ARM: OMAP4+: AESS: enable internal auto-gating during initial setup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Enable the AESS auto-gating control bit during AESS hwmod setup. This fixes the following boot warning on OMAP4: omap_hwmod: aess: _wait_target_disable failed Without this patch, the AESS IP block does not indicate to the PRCM that it is idle after it is reset. This prevents some types of SoC power management until something sets the auto-gating control bit. Signed-off-by: Paul Walmsley Signed-off-by: Sebastien Guiriec Cc: Benoît Cousson Cc: Péter Ujfalusi Cc: Tony Lindgren diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 947cafe..d88788f 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -8,7 +8,7 @@ obj-y := id.o io.o control.o mux.o devices.o fb.o serial.o gpmc.o timer.o pm.o \ omap_device.o sram.o omap-2-3-common = irq.o -hwmod-common = omap_hwmod.o \ +hwmod-common = omap_hwmod.o omap_hwmod_reset.o \ omap_hwmod_common_data.o clock-common = clock.o clock_common_data.o \ clkt_dpll.o clkt_clksel.o diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h index 41066b4..6ec73cb 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h @@ -673,6 +673,12 @@ extern void __init omap_hwmod_init(void); const char *omap_hwmod_get_main_clk(struct omap_hwmod *oh); /* + * + */ + +extern int omap_hwmod_aess_preprogram(struct omap_hwmod *oh); + +/* * Chip variant-specific hwmod init routines - XXX should be converted * to use initcalls once the initial boot ordering is straightened out */ diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 793f54a..c9c251e 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -322,6 +322,7 @@ static struct omap_hwmod_class_sysconfig omap44xx_aess_sysc = { static struct omap_hwmod_class omap44xx_aess_hwmod_class = { .name = "aess", .sysc = &omap44xx_aess_sysc, + .enable_preprogram = omap_hwmod_aess_preprogram, }; /* aess */ diff --git a/arch/arm/mach-omap2/omap_hwmod_reset.c b/arch/arm/mach-omap2/omap_hwmod_reset.c new file mode 100644 index 0000000..bba43fa --- /dev/null +++ b/arch/arm/mach-omap2/omap_hwmod_reset.c @@ -0,0 +1,52 @@ +/* + * OMAP IP block custom reset and preprogramming stubs + * + * Copyright (C) 2012 Texas Instruments, Inc. + * Paul Walmsley + * + * A small number of IP blocks need custom reset and preprogramming + * functions. The stubs in this file provide a standard way for the + * hwmod code to call these functions, which are to be located under + * drivers/. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation version 2. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA + */ +#include + +#include + +#include "omap_hwmod.h" + +/** + * omap_hwmod_aess_preprogram - enable AESS internal autogating + * @oh: struct omap_hwmod * + * + * The AESS will not IdleAck to the PRCM until its internal autogating + * is enabled. Since internal autogating is disabled by default after + * AESS reset, we must enable autogating after the hwmod code resets + * the AESS. Returns 0. + */ +int omap_hwmod_aess_preprogram(struct omap_hwmod *oh) +{ + void __iomem *va; + + va = omap_hwmod_get_mpu_rt_va(oh); + if (!va) + return -EINVAL; + + aess_enable_autogating(va); + + return 0; +} -- cgit v0.10.2 From 9f0c5996b73b31b482136462c8118148469c2030 Mon Sep 17 00:00:00 2001 From: Sebastien Guiriec Date: Sun, 10 Feb 2013 11:22:24 -0700 Subject: ARM: OMAP4: hwmod data: Update AESS data with memory bank area Add AESS memory bank data in hwmod in order to provide memory address information to the driver. This version also changes the AESS main clock to use a non-CLKCTRL-based functional clock. These are being removed from the clock data, since they should be handled by the IP block integration code. Without this change, the kernel crashes during boot. Thanks to Tony Lindgren for reporting this during a test merge. Signed-off-by: Sebastien Guiriec [paul@pwsan.com: updated to change the AESS main_clk] Cc: Tony Lindgren Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index c9c251e..a30c113 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -349,7 +349,7 @@ static struct omap_hwmod omap44xx_aess_hwmod = { .clkdm_name = "abe_clkdm", .mpu_irqs = omap44xx_aess_irqs, .sdma_reqs = omap44xx_aess_sdma_reqs, - .main_clk = "aess_fck", + .main_clk = "aess_fclk", .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM1_ABE_AESS_CLKCTRL_OFFSET, @@ -4250,6 +4250,27 @@ static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ocp_wp_noc = { static struct omap_hwmod_addr_space omap44xx_aess_addrs[] = { { + .name = "dmem", + .pa_start = 0x40180000, + .pa_end = 0x4018ffff + }, + { + .name = "cmem", + .pa_start = 0x401a0000, + .pa_end = 0x401a1fff + }, + { + .name = "smem", + .pa_start = 0x401c0000, + .pa_end = 0x401c5fff + }, + { + .name = "pmem", + .pa_start = 0x401e0000, + .pa_end = 0x401e1fff + }, + { + .name = "mpu", .pa_start = 0x401f1000, .pa_end = 0x401f13ff, .flags = ADDR_TYPE_RT @@ -4268,6 +4289,27 @@ static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l4_abe__aess = { static struct omap_hwmod_addr_space omap44xx_aess_dma_addrs[] = { { + .name = "dmem_dma", + .pa_start = 0x49080000, + .pa_end = 0x4908ffff + }, + { + .name = "cmem_dma", + .pa_start = 0x490a0000, + .pa_end = 0x490a1fff + }, + { + .name = "smem_dma", + .pa_start = 0x490c0000, + .pa_end = 0x490c5fff + }, + { + .name = "pmem_dma", + .pa_start = 0x490e0000, + .pa_end = 0x490e1fff + }, + { + .name = "dma", .pa_start = 0x490f1000, .pa_end = 0x490f13ff, .flags = ADDR_TYPE_RT -- cgit v0.10.2 From 5cebb23c6cbcfcae1d0586d07898677716f133bc Mon Sep 17 00:00:00 2001 From: Sebastien Guiriec Date: Sun, 10 Feb 2013 11:17:16 -0700 Subject: ARM: OMAP4: hwmod data: Enable AESS hwmod device Enable AESS data in hwmod in order to be able to probe audio driver. Signed-off-by: Sebastien Guiriec Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index a30c113..f908494 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -6325,7 +6325,7 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_l3_main_1__l3_main_3, &omap44xx_l3_main_2__l3_main_3, &omap44xx_l4_cfg__l3_main_3, - /* &omap44xx_aess__l4_abe, */ + &omap44xx_aess__l4_abe, &omap44xx_dsp__l4_abe, &omap44xx_l3_main_1__l4_abe, &omap44xx_mpu__l4_abe, @@ -6334,8 +6334,8 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_l4_cfg__l4_wkup, &omap44xx_mpu__mpu_private, &omap44xx_l4_cfg__ocp_wp_noc, - /* &omap44xx_l4_abe__aess, */ - /* &omap44xx_l4_abe__aess_dma, */ + &omap44xx_l4_abe__aess, + &omap44xx_l4_abe__aess_dma, &omap44xx_l3_main_2__c2c, &omap44xx_l4_wkup__counter_32k, &omap44xx_l4_cfg__ctrl_module_core, -- cgit v0.10.2 From 6efc3fe0f4058d6764e5c58c7377037f9da24d22 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Tue, 12 Feb 2013 03:58:35 +0000 Subject: ARM: OMAP2+: fix some omap_device_build() calls that aren't compiled by default Commit c1d1cd597fc77af3086470f8627d77f52f7f8b6c ("ARM: OMAP2+: omap_device: remove obsolete pm_lats and early_device code") missed a few omap_device_build() calls that aren't included as part of the default OMAP2+ Kconfig, omap2plus_defconfig. Ideally, all devices that are present on the SoC should be created by default, and only the corresponding device driver should be configured or deconfigured in Kconfig. This allows drivers to be built as modules and loaded later, even if they weren't part of the original kernel build. Unfortunately, we're not quite there yet. Thanks to Tony Lindgren for reporting this, found during his randconfig tests. Signed-off-by: Paul Walmsley Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/am35xx-emac.c b/arch/arm/mach-omap2/am35xx-emac.c index a00d391..25b79a2 100644 --- a/arch/arm/mach-omap2/am35xx-emac.c +++ b/arch/arm/mach-omap2/am35xx-emac.c @@ -62,8 +62,7 @@ static int __init omap_davinci_emac_dev_init(struct omap_hwmod *oh, { struct platform_device *pdev; - pdev = omap_device_build(oh->class->name, 0, oh, pdata, pdata_len, - false); + pdev = omap_device_build(oh->class->name, 0, oh, pdata, pdata_len); if (IS_ERR(pdev)) { WARN(1, "Can't build omap_device for %s:%s.\n", oh->class->name, oh->name); diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index d8a0cc3..6ecc89a 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -382,7 +382,7 @@ static void __init omap_init_hdmi_audio(void) return; } - pdev = omap_device_build("omap-hdmi-audio-dai", -1, oh, NULL, 0, 0); + pdev = omap_device_build("omap-hdmi-audio-dai", -1, oh, NULL, 0); WARN(IS_ERR(pdev), "Can't build omap_device for omap-hdmi-audio-dai.\n"); diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c index bb829e0..d7bc33f 100644 --- a/arch/arm/mach-omap2/sr_device.c +++ b/arch/arm/mach-omap2/sr_device.c @@ -152,7 +152,7 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user) sr_data->enable_on_init = sr_enable_on_init; - pdev = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data), 0); + pdev = omap_device_build(name, i, oh, sr_data, sizeof(*sr_data)); if (IS_ERR(pdev)) pr_warning("%s: Could not build omap_device for %s: %s.\n\n", __func__, name, oh->name); -- cgit v0.10.2 From 55ccb1a8b4c14c086427fd6b7272448fbd0c4449 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Thu, 14 Feb 2013 17:47:35 +0100 Subject: ARM: omap2: include linux/errno.h in hwmod_reset The newly created omap_hwmod_reset.c is missing an include of linux/errno.h in commit c02060d8 "ARM: OMAP4+: AESS: enable internal auto-gating during initial setup". It still works in omap2_defconfig, but not in all other combinations. Without this patch, building allmodconfig results in: arch/arm/mach-omap2/omap_hwmod_reset.c: In function 'omap_hwmod_aess_preprogram': arch/arm/mach-omap2/omap_hwmod_reset.c:47:11: error: 'EINVAL' undeclared (first use in this function) arch/arm/mach-omap2/omap_hwmod_reset.c:47:11: note: each undeclared identifier is reported only once for each function it appears in Signed-off-by: Arnd Bergmann Acked-by: Tony Lindgren Cc: Paul Walmsley Cc: Sebastien Guiriec diff --git a/arch/arm/mach-omap2/omap_hwmod_reset.c b/arch/arm/mach-omap2/omap_hwmod_reset.c index bba43fa..65e186c 100644 --- a/arch/arm/mach-omap2/omap_hwmod_reset.c +++ b/arch/arm/mach-omap2/omap_hwmod_reset.c @@ -24,6 +24,7 @@ * 02110-1301 USA */ #include +#include #include -- cgit v0.10.2