From 33939403112791866da6b64875385fa1b7d9865a Mon Sep 17 00:00:00 2001 From: Doug Anderson Date: Wed, 20 May 2015 13:34:08 -0700 Subject: ARM: rockchip: restore dapswjdp after suspend In the commit (0ea001d ARM: rockchip: disable dapswjdp during suspend) we made the assumption that we didn't need to restore dapswjdp after suspend because "the MASKROM will enable it back". It turns out that's not a safe assumption. In some cases (pending interrupts) it's possible that the WFI might act as a no-op and the MaskROM will never run. Since we're changing the bit, we should restore it ourselves. Signed-off-by: Doug Anderson Reviewed-by: Chris Zhong Signed-off-by: Heiko Stuebner diff --git a/arch/arm/mach-rockchip/pm.c b/arch/arm/mach-rockchip/pm.c index b0dcbe2..a7be465 100644 --- a/arch/arm/mach-rockchip/pm.c +++ b/arch/arm/mach-rockchip/pm.c @@ -48,6 +48,7 @@ static struct regmap *sgrf_regmap; static u32 rk3288_pmu_pwr_mode_con; static u32 rk3288_sgrf_soc_con0; +static u32 rk3288_sgrf_cpu_con0; static inline u32 rk3288_l2_config(void) { @@ -70,6 +71,7 @@ static void rk3288_slp_mode_set(int level) { u32 mode_set, mode_set1; + regmap_read(sgrf_regmap, RK3288_SGRF_CPU_CON0, &rk3288_sgrf_cpu_con0); regmap_read(sgrf_regmap, RK3288_SGRF_SOC_CON0, &rk3288_sgrf_soc_con0); regmap_read(pmu_regmap, RK3288_PMU_PWRMODE_CON, @@ -129,6 +131,9 @@ static void rk3288_slp_mode_set(int level) static void rk3288_slp_mode_set_resume(void) { + regmap_write(sgrf_regmap, RK3288_SGRF_CPU_CON0, + rk3288_sgrf_cpu_con0 | SGRF_DAPDEVICEEN_WRITE); + regmap_write(pmu_regmap, RK3288_PMU_PWRMODE_CON, rk3288_pmu_pwr_mode_con); -- cgit v0.10.2 From fe4407c0dc58215a7abfb7532740d79ddabe7a7a Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Tue, 9 Jun 2015 17:49:57 +0800 Subject: ARM: rockchip: fix the CPU soft reset We need different orderings when turning a core on and turning a core off. In one case we need to assert reset before turning power off. In ther other case we need to turn power on and the deassert reset. In general, the correct flow is: CPU off: reset_control_assert regmap_update_bits(pmu, PMU_PWRDN_CON, BIT(pd), BIT(pd)) wait_for_power_domain_to_turn_off CPU on: regmap_update_bits(pmu, PMU_PWRDN_CON, BIT(pd), 0) wait_for_power_domain_to_turn_on reset_control_deassert This is needed for stressing CPU up/down, as per: cd /sys/devices/system/cpu/ for i in $(seq 10000); do echo "================= $i ============" for j in $(seq 100); do while [[ "$(cat cpu1/online)$(cat cpu2/online)$(cat cpu3/online)" != "000"" ]] echo 0 > cpu1/online echo 0 > cpu2/online echo 0 > cpu3/online done while [[ "$(cat cpu1/online)$(cat cpu2/online)$(cat cpu3/online)" != "111" ]]; do echo 1 > cpu1/online echo 1 > cpu2/online echo 1 > cpu3/online done done done The following is reproducable log: [34466.186812] PM: noirq suspend of devices complete after 0.669 msecs [34466.186824] Disabling non-boot CPUs ... [34466.187509] CPU1: shutdown [34466.188672] CPU2: shutdown [34473.736627] Kernel panic - not syncing:Watchdog detected hard LOCKUP on cpu 0 ....... or others similar log: ....... [ 4072.454453] CPU1: shutdown [ 4072.504436] CPU2: shutdown [ 4072.554426] CPU3: shutdown [ 4072.577827] CPU1: Booted secondary processor [ 4072.582611] CPU2: Booted secondary processor Tested by cpu up/down scripts, the results told us need delay more time before write the sram. The wait time is affected by many aspects (e.g: cpu frequency, bootrom frequency, sram frequency, bus speed, ...). Although the cpus other than cpu0 will write the sram, the speedy is no the same as cpu0, if the cpu0 early wake up, perhaps the other cpus can't startup. As we know, the cpu0 can wake up when the cpu1/2/3 write the 'sram+4/8' and send the sev. Anyway..... At the moment, 1ms delay will be happy work for cpu up/down scripts test. Signed-off-by: Caesar Wang Reviewed-by: Doug Anderson Reviewed-by: Kever Yang Fixes: 3ee851e212d0 ("ARM: rockchip: add basic smp support for rk3288") Cc: stable@vger.kernel.org Signed-off-by: Heiko Stuebner diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c index 8fcec1c..d1a5fec 100644 --- a/arch/arm/mach-rockchip/platsmp.c +++ b/arch/arm/mach-rockchip/platsmp.c @@ -72,29 +72,22 @@ static struct reset_control *rockchip_get_core_reset(int cpu) static int pmu_set_power_domain(int pd, bool on) { u32 val = (on) ? 0 : BIT(pd); + struct reset_control *rstc = rockchip_get_core_reset(pd); int ret; + if (IS_ERR(rstc) && read_cpuid_part() != ARM_CPU_PART_CORTEX_A9) { + pr_err("%s: could not get reset control for core %d\n", + __func__, pd); + return PTR_ERR(rstc); + } + /* * We need to soft reset the cpu when we turn off the cpu power domain, * or else the active processors might be stalled when the individual * processor is powered down. */ - if (read_cpuid_part() != ARM_CPU_PART_CORTEX_A9) { - struct reset_control *rstc = rockchip_get_core_reset(pd); - - if (IS_ERR(rstc)) { - pr_err("%s: could not get reset control for core %d\n", - __func__, pd); - return PTR_ERR(rstc); - } - - if (on) - reset_control_deassert(rstc); - else - reset_control_assert(rstc); - - reset_control_put(rstc); - } + if (!IS_ERR(rstc) && !on) + reset_control_assert(rstc); ret = regmap_update_bits(pmu, PMU_PWRDN_CON, BIT(pd), val); if (ret < 0) { @@ -112,6 +105,12 @@ static int pmu_set_power_domain(int pd, bool on) } } + if (!IS_ERR(rstc)) { + if (on) + reset_control_deassert(rstc); + reset_control_put(rstc); + } + return 0; } @@ -146,9 +145,14 @@ static int rockchip_boot_secondary(unsigned int cpu, struct task_struct *idle) * the mailbox: * sram_base_addr + 4: 0xdeadbeaf * sram_base_addr + 8: start address for pc + * The cpu0 need to wait the other cpus other than cpu0 entering + * the wfe state.The wait time is affected by many aspects. + * (e.g: cpu frequency, bootrom frequency, sram frequency, ...) * */ - udelay(10); - writel(virt_to_phys(secondary_startup), sram_base_addr + 8); + mdelay(1); /* ensure the cpus other than cpu0 to startup */ + + writel(virt_to_phys(rockchip_secondary_startup), + sram_base_addr + 8); writel(0xDEADBEAF, sram_base_addr + 4); dsb_sev(); } -- cgit v0.10.2 From e306bc16c53199e7440e1fee69dd91dc0a56edee Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Tue, 9 Jun 2015 17:49:58 +0800 Subject: ARM: rockchip: ensure CPU to enter WFI/WFE state The patch can ensure that v7_exit_coherency_flush() in rockchip_cpu_die() executed in time. The mdelay(1) has enough time to fix the problem of CPU offlining. That's a workaround way in rockchip hotplug code, At least, we haven't a better way to solve it. Who know, that maybe fixed by chip (hardware) in the future. Signed-off-by: Caesar Wang Reviewed-by: Douglas Anderson Reviewed-by: Kever Yang Signed-off-by: Heiko Stuebner diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c index d1a5fec..4187ac2 100644 --- a/arch/arm/mach-rockchip/platsmp.c +++ b/arch/arm/mach-rockchip/platsmp.c @@ -321,6 +321,13 @@ static void __init rockchip_smp_prepare_cpus(unsigned int max_cpus) #ifdef CONFIG_HOTPLUG_CPU static int rockchip_cpu_kill(unsigned int cpu) { + /* + * We need a delay here to ensure that the dying CPU can finish + * executing v7_coherency_exit() and reach the WFI/WFE state + * prior to having the power domain disabled. + */ + mdelay(1); + pmu_set_power_domain(0 + cpu, false); return 1; } -- cgit v0.10.2 From 7f0b61ad34f04b076a3d1e2b5cfc6e1fae853ec4 Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Tue, 9 Jun 2015 17:49:59 +0800 Subject: ARM: rockchip: fix the SMP code style Use the below scripts to check: scripts/checkpatch.pl -f --subject arch/arm/mach-rockchip/platsmp.c Signed-off-by: Caesar Wang Reviewed-by: Douglas Anderson Reviewed-by: Kever Yang Signed-off-by: Heiko Stuebner diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c index 4187ac2..7ebd1c1 100644 --- a/arch/arm/mach-rockchip/platsmp.c +++ b/arch/arm/mach-rockchip/platsmp.c @@ -100,7 +100,7 @@ static int pmu_set_power_domain(int pd, bool on) ret = pmu_power_domain_is_on(pd); if (ret < 0) { pr_err("%s: could not read power domain state\n", - __func__); + __func__); return ret; } } @@ -129,7 +129,7 @@ static int rockchip_boot_secondary(unsigned int cpu, struct task_struct *idle) if (cpu >= ncores) { pr_err("%s: cpu %d outside maximum number of cpus %d\n", - __func__, cpu, ncores); + __func__, cpu, ncores); return -ENXIO; } @@ -139,7 +139,8 @@ static int rockchip_boot_secondary(unsigned int cpu, struct task_struct *idle) return ret; if (read_cpuid_part() != ARM_CPU_PART_CORTEX_A9) { - /* We communicate with the bootrom to active the cpus other + /* + * We communicate with the bootrom to active the cpus other * than cpu0, after a blob of initialize code, they will * stay at wfe state, once they are actived, they will check * the mailbox: @@ -148,11 +149,11 @@ static int rockchip_boot_secondary(unsigned int cpu, struct task_struct *idle) * The cpu0 need to wait the other cpus other than cpu0 entering * the wfe state.The wait time is affected by many aspects. * (e.g: cpu frequency, bootrom frequency, sram frequency, ...) - * */ + */ mdelay(1); /* ensure the cpus other than cpu0 to startup */ writel(virt_to_phys(rockchip_secondary_startup), - sram_base_addr + 8); + sram_base_addr + 8); writel(0xDEADBEAF, sram_base_addr + 4); dsb_sev(); } @@ -335,7 +336,7 @@ static int rockchip_cpu_kill(unsigned int cpu) static void rockchip_cpu_die(unsigned int cpu) { v7_exit_coherency_flush(louis); - while(1) + while (1) cpu_do_idle(); } #endif @@ -348,4 +349,5 @@ static struct smp_operations rockchip_smp_ops __initdata = { .cpu_die = rockchip_cpu_die, #endif }; + CPU_METHOD_OF_DECLARE(rk3066_smp, "rockchip,rk3066-smp", &rockchip_smp_ops); -- cgit v0.10.2 From 134f1f609bdf2f67ae23b7b1b686a3b9d5c67b03 Mon Sep 17 00:00:00 2001 From: Chris Zhong Date: Tue, 23 Jun 2015 20:53:39 +0800 Subject: ARM: rockchip: add support holding 24Mhz osc during suspend If we want to wake up system via usb, the 24Mhz osc could not be disabled during suspend, read the usb phy SIDDQ bit to decide whether to switch to 32khz clock-in. Signed-off-by: Chris Zhong Reviewed-by: Douglas Anderson Tested-by: Douglas Anderson Signed-off-by: Heiko Stuebner diff --git a/arch/arm/mach-rockchip/pm.c b/arch/arm/mach-rockchip/pm.c index a7be465..892bace 100644 --- a/arch/arm/mach-rockchip/pm.c +++ b/arch/arm/mach-rockchip/pm.c @@ -45,6 +45,7 @@ static phys_addr_t rk3288_bootram_phy; static struct regmap *pmu_regmap; static struct regmap *sgrf_regmap; +static struct regmap *grf_regmap; static u32 rk3288_pmu_pwr_mode_con; static u32 rk3288_sgrf_soc_con0; @@ -67,9 +68,35 @@ static void rk3288_config_bootdata(void) rkpm_bootdata_l2ctlr = rk3288_l2_config(); } +#define GRF_UOC0_CON0 0x320 +#define GRF_UOC1_CON0 0x334 +#define GRF_UOC2_CON0 0x348 +#define GRF_SIDDQ BIT(13) + +static bool rk3288_slp_disable_osc(void) +{ + static const u32 reg_offset[] = { GRF_UOC0_CON0, GRF_UOC1_CON0, + GRF_UOC2_CON0 }; + u32 reg, i; + + /* + * if any usb phy is still on(GRF_SIDDQ==0), that means we need the + * function of usb wakeup, so do not switch to 32khz, since the usb phy + * clk does not connect to 32khz osc + */ + for (i = 0; i < ARRAY_SIZE(reg_offset); i++) { + regmap_read(grf_regmap, reg_offset[i], ®); + if (!(reg & GRF_SIDDQ)) + return false; + } + + return true; +} + static void rk3288_slp_mode_set(int level) { u32 mode_set, mode_set1; + bool osc_switch_to_32k = rk3288_slp_disable_osc(); regmap_read(sgrf_regmap, RK3288_SGRF_CPU_CON0, &rk3288_sgrf_cpu_con0); regmap_read(sgrf_regmap, RK3288_SGRF_SOC_CON0, &rk3288_sgrf_soc_con0); @@ -109,11 +136,13 @@ static void rk3288_slp_mode_set(int level) if (level == ROCKCHIP_ARM_OFF_LOGIC_DEEP) { /* arm off, logic deep sleep */ - mode_set |= BIT(PMU_BUS_PD_EN) | + mode_set |= BIT(PMU_BUS_PD_EN) | BIT(PMU_PMU_USE_LF) | BIT(PMU_DDR1IO_RET_EN) | BIT(PMU_DDR0IO_RET_EN) | - BIT(PMU_OSC_24M_DIS) | BIT(PMU_PMU_USE_LF) | BIT(PMU_ALIVE_USE_LF) | BIT(PMU_PLL_PD_EN); + if (osc_switch_to_32k) + mode_set |= BIT(PMU_OSC_24M_DIS); + mode_set1 |= BIT(PMU_CLR_ALIVE) | BIT(PMU_CLR_BUS) | BIT(PMU_CLR_PERI) | BIT(PMU_CLR_DMA); } else { @@ -198,6 +227,13 @@ static int rk3288_suspend_init(struct device_node *np) return PTR_ERR(pmu_regmap); } + grf_regmap = syscon_regmap_lookup_by_compatible( + "rockchip,rk3288-grf"); + if (IS_ERR(grf_regmap)) { + pr_err("%s: could not find grf regmap\n", __func__); + return PTR_ERR(pmu_regmap); + } + sram_np = of_find_compatible_node(NULL, NULL, "rockchip,rk3288-pmu-sram"); if (!sram_np) { -- cgit v0.10.2 From e6ef15e4f6ca9cc760030f8f0616e25eed9449e4 Mon Sep 17 00:00:00 2001 From: Chris Zhong Date: Tue, 23 Jun 2015 20:53:40 +0800 Subject: ARM: rockchip: remove some useless macro in pm.h These are actually not used in the pm code, as we moved suspend handling to the clock driver, remove them here. Signed-off-by: Chris Zhong Reviewed-by: Douglas Anderson Signed-off-by: Heiko Stuebner diff --git a/arch/arm/mach-rockchip/pm.h b/arch/arm/mach-rockchip/pm.h index 3e8d39c..b6494c2 100644 --- a/arch/arm/mach-rockchip/pm.h +++ b/arch/arm/mach-rockchip/pm.h @@ -59,13 +59,6 @@ static inline void rockchip_suspend_init(void) #define SGRF_DAPDEVICEEN BIT(0) #define SGRF_DAPDEVICEEN_WRITE BIT(16) -#define RK3288_CRU_MODE_CON 0x50 -#define RK3288_CRU_SEL0_CON 0x60 -#define RK3288_CRU_SEL1_CON 0x64 -#define RK3288_CRU_SEL10_CON 0x88 -#define RK3288_CRU_SEL33_CON 0xe4 -#define RK3288_CRU_SEL37_CON 0xf4 - /* PMU_WAKEUP_CFG1 bits */ #define PMU_ARMINT_WAKEUP_EN BIT(0) -- cgit v0.10.2 From ec60d95b4faccd61c7ce10316ebc9333f2d7674a Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Mon, 1 Jun 2015 16:22:54 +0200 Subject: ARM: shmobile: Basic r8a7793 SoC support Minimal support without power management or SMP. Signed-off-by: Ulrich Hecht Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 4500647..c59d75e 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -80,6 +80,10 @@ config ARCH_R8A7791 select ARCH_RCAR_GEN2 select I2C +config ARCH_R8A7793 + bool "R-Car M2-N (R8A7793)" + select ARCH_RCAR_GEN2 + config ARCH_R8A7794 bool "R-Car E2 (R8A77940)" select ARCH_RCAR_GEN2 diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index 89e463d..e4b8fdb 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_ARCH_R8A7778) += setup-r8a7778.o obj-$(CONFIG_ARCH_R8A7779) += setup-r8a7779.o pm-r8a7779.o obj-$(CONFIG_ARCH_R8A7790) += setup-r8a7790.o obj-$(CONFIG_ARCH_R8A7791) += setup-r8a7791.o +obj-$(CONFIG_ARCH_R8A7793) += setup-r8a7793.o obj-$(CONFIG_ARCH_R8A7794) += setup-r8a7794.o obj-$(CONFIG_ARCH_EMEV2) += setup-emev2.o obj-$(CONFIG_ARCH_R7S72100) += setup-r7s72100.o diff --git a/arch/arm/mach-shmobile/setup-r8a7793.c b/arch/arm/mach-shmobile/setup-r8a7793.c new file mode 100644 index 0000000..1d2825c --- /dev/null +++ b/arch/arm/mach-shmobile/setup-r8a7793.c @@ -0,0 +1,33 @@ +/* + * r8a7793 processor support + * + * Copyright (C) 2015 Ulrich Hecht + * + * 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 of the License. + * + * 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. + */ + +#include +#include + +#include "common.h" +#include "rcar-gen2.h" + +static const char *r8a7793_boards_compat_dt[] __initconst = { + "renesas,r8a7793", + NULL, +}; + +DT_MACHINE_START(R8A7793_DT, "Generic R8A7793 (Flattened Device Tree)") + .init_early = shmobile_init_delay, + .init_time = rcar_gen2_timer_init, + .init_late = shmobile_init_late, + .reserve = rcar_gen2_reserve, + .dt_compat = r8a7793_boards_compat_dt, +MACHINE_END -- cgit v0.10.2 From 765b50030c218f65ee4ffd2eeb07045aa79fd5ee Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Mon, 1 Jun 2015 16:22:57 +0200 Subject: ARM: shmobile: gose: enable R-Car Gen2 regulator quirk Regulator setup seems identical to Koelsch. Signed-off-by: Ulrich Hecht Acked-by: Geert Uytterhoeven Signed-off-by: Simon Horman diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index c59d75e..429157d 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -83,6 +83,7 @@ config ARCH_R8A7791 config ARCH_R8A7793 bool "R-Car M2-N (R8A7793)" select ARCH_RCAR_GEN2 + select I2C config ARCH_R8A7794 bool "R-Car E2 (R8A77940)" diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile index e4b8fdb..def7a09 100644 --- a/arch/arm/mach-shmobile/Makefile +++ b/arch/arm/mach-shmobile/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_ARCH_RCAR_GEN2) += setup-rcar-gen2.o platsmp-apmu.o $(cpu-y) CFLAGS_setup-rcar-gen2.o += -march=armv7-a obj-$(CONFIG_ARCH_R8A7790) += regulator-quirk-rcar-gen2.o obj-$(CONFIG_ARCH_R8A7791) += regulator-quirk-rcar-gen2.o +obj-$(CONFIG_ARCH_R8A7793) += regulator-quirk-rcar-gen2.o # SMP objects smp-y := $(cpu-y) diff --git a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c index 384e6e9..62437b5 100644 --- a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c +++ b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c @@ -123,7 +123,8 @@ static int __init rcar_gen2_regulator_quirk(void) u32 mon; if (!of_machine_is_compatible("renesas,koelsch") && - !of_machine_is_compatible("renesas,lager")) + !of_machine_is_compatible("renesas,lager") && + !of_machine_is_compatible("renesas,gose")) return -ENODEV; irqc = ioremap(IRQC_BASE, PAGE_SIZE); -- cgit v0.10.2 From cb8cc37f4d38d96552f2c52deb15e511cdacf906 Mon Sep 17 00:00:00 2001 From: Caesar Wang Date: Mon, 6 Jul 2015 11:37:23 +0800 Subject: ARM: rockchip: fix broken build The following was seen in branch[0] build. arch/arm/mach-rockchip/platsmp.c:154:23: error: 'rockchip_secondary_startup' undeclared (first use in this function) branch[0]: git://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git v4.3-armsoc/soc The broken build is caused by the commit fe4407c0dc58 ("ARM: rockchip: fix the CPU soft reset"). Signed-off-by: Caesar Wang The breakage was a result of it being wrongly merged in my branch with the cache invalidation rework from Russell 02b4e2756e01c ("ARM: v7 setup function should invalidate L1 cache"). Signed-off-by: Heiko Stuebner diff --git a/arch/arm/mach-rockchip/platsmp.c b/arch/arm/mach-rockchip/platsmp.c index 7ebd1c1..3e7a4b7 100644 --- a/arch/arm/mach-rockchip/platsmp.c +++ b/arch/arm/mach-rockchip/platsmp.c @@ -152,8 +152,7 @@ static int rockchip_boot_secondary(unsigned int cpu, struct task_struct *idle) */ mdelay(1); /* ensure the cpus other than cpu0 to startup */ - writel(virt_to_phys(rockchip_secondary_startup), - sram_base_addr + 8); + writel(virt_to_phys(secondary_startup), sram_base_addr + 8); writel(0xDEADBEAF, sram_base_addr + 4); dsb_sev(); } -- cgit v0.10.2 From 16a624a9c81814cc2f1353eff2e502430c3fa79a Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 24 Jun 2015 08:17:02 +0200 Subject: soc: mediatek: Add infracfg misc driver support This adds support for some miscellaneous bits of the infracfg controller. The mtk_infracfg_set/clear_bus_protection functions are necessary for the scpsys power domain driver to handle the bus protection bits which are contained in the infacfg register space. Signed-off-by: Sascha Hauer Reviewed-by: Daniel Kurtz Signed-off-by: Matthias Brugger diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig index 3c18503..e609a6f 100644 --- a/drivers/soc/mediatek/Kconfig +++ b/drivers/soc/mediatek/Kconfig @@ -1,6 +1,15 @@ # # MediaTek SoC drivers # +config MTK_INFRACFG + bool "MediaTek INFRACFG Support" + depends on ARCH_MEDIATEK || COMPILE_TEST + select REGMAP + help + Say yes here to add support for the MediaTek INFRACFG controller. The + INFRACFG controller contains various infrastructure registers not + directly associated to any device. + config MTK_PMIC_WRAP tristate "MediaTek PMIC Wrapper Support" depends on ARCH_MEDIATEK diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile index ecaf4de..3fa940f 100644 --- a/drivers/soc/mediatek/Makefile +++ b/drivers/soc/mediatek/Makefile @@ -1 +1,2 @@ +obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o diff --git a/drivers/soc/mediatek/mtk-infracfg.c b/drivers/soc/mediatek/mtk-infracfg.c new file mode 100644 index 0000000..dba3055 --- /dev/null +++ b/drivers/soc/mediatek/mtk-infracfg.c @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2015 Pengutronix, Sascha Hauer + * + * 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. + */ + +#include +#include +#include +#include +#include + +#define INFRA_TOPAXI_PROTECTEN 0x0220 +#define INFRA_TOPAXI_PROTECTSTA1 0x0228 + +/** + * mtk_infracfg_set_bus_protection - enable bus protection + * @regmap: The infracfg regmap + * @mask: The mask containing the protection bits to be enabled. + * + * This function enables the bus protection bits for disabled power + * domains so that the system does not hang when some unit accesses the + * bus while in power down. + */ +int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask) +{ + unsigned long expired; + u32 val; + int ret; + + regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, mask); + + expired = jiffies + HZ; + + while (1) { + ret = regmap_read(infracfg, INFRA_TOPAXI_PROTECTSTA1, &val); + if (ret) + return ret; + + if ((val & mask) == mask) + break; + + cpu_relax(); + if (time_after(jiffies, expired)) + return -EIO; + } + + return 0; +} + +/** + * mtk_infracfg_clear_bus_protection - disable bus protection + * @regmap: The infracfg regmap + * @mask: The mask containing the protection bits to be disabled. + * + * This function disables the bus protection bits previously enabled with + * mtk_infracfg_set_bus_protection. + */ +int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask) +{ + unsigned long expired; + int ret; + + regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0); + + expired = jiffies + HZ; + + while (1) { + u32 val; + + ret = regmap_read(infracfg, INFRA_TOPAXI_PROTECTSTA1, &val); + if (ret) + return ret; + + if (!(val & mask)) + break; + + cpu_relax(); + if (time_after(jiffies, expired)) + return -EIO; + } + + return 0; +} diff --git a/include/linux/soc/mediatek/infracfg.h b/include/linux/soc/mediatek/infracfg.h new file mode 100644 index 0000000..a5714e9 --- /dev/null +++ b/include/linux/soc/mediatek/infracfg.h @@ -0,0 +1,26 @@ +#ifndef __SOC_MEDIATEK_INFRACFG_H +#define __SOC_MEDIATEK_INFRACFG_H + +#define MT8173_TOP_AXI_PROT_EN_MCI_M2 BIT(0) +#define MT8173_TOP_AXI_PROT_EN_MM_M0 BIT(1) +#define MT8173_TOP_AXI_PROT_EN_MM_M1 BIT(2) +#define MT8173_TOP_AXI_PROT_EN_MMAPB_S BIT(6) +#define MT8173_TOP_AXI_PROT_EN_L2C_M2 BIT(9) +#define MT8173_TOP_AXI_PROT_EN_L2SS_SMI BIT(11) +#define MT8173_TOP_AXI_PROT_EN_L2SS_ADD BIT(12) +#define MT8173_TOP_AXI_PROT_EN_CCI_M2 BIT(13) +#define MT8173_TOP_AXI_PROT_EN_MFG_S BIT(14) +#define MT8173_TOP_AXI_PROT_EN_PERI_M0 BIT(15) +#define MT8173_TOP_AXI_PROT_EN_PERI_M1 BIT(16) +#define MT8173_TOP_AXI_PROT_EN_DEBUGSYS BIT(17) +#define MT8173_TOP_AXI_PROT_EN_CQ_DMA BIT(18) +#define MT8173_TOP_AXI_PROT_EN_GCPU BIT(19) +#define MT8173_TOP_AXI_PROT_EN_IOMMU BIT(20) +#define MT8173_TOP_AXI_PROT_EN_MFG_M0 BIT(21) +#define MT8173_TOP_AXI_PROT_EN_MFG_M1 BIT(22) +#define MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT BIT(23) + +int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask); +int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask); + +#endif /* __SOC_MEDIATEK_INFRACFG_H */ -- cgit v0.10.2 From 859e42800bcfc4db9cefaa2c24d6e3a203fe961d Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 24 Jun 2015 08:17:03 +0200 Subject: dt-bindings: soc: Add documentation for the MediaTek SCPSYS unit This adds documentation for the MediaTek SCPSYS unit found in MT8173 SoCs. Signed-off-by: Sascha Hauer Reviewed-by: Daniel Kurtz Signed-off-by: Matthias Brugger diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt new file mode 100644 index 0000000..c051114 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt @@ -0,0 +1,41 @@ +MediaTek SCPSYS +=============== + +The System Control Processor System (SCPSYS) has several power management +related tasks in the system. The tasks include thermal measurement, dynamic +voltage frequency scaling (DVFS), interrupt filter and lowlevel sleep control. +The System Power Manager (SPM) inside the SCPSYS is for the MTCMOS power +domain control. + +The driver implements the Generic PM domain bindings described in +power/power_domain.txt. It provides the power domains defined in +include/dt-bindings/power/mt8173-power.h. + +Required properties: +- compatible: Must be "mediatek,mt8173-scpsys" +- #power-domain-cells: Must be 1 +- reg: Address range of the SCPSYS unit +- infracfg: must contain a phandle to the infracfg controller +- clock, clock-names: clocks according to the common clock binding. + The clocks needed "mm" and "mfg". These are the + clocks which hardware needs to be enabled before + enabling certain power domains. + +Example: + + scpsys: scpsys@10006000 { + #power-domain-cells = <1>; + compatible = "mediatek,mt8173-scpsys"; + reg = <0 0x10006000 0 0x1000>; + infracfg = <&infracfg>; + clocks = <&clk26m>, + <&topckgen CLK_TOP_MM_SEL>; + clock-names = "mfg", "mm"; + }; + +Example consumer: + + afe: mt8173-afe-pcm@11220000 { + compatible = "mediatek,mt8173-afe-pcm"; + power-domains = <&scpsys MT8173_POWER_DOMAIN_AUDIO>; + }; -- cgit v0.10.2 From c84e358718a66f76ac0de1681d15d8d0c68fcdab Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 24 Jun 2015 08:17:04 +0200 Subject: soc: Mediatek: Add SCPSYS power domain driver This adds a power domain driver for the Mediatek SCPSYS unit. The System Control Processor System (SCPSYS) has several power management related tasks in the system. The tasks include thermal measurement, dynamic voltage frequency scaling (DVFS), interrupt filter and lowlevel sleep control. The System Power Manager (SPM) inside the SCPSYS is for the MTCMOS power domain control. For now this driver only adds power domain support, the more advanced features are not yet supported. The driver implements the generic PM domain device tree bindings, the first user will most likely be the Mediatek AFE audio driver. Signed-off-by: Sascha Hauer Reviewed-by: Daniel Kurtz Signed-off-by: Matthias Brugger diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig index e609a6f..9d50682 100644 --- a/drivers/soc/mediatek/Kconfig +++ b/drivers/soc/mediatek/Kconfig @@ -19,3 +19,13 @@ config MTK_PMIC_WRAP Say yes here to add support for MediaTek PMIC Wrapper found on different MediaTek SoCs. The PMIC wrapper is a proprietary hardware to connect the PMIC. + +config MTK_SCPSYS + bool "MediaTek SCPSYS Support" + depends on ARCH_MEDIATEK || COMPILE_TEST + select REGMAP + select MTK_INFRACFG + select PM_GENERIC_DOMAINS if PM + help + Say yes here to add support for the MediaTek SCPSYS power domain + driver. diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile index 3fa940f..12998b0 100644 --- a/drivers/soc/mediatek/Makefile +++ b/drivers/soc/mediatek/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o +obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c new file mode 100644 index 0000000..43a79ed --- /dev/null +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -0,0 +1,487 @@ +/* + * Copyright (c) 2015 Pengutronix, Sascha Hauer + * + * 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. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SPM_VDE_PWR_CON 0x0210 +#define SPM_MFG_PWR_CON 0x0214 +#define SPM_VEN_PWR_CON 0x0230 +#define SPM_ISP_PWR_CON 0x0238 +#define SPM_DIS_PWR_CON 0x023c +#define SPM_VEN2_PWR_CON 0x0298 +#define SPM_AUDIO_PWR_CON 0x029c +#define SPM_MFG_2D_PWR_CON 0x02c0 +#define SPM_MFG_ASYNC_PWR_CON 0x02c4 +#define SPM_USB_PWR_CON 0x02cc +#define SPM_PWR_STATUS 0x060c +#define SPM_PWR_STATUS_2ND 0x0610 + +#define PWR_RST_B_BIT BIT(0) +#define PWR_ISO_BIT BIT(1) +#define PWR_ON_BIT BIT(2) +#define PWR_ON_2ND_BIT BIT(3) +#define PWR_CLK_DIS_BIT BIT(4) + +#define PWR_STATUS_DISP BIT(3) +#define PWR_STATUS_MFG BIT(4) +#define PWR_STATUS_ISP BIT(5) +#define PWR_STATUS_VDEC BIT(7) +#define PWR_STATUS_VENC_LT BIT(20) +#define PWR_STATUS_VENC BIT(21) +#define PWR_STATUS_MFG_2D BIT(22) +#define PWR_STATUS_MFG_ASYNC BIT(23) +#define PWR_STATUS_AUDIO BIT(24) +#define PWR_STATUS_USB BIT(25) + +enum clk_id { + MT8173_CLK_MM, + MT8173_CLK_MFG, + MT8173_CLK_NONE, + MT8173_CLK_MAX = MT8173_CLK_NONE, +}; + +struct scp_domain_data { + const char *name; + u32 sta_mask; + int ctl_offs; + u32 sram_pdn_bits; + u32 sram_pdn_ack_bits; + u32 bus_prot_mask; + enum clk_id clk_id; +}; + +static const struct scp_domain_data scp_domain_data[] __initconst = { + [MT8173_POWER_DOMAIN_VDEC] = { + .name = "vdec", + .sta_mask = PWR_STATUS_VDEC, + .ctl_offs = SPM_VDE_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(12, 12), + .clk_id = MT8173_CLK_MM, + }, + [MT8173_POWER_DOMAIN_VENC] = { + .name = "venc", + .sta_mask = PWR_STATUS_VENC, + .ctl_offs = SPM_VEN_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(15, 12), + .clk_id = MT8173_CLK_MM, + }, + [MT8173_POWER_DOMAIN_ISP] = { + .name = "isp", + .sta_mask = PWR_STATUS_ISP, + .ctl_offs = SPM_ISP_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(13, 12), + .clk_id = MT8173_CLK_MM, + }, + [MT8173_POWER_DOMAIN_MM] = { + .name = "mm", + .sta_mask = PWR_STATUS_DISP, + .ctl_offs = SPM_DIS_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(12, 12), + .clk_id = MT8173_CLK_MM, + .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 | + MT8173_TOP_AXI_PROT_EN_MM_M1, + }, + [MT8173_POWER_DOMAIN_VENC_LT] = { + .name = "venc_lt", + .sta_mask = PWR_STATUS_VENC_LT, + .ctl_offs = SPM_VEN2_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(15, 12), + .clk_id = MT8173_CLK_MM, + }, + [MT8173_POWER_DOMAIN_AUDIO] = { + .name = "audio", + .sta_mask = PWR_STATUS_AUDIO, + .ctl_offs = SPM_AUDIO_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(15, 12), + .clk_id = MT8173_CLK_NONE, + }, + [MT8173_POWER_DOMAIN_USB] = { + .name = "usb", + .sta_mask = PWR_STATUS_USB, + .ctl_offs = SPM_USB_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(15, 12), + .clk_id = MT8173_CLK_NONE, + }, + [MT8173_POWER_DOMAIN_MFG_ASYNC] = { + .name = "mfg_async", + .sta_mask = PWR_STATUS_MFG_ASYNC, + .ctl_offs = SPM_MFG_ASYNC_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = 0, + .clk_id = MT8173_CLK_MFG, + }, + [MT8173_POWER_DOMAIN_MFG_2D] = { + .name = "mfg_2d", + .sta_mask = PWR_STATUS_MFG_2D, + .ctl_offs = SPM_MFG_2D_PWR_CON, + .sram_pdn_bits = GENMASK(11, 8), + .sram_pdn_ack_bits = GENMASK(13, 12), + .clk_id = MT8173_CLK_NONE, + }, + [MT8173_POWER_DOMAIN_MFG] = { + .name = "mfg", + .sta_mask = PWR_STATUS_MFG, + .ctl_offs = SPM_MFG_PWR_CON, + .sram_pdn_bits = GENMASK(13, 8), + .sram_pdn_ack_bits = GENMASK(21, 16), + .clk_id = MT8173_CLK_NONE, + .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S | + MT8173_TOP_AXI_PROT_EN_MFG_M0 | + MT8173_TOP_AXI_PROT_EN_MFG_M1 | + MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT, + }, +}; + +#define NUM_DOMAINS ARRAY_SIZE(scp_domain_data) + +struct scp; + +struct scp_domain { + struct generic_pm_domain genpd; + struct scp *scp; + struct clk *clk; + u32 sta_mask; + void __iomem *ctl_addr; + u32 sram_pdn_bits; + u32 sram_pdn_ack_bits; + u32 bus_prot_mask; +}; + +struct scp { + struct scp_domain domains[NUM_DOMAINS]; + struct genpd_onecell_data pd_data; + struct device *dev; + void __iomem *base; + struct regmap *infracfg; +}; + +static int scpsys_domain_is_on(struct scp_domain *scpd) +{ + struct scp *scp = scpd->scp; + + u32 status = readl(scp->base + SPM_PWR_STATUS) & scpd->sta_mask; + u32 status2 = readl(scp->base + SPM_PWR_STATUS_2ND) & scpd->sta_mask; + + /* + * A domain is on when both status bits are set. If only one is set + * return an error. This happens while powering up a domain + */ + + if (status && status2) + return true; + if (!status && !status2) + return false; + + return -EINVAL; +} + +static int scpsys_power_on(struct generic_pm_domain *genpd) +{ + struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd); + struct scp *scp = scpd->scp; + unsigned long timeout; + bool expired; + void __iomem *ctl_addr = scpd->ctl_addr; + u32 sram_pdn_ack = scpd->sram_pdn_ack_bits; + u32 val; + int ret; + + if (scpd->clk) { + ret = clk_prepare_enable(scpd->clk); + if (ret) + goto err_clk; + } + + val = readl(ctl_addr); + val |= PWR_ON_BIT; + writel(val, ctl_addr); + val |= PWR_ON_2ND_BIT; + writel(val, ctl_addr); + + /* wait until PWR_ACK = 1 */ + timeout = jiffies + HZ; + expired = false; + while (1) { + ret = scpsys_domain_is_on(scpd); + if (ret > 0) + break; + + if (expired) { + ret = -ETIMEDOUT; + goto err_pwr_ack; + } + + cpu_relax(); + + if (time_after(jiffies, timeout)) + expired = true; + } + + val &= ~PWR_CLK_DIS_BIT; + writel(val, ctl_addr); + + val &= ~PWR_ISO_BIT; + writel(val, ctl_addr); + + val |= PWR_RST_B_BIT; + writel(val, ctl_addr); + + val &= ~scpd->sram_pdn_bits; + writel(val, ctl_addr); + + /* wait until SRAM_PDN_ACK all 0 */ + timeout = jiffies + HZ; + expired = false; + while (sram_pdn_ack && (readl(ctl_addr) & sram_pdn_ack)) { + + if (expired) { + ret = -ETIMEDOUT; + goto err_pwr_ack; + } + + cpu_relax(); + + if (time_after(jiffies, timeout)) + expired = true; + } + + if (scpd->bus_prot_mask) { + ret = mtk_infracfg_clear_bus_protection(scp->infracfg, + scpd->bus_prot_mask); + if (ret) + goto err_pwr_ack; + } + + return 0; + +err_pwr_ack: + clk_disable_unprepare(scpd->clk); +err_clk: + dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name); + + return ret; +} + +static int scpsys_power_off(struct generic_pm_domain *genpd) +{ + struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd); + struct scp *scp = scpd->scp; + unsigned long timeout; + bool expired; + void __iomem *ctl_addr = scpd->ctl_addr; + u32 pdn_ack = scpd->sram_pdn_ack_bits; + u32 val; + int ret; + + if (scpd->bus_prot_mask) { + ret = mtk_infracfg_set_bus_protection(scp->infracfg, + scpd->bus_prot_mask); + if (ret) + goto out; + } + + val = readl(ctl_addr); + val |= scpd->sram_pdn_bits; + writel(val, ctl_addr); + + /* wait until SRAM_PDN_ACK all 1 */ + timeout = jiffies + HZ; + expired = false; + while (pdn_ack && (readl(ctl_addr) & pdn_ack) != pdn_ack) { + if (expired) { + ret = -ETIMEDOUT; + goto out; + } + + cpu_relax(); + + if (time_after(jiffies, timeout)) + expired = true; + } + + val |= PWR_ISO_BIT; + writel(val, ctl_addr); + + val &= ~PWR_RST_B_BIT; + writel(val, ctl_addr); + + val |= PWR_CLK_DIS_BIT; + writel(val, ctl_addr); + + val &= ~PWR_ON_BIT; + writel(val, ctl_addr); + + val &= ~PWR_ON_2ND_BIT; + writel(val, ctl_addr); + + /* wait until PWR_ACK = 0 */ + timeout = jiffies + HZ; + expired = false; + while (1) { + ret = scpsys_domain_is_on(scpd); + if (ret == 0) + break; + + if (expired) { + ret = -ETIMEDOUT; + goto out; + } + + cpu_relax(); + + if (time_after(jiffies, timeout)) + expired = true; + } + + if (scpd->clk) + clk_disable_unprepare(scpd->clk); + + return 0; + +out: + dev_err(scp->dev, "Failed to power off domain %s\n", genpd->name); + + return ret; +} + +static int __init scpsys_probe(struct platform_device *pdev) +{ + struct genpd_onecell_data *pd_data; + struct resource *res; + int i, ret; + struct scp *scp; + struct clk *clk[MT8173_CLK_MAX]; + + scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL); + if (!scp) + return -ENOMEM; + + scp->dev = &pdev->dev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + scp->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(scp->base)) + return PTR_ERR(scp->base); + + pd_data = &scp->pd_data; + + pd_data->domains = devm_kzalloc(&pdev->dev, + sizeof(*pd_data->domains) * NUM_DOMAINS, GFP_KERNEL); + if (!pd_data->domains) + return -ENOMEM; + + clk[MT8173_CLK_MM] = devm_clk_get(&pdev->dev, "mm"); + if (IS_ERR(clk[MT8173_CLK_MM])) + return PTR_ERR(clk[MT8173_CLK_MM]); + + clk[MT8173_CLK_MFG] = devm_clk_get(&pdev->dev, "mfg"); + if (IS_ERR(clk[MT8173_CLK_MFG])) + return PTR_ERR(clk[MT8173_CLK_MFG]); + + scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, + "infracfg"); + if (IS_ERR(scp->infracfg)) { + dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n", + PTR_ERR(scp->infracfg)); + return PTR_ERR(scp->infracfg); + } + + pd_data->num_domains = NUM_DOMAINS; + + for (i = 0; i < NUM_DOMAINS; i++) { + struct scp_domain *scpd = &scp->domains[i]; + struct generic_pm_domain *genpd = &scpd->genpd; + const struct scp_domain_data *data = &scp_domain_data[i]; + + pd_data->domains[i] = genpd; + scpd->scp = scp; + + scpd->sta_mask = data->sta_mask; + scpd->ctl_addr = scp->base + data->ctl_offs; + scpd->sram_pdn_bits = data->sram_pdn_bits; + scpd->sram_pdn_ack_bits = data->sram_pdn_ack_bits; + scpd->bus_prot_mask = data->bus_prot_mask; + if (data->clk_id != MT8173_CLK_NONE) + scpd->clk = clk[data->clk_id]; + + genpd->name = data->name; + genpd->power_off = scpsys_power_off; + genpd->power_on = scpsys_power_on; + + /* + * Initially turn on all domains to make the domains usable + * with !CONFIG_PM and to get the hardware in sync with the + * software. The unused domains will be switched off during + * late_init time. + */ + genpd->power_on(genpd); + + pm_genpd_init(genpd, NULL, false); + } + + /* + * We are not allowed to fail here since there is no way to unregister + * a power domain. Once registered above we have to keep the domains + * valid. + */ + + ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_ASYNC], + pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D]); + if (ret && IS_ENABLED(CONFIG_PM)) + dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret); + + ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D], + pd_data->domains[MT8173_POWER_DOMAIN_MFG]); + if (ret && IS_ENABLED(CONFIG_PM)) + dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret); + + ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data); + if (ret) + dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret); + + return 0; +} + +static const struct of_device_id of_scpsys_match_tbl[] = { + { + .compatible = "mediatek,mt8173-scpsys", + }, { + /* sentinel */ + } +}; + +static struct platform_driver scpsys_drv = { + .driver = { + .name = "mtk-scpsys", + .owner = THIS_MODULE, + .of_match_table = of_match_ptr(of_scpsys_match_tbl), + }, +}; + +module_platform_driver_probe(scpsys_drv, scpsys_probe); diff --git a/include/dt-bindings/power/mt8173-power.h b/include/dt-bindings/power/mt8173-power.h new file mode 100644 index 0000000..b34cee9 --- /dev/null +++ b/include/dt-bindings/power/mt8173-power.h @@ -0,0 +1,15 @@ +#ifndef _DT_BINDINGS_POWER_MT8183_POWER_H +#define _DT_BINDINGS_POWER_MT8183_POWER_H + +#define MT8173_POWER_DOMAIN_VDEC 0 +#define MT8173_POWER_DOMAIN_VENC 1 +#define MT8173_POWER_DOMAIN_ISP 2 +#define MT8173_POWER_DOMAIN_MM 3 +#define MT8173_POWER_DOMAIN_VENC_LT 4 +#define MT8173_POWER_DOMAIN_AUDIO 5 +#define MT8173_POWER_DOMAIN_USB 6 +#define MT8173_POWER_DOMAIN_MFG_ASYNC 7 +#define MT8173_POWER_DOMAIN_MFG_2D 8 +#define MT8173_POWER_DOMAIN_MFG 9 + +#endif /* _DT_BINDINGS_POWER_MT8183_POWER_H */ -- cgit v0.10.2 From b33612e183dcbaa2cc2479cedff6984a6cccdf6a Mon Sep 17 00:00:00 2001 From: Hiraku Toyooka Date: Wed, 10 Jun 2015 07:47:19 +0000 Subject: ARM: socfpga: add smp_ops.cpu_kill to make kexec/kdump available Kexec_load syscall in ARM requires that machine-specific code has the smp_ops.cpu_kill() before loading kernel image. This patch adds the cpu_kill(), as a result, kexec reboot and kernel crash dump become available in mach-socfpga. Signed-off-by: Hiraku Toyooka Cc: Dinh Nguyen Cc: Russell King Cc: linux-arm-kernel@lists.infradead.org Cc: linux-kernel@vger.kernel.org Link: http://lists.infradead.org/pipermail/linux-arm-kernel/2015-June/348004.html Signed-off-by: Dinh Nguyen diff --git a/arch/arm/mach-socfpga/platsmp.c b/arch/arm/mach-socfpga/platsmp.c index c6f1df8..15c8ce8 100644 --- a/arch/arm/mach-socfpga/platsmp.c +++ b/arch/arm/mach-socfpga/platsmp.c @@ -106,11 +106,23 @@ static void socfpga_cpu_die(unsigned int cpu) cpu_do_idle(); } +/* + * We need a dummy function so that platform_can_cpu_hotplug() knows + * we support CPU hotplug. However, the function does not need to do + * anything, because CPUs going offline just do WFI. We could reset + * the CPUs but it would increase power consumption. + */ +static int socfpga_cpu_kill(unsigned int cpu) +{ + return 1; +} + static struct smp_operations socfpga_smp_ops __initdata = { .smp_prepare_cpus = socfpga_smp_prepare_cpus, .smp_boot_secondary = socfpga_boot_secondary, #ifdef CONFIG_HOTPLUG_CPU .cpu_die = socfpga_cpu_die, + .cpu_kill = socfpga_cpu_kill, #endif }; @@ -119,6 +131,7 @@ static struct smp_operations socfpga_a10_smp_ops __initdata = { .smp_boot_secondary = socfpga_a10_boot_secondary, #ifdef CONFIG_HOTPLUG_CPU .cpu_die = socfpga_cpu_die, + .cpu_kill = socfpga_cpu_kill, #endif }; -- cgit v0.10.2 From 3fd4079fe295b91cd1f4330e3c8f1e6e4618a27d Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Fri, 10 Jul 2015 15:29:45 +0900 Subject: soc: mediatek: Drop owner assignment from platform_driver platform_driver does not need to set an owner because platform_driver_register() will set it. Signed-off-by: Krzysztof Kozlowski Acked-by: Sascha Hauer Signed-off-by: Matthias Brugger diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c index f432291..8bc7b41 100644 --- a/drivers/soc/mediatek/mtk-pmic-wrap.c +++ b/drivers/soc/mediatek/mtk-pmic-wrap.c @@ -926,7 +926,6 @@ err_out1: static struct platform_driver pwrap_drv = { .driver = { .name = "mt-pmic-pwrap", - .owner = THIS_MODULE, .of_match_table = of_match_ptr(of_pwrap_match_tbl), }, .probe = pwrap_probe, -- cgit v0.10.2 From 022d0716bb7e8e0f11eff4ee65fb1e62ffe8f6e1 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Fri, 10 Jul 2015 02:09:41 +0800 Subject: ARM: imx: add i.mx6ul msl support i.MX6UL is a new SOC, add MSL support Signed-off-by: Frank Li Signed-off-by: Shawn Guo diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 573536f..8ceda28 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -548,6 +548,14 @@ config SOC_IMX6SX help This enables support for Freescale i.MX6 SoloX processor. +config SOC_IMX6UL + bool "i.MX6 UltraLite support" + select PINCTRL_IMX6UL + select SOC_IMX6 + + help + This enables support for Freescale i.MX6 UltraLite processor. + config SOC_IMX7D bool "i.MX7 Dual support" select PINCTRL_IMX7D diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index 37c502a..fb689d8 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -83,6 +83,7 @@ endif obj-$(CONFIG_SOC_IMX6Q) += mach-imx6q.o obj-$(CONFIG_SOC_IMX6SL) += mach-imx6sl.o obj-$(CONFIG_SOC_IMX6SX) += mach-imx6sx.o +obj-$(CONFIG_SOC_IMX6UL) += mach-imx6ul.o obj-$(CONFIG_SOC_IMX7D) += mach-imx7d.o ifeq ($(CONFIG_SUSPEND),y) diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index a7fa92a..5b0f752 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -130,6 +130,9 @@ struct device * __init imx_soc_device_init(void) case MXC_CPU_IMX6Q: soc_id = "i.MX6Q"; break; + case MXC_CPU_IMX6UL: + soc_id = "i.MX6UL"; + break; case MXC_CPU_IMX7D: soc_id = "i.MX7D"; break; diff --git a/arch/arm/mach-imx/mach-imx6ul.c b/arch/arm/mach-imx/mach-imx6ul.c new file mode 100644 index 0000000..f206506 --- /dev/null +++ b/arch/arm/mach-imx/mach-imx6ul.c @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2015 Freescale Semiconductor, Inc. + * + * 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 +#include +#include + +#include "common.h" + +static void __init imx6ul_init_machine(void) +{ + struct device *parent; + + parent = imx_soc_device_init(); + if (parent == NULL) + pr_warn("failed to initialize soc device\n"); + + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + imx_anatop_init(); +} + +static void __init imx6ul_init_irq(void) +{ + imx_init_revision_from_anatop(); + imx_src_init(); + irqchip_init(); +} + +static const char *imx6ul_dt_compat[] __initconst = { + "fsl,imx6ul", + NULL, +}; + +DT_MACHINE_START(IMX6UL, "Freescale i.MX6 Ultralite (Device Tree)") + .init_irq = imx6ul_init_irq, + .init_machine = imx6ul_init_machine, + .dt_compat = imx6ul_dt_compat, +MACHINE_END diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h index c4436d4..a5b1af6 100644 --- a/arch/arm/mach-imx/mxc.h +++ b/arch/arm/mach-imx/mxc.h @@ -38,6 +38,7 @@ #define MXC_CPU_IMX6DL 0x61 #define MXC_CPU_IMX6SX 0x62 #define MXC_CPU_IMX6Q 0x63 +#define MXC_CPU_IMX6UL 0x64 #define MXC_CPU_IMX7D 0x72 #define IMX_DDR_TYPE_LPDDR2 1 @@ -165,6 +166,11 @@ static inline bool cpu_is_imx6sx(void) return __mxc_cpu_type == MXC_CPU_IMX6SX; } +static inline bool cpu_is_imx6ul(void) +{ + return __mxc_cpu_type == MXC_CPU_IMX6UL; +} + static inline bool cpu_is_imx6q(void) { return __mxc_cpu_type == MXC_CPU_IMX6Q; -- cgit v0.10.2 From 20c305f66077d2e646b23336d4404261dc283cf9 Mon Sep 17 00:00:00 2001 From: Anson Huang Date: Fri, 10 Jul 2015 02:09:47 +0800 Subject: ARM: imx: add low-level debug support for i.mx6ul Enable low-level debug support for i.MX6UL by adding the debug port definitions for the SoC. Singed-off-by: Anson Huang Signed-off-by: Fugang Duan Signed-off-by: Frank Li Signed-off-by: Shawn Guo diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index f1b1579..f21daa8 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -411,6 +411,13 @@ choice Say Y here if you want kernel low-level debugging support on i.MX6SX. + config DEBUG_IMX6UL_UART + bool "i.MX6UL Debug UART" + depends on SOC_IMX6UL + help + Say Y here if you want kernel low-level debugging support + on i.MX6UL. + config DEBUG_IMX7D_UART bool "i.MX7D Debug UART" depends on SOC_IMX7D @@ -1269,6 +1276,7 @@ config DEBUG_IMX_UART_PORT DEBUG_IMX6Q_UART || \ DEBUG_IMX6SL_UART || \ DEBUG_IMX6SX_UART || \ + DEBUG_IMX6UL_UART || \ DEBUG_IMX7D_UART default 1 depends on ARCH_MXC @@ -1320,6 +1328,7 @@ config DEBUG_LL_INCLUDE DEBUG_IMX6Q_UART || \ DEBUG_IMX6SL_UART || \ DEBUG_IMX6SX_UART || \ + DEBUG_IMX6UL_UART || \ DEBUG_IMX7D_UART default "debug/ks8695.S" if DEBUG_KS8695_UART default "debug/msm.S" if DEBUG_QCOM_UARTDM diff --git a/arch/arm/include/debug/imx-uart.h b/arch/arm/include/debug/imx-uart.h index 66f736f..bce58e9 100644 --- a/arch/arm/include/debug/imx-uart.h +++ b/arch/arm/include/debug/imx-uart.h @@ -90,6 +90,17 @@ #define IMX6SX_UART_BASE_ADDR(n) IMX6SX_UART##n##_BASE_ADDR #define IMX6SX_UART_BASE(n) IMX6SX_UART_BASE_ADDR(n) +#define IMX6UL_UART1_BASE_ADDR 0x02020000 +#define IMX6UL_UART2_BASE_ADDR 0x021e8000 +#define IMX6UL_UART3_BASE_ADDR 0x021ec000 +#define IMX6UL_UART4_BASE_ADDR 0x021f0000 +#define IMX6UL_UART5_BASE_ADDR 0x021f4000 +#define IMX6UL_UART6_BASE_ADDR 0x021fc000 +#define IMX6UL_UART7_BASE_ADDR 0x02018000 +#define IMX6UL_UART8_BASE_ADDR 0x02024000 +#define IMX6UL_UART_BASE_ADDR(n) IMX6UL_UART##n##_BASE_ADDR +#define IMX6UL_UART_BASE(n) IMX6UL_UART_BASE_ADDR(n) + #define IMX7D_UART1_BASE_ADDR 0x30860000 #define IMX7D_UART2_BASE_ADDR 0x30890000 #define IMX7D_UART3_BASE_ADDR 0x30880000 @@ -124,6 +135,8 @@ #define UART_PADDR IMX_DEBUG_UART_BASE(IMX6SL) #elif defined(CONFIG_DEBUG_IMX6SX_UART) #define UART_PADDR IMX_DEBUG_UART_BASE(IMX6SX) +#elif defined(CONFIG_DEBUG_IMX6UL_UART) +#define UART_PADDR IMX_DEBUG_UART_BASE(IMX6UL) #elif defined(CONFIG_DEBUG_IMX7D_UART) #define UART_PADDR IMX_DEBUG_UART_BASE(IMX7D) -- cgit v0.10.2 From d482893b1caa5345b066c9721bab6636059e2a61 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Wed, 27 May 2015 00:25:57 +0800 Subject: rtc: snvs: use syscon to access register snvs included rtc, on/off key, power-off module change to syscon to access register Signed-off-by: Frank Li Acked-by: Alexandre Belloni Signed-off-by: Shawn Guo diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c index d87a85c..950c5d0 100644 --- a/drivers/rtc/rtc-snvs.c +++ b/drivers/rtc/rtc-snvs.c @@ -18,6 +18,10 @@ #include #include #include +#include +#include + +#define SNVS_LPREGISTER_OFFSET 0x34 /* These register offsets are relative to LP (Low Power) range */ #define SNVS_LPCR 0x04 @@ -37,31 +41,36 @@ struct snvs_rtc_data { struct rtc_device *rtc; - void __iomem *ioaddr; + struct regmap *regmap; + int offset; int irq; - spinlock_t lock; struct clk *clk; }; -static u32 rtc_read_lp_counter(void __iomem *ioaddr) +static u32 rtc_read_lp_counter(struct snvs_rtc_data *data) { u64 read1, read2; + u32 val; do { - read1 = readl(ioaddr + SNVS_LPSRTCMR); + regmap_read(data->regmap, data->offset + SNVS_LPSRTCMR, &val); + read1 = val; read1 <<= 32; - read1 |= readl(ioaddr + SNVS_LPSRTCLR); + regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &val); + read1 |= val; - read2 = readl(ioaddr + SNVS_LPSRTCMR); + regmap_read(data->regmap, data->offset + SNVS_LPSRTCMR, &val); + read2 = val; read2 <<= 32; - read2 |= readl(ioaddr + SNVS_LPSRTCLR); + regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &val); + read2 |= val; } while (read1 != read2); /* Convert 47-bit counter to 32-bit raw second count */ return (u32) (read1 >> CNTR_TO_SECS_SH); } -static void rtc_write_sync_lp(void __iomem *ioaddr) +static void rtc_write_sync_lp(struct snvs_rtc_data *data) { u32 count1, count2, count3; int i; @@ -69,15 +78,15 @@ static void rtc_write_sync_lp(void __iomem *ioaddr) /* Wait for 3 CKIL cycles */ for (i = 0; i < 3; i++) { do { - count1 = readl(ioaddr + SNVS_LPSRTCLR); - count2 = readl(ioaddr + SNVS_LPSRTCLR); + regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count1); + regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count2); } while (count1 != count2); /* Now wait until counter value changes */ do { do { - count2 = readl(ioaddr + SNVS_LPSRTCLR); - count3 = readl(ioaddr + SNVS_LPSRTCLR); + regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count2); + regmap_read(data->regmap, data->offset + SNVS_LPSRTCLR, &count3); } while (count2 != count3); } while (count3 == count1); } @@ -85,23 +94,14 @@ static void rtc_write_sync_lp(void __iomem *ioaddr) static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable) { - unsigned long flags; int timeout = 1000; u32 lpcr; - spin_lock_irqsave(&data->lock, flags); - - lpcr = readl(data->ioaddr + SNVS_LPCR); - if (enable) - lpcr |= SNVS_LPCR_SRTC_ENV; - else - lpcr &= ~SNVS_LPCR_SRTC_ENV; - writel(lpcr, data->ioaddr + SNVS_LPCR); - - spin_unlock_irqrestore(&data->lock, flags); + regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_SRTC_ENV, + enable ? SNVS_LPCR_SRTC_ENV : 0); while (--timeout) { - lpcr = readl(data->ioaddr + SNVS_LPCR); + regmap_read(data->regmap, data->offset + SNVS_LPCR, &lpcr); if (enable) { if (lpcr & SNVS_LPCR_SRTC_ENV) @@ -121,7 +121,7 @@ static int snvs_rtc_enable(struct snvs_rtc_data *data, bool enable) static int snvs_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct snvs_rtc_data *data = dev_get_drvdata(dev); - unsigned long time = rtc_read_lp_counter(data->ioaddr); + unsigned long time = rtc_read_lp_counter(data); rtc_time_to_tm(time, tm); @@ -139,8 +139,8 @@ static int snvs_rtc_set_time(struct device *dev, struct rtc_time *tm) snvs_rtc_enable(data, false); /* Write 32-bit time to 47-bit timer, leaving 15 LSBs blank */ - writel(time << CNTR_TO_SECS_SH, data->ioaddr + SNVS_LPSRTCLR); - writel(time >> (32 - CNTR_TO_SECS_SH), data->ioaddr + SNVS_LPSRTCMR); + regmap_write(data->regmap, data->offset + SNVS_LPSRTCLR, time << CNTR_TO_SECS_SH); + regmap_write(data->regmap, data->offset + SNVS_LPSRTCMR, time >> (32 - CNTR_TO_SECS_SH)); /* Enable RTC again */ snvs_rtc_enable(data, true); @@ -153,10 +153,10 @@ static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) struct snvs_rtc_data *data = dev_get_drvdata(dev); u32 lptar, lpsr; - lptar = readl(data->ioaddr + SNVS_LPTAR); + regmap_read(data->regmap, data->offset + SNVS_LPTAR, &lptar); rtc_time_to_tm(lptar, &alrm->time); - lpsr = readl(data->ioaddr + SNVS_LPSR); + regmap_read(data->regmap, data->offset + SNVS_LPSR, &lpsr); alrm->pending = (lpsr & SNVS_LPSR_LPTA) ? 1 : 0; return 0; @@ -165,21 +165,12 @@ static int snvs_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int snvs_rtc_alarm_irq_enable(struct device *dev, unsigned int enable) { struct snvs_rtc_data *data = dev_get_drvdata(dev); - u32 lpcr; - unsigned long flags; - - spin_lock_irqsave(&data->lock, flags); - lpcr = readl(data->ioaddr + SNVS_LPCR); - if (enable) - lpcr |= (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN); - else - lpcr &= ~(SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN); - writel(lpcr, data->ioaddr + SNVS_LPCR); + regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, + (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN), + enable ? (SNVS_LPCR_LPTA_EN | SNVS_LPCR_LPWUI_EN) : 0); - spin_unlock_irqrestore(&data->lock, flags); - - rtc_write_sync_lp(data->ioaddr); + rtc_write_sync_lp(data); return 0; } @@ -189,24 +180,14 @@ static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) struct snvs_rtc_data *data = dev_get_drvdata(dev); struct rtc_time *alrm_tm = &alrm->time; unsigned long time; - unsigned long flags; - u32 lpcr; rtc_tm_to_time(alrm_tm, &time); - spin_lock_irqsave(&data->lock, flags); - - /* Have to clear LPTA_EN before programming new alarm time in LPTAR */ - lpcr = readl(data->ioaddr + SNVS_LPCR); - lpcr &= ~SNVS_LPCR_LPTA_EN; - writel(lpcr, data->ioaddr + SNVS_LPCR); - - spin_unlock_irqrestore(&data->lock, flags); - - writel(time, data->ioaddr + SNVS_LPTAR); + regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_LPTA_EN, 0); + regmap_write(data->regmap, data->offset + SNVS_LPTAR, time); /* Clear alarm interrupt status bit */ - writel(SNVS_LPSR_LPTA, data->ioaddr + SNVS_LPSR); + regmap_write(data->regmap, data->offset + SNVS_LPSR, SNVS_LPSR_LPTA); return snvs_rtc_alarm_irq_enable(dev, alrm->enabled); } @@ -226,7 +207,7 @@ static irqreturn_t snvs_rtc_irq_handler(int irq, void *dev_id) u32 lpsr; u32 events = 0; - lpsr = readl(data->ioaddr + SNVS_LPSR); + regmap_read(data->regmap, data->offset + SNVS_LPSR, &lpsr); if (lpsr & SNVS_LPSR_LPTA) { events |= (RTC_AF | RTC_IRQF); @@ -238,25 +219,48 @@ static irqreturn_t snvs_rtc_irq_handler(int irq, void *dev_id) } /* clear interrupt status */ - writel(lpsr, data->ioaddr + SNVS_LPSR); + regmap_write(data->regmap, data->offset + SNVS_LPSR, lpsr); return events ? IRQ_HANDLED : IRQ_NONE; } +static const struct regmap_config snvs_rtc_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, +}; + static int snvs_rtc_probe(struct platform_device *pdev) { struct snvs_rtc_data *data; struct resource *res; int ret; + void __iomem *mmio; data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); if (!data) return -ENOMEM; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - data->ioaddr = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(data->ioaddr)) - return PTR_ERR(data->ioaddr); + data->regmap = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "regmap"); + + if (IS_ERR(data->regmap)) { + dev_warn(&pdev->dev, "snvs rtc: you use old dts file, please update it\n"); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + mmio = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(mmio)) + return PTR_ERR(mmio); + + data->regmap = devm_regmap_init_mmio(&pdev->dev, mmio, &snvs_rtc_config); + } else { + data->offset = SNVS_LPREGISTER_OFFSET; + of_property_read_u32(pdev->dev.of_node, "offset", &data->offset); + } + + if (!data->regmap) { + dev_err(&pdev->dev, "Can't find snvs syscon\n"); + return -ENODEV; + } data->irq = platform_get_irq(pdev, 0); if (data->irq < 0) @@ -276,13 +280,11 @@ static int snvs_rtc_probe(struct platform_device *pdev) platform_set_drvdata(pdev, data); - spin_lock_init(&data->lock); - /* Initialize glitch detect */ - writel(SNVS_LPPGDR_INIT, data->ioaddr + SNVS_LPPGDR); + regmap_write(data->regmap, data->offset + SNVS_LPPGDR, SNVS_LPPGDR_INIT); /* Clear interrupt status */ - writel(0xffffffff, data->ioaddr + SNVS_LPSR); + regmap_write(data->regmap, data->offset + SNVS_LPSR, 0xffffffff); /* Enable RTC */ snvs_rtc_enable(data, true); -- cgit v0.10.2 From 4fcb7dfd827d7d12ffc612fbc67769e002a482e4 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Wed, 27 May 2015 00:25:58 +0800 Subject: Document: dt: fsl: snvs: change support syscon snvs actually is multi fucntion driver. Change to use syscon to access register. Change snvs parent interrupt to option because single function may have seperated irq number. Signed-off-by: Frank Li Signed-off-by: Shawn Guo diff --git a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt index e402277..b21e7c2 100644 --- a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt +++ b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt @@ -288,12 +288,13 @@ Secure Non-Volatile Storage (SNVS) Node Node defines address range and the associated interrupt for the SNVS function. This function monitors security state information & reports - security violations. + security violations. This also included rtc, + system power off and ON/OFF key. - compatible Usage: required Value type: - Definition: Must include "fsl,sec-v4.0-mon". + Definition: Must include "fsl,sec-v4.0-mon" and "syscon". - reg Usage: required @@ -324,7 +325,7 @@ Secure Non-Volatile Storage (SNVS) Node the child address, parent address, & length. - interrupts - Usage: required + Usage: optional Value type: Definition: Specifies the interrupts generated by this device. The value of the interrupts property @@ -341,7 +342,7 @@ Secure Non-Volatile Storage (SNVS) Node EXAMPLE sec_mon@314000 { - compatible = "fsl,sec-v4.0-mon"; + compatible = "fsl,sec-v4.0-mon", "syscon"; reg = <0x314000 0x1000>; ranges = <0 0x314000 0x1000>; interrupt-parent = <&mpic>; @@ -358,16 +359,31 @@ Secure Non-Volatile Storage (SNVS) Low Power (LP) RTC Node Value type: Definition: Must include "fsl,sec-v4.0-mon-rtc-lp". - - reg + - interrupts Usage: required - Value type: - Definition: A standard property. Specifies the physical - address and length of the SNVS LP configuration registers. + Value type: + Definition: Specifies the interrupts generated by this + device. The value of the interrupts property + consists of one interrupt specifier. The format + of the specifier is defined by the binding document + describing the node's interrupt parent. + + - regmap + Usage: required + Value type: + Definition: this is phandle to the register map node. + + - offset + Usage: option + value type: + Definition: LP register offset. default it is 0x34. EXAMPLE - sec_mon_rtc_lp@314000 { + sec_mon_rtc_lp@1 { compatible = "fsl,sec-v4.0-mon-rtc-lp"; - reg = <0x34 0x58>; + interrupts = <93 2>; + regmap = <&snvs>; + offset = <0x34>; }; ===================================================================== @@ -443,12 +459,12 @@ FULL EXAMPLE compatible = "fsl,sec-v4.0-mon"; reg = <0x314000 0x1000>; ranges = <0 0x314000 0x1000>; - interrupt-parent = <&mpic>; - interrupts = <93 2>; sec_mon_rtc_lp@34 { compatible = "fsl,sec-v4.0-mon-rtc-lp"; - reg = <0x34 0x58>; + regmap = <&sec_mon>; + offset = <0x34>; + interrupts = <93 2>; }; }; -- cgit v0.10.2 From d3dc6e2322155087c19a1d6a71818be534de0602 Mon Sep 17 00:00:00 2001 From: Robin Gong Date: Wed, 27 May 2015 00:26:00 +0800 Subject: input: keyboard: imx: add snvs power key driver add snvs power key driver. It work in imx chips after i.mx6sx ON/OFF key used power on/off whole system. This driver make it wakeup from suspend state when short press ON/OFF key. Long time press will trig SNVS power off chip without software intervention. Signed-off-by: Robin Gong Signed-off-by: Frank Li Acked-by: Dmitry Torokhov Signed-off-by: Shawn Guo diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig index 4cd94fd..82a8fb5 100644 --- a/drivers/input/keyboard/Kconfig +++ b/drivers/input/keyboard/Kconfig @@ -401,6 +401,17 @@ config KEYBOARD_MPR121 To compile this driver as a module, choose M here: the module will be called mpr121_touchkey. +config KEYBOARD_SNVS_PWRKEY + tristate "IMX SNVS Power Key Driver" + depends on SOC_IMX6SX + depends on OF + help + This is the snvs powerkey driver for the Freescale i.MX application + processors that are newer than i.MX6 SX. + + To compile this driver as a module, choose M here; the + module will be called snvs_pwrkey. + config KEYBOARD_IMX tristate "IMX keypad support" depends on ARCH_MXC diff --git a/drivers/input/keyboard/Makefile b/drivers/input/keyboard/Makefile index df28d55..1d416dd 100644 --- a/drivers/input/keyboard/Makefile +++ b/drivers/input/keyboard/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_KEYBOARD_QT1070) += qt1070.o obj-$(CONFIG_KEYBOARD_QT2160) += qt2160.o obj-$(CONFIG_KEYBOARD_SAMSUNG) += samsung-keypad.o obj-$(CONFIG_KEYBOARD_SH_KEYSC) += sh_keysc.o +obj-$(CONFIG_KEYBOARD_SNVS_PWRKEY) += snvs_pwrkey.o obj-$(CONFIG_KEYBOARD_SPEAR) += spear-keyboard.o obj-$(CONFIG_KEYBOARD_STMPE) += stmpe-keypad.o obj-$(CONFIG_KEYBOARD_STOWAWAY) += stowaway.o diff --git a/drivers/input/keyboard/snvs_pwrkey.c b/drivers/input/keyboard/snvs_pwrkey.c new file mode 100644 index 0000000..512a1fc --- /dev/null +++ b/drivers/input/keyboard/snvs_pwrkey.c @@ -0,0 +1,227 @@ +/* + * Driver for the IMX SNVS ON/OFF Power Key + * Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved. + * + * The code contained herein is licensed under the GNU General Public + * License. You may obtain a copy of the GNU General Public License + * Version 2 or later at the following locations: + * + * http://www.opensource.org/licenses/gpl-license.html + * http://www.gnu.org/copyleft/gpl.html + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SNVS_LPSR_REG 0x4C /* LP Status Register */ +#define SNVS_LPCR_REG 0x38 /* LP Control Register */ +#define SNVS_HPSR_REG 0x14 +#define SNVS_HPSR_BTN BIT(6) +#define SNVS_LPSR_SPO BIT(18) +#define SNVS_LPCR_DEP_EN BIT(5) + +#define DEBOUNCE_TIME 30 +#define REPEAT_INTERVAL 60 + +struct pwrkey_drv_data { + struct regmap *snvs; + int irq; + int keycode; + int keystate; /* 1:pressed */ + int wakeup; + struct timer_list check_timer; + struct input_dev *input; +}; + +static void imx_imx_snvs_check_for_events(unsigned long data) +{ + struct pwrkey_drv_data *pdata = (struct pwrkey_drv_data *) data; + struct input_dev *input = pdata->input; + u32 state; + + regmap_read(pdata->snvs, SNVS_HPSR_REG, &state); + state = state & SNVS_HPSR_BTN ? 1 : 0; + + /* only report new event if status changed */ + if (state ^ pdata->keystate) { + pdata->keystate = state; + input_event(input, EV_KEY, pdata->keycode, state); + input_sync(input); + pm_relax(pdata->input->dev.parent); + } + + /* repeat check if pressed long */ + if (state) { + mod_timer(&pdata->check_timer, + jiffies + msecs_to_jiffies(REPEAT_INTERVAL)); + } +} + +static irqreturn_t imx_snvs_pwrkey_interrupt(int irq, void *dev_id) +{ + struct platform_device *pdev = dev_id; + struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev); + u32 lp_status; + + pm_wakeup_event(pdata->input->dev.parent, 0); + + regmap_read(pdata->snvs, SNVS_LPSR_REG, &lp_status); + if (lp_status & SNVS_LPSR_SPO) + mod_timer(&pdata->check_timer, jiffies + msecs_to_jiffies(DEBOUNCE_TIME)); + + /* clear SPO status */ + regmap_write(pdata->snvs, SNVS_LPSR_REG, SNVS_LPSR_SPO); + + return IRQ_HANDLED; +} + +static void imx_snvs_pwrkey_act(void *pdata) +{ + struct pwrkey_drv_data *pd = pdata; + + del_timer_sync(&pd->check_timer); +} + +static int imx_snvs_pwrkey_probe(struct platform_device *pdev) +{ + struct pwrkey_drv_data *pdata = NULL; + struct input_dev *input = NULL; + struct device_node *np; + int error; + + /* Get SNVS register Page */ + np = pdev->dev.of_node; + if (!np) + return -ENODEV; + + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + + pdata->snvs = syscon_regmap_lookup_by_phandle(np, "regmap");; + + if (!pdata->snvs) { + dev_err(&pdev->dev, "Can't get snvs syscon\n"); + return -ENODEV; + } + + if (of_property_read_u32(np, "linux,keycode", &pdata->keycode)) { + pdata->keycode = KEY_POWER; + dev_warn(&pdev->dev, "KEY_POWER without setting in dts\n"); + } + + pdata->wakeup = of_property_read_bool(np, "wakeup"); + + pdata->irq = platform_get_irq(pdev, 0); + if (pdata->irq < 0) { + dev_err(&pdev->dev, "no irq defined in platform data\n"); + return -EINVAL; + } + + regmap_update_bits(pdata->snvs, SNVS_LPCR_REG, SNVS_LPCR_DEP_EN, SNVS_LPCR_DEP_EN); + + /* clear the unexpected interrupt before driver ready */ + regmap_write(pdata->snvs, SNVS_LPSR_REG, SNVS_LPSR_SPO); + + setup_timer(&pdata->check_timer, + imx_imx_snvs_check_for_events, (unsigned long) pdata); + + input = devm_input_allocate_device(&pdev->dev); + if (!input) { + dev_err(&pdev->dev, "failed to allocate the input device\n"); + return -ENOMEM; + } + + input->name = pdev->name; + input->phys = "snvs-pwrkey/input0"; + input->id.bustype = BUS_HOST; + + input_set_capability(input, EV_KEY, pdata->keycode); + + /* input customer action to cancel release timer */ + error = devm_add_action(&pdev->dev, imx_snvs_pwrkey_act, pdata); + if (error) { + dev_err(&pdev->dev, "failed to register remove action\n"); + return error; + } + + error = devm_request_irq(&pdev->dev, pdata->irq, + imx_snvs_pwrkey_interrupt, + 0, pdev->name, pdev); + + if (error) { + dev_err(&pdev->dev, "interrupt not available.\n"); + return error; + } + + error = input_register_device(input); + if (error < 0) { + dev_err(&pdev->dev, "failed to register input device\n"); + input_free_device(input); + return error; + } + + pdata->input = input; + platform_set_drvdata(pdev, pdata); + + device_init_wakeup(&pdev->dev, pdata->wakeup); + + return 0; +} + +static int imx_snvs_pwrkey_suspend(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev); + + if (device_may_wakeup(&pdev->dev)) + enable_irq_wake(pdata->irq); + + return 0; +} + +static int imx_snvs_pwrkey_resume(struct device *dev) +{ + struct platform_device *pdev = to_platform_device(dev); + struct pwrkey_drv_data *pdata = platform_get_drvdata(pdev); + + if (device_may_wakeup(&pdev->dev)) + disable_irq_wake(pdata->irq); + + return 0; +} + +static const struct of_device_id imx_snvs_pwrkey_ids[] = { + { .compatible = "fsl,sec-v4.0-pwrkey" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, imx_snvs_pwrkey_ids); + +static SIMPLE_DEV_PM_OPS(imx_snvs_pwrkey_pm_ops, imx_snvs_pwrkey_suspend, + imx_snvs_pwrkey_resume); + +static struct platform_driver imx_snvs_pwrkey_driver = { + .driver = { + .name = "snvs_pwrkey", + .pm = &imx_snvs_pwrkey_pm_ops, + .of_match_table = imx_snvs_pwrkey_ids, + }, + .probe = imx_snvs_pwrkey_probe, +}; +module_platform_driver(imx_snvs_pwrkey_driver); + +MODULE_AUTHOR("Freescale Semiconductor"); +MODULE_DESCRIPTION("i.MX snvs power key Driver"); +MODULE_LICENSE("GPL"); -- cgit v0.10.2 From cc28791d5ece61eaa78e7b9bbc3ac1d14f664683 Mon Sep 17 00:00:00 2001 From: Frank Li Date: Wed, 27 May 2015 00:26:01 +0800 Subject: Document: devicetree: input: imx: i.mx snvs power device tree bindings The snvs-pwrkey is designed to enable POWER key function which controlled by SNVS ONOFF. the driver can report the status of POWER key and wakeup system if pressed after system suspend. Signed-off-by: Frank Li Signed-off-by: Robin Gong Signed-off-by: Shawn Guo diff --git a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt index b21e7c2..71a39c5 100644 --- a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt +++ b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt @@ -387,6 +387,47 @@ EXAMPLE }; ===================================================================== +System ON/OFF key driver + + The snvs-pwrkey is designed to enable POWER key function which controlled + by SNVS ONOFF, the driver can report the status of POWER key and wakeup + system if pressed after system suspend. + + - compatible: + Usage: required + Value type: + Definition: Mush include "fsl,sec-v4.0-pwrkey". + + - interrupts: + Usage: required + Value type: + Definition: The SNVS ON/OFF interrupt number to the CPU(s). + + - linux,keycode: + Usage: option + Value type: + Definition: Keycode to emit, KEY_POWER by default. + + - wakeup: + Usage: option + Value type: + Definition: Button can wake-up the system. + + - regmap: + Usage: required: + Value type: + Definition: this is phandle to the register map node. + +EXAMPLE: + snvs-pwrkey@0x020cc000 { + compatible = "fsl,sec-v4.0-pwrkey"; + regmap = <&snvs>; + interrupts = <0 4 0x4> + linux,keycode = <116>; /* KEY_POWER */ + wakeup; + }; + +===================================================================== FULL EXAMPLE crypto: crypto@300000 { @@ -466,6 +507,14 @@ FULL EXAMPLE offset = <0x34>; interrupts = <93 2>; }; + + snvs-pwrkey@0x020cc000 { + compatible = "fsl,sec-v4.0-pwrkey"; + regmap = <&sec_mon>; + interrupts = <0 4 0x4>; + linux,keycode = <116>; /* KEY_POWER */ + wakeup; + }; }; ===================================================================== diff --git a/Documentation/devicetree/bindings/input/snvs-pwrkey.txt b/Documentation/devicetree/bindings/input/snvs-pwrkey.txt new file mode 100644 index 0000000..70c1425 --- /dev/null +++ b/Documentation/devicetree/bindings/input/snvs-pwrkey.txt @@ -0,0 +1 @@ +See Documentation/devicetree/bindings/crypto/fsl-sec4.txt -- cgit v0.10.2 From b9e23f321940d2db2c9def8ff723b8464fb86343 Mon Sep 17 00:00:00 2001 From: Vignesh R Date: Wed, 3 Jun 2015 17:21:20 +0530 Subject: ARM: OMAP2+: DRA7: clockdomain: change l4per2_7xx_clkdm to SW_WKUP Legacy IPs like PWMSS, present under l4per2_7xx_clkdm, cannot support smart-idle when its clock domain is in HW_AUTO on DRA7 SoCs. Hence, program clock domain to SW_WKUP. Signed-off-by: Vignesh R Acked-by: Tero Kristo Reviewed-by: Paul Walmsley Signed-off-by: Paul Walmsley Cc: diff --git a/arch/arm/mach-omap2/clockdomains7xx_data.c b/arch/arm/mach-omap2/clockdomains7xx_data.c index 57d5df0..7581e03 100644 --- a/arch/arm/mach-omap2/clockdomains7xx_data.c +++ b/arch/arm/mach-omap2/clockdomains7xx_data.c @@ -331,7 +331,7 @@ static struct clockdomain l4per2_7xx_clkdm = { .dep_bit = DRA7XX_L4PER2_STATDEP_SHIFT, .wkdep_srcs = l4per2_wkup_sleep_deps, .sleepdep_srcs = l4per2_wkup_sleep_deps, - .flags = CLKDM_CAN_HWSUP_SWSUP, + .flags = CLKDM_CAN_SWSUP, }; static struct clockdomain mpu0_7xx_clkdm = { -- cgit v0.10.2 From aaf2c0fbbbb1ec56936e726eec6c253bc4bd469f Mon Sep 17 00:00:00 2001 From: Lokesh Vutla Date: Wed, 10 Jun 2015 14:56:24 +0530 Subject: ARM: OMAP2+: hwmod: add support for lock and unlock hooks Some IP blocks like RTC, needs an additional setting for writing to its registers. This is to prevent any spurious writes from changing the register values. This patch adds optional lock and unlock function pointers to the IP block's hwmod data. These unlock and lock function pointers are called by hwmod code before and after writing sysconfig registers. Signed-off-by: Lokesh Vutla [paul@pwsan.com: fixed indentation level to conform with the rest of the structure members] Reviewed-by: Paul Walmsley Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index d78c12e..2ceed31 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -299,7 +299,20 @@ static void _write_sysconfig(u32 v, struct omap_hwmod *oh) /* Module might have lost context, always update cache and register */ oh->_sysc_cache = v; + + /* + * Some IP blocks (such as RTC) require unlocking of IP before + * accessing its registers. If a function pointer is present + * to unlock, then call it before accessing sysconfig and + * call lock after writing sysconfig. + */ + if (oh->class->unlock) + oh->class->unlock(oh); + omap_hwmod_write(v, oh, oh->class->sysc->sysc_offs); + + if (oh->class->lock) + oh->class->lock(oh); } /** diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h index b5d27ec..13f3902 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h @@ -576,6 +576,8 @@ struct omap_hwmod_omap4_prcm { * @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 + * @lock: ptr to fn to be executed to lock IP registers + * @unlock: ptr to fn to be executed to unlock IP registers * * Represent the class of a OMAP hardware "modules" (e.g. timer, * smartreflex, gpio, uart...) @@ -600,6 +602,8 @@ struct omap_hwmod_class { int (*pre_shutdown)(struct omap_hwmod *oh); int (*reset)(struct omap_hwmod *oh); int (*enable_preprogram)(struct omap_hwmod *oh); + void (*lock)(struct omap_hwmod *oh); + void (*unlock)(struct omap_hwmod *oh); }; /** -- cgit v0.10.2 From f734a9b3b19e01d598d03a336de32a59a52c1575 Mon Sep 17 00:00:00 2001 From: Sekhar Nori Date: Sat, 11 Jul 2015 20:29:15 +0530 Subject: ARM: OMAP2+: sparse: add missing static declaration Add missing static declaration for file local variables. This fixes sparse warnings of type: arch/arm/mach-omap2/omap_hwmod_81xx_data.c:491:26: warning: symbol 'dm81xx_alwon_l3_slow__gpmc' was not declared. Should it be static? Signed-off-by: Sekhar Nori Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index 79f49d9..65024af 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c @@ -105,7 +105,7 @@ static void dummy_cpu_resume(void) static void dummy_scu_prepare(unsigned int cpu_id, unsigned int cpu_state) {} -struct cpu_pm_ops omap_pm_ops = { +static struct cpu_pm_ops omap_pm_ops = { .finish_suspend = default_finish_suspend, .resume = dummy_cpu_resume, .scu_prepare = dummy_scu_prepare, 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 6dcfd03..36bcd2e 100644 --- a/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c @@ -20,7 +20,7 @@ #include "prm-regbits-24xx.h" #include "wd_timer.h" -struct omap_hwmod_dma_info omap2xxx_dss_sdma_chs[] = { +static struct omap_hwmod_dma_info omap2xxx_dss_sdma_chs[] = { { .name = "dispc", .dma_req = 5 }, { .dma_req = -1, }, }; diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c index 215d5ef..e97a894 100644 --- a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c @@ -480,7 +480,7 @@ static struct omap_hwmod am43xx_dss_core_hwmod = { /* dispc */ -struct omap_dss_dispc_dev_attr am43xx_dss_dispc_dev_attr = { +static struct omap_dss_dispc_dev_attr am43xx_dss_dispc_dev_attr = { .manager_count = 1, .has_framedonetv_irq = 0 }; diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c index c924137..280789a 100644 --- a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c @@ -488,7 +488,7 @@ static struct omap_hwmod dm81xx_gpmc_hwmod = { }, }; -struct omap_hwmod_ocp_if dm81xx_alwon_l3_slow__gpmc = { +static struct omap_hwmod_ocp_if dm81xx_alwon_l3_slow__gpmc = { .master = &dm816x_alwon_l3_slow_hwmod, .slave = &dm81xx_gpmc_hwmod, .user = OCP_USER_MPU, @@ -729,7 +729,7 @@ static struct omap_hwmod_class dm816x_mdio_hwmod_class = { .sysc = &dm816x_emac_sysc, }; -struct omap_hwmod dm816x_emac0_mdio_hwmod = { +static struct omap_hwmod dm816x_emac0_mdio_hwmod = { .name = "davinci_mdio", .class = &dm816x_mdio_hwmod_class, .clkdm_name = "alwon_ethernet_clkdm", @@ -747,7 +747,7 @@ struct omap_hwmod dm816x_emac0_mdio_hwmod = { }, }; -struct omap_hwmod_ocp_if dm816x_emac0__mdio = { +static struct omap_hwmod_ocp_if dm816x_emac0__mdio = { .master = &dm816x_l4_hs_hwmod, .slave = &dm816x_emac0_mdio_hwmod, .user = OCP_USER_MPU, @@ -902,7 +902,7 @@ static struct omap_hwmod_class dm816x_tpcc_hwmod_class = { .name = "tpcc", }; -struct omap_hwmod dm816x_tpcc_hwmod = { +static struct omap_hwmod dm816x_tpcc_hwmod = { .name = "tpcc", .class = &dm816x_tpcc_hwmod_class, .clkdm_name = "alwon_l3s_clkdm", @@ -915,7 +915,7 @@ struct omap_hwmod dm816x_tpcc_hwmod = { }, }; -struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tpcc = { +static struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tpcc = { .master = &dm816x_alwon_l3_fast_hwmod, .slave = &dm816x_tpcc_hwmod, .clk = "sysclk4_ck", @@ -935,7 +935,7 @@ static struct omap_hwmod_class dm816x_tptc0_hwmod_class = { .name = "tptc0", }; -struct omap_hwmod dm816x_tptc0_hwmod = { +static struct omap_hwmod dm816x_tptc0_hwmod = { .name = "tptc0", .class = &dm816x_tptc0_hwmod_class, .clkdm_name = "alwon_l3s_clkdm", @@ -948,7 +948,7 @@ struct omap_hwmod dm816x_tptc0_hwmod = { }, }; -struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc0 = { +static struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc0 = { .master = &dm816x_alwon_l3_fast_hwmod, .slave = &dm816x_tptc0_hwmod, .clk = "sysclk4_ck", @@ -956,7 +956,7 @@ struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc0 = { .user = OCP_USER_MPU, }; -struct omap_hwmod_ocp_if dm816x_tptc0__alwon_l3_fast = { +static struct omap_hwmod_ocp_if dm816x_tptc0__alwon_l3_fast = { .master = &dm816x_tptc0_hwmod, .slave = &dm816x_alwon_l3_fast_hwmod, .clk = "sysclk4_ck", @@ -977,7 +977,7 @@ static struct omap_hwmod_class dm816x_tptc1_hwmod_class = { .name = "tptc1", }; -struct omap_hwmod dm816x_tptc1_hwmod = { +static struct omap_hwmod dm816x_tptc1_hwmod = { .name = "tptc1", .class = &dm816x_tptc1_hwmod_class, .clkdm_name = "alwon_l3s_clkdm", @@ -990,7 +990,7 @@ struct omap_hwmod dm816x_tptc1_hwmod = { }, }; -struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc1 = { +static struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc1 = { .master = &dm816x_alwon_l3_fast_hwmod, .slave = &dm816x_tptc1_hwmod, .clk = "sysclk4_ck", @@ -998,7 +998,7 @@ struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc1 = { .user = OCP_USER_MPU, }; -struct omap_hwmod_ocp_if dm816x_tptc1__alwon_l3_fast = { +static struct omap_hwmod_ocp_if dm816x_tptc1__alwon_l3_fast = { .master = &dm816x_tptc1_hwmod, .slave = &dm816x_alwon_l3_fast_hwmod, .clk = "sysclk4_ck", @@ -1019,7 +1019,7 @@ static struct omap_hwmod_class dm816x_tptc2_hwmod_class = { .name = "tptc2", }; -struct omap_hwmod dm816x_tptc2_hwmod = { +static struct omap_hwmod dm816x_tptc2_hwmod = { .name = "tptc2", .class = &dm816x_tptc2_hwmod_class, .clkdm_name = "alwon_l3s_clkdm", @@ -1032,7 +1032,7 @@ struct omap_hwmod dm816x_tptc2_hwmod = { }, }; -struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc2 = { +static struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc2 = { .master = &dm816x_alwon_l3_fast_hwmod, .slave = &dm816x_tptc2_hwmod, .clk = "sysclk4_ck", @@ -1040,7 +1040,7 @@ struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc2 = { .user = OCP_USER_MPU, }; -struct omap_hwmod_ocp_if dm816x_tptc2__alwon_l3_fast = { +static struct omap_hwmod_ocp_if dm816x_tptc2__alwon_l3_fast = { .master = &dm816x_tptc2_hwmod, .slave = &dm816x_alwon_l3_fast_hwmod, .clk = "sysclk4_ck", @@ -1061,7 +1061,7 @@ static struct omap_hwmod_class dm816x_tptc3_hwmod_class = { .name = "tptc3", }; -struct omap_hwmod dm816x_tptc3_hwmod = { +static struct omap_hwmod dm816x_tptc3_hwmod = { .name = "tptc3", .class = &dm816x_tptc3_hwmod_class, .clkdm_name = "alwon_l3s_clkdm", @@ -1074,7 +1074,7 @@ struct omap_hwmod dm816x_tptc3_hwmod = { }, }; -struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc3 = { +static struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc3 = { .master = &dm816x_alwon_l3_fast_hwmod, .slave = &dm816x_tptc3_hwmod, .clk = "sysclk4_ck", @@ -1082,7 +1082,7 @@ struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc3 = { .user = OCP_USER_MPU, }; -struct omap_hwmod_ocp_if dm816x_tptc3__alwon_l3_fast = { +static struct omap_hwmod_ocp_if dm816x_tptc3__alwon_l3_fast = { .master = &dm816x_tptc3_hwmod, .slave = &dm816x_alwon_l3_fast_hwmod, .clk = "sysclk4_ck", diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c index 821171c..1a352f5 100644 --- a/arch/arm/mach-omap2/pdata-quirks.c +++ b/arch/arm/mach-omap2/pdata-quirks.c @@ -31,7 +31,7 @@ struct pdata_init { void (*fn)(void); }; -struct of_dev_auxdata omap_auxdata_lookup[]; +static struct of_dev_auxdata omap_auxdata_lookup[]; static struct twl4030_gpio_platform_data twl_gpio_auxdata; #ifdef CONFIG_MACH_NOKIA_N8X0 @@ -128,7 +128,7 @@ static void __init omap3_sbc_t3530_legacy_init(void) omap3_sbc_t3x_usb_hub_init(167, "sb-t35 usb hub"); } -struct ti_st_plat_data wilink_pdata = { +static struct ti_st_plat_data wilink_pdata = { .nshutdown_gpio = 137, .dev_name = "/dev/ttyO1", .flow_cntrl = 1, @@ -323,7 +323,7 @@ static struct pdata_init auxdata_quirks[] __initdata = { { /* sentinel */ }, }; -struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { +static struct of_dev_auxdata omap_auxdata_lookup[] __initdata = { #ifdef CONFIG_MACH_NOKIA_N8X0 OF_DEV_AUXDATA("ti,omap2420-mmc", 0x4809c000, "mmci-omap.0", NULL), OF_DEV_AUXDATA("menelaus", 0x72, "1-0072", &n8x0_menelaus_platform_data), -- cgit v0.10.2 From 9e5d46b0510e686550c486c410491291c67e8f0e Mon Sep 17 00:00:00 2001 From: Sekhar Nori Date: Sat, 11 Jul 2015 20:29:16 +0530 Subject: ARM: OMAP2+: sparse: add missing function declarations omap3xxx_restart() and omap44xx_restart() are global functions declared in common.h. Include this file in omap3-restart.c and omap4-restart.c to prevent sparse warnings of type: arch/arm/mach-omap2/omap4-restart.c:22:6: warning: symbol 'omap44xx_restart' was not declared. Should it be static? Signed-off-by: Sekhar Nori Reviewed-by: Paul Walmsley Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/omap3-restart.c b/arch/arm/mach-omap2/omap3-restart.c index 103a49f..4bdd22e 100644 --- a/arch/arm/mach-omap2/omap3-restart.c +++ b/arch/arm/mach-omap2/omap3-restart.c @@ -14,6 +14,7 @@ #include #include +#include "common.h" #include "control.h" #include "prm.h" diff --git a/arch/arm/mach-omap2/omap4-restart.c b/arch/arm/mach-omap2/omap4-restart.c index a99e7f7..e17136a 100644 --- a/arch/arm/mach-omap2/omap4-restart.c +++ b/arch/arm/mach-omap2/omap4-restart.c @@ -9,6 +9,7 @@ #include #include +#include "common.h" #include "prm.h" /** -- cgit v0.10.2 From 9a0cb98589037c0ccb6210f5fd827445b3710c5e Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Tue, 30 Jun 2015 14:00:16 +0200 Subject: ARM: OMAP2: Delete an unnecessary check The of_node_put() function tests whether its argument is NULL and then returns immediately if so. Furthermore, the kerneldoc for of_node_put() explicitly supports passing in a NULL pointer as its argument. Thus the test around the call is not needed. This issue was detected by using the Coccinelle software. Signed-off-by: Markus Elfring [paul@pwsan.com: dropped the omap_device.c and omap_hwmod.c changes for now, edited the commit message accordingly and to note the documented "contract"] Reviewed-by: Paul Walmsley Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index cac46d8..15448221 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -208,8 +208,7 @@ static void __init omap_dmtimer_init(void) /* If we are a secure device, remove any secure timer nodes */ if ((omap_type() != OMAP2_DEVICE_TYPE_GP)) { np = omap_get_timer_dt(omap_timer_match, "ti,timer-secure"); - if (np) - of_node_put(np); + of_node_put(np); } } -- cgit v0.10.2 From d1dabab2841d546f8b946b4940fc63c15e35a739 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Wed, 3 Jun 2015 15:26:20 -0700 Subject: ARM: OMAP2+: Clean up omap4_local_timer_init Inspired by a patch from Felipe Balbi , we can now get rid of most the code in omap4_local_timer_init. Omap4 is now device tree only.. And we have not properly supported omap4 ES1.0 revision for a really long time AFAIK. Let's just remove all that code to simplify things. This assumes we have arm,cortex-a9-twd-timer entry in the omap4.dtsi file, which we do. Reviewed-by: Felipe Balbi Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index cac46d8..c52051b 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -649,23 +649,10 @@ static OMAP_SYS_32K_TIMER_INIT(4, 1, "timer_32k_ck", "ti,timer-alwon", #ifdef CONFIG_ARCH_OMAP4 #ifdef CONFIG_HAVE_ARM_TWD -static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, OMAP44XX_LOCAL_TWD_BASE, 29); void __init omap4_local_timer_init(void) { omap4_sync32k_timer_init(); - /* Local timers are not supprted on OMAP4430 ES1.0 */ - if (omap_rev() != OMAP4430_REV_ES1_0) { - int err; - - if (of_have_populated_dt()) { - clocksource_of_init(); - return; - } - - err = twd_local_timer_register(&twd_local_timer); - if (err) - pr_err("twd_local_timer_register failed %d\n", err); - } + clocksource_of_init(); } #else void __init omap4_local_timer_init(void) -- cgit v0.10.2 From ea827ad5ffbb78812f6dbdee005e1f364b6bdc58 Mon Sep 17 00:00:00 2001 From: Nishanth Menon Date: Mon, 22 Jun 2015 10:12:14 -0500 Subject: ARM: DRA7: Provide proper IO map table DRA7 uses OMAP5 IO table at the moment. This is purely spurious since the OMAP5 and DRA7 register maps are different in many aspects. AM57xx/DRA7 TRM Reference: http://www.ti.com/lit/ug/spruhz6/spruhz6.pdf NOTE: Most of the drivers are already doing ioremap, so, there should'nt be any functional improvement involved here, other than making the initial iotable more accurate. Fixes: a3a9384a1157 ("ARM: DRA7: Reuse io tables and add a new .init_early") Signed-off-by: Nishanth Menon Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 34ff14b..b4fbe50 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -297,7 +297,7 @@ static const char *const dra74x_boards_compat[] __initconst = { DT_MACHINE_START(DRA74X_DT, "Generic DRA74X (Flattened Device Tree)") .reserve = omap_reserve, .smp = smp_ops(omap4_smp_ops), - .map_io = omap5_map_io, + .map_io = dra7xx_map_io, .init_early = dra7xx_init_early, .init_late = dra7xx_init_late, .init_irq = omap_gic_of_init, @@ -316,7 +316,7 @@ static const char *const dra72x_boards_compat[] __initconst = { DT_MACHINE_START(DRA72X_DT, "Generic DRA72X (Flattened Device Tree)") .reserve = omap_reserve, - .map_io = omap5_map_io, + .map_io = dra7xx_map_io, .init_early = dra7xx_init_early, .init_late = dra7xx_init_late, .init_irq = omap_gic_of_init, diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h index cf3cf22..749d50b 100644 --- a/arch/arm/mach-omap2/common.h +++ b/arch/arm/mach-omap2/common.h @@ -198,6 +198,7 @@ void __init omap3_map_io(void); void __init am33xx_map_io(void); void __init omap4_map_io(void); void __init omap5_map_io(void); +void __init dra7xx_map_io(void); void __init ti81xx_map_io(void); /** diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 820dde8..c10fb29 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -236,7 +236,7 @@ static struct map_desc omap44xx_io_desc[] __initdata = { }; #endif -#if defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX) +#ifdef CONFIG_SOC_OMAP5 static struct map_desc omap54xx_io_desc[] __initdata = { { .virtual = L3_54XX_VIRT, @@ -265,6 +265,53 @@ static struct map_desc omap54xx_io_desc[] __initdata = { }; #endif +#ifdef CONFIG_SOC_DRA7XX +static struct map_desc dra7xx_io_desc[] __initdata = { + { + .virtual = L4_CFG_MPU_DRA7XX_VIRT, + .pfn = __phys_to_pfn(L4_CFG_MPU_DRA7XX_PHYS), + .length = L4_CFG_MPU_DRA7XX_SIZE, + .type = MT_DEVICE, + }, + { + .virtual = L3_MAIN_SN_DRA7XX_VIRT, + .pfn = __phys_to_pfn(L3_MAIN_SN_DRA7XX_PHYS), + .length = L3_MAIN_SN_DRA7XX_SIZE, + .type = MT_DEVICE, + }, + { + .virtual = L4_PER1_DRA7XX_VIRT, + .pfn = __phys_to_pfn(L4_PER1_DRA7XX_PHYS), + .length = L4_PER1_DRA7XX_SIZE, + .type = MT_DEVICE, + }, + { + .virtual = L4_PER2_DRA7XX_VIRT, + .pfn = __phys_to_pfn(L4_PER2_DRA7XX_PHYS), + .length = L4_PER2_DRA7XX_SIZE, + .type = MT_DEVICE, + }, + { + .virtual = L4_PER3_DRA7XX_VIRT, + .pfn = __phys_to_pfn(L4_PER3_DRA7XX_PHYS), + .length = L4_PER3_DRA7XX_SIZE, + .type = MT_DEVICE, + }, + { + .virtual = L4_CFG_DRA7XX_VIRT, + .pfn = __phys_to_pfn(L4_CFG_DRA7XX_PHYS), + .length = L4_CFG_DRA7XX_SIZE, + .type = MT_DEVICE, + }, + { + .virtual = L4_WKUP_DRA7XX_VIRT, + .pfn = __phys_to_pfn(L4_WKUP_DRA7XX_PHYS), + .length = L4_WKUP_DRA7XX_SIZE, + .type = MT_DEVICE, + }, +}; +#endif + #ifdef CONFIG_SOC_OMAP2420 void __init omap242x_map_io(void) { @@ -309,12 +356,19 @@ void __init omap4_map_io(void) } #endif -#if defined(CONFIG_SOC_OMAP5) || defined(CONFIG_SOC_DRA7XX) +#ifdef CONFIG_SOC_OMAP5 void __init omap5_map_io(void) { iotable_init(omap54xx_io_desc, ARRAY_SIZE(omap54xx_io_desc)); } #endif + +#ifdef CONFIG_SOC_DRA7XX +void __init dra7xx_map_io(void) +{ + iotable_init(dra7xx_io_desc, ARRAY_SIZE(dra7xx_io_desc)); +} +#endif /* * omap2_init_reprogram_sdrc - reprogram SDRC timing parameters * diff --git a/arch/arm/mach-omap2/iomap.h b/arch/arm/mach-omap2/iomap.h index cce2b65..6191d24 100644 --- a/arch/arm/mach-omap2/iomap.h +++ b/arch/arm/mach-omap2/iomap.h @@ -194,3 +194,66 @@ #define L4_PER_54XX_PHYS L4_PER_54XX_BASE /* 0x48000000 --> 0xfa000000 */ #define L4_PER_54XX_VIRT (L4_PER_54XX_PHYS + OMAP2_L4_IO_OFFSET) #define L4_PER_54XX_SIZE SZ_4M + +/* + * ---------------------------------------------------------------------------- + * DRA7xx specific IO mapping + * ---------------------------------------------------------------------------- + */ +/* + * L3_MAIN_SN_DRA7XX_PHYS 0x44000000 --> 0xf8000000 + * The overall space is 24MiB (0x4400_0000<->0x457F_FFFF), but mapping + * everything is just inefficient, since, there are too many address holes. + */ +#define L3_MAIN_SN_DRA7XX_PHYS L3_MAIN_SN_DRA7XX_BASE +#define L3_MAIN_SN_DRA7XX_VIRT (L3_MAIN_SN_DRA7XX_PHYS + OMAP4_L3_IO_OFFSET) +#define L3_MAIN_SN_DRA7XX_SIZE SZ_1M + +/* + * L4_PER1_DRA7XX_PHYS (0x4800_000<>0x480D_2FFF) -> 0.82MiB (alloc 1MiB) + * (0x48000000<->0x48100000) <=> (0xFA000000<->0xFA100000) + */ +#define L4_PER1_DRA7XX_PHYS L4_PER1_DRA7XX_BASE +#define L4_PER1_DRA7XX_VIRT (L4_PER1_DRA7XX_PHYS + OMAP2_L4_IO_OFFSET) +#define L4_PER1_DRA7XX_SIZE SZ_1M + +/* + * L4_CFG_MPU_DRA7XX_PHYS (0x48210000<>0x482A_F2FF) -> 0.62MiB (alloc 1MiB) + * (0x48210000<->0x48310000) <=> (0xFA210000<->0xFA310000) + * NOTE: This is a bit of an orphan memory map sitting isolated in TRM + */ +#define L4_CFG_MPU_DRA7XX_PHYS L4_CFG_MPU_DRA7XX_BASE +#define L4_CFG_MPU_DRA7XX_VIRT (L4_CFG_MPU_DRA7XX_PHYS + OMAP2_L4_IO_OFFSET) +#define L4_CFG_MPU_DRA7XX_SIZE SZ_1M + +/* + * L4_PER2_DRA7XX_PHYS (0x4840_0000<>0x4848_8FFF) -> .53MiB (alloc 1MiB) + * (0x48400000<->0x48500000) <=> (0xFA400000<->0xFA500000) + */ +#define L4_PER2_DRA7XX_PHYS L4_PER2_DRA7XX_BASE +#define L4_PER2_DRA7XX_VIRT (L4_PER2_DRA7XX_PHYS + OMAP2_L4_IO_OFFSET) +#define L4_PER2_DRA7XX_SIZE SZ_1M + +/* + * L4_PER3_DRA7XX_PHYS (0x4880_0000<>0x489E_0FFF) -> 1.87MiB (alloc 2MiB) + * (0x48800000<->0x48A00000) <=> (0xFA800000<->0xFAA00000) + */ +#define L4_PER3_DRA7XX_PHYS L4_PER3_DRA7XX_BASE +#define L4_PER3_DRA7XX_VIRT (L4_PER3_DRA7XX_PHYS + OMAP2_L4_IO_OFFSET) +#define L4_PER3_DRA7XX_SIZE SZ_2M + +/* + * L4_CFG_DRA7XX_PHYS (0x4A00_0000<>0x4A22_BFFF) ->2.17MiB (alloc 3MiB)? + * (0x4A000000<->0x4A300000) <=> (0xFC000000<->0xFC300000) + */ +#define L4_CFG_DRA7XX_PHYS L4_CFG_DRA7XX_BASE +#define L4_CFG_DRA7XX_VIRT (L4_CFG_DRA7XX_PHYS + OMAP2_L4_IO_OFFSET) +#define L4_CFG_DRA7XX_SIZE (SZ_1M + SZ_2M) + +/* + * L4_WKUP_DRA7XX_PHYS (0x4AE0_0000<>0x4AE3_EFFF) -> .24 mb (alloc 1MiB)? + * (0x4AE00000<->4AF00000) <=> (0xFCE00000<->0xFCF00000) + */ +#define L4_WKUP_DRA7XX_PHYS L4_WKUP_DRA7XX_BASE +#define L4_WKUP_DRA7XX_VIRT (L4_WKUP_DRA7XX_PHYS + OMAP2_L4_IO_OFFSET) +#define L4_WKUP_DRA7XX_SIZE SZ_1M diff --git a/arch/arm/mach-omap2/omap54xx.h b/arch/arm/mach-omap2/omap54xx.h index 2d35c57..0ca8e93 100644 --- a/arch/arm/mach-omap2/omap54xx.h +++ b/arch/arm/mach-omap2/omap54xx.h @@ -30,6 +30,14 @@ #define OMAP54XX_CTRL_BASE 0x4a002800 #define OMAP54XX_SAR_RAM_BASE 0x4ae26000 +/* DRA7 specific base addresses */ +#define L3_MAIN_SN_DRA7XX_BASE 0x44000000 +#define L4_PER1_DRA7XX_BASE 0x48000000 +#define L4_CFG_MPU_DRA7XX_BASE 0x48210000 +#define L4_PER2_DRA7XX_BASE 0x48400000 +#define L4_PER3_DRA7XX_BASE 0x48800000 +#define L4_CFG_DRA7XX_BASE 0x4A000000 +#define L4_WKUP_DRA7XX_BASE 0x4ae00000 #define DRA7XX_CM_CORE_AON_BASE 0x4a005000 #define DRA7XX_CTRL_BASE 0x4a003400 #define DRA7XX_TAP_BASE 0x4ae0c000 -- cgit v0.10.2 From 228e5fadba3c7d6ef39bac087cd086ab9d68d945 Mon Sep 17 00:00:00 2001 From: Suman Anna Date: Fri, 10 Jul 2015 15:43:05 -0500 Subject: ARM: OMAP2+: Remove module references from IOMMU machine layer The OMAP IOMMU driver has been adapted to the IOMMU framework for a while now, and it no longer supports being built as a module. Cleanup all the module related references both from the code and in the build. While at it, also relocate a comment around the initcall to avoid a checkpatch strict warning about using a blank line after function/struct/union/enum declarations. Signed-off-by: Suman Anna Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index 903c85b..d4579f8 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -234,8 +234,7 @@ obj-$(CONFIG_SOC_DRA7XX) += omap_hwmod_7xx_data.o # EMU peripherals obj-$(CONFIG_HW_PERF_EVENTS) += pmu.o -iommu-$(CONFIG_OMAP_IOMMU) := omap-iommu.o -obj-y += $(iommu-m) $(iommu-y) +obj-$(CONFIG_OMAP_IOMMU) += omap-iommu.o # OMAP2420 MSDI controller integration support ("MMC") obj-$(CONFIG_SOC_OMAP2420) += msdi.o diff --git a/arch/arm/mach-omap2/omap-iommu.c b/arch/arm/mach-omap2/omap-iommu.c index 4068350..8867eb4 100644 --- a/arch/arm/mach-omap2/omap-iommu.c +++ b/arch/arm/mach-omap2/omap-iommu.c @@ -11,7 +11,6 @@ */ #include -#include #include #include #include @@ -63,15 +62,5 @@ static int __init omap_iommu_init(void) return omap_hwmod_for_each_by_class("mmu", omap_iommu_dev_init, NULL); } -/* must be ready before omap3isp is probed */ omap_subsys_initcall(omap_iommu_init); - -static void __exit omap_iommu_exit(void) -{ - /* Do nothing */ -} -module_exit(omap_iommu_exit); - -MODULE_AUTHOR("Hiroshi DOYU"); -MODULE_DESCRIPTION("omap iommu: omap device registration"); -MODULE_LICENSE("GPL v2"); +/* must be ready before omap3isp is probed */ -- cgit v0.10.2 From 9fd274c069c7f96631ef6e0b9909c9a0e1f6b954 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 16 Jul 2015 02:08:55 -0700 Subject: ARM: OMAP2+: Fix dm814x DT_MACHINE_START Fix dm814x DT_MACHINE_START. Cc: Matthijs van Duin Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c index 34ff14b..a233860 100644 --- a/arch/arm/mach-omap2/board-generic.c +++ b/arch/arm/mach-omap2/board-generic.c @@ -169,7 +169,7 @@ static const char *const ti814x_boards_compat[] __initconst = { NULL, }; -DT_MACHINE_START(TI81XX_DT, "Generic ti814x (Flattened Device Tree)") +DT_MACHINE_START(TI814X_DT, "Generic ti814x (Flattened Device Tree)") .reserve = omap_reserve, .map_io = ti81xx_map_io, .init_early = ti814x_init_early, -- cgit v0.10.2 From 9444f103469f40c47993a1dd87687d126054969c Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 16 Jul 2015 01:55:57 -0700 Subject: ARM: OMAP2+: Fix scm compatible for dm814x Fix scm compatible for dm814x. Cc: Matthijs van Duin Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c index f008930..cf58551 100644 --- a/arch/arm/mach-omap2/control.c +++ b/arch/arm/mach-omap2/control.c @@ -652,6 +652,7 @@ static const struct of_device_id omap_scrm_dt_match_table[] = { { .compatible = "ti,am4-scm", .data = &ctrl_data }, { .compatible = "ti,omap2-scm", .data = &omap2_ctrl_data }, { .compatible = "ti,omap3-scm", .data = &omap2_ctrl_data }, + { .compatible = "ti,dm814-scm", .data = &ctrl_data }, { .compatible = "ti,dm816-scrm", .data = &ctrl_data }, { .compatible = "ti,omap4-scm-core", .data = &ctrl_data }, { .compatible = "ti,omap5-scm-core", .data = &ctrl_data }, -- cgit v0.10.2 From 185fde6d5b38cd03bf24bee90198b436b721d37c Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 16 Jul 2015 01:55:57 -0700 Subject: ARM: OMAP2+: Add minimal clockdomains for dm814x For now, let's just add the ones shared with dm816x. The dm814x specific ones can be added as they are tested. Cc: Matthijs van Duin Cc: Paul Walmsley Cc: Tero Kristo Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h index 77bab5f..2c398ce 100644 --- a/arch/arm/mach-omap2/clockdomain.h +++ b/arch/arm/mach-omap2/clockdomain.h @@ -216,7 +216,8 @@ extern void __init omap242x_clockdomains_init(void); extern void __init omap243x_clockdomains_init(void); extern void __init omap3xxx_clockdomains_init(void); extern void __init am33xx_clockdomains_init(void); -extern void __init ti81xx_clockdomains_init(void); +extern void __init ti814x_clockdomains_init(void); +extern void __init ti816x_clockdomains_init(void); extern void __init omap44xx_clockdomains_init(void); extern void __init omap54xx_clockdomains_init(void); extern void __init dra7xx_clockdomains_init(void); diff --git a/arch/arm/mach-omap2/clockdomains81xx_data.c b/arch/arm/mach-omap2/clockdomains81xx_data.c index ce2a820..53442c8 100644 --- a/arch/arm/mach-omap2/clockdomains81xx_data.c +++ b/arch/arm/mach-omap2/clockdomains81xx_data.c @@ -165,7 +165,24 @@ static struct clockdomain default_l3_slow_816x_clkdm = { .flags = CLKDM_CAN_SWSUP, }; -static struct clockdomain *clockdomains_ti81xx[] __initdata = { +static struct clockdomain *clockdomains_ti814x[] __initdata = { + &alwon_l3_slow_81xx_clkdm, + &alwon_l3_med_81xx_clkdm, + &alwon_l3_fast_81xx_clkdm, + &alwon_ethernet_81xx_clkdm, + &mmu_81xx_clkdm, + &mmu_cfg_81xx_clkdm, + NULL, +}; + +void __init ti814x_clockdomains_init(void) +{ + clkdm_register_platform_funcs(&am33xx_clkdm_operations); + clkdm_register_clkdms(clockdomains_ti814x); + clkdm_complete_init(); +} + +static struct clockdomain *clockdomains_ti816x[] __initdata = { &alwon_mpu_816x_clkdm, &alwon_l3_slow_81xx_clkdm, &alwon_l3_med_81xx_clkdm, @@ -185,10 +202,10 @@ static struct clockdomain *clockdomains_ti81xx[] __initdata = { NULL, }; -void __init ti81xx_clockdomains_init(void) +void __init ti816x_clockdomains_init(void) { clkdm_register_platform_funcs(&am33xx_clkdm_operations); - clkdm_register_clkdms(clockdomains_ti81xx); + clkdm_register_clkdms(clockdomains_ti816x); clkdm_complete_init(); } #endif diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 820dde8..6779a9f 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -554,7 +554,7 @@ void __init ti814x_init_early(void) omap2_prcm_base_init(); omap3xxx_voltagedomains_init(); omap3xxx_powerdomains_init(); - ti81xx_clockdomains_init(); + ti814x_clockdomains_init(); ti81xx_hwmod_init(); omap_hwmod_init_postsetup(); if (of_have_populated_dt()) @@ -571,7 +571,7 @@ void __init ti816x_init_early(void) omap2_prcm_base_init(); omap3xxx_voltagedomains_init(); omap3xxx_powerdomains_init(); - ti81xx_clockdomains_init(); + ti816x_clockdomains_init(); ti81xx_hwmod_init(); omap_hwmod_init_postsetup(); if (of_have_populated_dt()) -- cgit v0.10.2 From 7c80a3f89c51cfa935493a81b401c4e93f0c0f90 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 16 Jul 2015 01:55:57 -0700 Subject: ARM: OMAP2+: Add custom prwdm_operations for 81xx to support dm814x Looking at the TI kernel tree I noticed that dm81xx need custom ti81xx_pwrdm_operations. Let's also change dm816x over to use them as the registers are different for dm81xx compared to others. Cc: Matthijs van Duin Cc: Paul Walmsley Cc: Tero Kristo Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c index 70bc706..7829d27 100644 --- a/arch/arm/mach-omap2/powerdomains3xxx_data.c +++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c @@ -349,6 +349,41 @@ static struct powerdomain device_81xx_pwrdm = { .voltdm = { .name = "core" }, }; +static struct powerdomain gem_814x_pwrdm = { + .name = "gem_pwrdm", + .prcm_offs = TI814X_PRM_DSP_MOD, + .pwrsts = PWRSTS_OFF_ON, + .voltdm = { .name = "dsp" }, +}; + +static struct powerdomain ivahd_814x_pwrdm = { + .name = "ivahd_pwrdm", + .prcm_offs = TI814X_PRM_HDVICP_MOD, + .pwrsts = PWRSTS_OFF_ON, + .voltdm = { .name = "iva" }, +}; + +static struct powerdomain hdvpss_814x_pwrdm = { + .name = "hdvpss_pwrdm", + .prcm_offs = TI814X_PRM_HDVPSS_MOD, + .pwrsts = PWRSTS_OFF_ON, + .voltdm = { .name = "dsp" }, +}; + +static struct powerdomain sgx_814x_pwrdm = { + .name = "sgx_pwrdm", + .prcm_offs = TI814X_PRM_GFX_MOD, + .pwrsts = PWRSTS_OFF_ON, + .voltdm = { .name = "core" }, +}; + +static struct powerdomain isp_814x_pwrdm = { + .name = "isp_pwrdm", + .prcm_offs = TI814X_PRM_ISP_MOD, + .pwrsts = PWRSTS_OFF_ON, + .voltdm = { .name = "core" }, +}; + static struct powerdomain active_816x_pwrdm = { .name = "active_pwrdm", .prcm_offs = TI816X_PRM_ACTIVE_MOD, @@ -448,7 +483,18 @@ static struct powerdomain *powerdomains_am35x[] __initdata = { NULL }; -static struct powerdomain *powerdomains_ti81xx[] __initdata = { +static struct powerdomain *powerdomains_ti814x[] __initdata = { + &alwon_81xx_pwrdm, + &device_81xx_pwrdm, + &gem_814x_pwrdm, + &ivahd_814x_pwrdm, + &hdvpss_814x_pwrdm, + &sgx_814x_pwrdm, + &isp_814x_pwrdm, + NULL +}; + +static struct powerdomain *powerdomains_ti816x[] __initdata = { &alwon_81xx_pwrdm, &device_81xx_pwrdm, &active_816x_pwrdm, @@ -460,6 +506,73 @@ static struct powerdomain *powerdomains_ti81xx[] __initdata = { NULL }; +/* TI81XX specific ops */ +#define TI81XX_PM_PWSTCTRL 0x0000 +#define TI81XX_RM_RSTCTRL 0x0010 +#define TI81XX_PM_PWSTST 0x0004 + +static int ti81xx_pwrdm_set_next_pwrst(struct powerdomain *pwrdm, u8 pwrst) +{ + omap2_prm_rmw_mod_reg_bits(OMAP_POWERSTATE_MASK, + (pwrst << OMAP_POWERSTATE_SHIFT), + pwrdm->prcm_offs, TI81XX_PM_PWSTCTRL); + return 0; +} + +static int ti81xx_pwrdm_read_next_pwrst(struct powerdomain *pwrdm) +{ + return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, + TI81XX_PM_PWSTCTRL, + OMAP_POWERSTATE_MASK); +} + +static int ti81xx_pwrdm_read_pwrst(struct powerdomain *pwrdm) +{ + return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, + (pwrdm->prcm_offs == TI814X_PRM_GFX_MOD) ? TI81XX_RM_RSTCTRL : + TI81XX_PM_PWSTST, + OMAP_POWERSTATEST_MASK); +} + +static int ti81xx_pwrdm_read_logic_pwrst(struct powerdomain *pwrdm) +{ + return omap2_prm_read_mod_bits_shift(pwrdm->prcm_offs, + (pwrdm->prcm_offs == TI814X_PRM_GFX_MOD) ? TI81XX_RM_RSTCTRL : + TI81XX_PM_PWSTST, + OMAP3430_LOGICSTATEST_MASK); +} + +static int ti81xx_pwrdm_wait_transition(struct powerdomain *pwrdm) +{ + u32 c = 0; + + while ((omap2_prm_read_mod_reg(pwrdm->prcm_offs, + (pwrdm->prcm_offs == TI814X_PRM_GFX_MOD) ? TI81XX_RM_RSTCTRL : + TI81XX_PM_PWSTST) & + OMAP_INTRANSITION_MASK) && + (c++ < PWRDM_TRANSITION_BAILOUT)) + udelay(1); + + if (c > PWRDM_TRANSITION_BAILOUT) { + pr_err("powerdomain: %s timeout waiting for transition\n", + pwrdm->name); + return -EAGAIN; + } + + pr_debug("powerdomain: completed transition in %d loops\n", c); + + return 0; +} + +/* For dm814x we need to fix up fix GFX pwstst and rstctrl reg offsets */ +static struct pwrdm_ops ti81xx_pwrdm_operations = { + .pwrdm_set_next_pwrst = ti81xx_pwrdm_set_next_pwrst, + .pwrdm_read_next_pwrst = ti81xx_pwrdm_read_next_pwrst, + .pwrdm_read_pwrst = ti81xx_pwrdm_read_pwrst, + .pwrdm_read_logic_pwrst = ti81xx_pwrdm_read_logic_pwrst, + .pwrdm_wait_transition = ti81xx_pwrdm_wait_transition, +}; + void __init omap3xxx_powerdomains_init(void) { unsigned int rev; @@ -467,15 +580,18 @@ void __init omap3xxx_powerdomains_init(void) if (!cpu_is_omap34xx() && !cpu_is_ti81xx()) return; - pwrdm_register_platform_funcs(&omap3_pwrdm_operations); + pwrdm_register_platform_funcs(&ti81xx_pwrdm_operations); rev = omap_rev(); if (rev == AM35XX_REV_ES1_0 || rev == AM35XX_REV_ES1_1) { pwrdm_register_pwrdms(powerdomains_am35x); + } else if (rev == TI8148_REV_ES1_0 || rev == TI8148_REV_ES2_0 || + rev == TI8148_REV_ES2_1) { + pwrdm_register_pwrdms(powerdomains_ti814x); } else if (rev == TI8168_REV_ES1_0 || rev == TI8168_REV_ES1_1 || rev == TI8168_REV_ES2_0 || rev == TI8168_REV_ES2_1) { - pwrdm_register_pwrdms(powerdomains_ti81xx); + pwrdm_register_pwrdms(powerdomains_ti816x); } else { pwrdm_register_pwrdms(powerdomains_omap3430_common); diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index 6ae0b3a..0ae9466 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h @@ -51,6 +51,12 @@ /* * TI81XX PRM module offsets */ +#define TI814X_PRM_DSP_MOD 0x0a00 +#define TI814X_PRM_HDVICP_MOD 0x0c00 +#define TI814X_PRM_ISP_MOD 0x0d00 +#define TI814X_PRM_HDVPSS_MOD 0x0e00 +#define TI814X_PRM_GFX_MOD 0x0f00 + #define TI81XX_PRM_DEVICE_MOD 0x0000 #define TI816X_PRM_ACTIVE_MOD 0x0a00 #define TI81XX_PRM_DEFAULT_MOD 0x0b00 -- cgit v0.10.2 From 9cf705de06a27cc99874626c9717b32e9874b3bb Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 16 Jul 2015 01:55:57 -0700 Subject: ARM: OMAP2+: Add support for initializing dm814x clocks Let's add a minimal clocks for dm814x to get it booted. This is mostly a placeholder and relies on the PLLs being on from the bootloader. Note that the divider clocks work the same way as on dm816x and am335x. Cc: Matthijs van Duin Cc: Mike Turquette Cc: Paul Walmsley Cc: Stephen Boyd Cc: Tero Kristo Acked-by: Stephen Boyd Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 6779a9f..596af73 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -558,7 +558,7 @@ void __init ti814x_init_early(void) ti81xx_hwmod_init(); omap_hwmod_init_postsetup(); if (of_have_populated_dt()) - omap_clk_soc_init = ti81xx_dt_clk_init; + omap_clk_soc_init = dm814x_dt_clk_init; } void __init ti816x_init_early(void) @@ -575,7 +575,7 @@ void __init ti816x_init_early(void) ti81xx_hwmod_init(); omap_hwmod_init_postsetup(); if (of_have_populated_dt()) - omap_clk_soc_init = ti81xx_dt_clk_init; + omap_clk_soc_init = dm816x_dt_clk_init; } #endif diff --git a/drivers/clk/ti/Makefile b/drivers/clk/ti/Makefile index 105ffd0..80b4288 100644 --- a/drivers/clk/ti/Makefile +++ b/drivers/clk/ti/Makefile @@ -2,7 +2,7 @@ obj-y += clk.o autoidle.o clockdomain.o clk-common = dpll.o composite.o divider.o gate.o \ fixed-factor.o mux.o apll.o obj-$(CONFIG_SOC_AM33XX) += $(clk-common) clk-33xx.o -obj-$(CONFIG_SOC_TI81XX) += $(clk-common) fapll.o clk-816x.o +obj-$(CONFIG_SOC_TI81XX) += $(clk-common) fapll.o clk-814x.o clk-816x.o obj-$(CONFIG_ARCH_OMAP2) += $(clk-common) interface.o clk-2xxx.o obj-$(CONFIG_ARCH_OMAP3) += $(clk-common) interface.o \ clk-3xxx.o diff --git a/drivers/clk/ti/clk-814x.c b/drivers/clk/ti/clk-814x.c new file mode 100644 index 0000000..d490d42 --- /dev/null +++ b/drivers/clk/ti/clk-814x.c @@ -0,0 +1,31 @@ +/* + * 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. + */ + +#include +#include +#include + +static struct ti_dt_clk dm814_clks[] = { + DT_CLK(NULL, "devosc_ck", "devosc_ck"), + DT_CLK(NULL, "mpu_ck", "mpu_ck"), + DT_CLK(NULL, "sysclk4_ck", "sysclk4_ck"), + DT_CLK(NULL, "sysclk6_ck", "sysclk6_ck"), + DT_CLK(NULL, "sysclk10_ck", "sysclk10_ck"), + DT_CLK(NULL, "sysclk18_ck", "sysclk18_ck"), + DT_CLK(NULL, "timer_sys_ck", "devosc_ck"), + DT_CLK(NULL, "cpsw_125mhz_gclk", "cpsw_125mhz_gclk"), + DT_CLK(NULL, "cpsw_cpts_rft_clk", "cpsw_cpts_rft_clk"), + { .node_name = NULL }, +}; + +int __init dm814x_dt_clk_init(void) +{ + ti_dt_clocks_register(dm814_clks); + omap2_clk_disable_autoidle_all(); + omap2_clk_enable_init_clocks(NULL, 0); + + return 0; +} diff --git a/drivers/clk/ti/clk-816x.c b/drivers/clk/ti/clk-816x.c index 9451e65..43d0745 100644 --- a/drivers/clk/ti/clk-816x.c +++ b/drivers/clk/ti/clk-816x.c @@ -42,7 +42,7 @@ static const char *enable_init_clks[] = { "ddr_pll_clk3", }; -int __init ti81xx_dt_clk_init(void) +int __init dm816x_dt_clk_init(void) { ti_dt_clocks_register(dm816x_clks); omap2_clk_disable_autoidle_all(); diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h index 79b76e1..1736e29 100644 --- a/include/linux/clk/ti.h +++ b/include/linux/clk/ti.h @@ -329,7 +329,8 @@ int ti_clk_add_component(struct device_node *node, struct clk_hw *hw, int type); int omap3430_dt_clk_init(void); int omap3630_dt_clk_init(void); int am35xx_dt_clk_init(void); -int ti81xx_dt_clk_init(void); +int dm814x_dt_clk_init(void); +int dm816x_dt_clk_init(void); int omap4xxx_dt_clk_init(void); int omap5xxx_dt_clk_init(void); int dra7xx_dt_clk_init(void); -- cgit v0.10.2 From def56bba7a5c623fd887d1f4b4c864521d615a76 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Wed, 15 Jul 2015 10:36:37 +0800 Subject: input: snvs_pwrkey: use "wakeup-source" as deivce tree property name Instead of inventing a new property name, let's use "wakeup-source" to be consistent with other driver and subsystem bindings. Signed-off-by: Shawn Guo Acked-by: Dmitry Torokhov diff --git a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt index 71a39c5..f16bbd6 100644 --- a/Documentation/devicetree/bindings/crypto/fsl-sec4.txt +++ b/Documentation/devicetree/bindings/crypto/fsl-sec4.txt @@ -408,7 +408,7 @@ System ON/OFF key driver Value type: Definition: Keycode to emit, KEY_POWER by default. - - wakeup: + - wakeup-source: Usage: option Value type: Definition: Button can wake-up the system. diff --git a/drivers/input/keyboard/snvs_pwrkey.c b/drivers/input/keyboard/snvs_pwrkey.c index 512a1fc..78fd24c 100644 --- a/drivers/input/keyboard/snvs_pwrkey.c +++ b/drivers/input/keyboard/snvs_pwrkey.c @@ -122,7 +122,7 @@ static int imx_snvs_pwrkey_probe(struct platform_device *pdev) dev_warn(&pdev->dev, "KEY_POWER without setting in dts\n"); } - pdata->wakeup = of_property_read_bool(np, "wakeup"); + pdata->wakeup = of_property_read_bool(np, "wakeup-source"); pdata->irq = platform_get_irq(pdev, 0); if (pdata->irq < 0) { -- cgit v0.10.2 From 4be0856fa34ef3b0681aeec669e50c13e394f145 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Sat, 14 Feb 2015 23:38:39 +0100 Subject: ARM: pxa: transition to dmaengine phase 1 In order to slowly transition pxa to dmaengine, the legacy code will now rely on dmaengine to request a channel. This implies that PXA architecture selects DMADEVICES and PXA_DMA, which is not pretty. Yet it enables PXA drivers to be ported one by one, with part of them using dmaengine, and the other part using the legacy code. Signed-off-by: Robert Jarzmik diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index 3543466..e6ce669 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "devices.h" @@ -1193,3 +1194,39 @@ void __init pxa2xx_set_spi_info(unsigned id, struct pxa2xx_spi_master *info) pd->dev.platform_data = info; platform_device_add(pd); } + +static struct mmp_dma_platdata pxa_dma_pdata = { + .dma_channels = 0, +}; + +static struct resource pxa_dma_resource[] = { + [0] = { + .start = 0x40000000, + .end = 0x4000ffff, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_DMA, + .end = IRQ_DMA, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 pxadma_dmamask = 0xffffffffUL; + +static struct platform_device pxa2xx_pxa_dma = { + .name = "pxa-dma", + .id = 0, + .dev = { + .dma_mask = &pxadma_dmamask, + .coherent_dma_mask = 0xffffffff, + }, + .num_resources = ARRAY_SIZE(pxa_dma_resource), + .resource = pxa_dma_resource, +}; + +void __init pxa2xx_set_dmac_info(int nb_channels) +{ + pxa_dma_pdata.dma_channels = nb_channels; + pxa_register_device(&pxa2xx_pxa_dma, &pxa_dma_pdata); +} diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index 23a90c6..1dc85ff 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -206,6 +206,7 @@ static int __init pxa25x_init(void) register_syscore_ops(&pxa_irq_syscore_ops); register_syscore_ops(&pxa2xx_mfp_syscore_ops); + pxa2xx_set_dmac_info(16); pxa_register_device(&pxa25x_device_gpio, &pxa25x_gpio_info); ret = platform_add_devices(pxa25x_devices, ARRAY_SIZE(pxa25x_devices)); diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index b5abdeb..e6aae9e 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -310,6 +310,7 @@ static int __init pxa27x_init(void) if (!of_have_populated_dt()) { pxa_register_device(&pxa27x_device_gpio, &pxa27x_gpio_info); + pxa2xx_set_dmac_info(32); ret = platform_add_devices(devices, ARRAY_SIZE(devices)); } diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index bd4cbef..aa85ec1 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -431,6 +431,7 @@ static int __init pxa3xx_init(void) if (of_have_populated_dt()) return 0; + pxa2xx_set_dmac_info(32); ret = platform_add_devices(devices, ARRAY_SIZE(devices)); if (ret) return ret; diff --git a/arch/arm/plat-pxa/dma.c b/arch/arm/plat-pxa/dma.c index d92f07f..de2b061 100644 --- a/arch/arm/plat-pxa/dma.c +++ b/arch/arm/plat-pxa/dma.c @@ -289,7 +289,8 @@ int pxa_request_dma (char *name, pxa_dma_prio prio, /* try grabbing a DMA channel with the requested priority */ for (i = 0; i < num_dma_channels; i++) { if ((dma_channels[i].prio == prio) && - !dma_channels[i].name) { + !dma_channels[i].name && + !pxad_toggle_reserved_channel(i)) { found = 1; break; } @@ -326,13 +327,14 @@ void pxa_free_dma (int dma_ch) local_irq_save(flags); DCSR(dma_ch) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR; dma_channels[dma_ch].name = NULL; + pxad_toggle_reserved_channel(dma_ch); local_irq_restore(flags); } EXPORT_SYMBOL(pxa_free_dma); static irqreturn_t dma_irq_handler(int irq, void *dev_id) { - int i, dint = DINT; + int i, dint = DINT, done = 0; struct dma_channel *channel; while (dint) { @@ -341,16 +343,13 @@ static irqreturn_t dma_irq_handler(int irq, void *dev_id) channel = &dma_channels[i]; if (channel->name && channel->irq_handler) { channel->irq_handler(i, channel->data); - } else { - /* - * IRQ for an unregistered DMA channel: - * let's clear the interrupts and disable it. - */ - printk (KERN_WARNING "spurious IRQ for DMA channel %d\n", i); - DCSR(i) = DCSR_STARTINTR|DCSR_ENDINTR|DCSR_BUSERR; + done++; } } - return IRQ_HANDLED; + if (done) + return IRQ_HANDLED; + else + return IRQ_NONE; } int __init pxa_init_dma(int irq, int num_ch) @@ -372,7 +371,8 @@ int __init pxa_init_dma(int irq, int num_ch) spin_lock_init(&dma_channels[i].lock); } - ret = request_irq(irq, dma_irq_handler, 0, "DMA", NULL); + ret = request_irq(irq, dma_irq_handler, IRQF_SHARED, "DMA", + dma_channels); if (ret) { printk (KERN_CRIT "Wow! Can't register IRQ for DMA\n"); kfree(dma_channels); diff --git a/arch/arm/plat-pxa/include/plat/dma.h b/arch/arm/plat-pxa/include/plat/dma.h index a7b91dc..28848b3 100644 --- a/arch/arm/plat-pxa/include/plat/dma.h +++ b/arch/arm/plat-pxa/include/plat/dma.h @@ -82,4 +82,19 @@ int pxa_request_dma (char *name, void pxa_free_dma (int dma_ch); +/* + * Cooperation with pxa_dma + dmaengine while there remains at least one pxa + * driver not converted to dmaengine. + */ +#if defined(CONFIG_PXA_DMA) +extern int pxad_toggle_reserved_channel(int legacy_channel); +#else +static inline int pxad_toggle_reserved_channel(int legacy_channel) +{ + return 0; +} +#endif + +extern void __init pxa2xx_set_dmac_info(int nb_channels); + #endif /* __PLAT_DMA_H */ -- cgit v0.10.2 From 9754c8ef1f54bff1e1448a1a02039681a4a98fa0 Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Fri, 3 Jul 2015 17:40:45 +0530 Subject: ARM: pxa: Use module_platform_driver Use module_platform_driver for drivers whose init and exit functions only register and unregister, respectively. A simplified version of the Coccinelle semantic patch that performs this transformation is as follows: @a@ identifier f, x; @@ -static f(...) { return platform_driver_register(&x); } @b depends on a@ identifier e, a.x; @@ -static e(...) { platform_driver_unregister(&x); } @c depends on a && b@ identifier a.f; declarer name module_init; @@ -module_init(f); @d depends on a && b && c@ identifier b.e, a.x; declarer name module_exit; declarer name module_platform_driver; @@ -module_exit(e); +module_platform_driver(x); Signed-off-by: Vaishali Thakkar Signed-off-by: Robert Jarzmik diff --git a/arch/arm/mach-pxa/tosa-bt.c b/arch/arm/mach-pxa/tosa-bt.c index 685deff..e0a5320 100644 --- a/arch/arm/mach-pxa/tosa-bt.c +++ b/arch/arm/mach-pxa/tosa-bt.c @@ -131,17 +131,4 @@ static struct platform_driver tosa_bt_driver = { .name = "tosa-bt", }, }; - - -static int __init tosa_bt_init(void) -{ - return platform_driver_register(&tosa_bt_driver); -} - -static void __exit tosa_bt_exit(void) -{ - platform_driver_unregister(&tosa_bt_driver); -} - -module_init(tosa_bt_init); -module_exit(tosa_bt_exit); +module_platform_driver(tosa_bt_driver); -- cgit v0.10.2 From 6d6db340a7e832dc18a6a95d9f9fc79d03ff959e Mon Sep 17 00:00:00 2001 From: Vaishali Thakkar Date: Thu, 11 Jun 2015 10:57:35 +0530 Subject: ARM: pxa: Use setup_timer Use the timer API function setup_timer instead of structure field assignments to initialize a timer. A simplified version of the Coccinelle semantic patch that performs this transformation is as follows: @change@ expression e1, e2, a; @@ -init_timer(&e1); +setup_timer(&e1, a, 0UL); ... when != a = e2 -e1.function = a; Signed-off-by: Vaishali Thakkar Signed-off-by: Robert Jarzmik diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c index 051a655..bdc0c41 100644 --- a/arch/arm/mach-pxa/sharpsl_pm.c +++ b/arch/arm/mach-pxa/sharpsl_pm.c @@ -841,11 +841,9 @@ static int sharpsl_pm_probe(struct platform_device *pdev) sharpsl_pm.charge_mode = CHRG_OFF; sharpsl_pm.flags = 0; - init_timer(&sharpsl_pm.ac_timer); - sharpsl_pm.ac_timer.function = sharpsl_ac_timer; + setup_timer(&sharpsl_pm.ac_timer, sharpsl_ac_timer, 0UL); - init_timer(&sharpsl_pm.chrg_full_timer); - sharpsl_pm.chrg_full_timer.function = sharpsl_chrg_full_timer; + setup_timer(&sharpsl_pm.chrg_full_timer, sharpsl_chrg_full_timer, 0UL); led_trigger_register_simple("sharpsl-charge", &sharpsl_charge_led_trigger); -- cgit v0.10.2 From cd871d517d46f26943f3c8f61c0d2ac6665da6a2 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Mon, 20 Jul 2015 11:23:13 -0500 Subject: ARM: socfpga: add reset for the Arria 10 platform Since the Arria10's reset register offset is different from the Cyclone/Arria 5, it's best to add a new DT_MACHINE_START() for the Arria10. Signed-off-by: Dinh Nguyen --- v2: use altera_a10_dt_match for the A10 machine desc diff --git a/arch/arm/mach-socfpga/core.h b/arch/arm/mach-socfpga/core.h index 7259c37..5bc6ea8 100644 --- a/arch/arm/mach-socfpga/core.h +++ b/arch/arm/mach-socfpga/core.h @@ -25,6 +25,7 @@ #define SOCFPGA_RSTMGR_MODPERRST 0x14 #define SOCFPGA_RSTMGR_BRGMODRST 0x1c +#define SOCFPGA_A10_RSTMGR_CTRL 0xC #define SOCFPGA_A10_RSTMGR_MODMPURST 0x20 /* System Manager bits */ diff --git a/arch/arm/mach-socfpga/socfpga.c b/arch/arm/mach-socfpga/socfpga.c index 19643a7..a1c0efa 100644 --- a/arch/arm/mach-socfpga/socfpga.c +++ b/arch/arm/mach-socfpga/socfpga.c @@ -74,6 +74,19 @@ static void socfpga_cyclone5_restart(enum reboot_mode mode, const char *cmd) writel(temp, rst_manager_base_addr + SOCFPGA_RSTMGR_CTRL); } +static void socfpga_arria10_restart(enum reboot_mode mode, const char *cmd) +{ + u32 temp; + + temp = readl(rst_manager_base_addr + SOCFPGA_A10_RSTMGR_CTRL); + + if (mode == REBOOT_HARD) + temp |= RSTMGR_CTRL_SWCOLDRSTREQ; + else + temp |= RSTMGR_CTRL_SWWARMRSTREQ; + writel(temp, rst_manager_base_addr + SOCFPGA_A10_RSTMGR_CTRL); +} + static const char *altera_dt_match[] = { "altr,socfpga", NULL @@ -86,3 +99,16 @@ DT_MACHINE_START(SOCFPGA, "Altera SOCFPGA") .restart = socfpga_cyclone5_restart, .dt_compat = altera_dt_match, MACHINE_END + +static const char *altera_a10_dt_match[] = { + "altr,socfpga-arria10", + NULL +}; + +DT_MACHINE_START(SOCFPGA_A10, "Altera SOCFPGA Arria10") + .l2c_aux_val = 0, + .l2c_aux_mask = ~0, + .init_irq = socfpga_init_irq, + .restart = socfpga_arria10_restart, + .dt_compat = altera_a10_dt_match, +MACHINE_END -- cgit v0.10.2 From 974a2aba99d29bada9212134e7565d2364967636 Mon Sep 17 00:00:00 2001 From: Arun Chandran Date: Fri, 12 Jun 2015 12:23:24 +0530 Subject: ARM: zynq: Fix earlyprintk in big endian mode earlyprintk messages are not appearing on the terminal emulator during a big endian kernel boot. In BE mode sending full words to UART will result in unprintable characters as they are byte swapped versions of printable ones. So send only bytes. Signed-off-by: Arun Chandran Tested-by: Michal Simek Signed-off-by: Michal Simek diff --git a/arch/arm/include/debug/zynq.S b/arch/arm/include/debug/zynq.S index bd13ded..de86b92 100644 --- a/arch/arm/include/debug/zynq.S +++ b/arch/arm/include/debug/zynq.S @@ -38,7 +38,7 @@ .endm .macro senduart,rd,rx - str \rd, [\rx, #UART_FIFO_OFFSET] @ TXDATA + strb \rd, [\rx, #UART_FIFO_OFFSET] @ TXDATA .endm .macro waituart,rd,rx -- cgit v0.10.2 From 6632d4fdd790965a2e4741a3652a1c365d52ae2e Mon Sep 17 00:00:00 2001 From: Thomas Betker Date: Tue, 12 May 2015 08:22:01 +0200 Subject: ARM: zynq: Set bit 22 in PL310 AuxCtrl register (6395/1) This patch is based on the commit 1a8e41cd672f ("ARM: 6395/1: VExpress: Set bit 22 in the PL310 (cache controller) AuxCtlr register") Clearing bit 22 in the PL310 Auxiliary Control register (shared attribute override enable) has the side effect of transforming Normal Shared Non-cacheable reads into Cacheable no-allocate reads. Coherent DMA buffers in Linux always have a cacheable alias via the kernel linear mapping and the processor can speculatively load cache lines into the PL310 controller. With bit 22 cleared, Non-cacheable reads would unexpectedly hit such cache lines leading to buffer corruption. For Zynq, this fix avoids memory inconsistencies between Gigabit Ethernet controller (GEM) and CPU when DMA_CMA is disabled. Suggested-by: Punnaiah Choudary Kalluri Signed-off-by: Thomas Betker Signed-off-by: Michal Simek diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c index 616d584..6bd4a43 100644 --- a/arch/arm/mach-zynq/common.c +++ b/arch/arm/mach-zynq/common.c @@ -197,8 +197,8 @@ static const char * const zynq_dt_match[] = { DT_MACHINE_START(XILINX_EP107, "Xilinx Zynq Platform") /* 64KB way size, 8-way associativity, parity disabled */ - .l2c_aux_val = 0x00000000, - .l2c_aux_mask = 0xffffffff, + .l2c_aux_val = 0x00400000, + .l2c_aux_mask = 0xffbfffff, .smp = smp_ops(zynq_smp_ops), .map_io = zynq_map_io, .init_irq = zynq_irq_init, -- cgit v0.10.2 From 94a8cfceaa7ee7e7187c5de074eb5138a6b77dcf Mon Sep 17 00:00:00 2001 From: Peter Griffin Date: Tue, 9 Jun 2015 15:33:00 +0200 Subject: ARM: STi: Add code to release secondary cores from holding pen. Most upstream devs boot STi platform via JTAG which abuses the boot process by setting the PC of secondary cores directly. As a consquence, booting STi platforms via u-boot results in only the primary core being brought up as the code to manage the holding pen is not upstream. This patch adds the necessary code to bring the secondary cores out of the holding pen. It uses the cpu-release-addr DT property to get the address of the holding pen from the bootloader. With this patch booting upstream kernels via u-boot works correctly: [ 0.045456] CPU: Testing write buffer coherency: ok [ 0.045597] CPU0: thread -1, cpu 0, socket 0, mpidr 80000000 [ 0.045734] Setting up static identity map for 0x40209000 - 0x40209098 [ 0.065047] CPU1: thread -1, cpu 1, socket 0, mpidr 80000001 [ 0.065081] Brought up 2 CPUs [ 0.065089] SMP: Total of 2 processors activated (5983.43 BogoMIPS). [ 0.065092] CPU: All CPU(s) started in SVC mode. Signed-off-by: Peter Griffin Acked-by: Maxime Coquelin Signed-off-by: Maxime Coquelin diff --git a/arch/arm/mach-sti/headsmp.S b/arch/arm/mach-sti/headsmp.S index 4c09bae..e0ad4517 100644 --- a/arch/arm/mach-sti/headsmp.S +++ b/arch/arm/mach-sti/headsmp.S @@ -37,6 +37,7 @@ pen: ldr r7, [r6] * should now contain the SVC stack for this core */ b secondary_startup +ENDPROC(sti_secondary_startup) 1: .long . .long pen_release diff --git a/arch/arm/mach-sti/platsmp.c b/arch/arm/mach-sti/platsmp.c index d4b624f..86bb48d8 100644 --- a/arch/arm/mach-sti/platsmp.c +++ b/arch/arm/mach-sti/platsmp.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -99,14 +100,62 @@ static int sti_boot_secondary(unsigned int cpu, struct task_struct *idle) static void __init sti_smp_prepare_cpus(unsigned int max_cpus) { - void __iomem *scu_base = NULL; - struct device_node *np = of_find_compatible_node( - NULL, NULL, "arm,cortex-a9-scu"); + struct device_node *np; + void __iomem *scu_base; + u32 __iomem *cpu_strt_ptr; + u32 release_phys; + int cpu; + unsigned long entry_pa = virt_to_phys(sti_secondary_startup); + + np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu"); + if (np) { scu_base = of_iomap(np, 0); scu_enable(scu_base); of_node_put(np); } + + if (max_cpus <= 1) + return; + + for_each_possible_cpu(cpu) { + + np = of_get_cpu_node(cpu, NULL); + + if (!np) + continue; + + if (of_property_read_u32(np, "cpu-release-addr", + &release_phys)) { + pr_err("CPU %d: missing or invalid cpu-release-addr " + "property\n", cpu); + continue; + } + + /* + * holding pen is usually configured in SBC DMEM but can also be + * in RAM. + */ + + if (!memblock_is_memory(release_phys)) + cpu_strt_ptr = + ioremap(release_phys, sizeof(release_phys)); + else + cpu_strt_ptr = + (u32 __iomem *)phys_to_virt(release_phys); + + __raw_writel(entry_pa, cpu_strt_ptr); + + /* + * wmb so that data is actually written + * before cache flush is done + */ + smp_wmb(); + sync_cache_w(cpu_strt_ptr); + + if (!memblock_is_memory(release_phys)) + iounmap(cpu_strt_ptr); + } } struct smp_operations __initdata sti_smp_ops = { diff --git a/arch/arm/mach-sti/smp.h b/arch/arm/mach-sti/smp.h index 1871b72..ae22707 100644 --- a/arch/arm/mach-sti/smp.h +++ b/arch/arm/mach-sti/smp.h @@ -14,4 +14,6 @@ extern struct smp_operations sti_smp_ops; +void sti_secondary_startup(void); + #endif -- cgit v0.10.2 From 50de4dd4bc6a6e378841a6705696d2c1f37ac038 Mon Sep 17 00:00:00 2001 From: Peter Griffin Date: Tue, 9 Jun 2015 23:47:00 +0200 Subject: ARM: STi: Remove platform call to trace_hardirqs_off() Calling trace_hardirqs_off() from the platform specific secondary startup code as not been necessary since Dec 2010 when Russell King consolidated the call into the common SMP code. 2c0136d ARM: SMP: consolidate trace_hardirqs_off() into common SMP code Signed-off-by: Peter Griffin Signed-off-by: Maxime Coquelin diff --git a/arch/arm/mach-sti/platsmp.c b/arch/arm/mach-sti/platsmp.c index 86bb48d8..c4ad6ea 100644 --- a/arch/arm/mach-sti/platsmp.c +++ b/arch/arm/mach-sti/platsmp.c @@ -39,8 +39,6 @@ static DEFINE_SPINLOCK(boot_lock); static void sti_secondary_init(unsigned int cpu) { - trace_hardirqs_off(); - /* * let the primary processor know we're out of the * pen, then head off into the C entry point -- cgit v0.10.2 From fac03f12f8d86f349a3b3992ae9d59a53bc250f6 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Thu, 16 Jul 2015 17:23:16 +0530 Subject: ARM: OMAP4: PRM: Remove hardcoding of PRM_IO_PMCTRL_OFFSET register PRM_IO_PMCTRL_OFFSET need not be same for all SOCs hence remove hardcoding and use the value provided by the omap_prcm_irq_setup structure. This is done to support IO wakeup on am437x series. Signed-off-by: Keerthy Reviewed-by: Paul Walmsley Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index 6ae0b3a..af0cee0 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h @@ -472,6 +472,7 @@ struct omap_prcm_irq { * struct omap_prcm_irq_setup - PRCM interrupt controller details * @ack: PRM register offset for the first PRM_IRQSTATUS_MPU register * @mask: PRM register offset for the first PRM_IRQENABLE_MPU register + * @pm_ctrl: PRM register offset for the PRM_IO_PMCTRL register * @nr_regs: number of PRM_IRQ{STATUS,ENABLE}_MPU* registers * @nr_irqs: number of entries in the @irqs array * @irqs: ptr to an array of PRCM interrupt bits (see @nr_irqs) @@ -494,6 +495,7 @@ struct omap_prcm_irq { struct omap_prcm_irq_setup { u16 ack; u16 mask; + u16 pm_ctrl; u8 nr_regs; u8 nr_irqs; const struct omap_prcm_irq *irqs; diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index 4541700..8149e5a 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c @@ -45,6 +45,7 @@ static const struct omap_prcm_irq omap4_prcm_irqs[] = { static struct omap_prcm_irq_setup omap4_prcm_irq_setup = { .ack = OMAP4_PRM_IRQSTATUS_MPU_OFFSET, .mask = OMAP4_PRM_IRQENABLE_MPU_OFFSET, + .pm_ctrl = OMAP4_PRM_IO_PMCTRL_OFFSET, .nr_regs = 2, .irqs = omap4_prcm_irqs, .nr_irqs = ARRAY_SIZE(omap4_prcm_irqs), @@ -306,10 +307,10 @@ static void omap44xx_prm_reconfigure_io_chain(void) omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, OMAP4430_WUCLK_CTRL_MASK, inst, - OMAP4_PRM_IO_PMCTRL_OFFSET); + omap4_prcm_irq_setup.pm_ctrl); omap_test_timeout( (((omap4_prm_read_inst_reg(inst, - OMAP4_PRM_IO_PMCTRL_OFFSET) & + omap4_prcm_irq_setup.pm_ctrl) & OMAP4430_WUCLK_STATUS_MASK) >> OMAP4430_WUCLK_STATUS_SHIFT) == 1), MAX_IOPAD_LATCH_TIME, i); @@ -319,10 +320,10 @@ static void omap44xx_prm_reconfigure_io_chain(void) /* Trigger WUCLKIN disable */ omap4_prm_rmw_inst_reg_bits(OMAP4430_WUCLK_CTRL_MASK, 0x0, inst, - OMAP4_PRM_IO_PMCTRL_OFFSET); + omap4_prcm_irq_setup.pm_ctrl); omap_test_timeout( (((omap4_prm_read_inst_reg(inst, - OMAP4_PRM_IO_PMCTRL_OFFSET) & + omap4_prcm_irq_setup.pm_ctrl) & OMAP4430_WUCLK_STATUS_MASK) >> OMAP4430_WUCLK_STATUS_SHIFT) == 0), MAX_IOPAD_LATCH_TIME, i); @@ -350,7 +351,7 @@ static void __init omap44xx_prm_enable_io_wakeup(void) omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK, OMAP4430_GLOBAL_WUEN_MASK, inst, - OMAP4_PRM_IO_PMCTRL_OFFSET); + omap4_prcm_irq_setup.pm_ctrl); } /** -- cgit v0.10.2 From 39db67a5ff5b29f5e55f129e9da0d77dc17f24e2 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Wed, 8 Jul 2015 11:12:24 +0530 Subject: ARM: AM43xx: Add the PRM IRQ register offsets Add the PRM IRQ register offsets. This is needed to support PRM I/O wakeup on AM43xx. Signed-off-by: Keerthy [paul@pwsan.com: improved patch description, moved the PRM_IO_PMCTRL macro out of the CM section] Reviewed-by: Paul Walmsley Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/prcm43xx.h b/arch/arm/mach-omap2/prcm43xx.h index 7eebc27..7c34c44e 100644 --- a/arch/arm/mach-omap2/prcm43xx.h +++ b/arch/arm/mach-omap2/prcm43xx.h @@ -25,6 +25,13 @@ #define AM43XX_PRM_WKUP_INST 0x2000 #define AM43XX_PRM_DEVICE_INST 0x4000 +/* PRM_IRQ offsets */ +#define AM43XX_PRM_IRQSTATUS_MPU_OFFSET 0x0004 +#define AM43XX_PRM_IRQENABLE_MPU_OFFSET 0x0008 + +/* Other PRM offsets */ +#define AM43XX_PRM_IO_PMCTRL_OFFSET 0x0024 + /* RM RSTCTRL offsets */ #define AM43XX_RM_PER_RSTCTRL_OFFSET 0x0010 #define AM43XX_RM_GFX_RSTCTRL_OFFSET 0x0010 -- cgit v0.10.2 From 6e487001c5b0939e6083327432565559d8aab6fc Mon Sep 17 00:00:00 2001 From: Keerthy Date: Mon, 22 Jun 2015 11:52:53 +0530 Subject: ARM: dts: AM4372: Add PRCM IRQ entry Add PRCM IRQ entry. This is needed for I/O wakeup support. Signed-off-by: Keerthy [paul@pwsan.com: added I/O wakeup note in commit description] Reviewed-by: Paul Walmsley Signed-off-by: Paul Walmsley diff --git a/arch/arm/boot/dts/am4372.dtsi b/arch/arm/boot/dts/am4372.dtsi index c80a3e2..637133b 100644 --- a/arch/arm/boot/dts/am4372.dtsi +++ b/arch/arm/boot/dts/am4372.dtsi @@ -86,6 +86,7 @@ prcm: prcm@1f0000 { compatible = "ti,am4-prcm"; reg = <0x1f0000 0x11000>; + interrupts = ; prcm_clocks: clocks { #address-cells = <1>; -- cgit v0.10.2 From 8d4be7d8bf04f93cfb1512a078bd276efc270793 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Wed, 8 Jul 2015 11:12:26 +0530 Subject: ARM: OMAP: PRM: Remove hardcoding of IRQENABLE_MPU_2 and IRQSTATUS_MPU_2 register offsets The register offsets of IRQENABLE_MPU_2 and IRQSTATUS_MPU_2 are hardcoded. This makes it difficult to reuse the code for SoCs like AM437x that have a single instance of IRQENABLE_MPU and IRQSTATUS_MPU registers. Hence handling the case using offset of 4 to accommodate single set of IRQ* registers generically. Signed-off-by: Keerthy [paul@pwsan.com: fixed whitespace alignment problems reported by checkpatch.pl] Reviewed-by: Paul Walmsley Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index 8149e5a..e6262d3 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c @@ -217,11 +217,11 @@ static inline u32 _read_pending_irq_reg(u16 irqen_offs, u16 irqst_offs) */ static void omap44xx_prm_read_pending_irqs(unsigned long *events) { - events[0] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_OFFSET, - OMAP4_PRM_IRQSTATUS_MPU_OFFSET); + int i; - events[1] = _read_pending_irq_reg(OMAP4_PRM_IRQENABLE_MPU_2_OFFSET, - OMAP4_PRM_IRQSTATUS_MPU_2_OFFSET); + for (i = 0; i < omap4_prcm_irq_setup.nr_regs; i++) + events[i] = _read_pending_irq_reg(omap4_prcm_irq_setup.mask + + i * 4, omap4_prcm_irq_setup.ack + i * 4); } /** @@ -251,17 +251,17 @@ static void omap44xx_prm_ocp_barrier(void) */ static void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask) { - saved_mask[0] = - omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, - OMAP4_PRM_IRQENABLE_MPU_OFFSET); - saved_mask[1] = - omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, - OMAP4_PRM_IRQENABLE_MPU_2_OFFSET); + int i; + u16 reg; - omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST, - OMAP4_PRM_IRQENABLE_MPU_OFFSET); - omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST, - OMAP4_PRM_IRQENABLE_MPU_2_OFFSET); + for (i = 0; i < omap4_prcm_irq_setup.nr_regs; i++) { + reg = omap4_prcm_irq_setup.mask + i * 4; + + saved_mask[i] = + omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, + reg); + omap4_prm_write_inst_reg(0, OMAP4430_PRM_OCP_SOCKET_INST, reg); + } /* OCP barrier */ omap4_prm_read_inst_reg(OMAP4430_PRM_OCP_SOCKET_INST, @@ -280,10 +280,12 @@ static void omap44xx_prm_save_and_clear_irqen(u32 *saved_mask) */ static void omap44xx_prm_restore_irqen(u32 *saved_mask) { - omap4_prm_write_inst_reg(saved_mask[0], OMAP4430_PRM_OCP_SOCKET_INST, - OMAP4_PRM_IRQENABLE_MPU_OFFSET); - omap4_prm_write_inst_reg(saved_mask[1], OMAP4430_PRM_OCP_SOCKET_INST, - OMAP4_PRM_IRQENABLE_MPU_2_OFFSET); + int i; + + for (i = 0; i < omap4_prcm_irq_setup.nr_regs; i++) + omap4_prm_write_inst_reg(saved_mask[i], + OMAP4430_PRM_OCP_SOCKET_INST, + omap4_prcm_irq_setup.mask + i * 4); } /** -- cgit v0.10.2 From cc843711fdcf345fe46db6e2a9dbc0091f336746 Mon Sep 17 00:00:00 2001 From: Keerthy Date: Thu, 16 Jul 2015 17:23:18 +0530 Subject: ARM: OMAP4+: PRM: Add AM437x specific data The register offsets for some of the PRM Registers are different hence populating the differing fields. This is needed to support IO wake up feature for am437x family. Signed-off-by: Keerthy Reviewed-by: Paul Walmsley Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index e6262d3..3076800 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c @@ -18,13 +18,14 @@ #include #include #include - +#include #include "soc.h" #include "iomap.h" #include "common.h" #include "vp.h" #include "prm44xx.h" +#include "prcm43xx.h" #include "prm-regbits-44xx.h" #include "prcm44xx.h" #include "prminst44xx.h" @@ -722,6 +723,15 @@ int __init omap44xx_prm_init(const struct omap_prcm_init_data *data) omap4_prminst_set_prm_dev_inst(data->device_inst_offset); + /* Add AM437X specific differences */ + if (of_device_is_compatible(data->np, "ti,am4-prcm")) { + omap4_prcm_irq_setup.nr_irqs = 1; + omap4_prcm_irq_setup.nr_regs = 1; + omap4_prcm_irq_setup.pm_ctrl = AM43XX_PRM_IO_PMCTRL_OFFSET; + omap4_prcm_irq_setup.ack = AM43XX_PRM_IRQSTATUS_MPU_OFFSET; + omap4_prcm_irq_setup.mask = AM43XX_PRM_IRQENABLE_MPU_OFFSET; + } + return prm_register(&omap44xx_prm_ll_data); } -- cgit v0.10.2 From 8740a1444ed3696c3418c2e90481e9528bad60fa Mon Sep 17 00:00:00 2001 From: Keerthy Date: Thu, 16 Jul 2015 17:23:19 +0530 Subject: ARM: PRM: AM437x: Enable IO wakeup feature Enable IO wakeup feature. This enables am437x pads to generate daisy chained wake ups(eventually generates aprcm Interrupt) especially when in low power modes. Signed-off-by: Keerthy Reviewed-by: Paul Walmsley Signed-off-by: Paul Walmsley diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index 7add799..1730fc4 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -696,6 +696,7 @@ static struct omap_prcm_init_data am4_prm_data __initdata = { .index = TI_CLKM_PRM, .init = omap44xx_prm_init, .device_inst_offset = AM43XX_PRM_DEVICE_INST, + .flags = PRM_HAS_IO_WAKEUP, }; #endif -- cgit v0.10.2 From 3e0452d27a784d50f09bec9de8ac673849b9e303 Mon Sep 17 00:00:00 2001 From: Matthias Brugger Date: Fri, 17 Jul 2015 22:53:26 +0200 Subject: ARM: mediatek: Add regmap to mediatek Kconfig Mediatek SoC needs the regmap/syscon infrastructure. The infrastructure is used by the clock and pinctrl driver. This patch adds MD_SYSCON to Kconfig for all Mediatek devices. Signed-off-by: Matthias Brugger diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig index 9f59e58..aeece17 100644 --- a/arch/arm/mach-mediatek/Kconfig +++ b/arch/arm/mach-mediatek/Kconfig @@ -3,6 +3,7 @@ menuconfig ARCH_MEDIATEK select ARM_GIC select PINCTRL select MTK_TIMER + select MFD_SYSCON help Support for Mediatek MT65xx & MT81xx SoCs -- cgit v0.10.2 From 7e1b11d145b264fd7e7b4bf79d910272d4a1bd52 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 16 Jul 2015 01:55:58 -0700 Subject: ARM: OMAP2+: Prepare dm81xx hwmod code for adding minimal dm814x support Let's change the defines so we can share the hwmod code better between dm816x and dm814x, and let's add the dm814x specific defines. And let's rename the shared ones to start with dm81xx. No functional changes. Cc: Matthijs van Duin Cc: Paul Walmsley Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c index c924137..bf08f5f 100644 --- a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c @@ -32,21 +32,59 @@ */ /* - * The alwon .clkctrl_offs field is offset from the CM_ALWON, that's - * TRM 18.7.17 CM_ALWON device register values minus 0x1400. + * Common alwon .clkctrl_offs from dm814x TRM "Table 2-278. CM_ALWON REGISTERS" + * also dm816x TRM 18.7.17 CM_ALWON device register values minus 0x1400. */ +#define DM81XX_CM_ALWON_MCASP0_CLKCTRL 0x140 +#define DM81XX_CM_ALWON_MCASP1_CLKCTRL 0x144 +#define DM81XX_CM_ALWON_MCASP2_CLKCTRL 0x148 +#define DM81XX_CM_ALWON_MCBSP_CLKCTRL 0x14c +#define DM81XX_CM_ALWON_UART_0_CLKCTRL 0x150 +#define DM81XX_CM_ALWON_UART_1_CLKCTRL 0x154 +#define DM81XX_CM_ALWON_UART_2_CLKCTRL 0x158 +#define DM81XX_CM_ALWON_GPIO_0_CLKCTRL 0x15c +#define DM81XX_CM_ALWON_GPIO_1_CLKCTRL 0x160 +#define DM81XX_CM_ALWON_I2C_0_CLKCTRL 0x164 +#define DM81XX_CM_ALWON_I2C_1_CLKCTRL 0x168 +#define DM81XX_CM_ALWON_WDTIMER_CLKCTRL 0x18c +#define DM81XX_CM_ALWON_SPI_CLKCTRL 0x190 +#define DM81XX_CM_ALWON_MAILBOX_CLKCTRL 0x194 +#define DM81XX_CM_ALWON_SPINBOX_CLKCTRL 0x198 +#define DM81XX_CM_ALWON_MMUDATA_CLKCTRL 0x19c +#define DM81XX_CM_ALWON_MMUCFG_CLKCTRL 0x1a8 +#define DM81XX_CM_ALWON_CONTROL_CLKCTRL 0x1c4 +#define DM81XX_CM_ALWON_GPMC_CLKCTRL 0x1d0 +#define DM81XX_CM_ALWON_ETHERNET_0_CLKCTRL 0x1d4 +#define DM81XX_CM_ALWON_L3_CLKCTRL 0x1e4 +#define DM81XX_CM_ALWON_L4HS_CLKCTRL 0x1e8 +#define DM81XX_CM_ALWON_L4LS_CLKCTRL 0x1ec +#define DM81XX_CM_ALWON_RTC_CLKCTRL 0x1f0 +#define DM81XX_CM_ALWON_TPCC_CLKCTRL 0x1f4 +#define DM81XX_CM_ALWON_TPTC0_CLKCTRL 0x1f8 +#define DM81XX_CM_ALWON_TPTC1_CLKCTRL 0x1fc +#define DM81XX_CM_ALWON_TPTC2_CLKCTRL 0x200 +#define DM81XX_CM_ALWON_TPTC3_CLKCTRL 0x204 + +/* Registers specific to dm814x */ +#define DM814X_CM_ALWON_MCASP_3_4_5_CLKCTRL 0x16c +#define DM814X_CM_ALWON_ATL_CLKCTRL 0x170 +#define DM814X_CM_ALWON_MLB_CLKCTRL 0x174 +#define DM814X_CM_ALWON_PATA_CLKCTRL 0x178 +#define DM814X_CM_ALWON_UART_3_CLKCTRL 0x180 +#define DM814X_CM_ALWON_UART_4_CLKCTRL 0x184 +#define DM814X_CM_ALWON_UART_5_CLKCTRL 0x188 +#define DM814X_CM_ALWON_OCM_0_CLKCTRL 0x1b4 +#define DM814X_CM_ALWON_VCP_CLKCTRL 0x1b8 +#define DM814X_CM_ALWON_MPU_CLKCTRL 0x1dc +#define DM814X_CM_ALWON_DEBUGSS_CLKCTRL 0x1e0 +#define DM814X_CM_ALWON_DCAN_0_1_CLKCTRL 0x218 +#define DM814X_CM_ALWON_MMCHS_0_CLKCTRL 0x21c +#define DM814X_CM_ALWON_MMCHS_1_CLKCTRL 0x220 +#define DM814X_CM_ALWON_MMCHS_2_CLKCTRL 0x224 +#define DM814X_CM_ALWON_CUST_EFUSE_CLKCTRL 0x228 + +/* Registers specific to dm816x */ #define DM816X_DM_ALWON_BASE 0x1400 -#define DM816X_CM_ALWON_MCASP0_CLKCTRL (0x1540 - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_MCASP1_CLKCTRL (0x1544 - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_MCASP2_CLKCTRL (0x1548 - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_MCBSP_CLKCTRL (0x154c - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_UART_0_CLKCTRL (0x1550 - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_UART_1_CLKCTRL (0x1554 - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_UART_2_CLKCTRL (0x1558 - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_GPIO_0_CLKCTRL (0x155c - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_GPIO_1_CLKCTRL (0x1560 - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_I2C_0_CLKCTRL (0x1564 - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_I2C_1_CLKCTRL (0x1568 - DM816X_DM_ALWON_BASE) #define DM816X_CM_ALWON_TIMER_1_CLKCTRL (0x1570 - DM816X_DM_ALWON_BASE) #define DM816X_CM_ALWON_TIMER_2_CLKCTRL (0x1574 - DM816X_DM_ALWON_BASE) #define DM816X_CM_ALWON_TIMER_3_CLKCTRL (0x1578 - DM816X_DM_ALWON_BASE) @@ -54,29 +92,11 @@ #define DM816X_CM_ALWON_TIMER_5_CLKCTRL (0x1580 - DM816X_DM_ALWON_BASE) #define DM816X_CM_ALWON_TIMER_6_CLKCTRL (0x1584 - DM816X_DM_ALWON_BASE) #define DM816X_CM_ALWON_TIMER_7_CLKCTRL (0x1588 - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_WDTIMER_CLKCTRL (0x158c - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_SPI_CLKCTRL (0x1590 - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_MAILBOX_CLKCTRL (0x1594 - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_SPINBOX_CLKCTRL (0x1598 - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_MMUDATA_CLKCTRL (0x159c - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_MMUCFG_CLKCTRL (0x15a8 - DM816X_DM_ALWON_BASE) #define DM816X_CM_ALWON_SDIO_CLKCTRL (0x15b0 - DM816X_DM_ALWON_BASE) #define DM816X_CM_ALWON_OCMC_0_CLKCTRL (0x15b4 - DM816X_DM_ALWON_BASE) #define DM816X_CM_ALWON_OCMC_1_CLKCTRL (0x15b8 - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_CONTRL_CLKCTRL (0x15c4 - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_GPMC_CLKCTRL (0x15d0 - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_ETHERNET_0_CLKCTRL (0x15d4 - DM816X_DM_ALWON_BASE) #define DM816X_CM_ALWON_ETHERNET_1_CLKCTRL (0x15d8 - DM816X_DM_ALWON_BASE) #define DM816X_CM_ALWON_MPU_CLKCTRL (0x15dc - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_L3_CLKCTRL (0x15e4 - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_L4HS_CLKCTRL (0x15e8 - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_L4LS_CLKCTRL (0x15ec - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_RTC_CLKCTRL (0x15f0 - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_TPCC_CLKCTRL (0x15f4 - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_TPTC0_CLKCTRL (0x15f8 - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_TPTC1_CLKCTRL (0x15fc - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_TPTC2_CLKCTRL (0x1600 - DM816X_DM_ALWON_BASE) -#define DM816X_CM_ALWON_TPTC3_CLKCTRL (0x1604 - DM816X_DM_ALWON_BASE) #define DM816X_CM_ALWON_SR_0_CLKCTRL (0x1608 - DM816X_DM_ALWON_BASE) #define DM816X_CM_ALWON_SR_1_CLKCTRL (0x160c - DM816X_DM_ALWON_BASE) @@ -88,28 +108,28 @@ #define DM816X_CM_DEFAULT_USB_CLKCTRL (0x558 - DM816X_CM_DEFAULT_OFFSET) /* L3 Interconnect entries clocked at 125, 250 and 500MHz */ -static struct omap_hwmod dm816x_alwon_l3_slow_hwmod = { +static struct omap_hwmod dm81xx_alwon_l3_slow_hwmod = { .name = "alwon_l3_slow", .clkdm_name = "alwon_l3s_clkdm", .class = &l3_hwmod_class, .flags = HWMOD_NO_IDLEST, }; -static struct omap_hwmod dm816x_default_l3_slow_hwmod = { +static struct omap_hwmod dm81xx_default_l3_slow_hwmod = { .name = "default_l3_slow", .clkdm_name = "default_l3_slow_clkdm", .class = &l3_hwmod_class, .flags = HWMOD_NO_IDLEST, }; -static struct omap_hwmod dm816x_alwon_l3_med_hwmod = { +static struct omap_hwmod dm81xx_alwon_l3_med_hwmod = { .name = "l3_med", .clkdm_name = "alwon_l3_med_clkdm", .class = &l3_hwmod_class, .flags = HWMOD_NO_IDLEST, }; -static struct omap_hwmod dm816x_alwon_l3_fast_hwmod = { +static struct omap_hwmod dm81xx_alwon_l3_fast_hwmod = { .name = "l3_fast", .clkdm_name = "alwon_l3_fast_clkdm", .class = &l3_hwmod_class, @@ -120,7 +140,7 @@ static struct omap_hwmod dm816x_alwon_l3_fast_hwmod = { * L4 standard peripherals, see TRM table 1-12 for devices using this. * See TRM table 1-73 for devices using the 125MHz SYSCLK6 clock. */ -static struct omap_hwmod dm816x_l4_ls_hwmod = { +static struct omap_hwmod dm81xx_l4_ls_hwmod = { .name = "l4_ls", .clkdm_name = "alwon_l3s_clkdm", .class = &l4_hwmod_class, @@ -131,23 +151,23 @@ static struct omap_hwmod dm816x_l4_ls_hwmod = { * table 1-13. On dm816x, only EMAC, MDIO and SATA use this. See also TRM * table 1-73 for devices using 250MHz SYSCLK5 clock. */ -static struct omap_hwmod dm816x_l4_hs_hwmod = { +static struct omap_hwmod dm81xx_l4_hs_hwmod = { .name = "l4_hs", .clkdm_name = "alwon_l3_med_clkdm", .class = &l4_hwmod_class, }; /* L3 slow -> L4 ls peripheral interface running at 125MHz */ -static struct omap_hwmod_ocp_if dm816x_alwon_l3_slow__l4_ls = { - .master = &dm816x_alwon_l3_slow_hwmod, - .slave = &dm816x_l4_ls_hwmod, +static struct omap_hwmod_ocp_if dm81xx_alwon_l3_slow__l4_ls = { + .master = &dm81xx_alwon_l3_slow_hwmod, + .slave = &dm81xx_l4_ls_hwmod, .user = OCP_USER_MPU, }; /* L3 med -> L4 fast peripheral interface running at 250MHz */ -static struct omap_hwmod_ocp_if dm816x_alwon_l3_slow__l4_hs = { - .master = &dm816x_alwon_l3_med_hwmod, - .slave = &dm816x_l4_hs_hwmod, +static struct omap_hwmod_ocp_if dm81xx_alwon_l3_slow__l4_hs = { + .master = &dm81xx_alwon_l3_med_hwmod, + .slave = &dm81xx_l4_hs_hwmod, .user = OCP_USER_MPU, }; @@ -168,14 +188,14 @@ static struct omap_hwmod dm816x_mpu_hwmod = { static struct omap_hwmod_ocp_if dm816x_mpu__alwon_l3_slow = { .master = &dm816x_mpu_hwmod, - .slave = &dm816x_alwon_l3_slow_hwmod, + .slave = &dm81xx_alwon_l3_slow_hwmod, .user = OCP_USER_MPU, }; /* L3 med peripheral interface running at 250MHz */ static struct omap_hwmod_ocp_if dm816x_mpu__alwon_l3_med = { .master = &dm816x_mpu_hwmod, - .slave = &dm816x_alwon_l3_med_hwmod, + .slave = &dm81xx_alwon_l3_med_hwmod, .user = OCP_USER_MPU, }; @@ -197,13 +217,13 @@ static struct omap_hwmod_class uart_class = { .sysc = &uart_sysc, }; -static struct omap_hwmod dm816x_uart1_hwmod = { +static struct omap_hwmod dm81xx_uart1_hwmod = { .name = "uart1", .clkdm_name = "alwon_l3s_clkdm", .main_clk = "sysclk10_ck", .prcm = { .omap4 = { - .clkctrl_offs = DM816X_CM_ALWON_UART_0_CLKCTRL, + .clkctrl_offs = DM81XX_CM_ALWON_UART_0_CLKCTRL, .modulemode = MODULEMODE_SWCTRL, }, }, @@ -211,20 +231,20 @@ static struct omap_hwmod dm816x_uart1_hwmod = { .flags = DEBUG_TI81XXUART1_FLAGS, }; -static struct omap_hwmod_ocp_if dm816x_l4_ls__uart1 = { - .master = &dm816x_l4_ls_hwmod, - .slave = &dm816x_uart1_hwmod, +static struct omap_hwmod_ocp_if dm81xx_l4_ls__uart1 = { + .master = &dm81xx_l4_ls_hwmod, + .slave = &dm81xx_uart1_hwmod, .clk = "sysclk6_ck", .user = OCP_USER_MPU, }; -static struct omap_hwmod dm816x_uart2_hwmod = { +static struct omap_hwmod dm81xx_uart2_hwmod = { .name = "uart2", .clkdm_name = "alwon_l3s_clkdm", .main_clk = "sysclk10_ck", .prcm = { .omap4 = { - .clkctrl_offs = DM816X_CM_ALWON_UART_1_CLKCTRL, + .clkctrl_offs = DM81XX_CM_ALWON_UART_1_CLKCTRL, .modulemode = MODULEMODE_SWCTRL, }, }, @@ -232,20 +252,20 @@ static struct omap_hwmod dm816x_uart2_hwmod = { .flags = DEBUG_TI81XXUART2_FLAGS, }; -static struct omap_hwmod_ocp_if dm816x_l4_ls__uart2 = { - .master = &dm816x_l4_ls_hwmod, - .slave = &dm816x_uart2_hwmod, +static struct omap_hwmod_ocp_if dm81xx_l4_ls__uart2 = { + .master = &dm81xx_l4_ls_hwmod, + .slave = &dm81xx_uart2_hwmod, .clk = "sysclk6_ck", .user = OCP_USER_MPU, }; -static struct omap_hwmod dm816x_uart3_hwmod = { +static struct omap_hwmod dm81xx_uart3_hwmod = { .name = "uart3", .clkdm_name = "alwon_l3s_clkdm", .main_clk = "sysclk10_ck", .prcm = { .omap4 = { - .clkctrl_offs = DM816X_CM_ALWON_UART_2_CLKCTRL, + .clkctrl_offs = DM81XX_CM_ALWON_UART_2_CLKCTRL, .modulemode = MODULEMODE_SWCTRL, }, }, @@ -253,9 +273,9 @@ static struct omap_hwmod dm816x_uart3_hwmod = { .flags = DEBUG_TI81XXUART3_FLAGS, }; -static struct omap_hwmod_ocp_if dm816x_l4_ls__uart3 = { - .master = &dm816x_l4_ls_hwmod, - .slave = &dm816x_uart3_hwmod, +static struct omap_hwmod_ocp_if dm81xx_l4_ls__uart3 = { + .master = &dm81xx_l4_ls_hwmod, + .slave = &dm81xx_uart3_hwmod, .clk = "sysclk6_ck", .user = OCP_USER_MPU, }; @@ -276,23 +296,23 @@ static struct omap_hwmod_class wd_timer_class = { .reset = &omap2_wd_timer_reset, }; -static struct omap_hwmod dm816x_wd_timer_hwmod = { +static struct omap_hwmod dm81xx_wd_timer_hwmod = { .name = "wd_timer", .clkdm_name = "alwon_l3s_clkdm", .main_clk = "sysclk18_ck", .flags = HWMOD_NO_IDLEST, .prcm = { .omap4 = { - .clkctrl_offs = DM816X_CM_ALWON_WDTIMER_CLKCTRL, + .clkctrl_offs = DM81XX_CM_ALWON_WDTIMER_CLKCTRL, .modulemode = MODULEMODE_SWCTRL, }, }, .class = &wd_timer_class, }; -static struct omap_hwmod_ocp_if dm816x_l4_ls__wd_timer1 = { - .master = &dm816x_l4_ls_hwmod, - .slave = &dm816x_wd_timer_hwmod, +static struct omap_hwmod_ocp_if dm81xx_l4_ls__wd_timer1 = { + .master = &dm81xx_l4_ls_hwmod, + .slave = &dm81xx_wd_timer_hwmod, .clk = "sysclk6_ck", .user = OCP_USER_MPU, }; @@ -320,27 +340,27 @@ static struct omap_hwmod dm81xx_i2c1_hwmod = { .main_clk = "sysclk10_ck", .prcm = { .omap4 = { - .clkctrl_offs = DM816X_CM_ALWON_I2C_0_CLKCTRL, + .clkctrl_offs = DM81XX_CM_ALWON_I2C_0_CLKCTRL, .modulemode = MODULEMODE_SWCTRL, }, }, .class = &i2c_class, }; -static struct omap_hwmod_ocp_if dm816x_l4_ls__i2c1 = { - .master = &dm816x_l4_ls_hwmod, +static struct omap_hwmod_ocp_if dm81xx_l4_ls__i2c1 = { + .master = &dm81xx_l4_ls_hwmod, .slave = &dm81xx_i2c1_hwmod, .clk = "sysclk6_ck", .user = OCP_USER_MPU, }; -static struct omap_hwmod dm816x_i2c2_hwmod = { +static struct omap_hwmod dm81xx_i2c2_hwmod = { .name = "i2c2", .clkdm_name = "alwon_l3s_clkdm", .main_clk = "sysclk10_ck", .prcm = { .omap4 = { - .clkctrl_offs = DM816X_CM_ALWON_I2C_1_CLKCTRL, + .clkctrl_offs = DM81XX_CM_ALWON_I2C_1_CLKCTRL, .modulemode = MODULEMODE_SWCTRL, }, }, @@ -358,9 +378,9 @@ static struct omap_hwmod_class_sysconfig dm81xx_elm_sysc = { .sysc_fields = &omap_hwmod_sysc_type1, }; -static struct omap_hwmod_ocp_if dm816x_l4_ls__i2c2 = { - .master = &dm816x_l4_ls_hwmod, - .slave = &dm816x_i2c2_hwmod, +static struct omap_hwmod_ocp_if dm81xx_l4_ls__i2c2 = { + .master = &dm81xx_l4_ls_hwmod, + .slave = &dm81xx_i2c2_hwmod, .clk = "sysclk6_ck", .user = OCP_USER_MPU, }; @@ -378,7 +398,7 @@ static struct omap_hwmod dm81xx_elm_hwmod = { }; static struct omap_hwmod_ocp_if dm81xx_l4_ls__elm = { - .master = &dm816x_l4_ls_hwmod, + .master = &dm81xx_l4_ls_hwmod, .slave = &dm81xx_elm_hwmod, .user = OCP_USER_MPU, }; @@ -417,7 +437,7 @@ static struct omap_hwmod dm81xx_gpio1_hwmod = { .main_clk = "sysclk6_ck", .prcm = { .omap4 = { - .clkctrl_offs = DM816X_CM_ALWON_GPIO_0_CLKCTRL, + .clkctrl_offs = DM81XX_CM_ALWON_GPIO_0_CLKCTRL, .modulemode = MODULEMODE_SWCTRL, }, }, @@ -427,7 +447,7 @@ static struct omap_hwmod dm81xx_gpio1_hwmod = { }; static struct omap_hwmod_ocp_if dm81xx_l4_ls__gpio1 = { - .master = &dm816x_l4_ls_hwmod, + .master = &dm81xx_l4_ls_hwmod, .slave = &dm81xx_gpio1_hwmod, .user = OCP_USER_MPU, }; @@ -443,7 +463,7 @@ static struct omap_hwmod dm81xx_gpio2_hwmod = { .main_clk = "sysclk6_ck", .prcm = { .omap4 = { - .clkctrl_offs = DM816X_CM_ALWON_GPIO_1_CLKCTRL, + .clkctrl_offs = DM81XX_CM_ALWON_GPIO_1_CLKCTRL, .modulemode = MODULEMODE_SWCTRL, }, }, @@ -453,7 +473,7 @@ static struct omap_hwmod dm81xx_gpio2_hwmod = { }; static struct omap_hwmod_ocp_if dm81xx_l4_ls__gpio2 = { - .master = &dm816x_l4_ls_hwmod, + .master = &dm81xx_l4_ls_hwmod, .slave = &dm81xx_gpio2_hwmod, .user = OCP_USER_MPU, }; @@ -482,14 +502,14 @@ static struct omap_hwmod dm81xx_gpmc_hwmod = { .flags = DEBUG_OMAP_GPMC_HWMOD_FLAGS, .prcm = { .omap4 = { - .clkctrl_offs = DM816X_CM_ALWON_GPMC_CLKCTRL, + .clkctrl_offs = DM81XX_CM_ALWON_GPMC_CLKCTRL, .modulemode = MODULEMODE_SWCTRL, }, }, }; struct omap_hwmod_ocp_if dm81xx_alwon_l3_slow__gpmc = { - .master = &dm816x_alwon_l3_slow_hwmod, + .master = &dm81xx_alwon_l3_slow_hwmod, .slave = &dm81xx_gpmc_hwmod, .user = OCP_USER_MPU, }; @@ -522,7 +542,7 @@ static struct omap_hwmod dm81xx_usbss_hwmod = { }; static struct omap_hwmod_ocp_if dm81xx_default_l3_slow__usbss = { - .master = &dm816x_default_l3_slow_hwmod, + .master = &dm81xx_default_l3_slow_hwmod, .slave = &dm81xx_usbss_hwmod, .clk = "sysclk6_ck", .user = OCP_USER_MPU, @@ -562,7 +582,7 @@ static struct omap_hwmod dm816x_timer1_hwmod = { }; static struct omap_hwmod_ocp_if dm816x_l4_ls__timer1 = { - .master = &dm816x_l4_ls_hwmod, + .master = &dm81xx_l4_ls_hwmod, .slave = &dm816x_timer1_hwmod, .clk = "sysclk6_ck", .user = OCP_USER_MPU, @@ -583,7 +603,7 @@ static struct omap_hwmod dm816x_timer2_hwmod = { }; static struct omap_hwmod_ocp_if dm816x_l4_ls__timer2 = { - .master = &dm816x_l4_ls_hwmod, + .master = &dm81xx_l4_ls_hwmod, .slave = &dm816x_timer2_hwmod, .clk = "sysclk6_ck", .user = OCP_USER_MPU, @@ -604,7 +624,7 @@ static struct omap_hwmod dm816x_timer3_hwmod = { }; static struct omap_hwmod_ocp_if dm816x_l4_ls__timer3 = { - .master = &dm816x_l4_ls_hwmod, + .master = &dm81xx_l4_ls_hwmod, .slave = &dm816x_timer3_hwmod, .clk = "sysclk6_ck", .user = OCP_USER_MPU, @@ -625,7 +645,7 @@ static struct omap_hwmod dm816x_timer4_hwmod = { }; static struct omap_hwmod_ocp_if dm816x_l4_ls__timer4 = { - .master = &dm816x_l4_ls_hwmod, + .master = &dm81xx_l4_ls_hwmod, .slave = &dm816x_timer4_hwmod, .clk = "sysclk6_ck", .user = OCP_USER_MPU, @@ -646,7 +666,7 @@ static struct omap_hwmod dm816x_timer5_hwmod = { }; static struct omap_hwmod_ocp_if dm816x_l4_ls__timer5 = { - .master = &dm816x_l4_ls_hwmod, + .master = &dm81xx_l4_ls_hwmod, .slave = &dm816x_timer5_hwmod, .clk = "sysclk6_ck", .user = OCP_USER_MPU, @@ -667,7 +687,7 @@ static struct omap_hwmod dm816x_timer6_hwmod = { }; static struct omap_hwmod_ocp_if dm816x_l4_ls__timer6 = { - .master = &dm816x_l4_ls_hwmod, + .master = &dm81xx_l4_ls_hwmod, .slave = &dm816x_timer6_hwmod, .clk = "sysclk6_ck", .user = OCP_USER_MPU, @@ -688,7 +708,7 @@ static struct omap_hwmod dm816x_timer7_hwmod = { }; static struct omap_hwmod_ocp_if dm816x_l4_ls__timer7 = { - .master = &dm816x_l4_ls_hwmod, + .master = &dm81xx_l4_ls_hwmod, .slave = &dm816x_timer7_hwmod, .clk = "sysclk6_ck", .user = OCP_USER_MPU, @@ -717,21 +737,21 @@ static struct omap_hwmod dm816x_emac0_hwmod = { .class = &dm816x_emac_hwmod_class, }; -static struct omap_hwmod_ocp_if dm816x_l4_hs__emac0 = { - .master = &dm816x_l4_hs_hwmod, +static struct omap_hwmod_ocp_if dm81xx_l4_hs__emac0 = { + .master = &dm81xx_l4_hs_hwmod, .slave = &dm816x_emac0_hwmod, .clk = "sysclk5_ck", .user = OCP_USER_MPU, }; -static struct omap_hwmod_class dm816x_mdio_hwmod_class = { +static struct omap_hwmod_class dm81xx_mdio_hwmod_class = { .name = "davinci_mdio", .sysc = &dm816x_emac_sysc, }; -struct omap_hwmod dm816x_emac0_mdio_hwmod = { +struct omap_hwmod dm81xx_emac0_mdio_hwmod = { .name = "davinci_mdio", - .class = &dm816x_mdio_hwmod_class, + .class = &dm81xx_mdio_hwmod_class, .clkdm_name = "alwon_ethernet_clkdm", .main_clk = "sysclk24_ck", .flags = HWMOD_NO_IDLEST, @@ -741,15 +761,15 @@ struct omap_hwmod dm816x_emac0_mdio_hwmod = { */ .prcm = { .omap4 = { - .clkctrl_offs = DM816X_CM_ALWON_ETHERNET_0_CLKCTRL, + .clkctrl_offs = DM81XX_CM_ALWON_ETHERNET_0_CLKCTRL, .modulemode = MODULEMODE_SWCTRL, }, }, }; -struct omap_hwmod_ocp_if dm816x_emac0__mdio = { - .master = &dm816x_l4_hs_hwmod, - .slave = &dm816x_emac0_mdio_hwmod, +struct omap_hwmod_ocp_if dm81xx_emac0__mdio = { + .master = &dm81xx_l4_hs_hwmod, + .slave = &dm81xx_emac0_mdio_hwmod, .user = OCP_USER_MPU, }; @@ -768,7 +788,7 @@ static struct omap_hwmod dm816x_emac1_hwmod = { }; static struct omap_hwmod_ocp_if dm816x_l4_hs__emac1 = { - .master = &dm816x_l4_hs_hwmod, + .master = &dm81xx_l4_hs_hwmod, .slave = &dm816x_emac1_hwmod, .clk = "sysclk5_ck", .user = OCP_USER_MPU, @@ -815,7 +835,7 @@ static struct omap_hwmod dm816x_mmc1_hwmod = { }; static struct omap_hwmod_ocp_if dm816x_l4_ls__mmc1 = { - .master = &dm816x_l4_ls_hwmod, + .master = &dm81xx_l4_ls_hwmod, .slave = &dm816x_mmc1_hwmod, .clk = "sysclk6_ck", .user = OCP_USER_MPU, @@ -843,13 +863,13 @@ static struct omap2_mcspi_dev_attr dm816x_mcspi1_dev_attr = { .num_chipselect = 4, }; -static struct omap_hwmod dm816x_mcspi1_hwmod = { +static struct omap_hwmod dm81xx_mcspi1_hwmod = { .name = "mcspi1", .clkdm_name = "alwon_l3s_clkdm", .main_clk = "sysclk10_ck", .prcm = { .omap4 = { - .clkctrl_offs = DM816X_CM_ALWON_SPI_CLKCTRL, + .clkctrl_offs = DM81XX_CM_ALWON_SPI_CLKCTRL, .modulemode = MODULEMODE_SWCTRL, }, }, @@ -857,14 +877,14 @@ static struct omap_hwmod dm816x_mcspi1_hwmod = { .dev_attr = &dm816x_mcspi1_dev_attr, }; -static struct omap_hwmod_ocp_if dm816x_l4_ls__mcspi1 = { - .master = &dm816x_l4_ls_hwmod, - .slave = &dm816x_mcspi1_hwmod, +static struct omap_hwmod_ocp_if dm81xx_l4_ls__mcspi1 = { + .master = &dm81xx_l4_ls_hwmod, + .slave = &dm81xx_mcspi1_hwmod, .clk = "sysclk6_ck", .user = OCP_USER_MPU, }; -static struct omap_hwmod_class_sysconfig dm816x_mailbox_sysc = { +static struct omap_hwmod_class_sysconfig dm81xx_mailbox_sysc = { .rev_offs = 0x000, .sysc_offs = 0x010, .syss_offs = 0x014, @@ -874,55 +894,55 @@ static struct omap_hwmod_class_sysconfig dm816x_mailbox_sysc = { .sysc_fields = &omap_hwmod_sysc_type1, }; -static struct omap_hwmod_class dm816x_mailbox_hwmod_class = { +static struct omap_hwmod_class dm81xx_mailbox_hwmod_class = { .name = "mailbox", - .sysc = &dm816x_mailbox_sysc, + .sysc = &dm81xx_mailbox_sysc, }; -static struct omap_hwmod dm816x_mailbox_hwmod = { +static struct omap_hwmod dm81xx_mailbox_hwmod = { .name = "mailbox", .clkdm_name = "alwon_l3s_clkdm", - .class = &dm816x_mailbox_hwmod_class, + .class = &dm81xx_mailbox_hwmod_class, .main_clk = "sysclk6_ck", .prcm = { .omap4 = { - .clkctrl_offs = DM816X_CM_ALWON_MAILBOX_CLKCTRL, + .clkctrl_offs = DM81XX_CM_ALWON_MAILBOX_CLKCTRL, .modulemode = MODULEMODE_SWCTRL, }, }, }; -static struct omap_hwmod_ocp_if dm816x_l4_ls__mailbox = { - .master = &dm816x_l4_ls_hwmod, - .slave = &dm816x_mailbox_hwmod, +static struct omap_hwmod_ocp_if dm81xx_l4_ls__mailbox = { + .master = &dm81xx_l4_ls_hwmod, + .slave = &dm81xx_mailbox_hwmod, .user = OCP_USER_MPU, }; -static struct omap_hwmod_class dm816x_tpcc_hwmod_class = { +static struct omap_hwmod_class dm81xx_tpcc_hwmod_class = { .name = "tpcc", }; -struct omap_hwmod dm816x_tpcc_hwmod = { +struct omap_hwmod dm81xx_tpcc_hwmod = { .name = "tpcc", - .class = &dm816x_tpcc_hwmod_class, + .class = &dm81xx_tpcc_hwmod_class, .clkdm_name = "alwon_l3s_clkdm", .main_clk = "sysclk4_ck", .prcm = { .omap4 = { - .clkctrl_offs = DM816X_CM_ALWON_TPCC_CLKCTRL, + .clkctrl_offs = DM81XX_CM_ALWON_TPCC_CLKCTRL, .modulemode = MODULEMODE_SWCTRL, }, }, }; -struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tpcc = { - .master = &dm816x_alwon_l3_fast_hwmod, - .slave = &dm816x_tpcc_hwmod, +struct omap_hwmod_ocp_if dm81xx_alwon_l3_fast__tpcc = { + .master = &dm81xx_alwon_l3_fast_hwmod, + .slave = &dm81xx_tpcc_hwmod, .clk = "sysclk4_ck", .user = OCP_USER_MPU, }; -static struct omap_hwmod_addr_space dm816x_tptc0_addr_space[] = { +static struct omap_hwmod_addr_space dm81xx_tptc0_addr_space[] = { { .pa_start = 0x49800000, .pa_end = 0x49800000 + SZ_8K - 1, @@ -931,40 +951,40 @@ static struct omap_hwmod_addr_space dm816x_tptc0_addr_space[] = { { }, }; -static struct omap_hwmod_class dm816x_tptc0_hwmod_class = { +static struct omap_hwmod_class dm81xx_tptc0_hwmod_class = { .name = "tptc0", }; -struct omap_hwmod dm816x_tptc0_hwmod = { +struct omap_hwmod dm81xx_tptc0_hwmod = { .name = "tptc0", - .class = &dm816x_tptc0_hwmod_class, + .class = &dm81xx_tptc0_hwmod_class, .clkdm_name = "alwon_l3s_clkdm", .main_clk = "sysclk4_ck", .prcm = { .omap4 = { - .clkctrl_offs = DM816X_CM_ALWON_TPTC0_CLKCTRL, + .clkctrl_offs = DM81XX_CM_ALWON_TPTC0_CLKCTRL, .modulemode = MODULEMODE_SWCTRL, }, }, }; -struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc0 = { - .master = &dm816x_alwon_l3_fast_hwmod, - .slave = &dm816x_tptc0_hwmod, +struct omap_hwmod_ocp_if dm81xx_alwon_l3_fast__tptc0 = { + .master = &dm81xx_alwon_l3_fast_hwmod, + .slave = &dm81xx_tptc0_hwmod, .clk = "sysclk4_ck", - .addr = dm816x_tptc0_addr_space, + .addr = dm81xx_tptc0_addr_space, .user = OCP_USER_MPU, }; -struct omap_hwmod_ocp_if dm816x_tptc0__alwon_l3_fast = { - .master = &dm816x_tptc0_hwmod, - .slave = &dm816x_alwon_l3_fast_hwmod, +struct omap_hwmod_ocp_if dm81xx_tptc0__alwon_l3_fast = { + .master = &dm81xx_tptc0_hwmod, + .slave = &dm81xx_alwon_l3_fast_hwmod, .clk = "sysclk4_ck", - .addr = dm816x_tptc0_addr_space, + .addr = dm81xx_tptc0_addr_space, .user = OCP_USER_MPU, }; -static struct omap_hwmod_addr_space dm816x_tptc1_addr_space[] = { +static struct omap_hwmod_addr_space dm81xx_tptc1_addr_space[] = { { .pa_start = 0x49900000, .pa_end = 0x49900000 + SZ_8K - 1, @@ -973,40 +993,40 @@ static struct omap_hwmod_addr_space dm816x_tptc1_addr_space[] = { { }, }; -static struct omap_hwmod_class dm816x_tptc1_hwmod_class = { +static struct omap_hwmod_class dm81xx_tptc1_hwmod_class = { .name = "tptc1", }; -struct omap_hwmod dm816x_tptc1_hwmod = { +struct omap_hwmod dm81xx_tptc1_hwmod = { .name = "tptc1", - .class = &dm816x_tptc1_hwmod_class, + .class = &dm81xx_tptc1_hwmod_class, .clkdm_name = "alwon_l3s_clkdm", .main_clk = "sysclk4_ck", .prcm = { .omap4 = { - .clkctrl_offs = DM816X_CM_ALWON_TPTC1_CLKCTRL, + .clkctrl_offs = DM81XX_CM_ALWON_TPTC1_CLKCTRL, .modulemode = MODULEMODE_SWCTRL, }, }, }; -struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc1 = { - .master = &dm816x_alwon_l3_fast_hwmod, - .slave = &dm816x_tptc1_hwmod, +struct omap_hwmod_ocp_if dm81xx_alwon_l3_fast__tptc1 = { + .master = &dm81xx_alwon_l3_fast_hwmod, + .slave = &dm81xx_tptc1_hwmod, .clk = "sysclk4_ck", - .addr = dm816x_tptc1_addr_space, + .addr = dm81xx_tptc1_addr_space, .user = OCP_USER_MPU, }; -struct omap_hwmod_ocp_if dm816x_tptc1__alwon_l3_fast = { - .master = &dm816x_tptc1_hwmod, - .slave = &dm816x_alwon_l3_fast_hwmod, +struct omap_hwmod_ocp_if dm81xx_tptc1__alwon_l3_fast = { + .master = &dm81xx_tptc1_hwmod, + .slave = &dm81xx_alwon_l3_fast_hwmod, .clk = "sysclk4_ck", - .addr = dm816x_tptc1_addr_space, + .addr = dm81xx_tptc1_addr_space, .user = OCP_USER_MPU, }; -static struct omap_hwmod_addr_space dm816x_tptc2_addr_space[] = { +static struct omap_hwmod_addr_space dm81xx_tptc2_addr_space[] = { { .pa_start = 0x49a00000, .pa_end = 0x49a00000 + SZ_8K - 1, @@ -1015,40 +1035,40 @@ static struct omap_hwmod_addr_space dm816x_tptc2_addr_space[] = { { }, }; -static struct omap_hwmod_class dm816x_tptc2_hwmod_class = { +static struct omap_hwmod_class dm81xx_tptc2_hwmod_class = { .name = "tptc2", }; -struct omap_hwmod dm816x_tptc2_hwmod = { +struct omap_hwmod dm81xx_tptc2_hwmod = { .name = "tptc2", - .class = &dm816x_tptc2_hwmod_class, + .class = &dm81xx_tptc2_hwmod_class, .clkdm_name = "alwon_l3s_clkdm", .main_clk = "sysclk4_ck", .prcm = { .omap4 = { - .clkctrl_offs = DM816X_CM_ALWON_TPTC2_CLKCTRL, + .clkctrl_offs = DM81XX_CM_ALWON_TPTC2_CLKCTRL, .modulemode = MODULEMODE_SWCTRL, }, }, }; -struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc2 = { - .master = &dm816x_alwon_l3_fast_hwmod, - .slave = &dm816x_tptc2_hwmod, +struct omap_hwmod_ocp_if dm81xx_alwon_l3_fast__tptc2 = { + .master = &dm81xx_alwon_l3_fast_hwmod, + .slave = &dm81xx_tptc2_hwmod, .clk = "sysclk4_ck", - .addr = dm816x_tptc2_addr_space, + .addr = dm81xx_tptc2_addr_space, .user = OCP_USER_MPU, }; -struct omap_hwmod_ocp_if dm816x_tptc2__alwon_l3_fast = { - .master = &dm816x_tptc2_hwmod, - .slave = &dm816x_alwon_l3_fast_hwmod, +struct omap_hwmod_ocp_if dm81xx_tptc2__alwon_l3_fast = { + .master = &dm81xx_tptc2_hwmod, + .slave = &dm81xx_alwon_l3_fast_hwmod, .clk = "sysclk4_ck", - .addr = dm816x_tptc2_addr_space, + .addr = dm81xx_tptc2_addr_space, .user = OCP_USER_MPU, }; -static struct omap_hwmod_addr_space dm816x_tptc3_addr_space[] = { +static struct omap_hwmod_addr_space dm81xx_tptc3_addr_space[] = { { .pa_start = 0x49b00000, .pa_end = 0x49b00000 + SZ_8K - 1, @@ -1057,50 +1077,50 @@ static struct omap_hwmod_addr_space dm816x_tptc3_addr_space[] = { { }, }; -static struct omap_hwmod_class dm816x_tptc3_hwmod_class = { +static struct omap_hwmod_class dm81xx_tptc3_hwmod_class = { .name = "tptc3", }; -struct omap_hwmod dm816x_tptc3_hwmod = { +struct omap_hwmod dm81xx_tptc3_hwmod = { .name = "tptc3", - .class = &dm816x_tptc3_hwmod_class, + .class = &dm81xx_tptc3_hwmod_class, .clkdm_name = "alwon_l3s_clkdm", .main_clk = "sysclk4_ck", .prcm = { .omap4 = { - .clkctrl_offs = DM816X_CM_ALWON_TPTC3_CLKCTRL, + .clkctrl_offs = DM81XX_CM_ALWON_TPTC3_CLKCTRL, .modulemode = MODULEMODE_SWCTRL, }, }, }; -struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc3 = { - .master = &dm816x_alwon_l3_fast_hwmod, - .slave = &dm816x_tptc3_hwmod, +struct omap_hwmod_ocp_if dm81xx_alwon_l3_fast__tptc3 = { + .master = &dm81xx_alwon_l3_fast_hwmod, + .slave = &dm81xx_tptc3_hwmod, .clk = "sysclk4_ck", - .addr = dm816x_tptc3_addr_space, + .addr = dm81xx_tptc3_addr_space, .user = OCP_USER_MPU, }; -struct omap_hwmod_ocp_if dm816x_tptc3__alwon_l3_fast = { - .master = &dm816x_tptc3_hwmod, - .slave = &dm816x_alwon_l3_fast_hwmod, +struct omap_hwmod_ocp_if dm81xx_tptc3__alwon_l3_fast = { + .master = &dm81xx_tptc3_hwmod, + .slave = &dm81xx_alwon_l3_fast_hwmod, .clk = "sysclk4_ck", - .addr = dm816x_tptc3_addr_space, + .addr = dm81xx_tptc3_addr_space, .user = OCP_USER_MPU, }; static struct omap_hwmod_ocp_if *dm816x_hwmod_ocp_ifs[] __initdata = { &dm816x_mpu__alwon_l3_slow, &dm816x_mpu__alwon_l3_med, - &dm816x_alwon_l3_slow__l4_ls, - &dm816x_alwon_l3_slow__l4_hs, - &dm816x_l4_ls__uart1, - &dm816x_l4_ls__uart2, - &dm816x_l4_ls__uart3, - &dm816x_l4_ls__wd_timer1, - &dm816x_l4_ls__i2c1, - &dm816x_l4_ls__i2c2, + &dm81xx_alwon_l3_slow__l4_ls, + &dm81xx_alwon_l3_slow__l4_hs, + &dm81xx_l4_ls__uart1, + &dm81xx_l4_ls__uart2, + &dm81xx_l4_ls__uart3, + &dm81xx_l4_ls__wd_timer1, + &dm81xx_l4_ls__i2c1, + &dm81xx_l4_ls__i2c2, &dm81xx_l4_ls__gpio1, &dm81xx_l4_ls__gpio2, &dm81xx_l4_ls__elm, @@ -1112,20 +1132,20 @@ static struct omap_hwmod_ocp_if *dm816x_hwmod_ocp_ifs[] __initdata = { &dm816x_l4_ls__timer5, &dm816x_l4_ls__timer6, &dm816x_l4_ls__timer7, - &dm816x_l4_ls__mcspi1, - &dm816x_l4_ls__mailbox, - &dm816x_l4_hs__emac0, - &dm816x_emac0__mdio, + &dm81xx_l4_ls__mcspi1, + &dm81xx_l4_ls__mailbox, + &dm81xx_l4_hs__emac0, + &dm81xx_emac0__mdio, &dm816x_l4_hs__emac1, - &dm816x_alwon_l3_fast__tpcc, - &dm816x_alwon_l3_fast__tptc0, - &dm816x_alwon_l3_fast__tptc1, - &dm816x_alwon_l3_fast__tptc2, - &dm816x_alwon_l3_fast__tptc3, - &dm816x_tptc0__alwon_l3_fast, - &dm816x_tptc1__alwon_l3_fast, - &dm816x_tptc2__alwon_l3_fast, - &dm816x_tptc3__alwon_l3_fast, + &dm81xx_alwon_l3_fast__tpcc, + &dm81xx_alwon_l3_fast__tptc0, + &dm81xx_alwon_l3_fast__tptc1, + &dm81xx_alwon_l3_fast__tptc2, + &dm81xx_alwon_l3_fast__tptc3, + &dm81xx_tptc0__alwon_l3_fast, + &dm81xx_tptc1__alwon_l3_fast, + &dm81xx_tptc2__alwon_l3_fast, + &dm81xx_tptc3__alwon_l3_fast, &dm81xx_alwon_l3_slow__gpmc, &dm81xx_default_l3_slow__usbss, NULL, -- cgit v0.10.2 From 0f3ccb24c0347cd80160810df79bfa233749074e Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 16 Jul 2015 01:55:58 -0700 Subject: ARM: OMAP2: Add minimal dm814x hwmod support Let's add minimal set of dm814x hwmods to have a bootable system. Cc: Matthijs van Duin Cc: Paul Walmsley Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 596af73..056a0e6 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -555,7 +555,7 @@ void __init ti814x_init_early(void) omap3xxx_voltagedomains_init(); omap3xxx_powerdomains_init(); ti814x_clockdomains_init(); - ti81xx_hwmod_init(); + dm814x_hwmod_init(); omap_hwmod_init_postsetup(); if (of_have_populated_dt()) omap_clk_soc_init = dm814x_dt_clk_init; @@ -572,7 +572,7 @@ void __init ti816x_init_early(void) omap3xxx_voltagedomains_init(); omap3xxx_powerdomains_init(); ti816x_clockdomains_init(); - ti81xx_hwmod_init(); + dm816x_hwmod_init(); omap_hwmod_init_postsetup(); if (of_have_populated_dt()) omap_clk_soc_init = dm816x_dt_clk_init; diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index d78c12e..33033ff 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -3878,7 +3878,8 @@ void __init omap_hwmod_init(void) soc_ops.init_clkdm = _init_clkdm; soc_ops.update_context_lost = _omap4_update_context_lost; soc_ops.get_context_lost = _omap4_get_context_lost; - } else if (cpu_is_ti816x() || soc_is_am33xx() || soc_is_am43xx()) { + } else if (cpu_is_ti814x() || cpu_is_ti816x() || soc_is_am33xx() || + soc_is_am43xx()) { soc_ops.enable_module = _omap4_enable_module; soc_ops.disable_module = _omap4_disable_module; soc_ops.wait_target_ready = _omap4_wait_target_ready; diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h index b5d27ec..ed95334 100644 --- a/arch/arm/mach-omap2/omap_hwmod.h +++ b/arch/arm/mach-omap2/omap_hwmod.h @@ -755,7 +755,8 @@ extern int omap3xxx_hwmod_init(void); extern int omap44xx_hwmod_init(void); extern int omap54xx_hwmod_init(void); extern int am33xx_hwmod_init(void); -extern int ti81xx_hwmod_init(void); +extern int dm814x_hwmod_init(void); +extern int dm816x_hwmod_init(void); extern int dra7xx_hwmod_init(void); int am43xx_hwmod_init(void); diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c index bf08f5f..f12db1f 100644 --- a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c @@ -172,6 +172,33 @@ static struct omap_hwmod_ocp_if dm81xx_alwon_l3_slow__l4_hs = { }; /* MPU */ +static struct omap_hwmod dm814x_mpu_hwmod = { + .name = "mpu", + .clkdm_name = "alwon_l3s_clkdm", + .class = &mpu_hwmod_class, + .flags = HWMOD_INIT_NO_IDLE, + .main_clk = "mpu_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = DM814X_CM_ALWON_MPU_CLKCTRL, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod_ocp_if dm814x_mpu__alwon_l3_slow = { + .master = &dm814x_mpu_hwmod, + .slave = &dm81xx_alwon_l3_slow_hwmod, + .user = OCP_USER_MPU, +}; + +/* L3 med peripheral interface running at 200MHz */ +static struct omap_hwmod_ocp_if dm814x_mpu__alwon_l3_med = { + .master = &dm814x_mpu_hwmod, + .slave = &dm81xx_alwon_l3_med_hwmod, + .user = OCP_USER_MPU, +}; + static struct omap_hwmod dm816x_mpu_hwmod = { .name = "mpu", .clkdm_name = "alwon_mpu_clkdm", @@ -567,6 +594,22 @@ static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = { .timer_capability = OMAP_TIMER_ALWON, }; +static struct omap_hwmod dm814x_timer1_hwmod = { + .name = "timer1", + .clkdm_name = "alwon_l3s_clkdm", + .main_clk = "timer_sys_ck", + .dev_attr = &capability_alwon_dev_attr, + .class = &dm816x_timer_hwmod_class, + .flags = HWMOD_NO_IDLEST, +}; + +static struct omap_hwmod_ocp_if dm814x_l4_ls__timer1 = { + .master = &dm81xx_l4_ls_hwmod, + .slave = &dm814x_timer1_hwmod, + .clk = "timer_sys_ck", + .user = OCP_USER_MPU, +}; + static struct omap_hwmod dm816x_timer1_hwmod = { .name = "timer1", .clkdm_name = "alwon_l3s_clkdm", @@ -588,6 +631,22 @@ static struct omap_hwmod_ocp_if dm816x_l4_ls__timer1 = { .user = OCP_USER_MPU, }; +static struct omap_hwmod dm814x_timer2_hwmod = { + .name = "timer2", + .clkdm_name = "alwon_l3s_clkdm", + .main_clk = "timer_sys_ck", + .dev_attr = &capability_alwon_dev_attr, + .class = &dm816x_timer_hwmod_class, + .flags = HWMOD_NO_IDLEST, +}; + +static struct omap_hwmod_ocp_if dm814x_l4_ls__timer2 = { + .master = &dm81xx_l4_ls_hwmod, + .slave = &dm814x_timer2_hwmod, + .clk = "timer_sys_ck", + .user = OCP_USER_MPU, +}; + static struct omap_hwmod dm816x_timer2_hwmod = { .name = "timer2", .clkdm_name = "alwon_l3s_clkdm", @@ -714,6 +773,62 @@ static struct omap_hwmod_ocp_if dm816x_l4_ls__timer7 = { .user = OCP_USER_MPU, }; +/* CPSW on dm814x */ +static struct omap_hwmod_class_sysconfig dm814x_cpgmac_sysc = { + .rev_offs = 0x0, + .sysc_offs = 0x8, + .syss_offs = 0x4, + .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE | + SYSS_HAS_RESET_STATUS, + .idlemodes = SIDLE_FORCE | SIDLE_NO | MSTANDBY_FORCE | + MSTANDBY_NO, + .sysc_fields = &omap_hwmod_sysc_type3, +}; + +static struct omap_hwmod_class dm814x_cpgmac0_hwmod_class = { + .name = "cpgmac0", + .sysc = &dm814x_cpgmac_sysc, +}; + +struct omap_hwmod dm814x_cpgmac0_hwmod = { + .name = "cpgmac0", + .class = &dm814x_cpgmac0_hwmod_class, + .clkdm_name = "alwon_ethernet_clkdm", + .flags = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY, + .main_clk = "cpsw_125mhz_gclk", + .prcm = { + .omap4 = { + .clkctrl_offs = DM81XX_CM_ALWON_ETHERNET_0_CLKCTRL, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod_class dm814x_mdio_hwmod_class = { + .name = "davinci_mdio", +}; + +struct omap_hwmod dm814x_mdio_hwmod = { + .name = "davinci_mdio", + .class = &dm814x_mdio_hwmod_class, + .clkdm_name = "alwon_ethernet_clkdm", + .main_clk = "cpsw_125mhz_gclk", +}; + +static struct omap_hwmod_ocp_if dm814x_l4_hs__cpgmac0 = { + .master = &dm81xx_l4_hs_hwmod, + .slave = &dm814x_cpgmac0_hwmod, + .clk = "cpsw_125mhz_gclk", + .user = OCP_USER_MPU, +}; + +struct omap_hwmod_ocp_if dm814x_cpgmac0__mdio = { + .master = &dm814x_cpgmac0_hwmod, + .slave = &dm814x_mdio_hwmod, + .user = OCP_USER_MPU, + .flags = HWMOD_NO_IDLEST, +}; + /* EMAC Ethernet */ static struct omap_hwmod_class_sysconfig dm816x_emac_sysc = { .rev_offs = 0x0, @@ -1110,6 +1225,52 @@ struct omap_hwmod_ocp_if dm81xx_tptc3__alwon_l3_fast = { .user = OCP_USER_MPU, }; +/* + * REVISIT: Test and enable the following once clocks work: + * dm81xx_l4_ls__gpio1 + * dm81xx_l4_ls__gpio2 + * dm81xx_l4_ls__mailbox + * dm81xx_alwon_l3_slow__gpmc + * dm81xx_default_l3_slow__usbss + * + * Also note that some devices share a single clkctrl_offs.. + * For example, i2c1 and 3 share one, and i2c2 and 4 share one. + */ +static struct omap_hwmod_ocp_if *dm814x_hwmod_ocp_ifs[] __initdata = { + &dm814x_mpu__alwon_l3_slow, + &dm814x_mpu__alwon_l3_med, + &dm81xx_alwon_l3_slow__l4_ls, + &dm81xx_alwon_l3_slow__l4_hs, + &dm81xx_l4_ls__uart1, + &dm81xx_l4_ls__uart2, + &dm81xx_l4_ls__uart3, + &dm81xx_l4_ls__wd_timer1, + &dm81xx_l4_ls__i2c1, + &dm81xx_l4_ls__i2c2, + &dm81xx_l4_ls__elm, + &dm81xx_l4_ls__mcspi1, + &dm81xx_alwon_l3_fast__tpcc, + &dm81xx_alwon_l3_fast__tptc0, + &dm81xx_alwon_l3_fast__tptc1, + &dm81xx_alwon_l3_fast__tptc2, + &dm81xx_alwon_l3_fast__tptc3, + &dm81xx_tptc0__alwon_l3_fast, + &dm81xx_tptc1__alwon_l3_fast, + &dm81xx_tptc2__alwon_l3_fast, + &dm81xx_tptc3__alwon_l3_fast, + &dm814x_l4_ls__timer1, + &dm814x_l4_ls__timer2, + &dm814x_l4_hs__cpgmac0, + &dm814x_cpgmac0__mdio, + NULL, +}; + +int __init dm814x_hwmod_init(void) +{ + omap_hwmod_init(); + return omap_hwmod_register_links(dm814x_hwmod_ocp_ifs); +} + static struct omap_hwmod_ocp_if *dm816x_hwmod_ocp_ifs[] __initdata = { &dm816x_mpu__alwon_l3_slow, &dm816x_mpu__alwon_l3_med, @@ -1151,7 +1312,7 @@ static struct omap_hwmod_ocp_if *dm816x_hwmod_ocp_ifs[] __initdata = { NULL, }; -int __init ti81xx_hwmod_init(void) +int __init dm816x_hwmod_init(void) { omap_hwmod_init(); return omap_hwmod_register_links(dm816x_hwmod_ocp_ifs); -- cgit v0.10.2 From 01049a5deb1d6b9fc3f2df512af09fddd0db6730 Mon Sep 17 00:00:00 2001 From: Nadav Haklai Date: Wed, 8 Jul 2015 17:02:30 +0200 Subject: ARM: mvebu: prepare set_cpu_coherent() for future extension This patch prepares the set_cpu_coherent() function in coherency.c to be extended to support other SoCs than Armada XP. It will be needed on Armada 38x to re-enable the coherency after exiting from suspend to RAM. This preparation simply moves the function further down in coherency.c so that it can use coherency_type(), and uses that function to only do the Armada XP specific work if we are on Armada XP. Signed-off-by: Nadav Haklai Signed-off-by: Thomas Petazzoni Acked-by: Gregory CLEMENT Signed-off-by: Gregory CLEMENT diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c index e46e9ea..44eedf3 100644 --- a/arch/arm/mach-mvebu/coherency.c +++ b/arch/arm/mach-mvebu/coherency.c @@ -65,18 +65,6 @@ static const struct of_device_id of_coherency_table[] = { int ll_enable_coherency(void); void ll_add_cpu_to_smp_group(void); -int set_cpu_coherent(void) -{ - if (!coherency_base) { - pr_warn("Can't make current CPU cache coherent.\n"); - pr_warn("Coherency fabric is not initialized\n"); - return 1; - } - - ll_add_cpu_to_smp_group(); - return ll_enable_coherency(); -} - static int mvebu_hwcc_notifier(struct notifier_block *nb, unsigned long event, void *__dev) { @@ -206,6 +194,23 @@ static int coherency_type(void) return type; } +int set_cpu_coherent(void) +{ + int type = coherency_type(); + + if (type == COHERENCY_FABRIC_TYPE_ARMADA_370_XP) { + if (!coherency_base) { + pr_warn("Can't make current CPU cache coherent.\n"); + pr_warn("Coherency fabric is not initialized\n"); + return 1; + } + ll_add_cpu_to_smp_group(); + return ll_enable_coherency(); + } + + return 0; +} + int coherency_available(void) { return coherency_type() != COHERENCY_FABRIC_TYPE_NONE; -- cgit v0.10.2 From a101b53d3af16255c0038aad26902be590a96ffa Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Wed, 8 Jul 2015 17:02:31 +0200 Subject: ARM: mvebu: do not check machine in mvebu_pm_init() The mvebu_pm_init() initializes the support for suspend/resume, and before doing that, it checks if we are on a board on which suspend/resume is actually supported. However, this check is already done by mvebu_armada_xp_gp_pm_init(), and there is no need to duplicate the check: callers of mvebu_pm_init() should now what they are doing. This commit is done in preparation to the addition of suspend/resume support on Armada 38x. Signed-off-by: Thomas Petazzoni Acked-by: Gregory CLEMENT Signed-off-by: Gregory CLEMENT diff --git a/arch/arm/mach-mvebu/pm.c b/arch/arm/mach-mvebu/pm.c index 6573a8f..eca650b 100644 --- a/arch/arm/mach-mvebu/pm.c +++ b/arch/arm/mach-mvebu/pm.c @@ -182,9 +182,6 @@ int mvebu_pm_init(void (*board_pm_enter)(void __iomem *sdram_reg, u32 srcmd)) struct device_node *np; struct resource res; - if (!of_machine_is_compatible("marvell,armadaxp")) - return -ENODEV; - np = of_find_compatible_node(NULL, NULL, "marvell,armada-xp-sdram-controller"); if (!np) -- cgit v0.10.2 From 88ed69f2a1e1e8e5eb9e16d8cdebd9d5f1deef67 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Wed, 8 Jul 2015 17:02:32 +0200 Subject: ARM: mvebu: prepare mvebu_pm_store_bootinfo() to support multiple SoCs As we are going to introduce support for Armada 38x in pm.c, split out the Armada XP part of mvebu_pm_store_bootinfo() into mvebu_pm_store_armadaxp_bootinfo(), and make the former retunr an error when an unsupported SoC is used. Signed-off-by: Thomas Petazzoni Acked-by: Gregory CLEMENT Signed-off-by: Gregory CLEMENT diff --git a/arch/arm/mach-mvebu/pm.c b/arch/arm/mach-mvebu/pm.c index eca650b..02fdf67 100644 --- a/arch/arm/mach-mvebu/pm.c +++ b/arch/arm/mach-mvebu/pm.c @@ -105,12 +105,10 @@ static phys_addr_t mvebu_internal_reg_base(void) return of_translate_address(np, in_addr); } -static void mvebu_pm_store_bootinfo(void) +static void mvebu_pm_store_armadaxp_bootinfo(u32 *store_addr) { - u32 *store_addr; phys_addr_t resume_pc; - store_addr = phys_to_virt(BOOT_INFO_ADDR); resume_pc = virt_to_phys(armada_370_xp_cpu_resume); /* @@ -151,14 +149,33 @@ static void mvebu_pm_store_bootinfo(void) writel(BOOT_MAGIC_LIST_END, store_addr); } +static int mvebu_pm_store_bootinfo(void) +{ + u32 *store_addr; + + store_addr = phys_to_virt(BOOT_INFO_ADDR); + + if (of_machine_is_compatible("marvell,armadaxp")) + mvebu_pm_store_armadaxp_bootinfo(store_addr); + else + return -ENODEV; + + return 0; +} + static int mvebu_pm_enter(suspend_state_t state) { + int ret; + if (state != PM_SUSPEND_MEM) return -EINVAL; + ret = mvebu_pm_store_bootinfo(); + if (ret) + return ret; + cpu_pm_enter(); - mvebu_pm_store_bootinfo(); cpu_suspend(0, mvebu_pm_powerdown); outer_resume(); -- cgit v0.10.2 From 32f9494c9dfd7494721b314897008dcde6415cb3 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Wed, 8 Jul 2015 17:02:33 +0200 Subject: ARM: mvebu: prepare pm-board.c for the introduction of Armada 38x support The pm-board.c code contains the board-specific logic to enter suspend to RAM. Until now, the code supported only the Armada XP GP board, so all functions and symbols were named with armada_xp_gp. However, it turns out that the Armada 388 GP also uses the same 3 GPIOs protocol to talk to the PIC microcontroller that controls the power supply. Since we are going to re-use the same code with no change for Armada 38x, this commit renames the functions and symbols to use just "armada" instead of "armada_xp_gp". Better names can be found if one day other boards having a different protocol/mechanism are supported in the kernel. Signed-off-by: Thomas Petazzoni Acked-by: Gregory CLEMENT Signed-off-by: Gregory CLEMENT diff --git a/arch/arm/mach-mvebu/pm-board.c b/arch/arm/mach-mvebu/pm-board.c index 301ab38..b8c26cb 100644 --- a/arch/arm/mach-mvebu/pm-board.c +++ b/arch/arm/mach-mvebu/pm-board.c @@ -1,7 +1,7 @@ /* * Board-level suspend/resume support. * - * Copyright (C) 2014 Marvell + * Copyright (C) 2014-2015 Marvell * * Thomas Petazzoni * @@ -20,27 +20,27 @@ #include #include "common.h" -#define ARMADA_XP_GP_PIC_NR_GPIOS 3 +#define ARMADA_PIC_NR_GPIOS 3 static void __iomem *gpio_ctrl; -static int pic_gpios[ARMADA_XP_GP_PIC_NR_GPIOS]; -static int pic_raw_gpios[ARMADA_XP_GP_PIC_NR_GPIOS]; +static int pic_gpios[ARMADA_PIC_NR_GPIOS]; +static int pic_raw_gpios[ARMADA_PIC_NR_GPIOS]; -static void mvebu_armada_xp_gp_pm_enter(void __iomem *sdram_reg, u32 srcmd) +static void mvebu_armada_pm_enter(void __iomem *sdram_reg, u32 srcmd) { u32 reg, ackcmd; int i; /* Put 001 as value on the GPIOs */ reg = readl(gpio_ctrl); - for (i = 0; i < ARMADA_XP_GP_PIC_NR_GPIOS; i++) + for (i = 0; i < ARMADA_PIC_NR_GPIOS; i++) reg &= ~BIT(pic_raw_gpios[i]); reg |= BIT(pic_raw_gpios[0]); writel(reg, gpio_ctrl); /* Prepare writing 111 to the GPIOs */ ackcmd = readl(gpio_ctrl); - for (i = 0; i < ARMADA_XP_GP_PIC_NR_GPIOS; i++) + for (i = 0; i < ARMADA_PIC_NR_GPIOS; i++) ackcmd |= BIT(pic_raw_gpios[i]); srcmd = cpu_to_le32(srcmd); @@ -76,7 +76,7 @@ static void mvebu_armada_xp_gp_pm_enter(void __iomem *sdram_reg, u32 srcmd) [ackcmd] "r" (ackcmd), [gpio_ctrl] "r" (gpio_ctrl) : "r1"); } -static int mvebu_armada_xp_gp_pm_init(void) +static int mvebu_armada_pm_init(void) { struct device_node *np; struct device_node *gpio_ctrl_np; @@ -89,7 +89,7 @@ static int mvebu_armada_xp_gp_pm_init(void) if (!np) return -ENODEV; - for (i = 0; i < ARMADA_XP_GP_PIC_NR_GPIOS; i++) { + for (i = 0; i < ARMADA_PIC_NR_GPIOS; i++) { char *name; struct of_phandle_args args; @@ -134,11 +134,11 @@ static int mvebu_armada_xp_gp_pm_init(void) if (!gpio_ctrl) return -ENOMEM; - mvebu_pm_init(mvebu_armada_xp_gp_pm_enter); + mvebu_pm_init(mvebu_armada_pm_enter); out: of_node_put(np); return ret; } -late_initcall(mvebu_armada_xp_gp_pm_init); +late_initcall(mvebu_armada_pm_init); -- cgit v0.10.2 From bb253e743affa9d0053add8d3a1089df82f1c854 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Fri, 3 Jul 2015 13:55:50 +0200 Subject: ARM: mvebu: Use __init for the PM initialization functions mvebu_pm_init and mvebu_armada_pm_init are only called during boot, so flag them with __init and save some memory. Signed-off-by: Gregory CLEMENT Reviewed-by: Thomas Petazzoni diff --git a/arch/arm/mach-mvebu/pm-board.c b/arch/arm/mach-mvebu/pm-board.c index b8c26cb..3ab06e7 100644 --- a/arch/arm/mach-mvebu/pm-board.c +++ b/arch/arm/mach-mvebu/pm-board.c @@ -76,7 +76,7 @@ static void mvebu_armada_pm_enter(void __iomem *sdram_reg, u32 srcmd) [ackcmd] "r" (ackcmd), [gpio_ctrl] "r" (gpio_ctrl) : "r1"); } -static int mvebu_armada_pm_init(void) +static int __init mvebu_armada_pm_init(void) { struct device_node *np; struct device_node *gpio_ctrl_np; diff --git a/arch/arm/mach-mvebu/pm.c b/arch/arm/mach-mvebu/pm.c index 02fdf67..ca94f07 100644 --- a/arch/arm/mach-mvebu/pm.c +++ b/arch/arm/mach-mvebu/pm.c @@ -194,7 +194,7 @@ static const struct platform_suspend_ops mvebu_pm_ops = { .valid = suspend_valid_only_mem, }; -int mvebu_pm_init(void (*board_pm_enter)(void __iomem *sdram_reg, u32 srcmd)) +int __init mvebu_pm_init(void (*board_pm_enter)(void __iomem *sdram_reg, u32 srcmd)) { struct device_node *np; struct resource res; -- cgit v0.10.2 From 3cbd6a6ca81c9e8438b592099495a7c2b72de9e3 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Fri, 3 Jul 2015 13:55:51 +0200 Subject: ARM: mvebu: Add standby support Until now only one Armada XP and one Armada 388 based board supported suspend to ram. However, most of the recent mvebu SoCs can support the standby mode. Unlike for the suspend to ram, nothing special has to be done for these SoCs. This patch allows the system to use the standby mode on Armada 370, 38x, 39x and XP SoCs. There are issues with the Armada 375, and the support might be added (if possible) in a future patch. Signed-off-by: Gregory CLEMENT diff --git a/arch/arm/mach-mvebu/common.h b/arch/arm/mach-mvebu/common.h index 3e0aca1..6b77549 100644 --- a/arch/arm/mach-mvebu/common.h +++ b/arch/arm/mach-mvebu/common.h @@ -25,6 +25,6 @@ int mvebu_system_controller_get_soc_id(u32 *dev, u32 *rev); void __iomem *mvebu_get_scu_base(void); -int mvebu_pm_init(void (*board_pm_enter)(void __iomem *sdram_reg, u32 srcmd)); - +int mvebu_pm_suspend_init(void (*board_pm_enter)(void __iomem *sdram_reg, + u32 srcmd)); #endif diff --git a/arch/arm/mach-mvebu/pm-board.c b/arch/arm/mach-mvebu/pm-board.c index 3ab06e7..db17121 100644 --- a/arch/arm/mach-mvebu/pm-board.c +++ b/arch/arm/mach-mvebu/pm-board.c @@ -134,11 +134,19 @@ static int __init mvebu_armada_pm_init(void) if (!gpio_ctrl) return -ENOMEM; - mvebu_pm_init(mvebu_armada_pm_enter); + mvebu_pm_suspend_init(mvebu_armada_pm_enter); out: of_node_put(np); return ret; } -late_initcall(mvebu_armada_pm_init); +/* + * Registering the mvebu_board_pm_enter callback must be done before + * the platform_suspend_ops will be registered. In the same time we + * also need to have the gpio devices registered. That's why we use a + * device_initcall_sync which is called after all the device_initcall + * (used by the gpio device) but before the late_initcall (used to + * register the platform_suspend_ops) + */ +device_initcall_sync(mvebu_armada_pm_init); diff --git a/arch/arm/mach-mvebu/pm.c b/arch/arm/mach-mvebu/pm.c index ca94f07..b058307 100644 --- a/arch/arm/mach-mvebu/pm.c +++ b/arch/arm/mach-mvebu/pm.c @@ -163,13 +163,10 @@ static int mvebu_pm_store_bootinfo(void) return 0; } -static int mvebu_pm_enter(suspend_state_t state) +static int mvebu_enter_suspend(void) { int ret; - if (state != PM_SUSPEND_MEM) - return -EINVAL; - ret = mvebu_pm_store_bootinfo(); if (ret) return ret; @@ -185,16 +182,57 @@ static int mvebu_pm_enter(suspend_state_t state) set_cpu_coherent(); cpu_pm_exit(); + return 0; +} + +static int mvebu_pm_enter(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_STANDBY: + cpu_do_idle(); + break; + case PM_SUSPEND_MEM: + return mvebu_enter_suspend(); + default: + return -EINVAL; + } + return 0; +} + +static int mvebu_pm_valid(suspend_state_t state) +{ + if (state == PM_SUSPEND_STANDBY) + return 1; + + if (state == PM_SUSPEND_MEM && mvebu_board_pm_enter != NULL) + return 1; return 0; } static const struct platform_suspend_ops mvebu_pm_ops = { .enter = mvebu_pm_enter, - .valid = suspend_valid_only_mem, + .valid = mvebu_pm_valid, }; -int __init mvebu_pm_init(void (*board_pm_enter)(void __iomem *sdram_reg, u32 srcmd)) +static int __init mvebu_pm_init(void) +{ + if (!of_machine_is_compatible("marvell,armadaxp") && + !of_machine_is_compatible("marvell,armada370") && + !of_machine_is_compatible("marvell,armada380") && + !of_machine_is_compatible("marvell,armada390")) + return -ENODEV; + + suspend_set_ops(&mvebu_pm_ops); + + return 0; +} + + +late_initcall(mvebu_pm_init); + +int __init mvebu_pm_suspend_init(void (*board_pm_enter)(void __iomem *sdram_reg, + u32 srcmd)) { struct device_node *np; struct resource res; @@ -226,7 +264,5 @@ int __init mvebu_pm_init(void (*board_pm_enter)(void __iomem *sdram_reg, u32 src mvebu_board_pm_enter = board_pm_enter; - suspend_set_ops(&mvebu_pm_ops); - return 0; } -- cgit v0.10.2 From a3ff83d205ed48fadfc30ba9502dcf37a5d09b27 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 25 Jul 2015 16:23:24 +0900 Subject: MAINTAINERS: add entries for UniPhier device trees and drivers This clarifies the location of the files maintained by me. Signed-off-by: Masahiro Yamada Signed-off-by: Olof Johansson diff --git a/MAINTAINERS b/MAINTAINERS index fd60784..07280fa 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1578,7 +1578,10 @@ ARM/UNIPHIER ARCHITECTURE M: Masahiro Yamada L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Maintained +F: arch/arm/boot/dts/uniphier* F: arch/arm/mach-uniphier/ +F: drivers/pinctrl/uniphier/ +F: drivers/tty/serial/8250/8250_uniphier.c N: uniphier ARM/Ux500 ARM ARCHITECTURE -- cgit v0.10.2 From 482d638f98cc626bf01d4c9f6d6d35fc77d630c8 Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Fri, 3 Jul 2015 13:55:53 +0200 Subject: ARM: mvebu: Warn about the wake-up sources not taken into account in suspend On the Armada 370/XP/38x/39x SoCs when the suspend to ram feature is supported, the SoCs are shutdown and will be woken up by an external micro-controller, so there is no possibility to setup wake-up sources from Linux. However, in standby mode, the SoCs stay powered and it is possible to wake-up from any interrupt sources. Since when the users configures the enabled wake-up sources there is no way to know if the user will be doing suspend to RAM or standby, we just allow all wake-up sources to be enabled, and only warn when entering suspend to RAM The purpose of this patch is to inform the user that in suspend to ram mode, the wake-up sources won't be taken into consideration. Signed-off-by: Gregory CLEMENT diff --git a/arch/arm/mach-mvebu/pm.c b/arch/arm/mach-mvebu/pm.c index b058307..8d32bf7 100644 --- a/arch/arm/mach-mvebu/pm.c +++ b/arch/arm/mach-mvebu/pm.c @@ -192,6 +192,7 @@ static int mvebu_pm_enter(suspend_state_t state) cpu_do_idle(); break; case PM_SUSPEND_MEM: + pr_warn("Entering suspend to RAM. Only special wake-up sources will resume the system\n"); return mvebu_enter_suspend(); default: return -EINVAL; -- cgit v0.10.2 From f15107f41282d5ae9c6c26832dcc485729821ccc Mon Sep 17 00:00:00 2001 From: Jun Nie Date: Wed, 29 Jul 2015 14:16:58 +0800 Subject: ARM: zx: Add power domains for ZX296702 Add power domains for ZX296702 to power off inactive power domains in runtime. Signed-off-by: Jun Nie [olof: Marked zx296702_pd_driver as __initdata to avoid section mismatch] Signed-off-by: Olof Johansson diff --git a/arch/arm/mach-zx/Kconfig b/arch/arm/mach-zx/Kconfig index 2a910dc..7fdc5bf 100644 --- a/arch/arm/mach-zx/Kconfig +++ b/arch/arm/mach-zx/Kconfig @@ -13,6 +13,7 @@ config SOC_ZX296702 select ARM_GLOBAL_TIMER select HAVE_ARM_SCU if SMP select HAVE_ARM_TWD if SMP + select PM_GENERIC_DOMAINS help Support for ZTE ZX296702 SoC which is a dual core CortexA9MP endif diff --git a/arch/arm/mach-zx/Makefile b/arch/arm/mach-zx/Makefile index 7c2edf6..a4b4864 100644 --- a/arch/arm/mach-zx/Makefile +++ b/arch/arm/mach-zx/Makefile @@ -1,2 +1,2 @@ -obj-$(CONFIG_SOC_ZX296702) += zx296702.o +obj-$(CONFIG_SOC_ZX296702) += zx296702.o zx296702-pm-domain.o obj-$(CONFIG_SMP) += headsmp.o platsmp.o diff --git a/arch/arm/mach-zx/zx296702-pm-domain.c b/arch/arm/mach-zx/zx296702-pm-domain.c new file mode 100644 index 0000000..e08574d --- /dev/null +++ b/arch/arm/mach-zx/zx296702-pm-domain.c @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2015 Linaro Ltd. + * + * Author: Jun Nie + * License terms: GNU General Public License (GPL) version 2 + */ +#include +#include +#include +#include +#include +#include +#include + +#define PCU_DM_CLKEN 0x18 +#define PCU_DM_RSTEN 0x1C +#define PCU_DM_ISOEN 0x20 +#define PCU_DM_PWRDN 0x24 +#define PCU_DM_ACK_SYNC 0x28 + +enum { + PCU_DM_NEON0 = 0, + PCU_DM_NEON1, + PCU_DM_GPU, + PCU_DM_DECPPU, + PCU_DM_VOU, + PCU_DM_R2D, + PCU_DM_TOP, +}; + +static void __iomem *pcubase; + +struct zx_pm_domain { + struct generic_pm_domain dm; + unsigned int bit; +}; + +static int normal_power_off(struct generic_pm_domain *domain) +{ + struct zx_pm_domain *zpd = (struct zx_pm_domain *)domain; + unsigned long loop = 1000; + u32 tmp; + + tmp = readl_relaxed(pcubase + PCU_DM_CLKEN); + tmp &= ~BIT(zpd->bit); + writel_relaxed(tmp, pcubase + PCU_DM_CLKEN); + udelay(5); + + tmp = readl_relaxed(pcubase + PCU_DM_ISOEN); + tmp &= ~BIT(zpd->bit); + writel_relaxed(tmp | BIT(zpd->bit), pcubase + PCU_DM_ISOEN); + udelay(5); + + tmp = readl_relaxed(pcubase + PCU_DM_RSTEN); + tmp &= ~BIT(zpd->bit); + writel_relaxed(tmp, pcubase + PCU_DM_RSTEN); + udelay(5); + + tmp = readl_relaxed(pcubase + PCU_DM_PWRDN); + tmp &= ~BIT(zpd->bit); + writel_relaxed(tmp | BIT(zpd->bit), pcubase + PCU_DM_PWRDN); + do { + tmp = readl_relaxed(pcubase + PCU_DM_ACK_SYNC) & BIT(zpd->bit); + } while (--loop && !tmp); + + if (!loop) { + pr_err("Error: %s %s fail\n", __func__, domain->name); + return -EIO; + } + + return 0; +} + +static int normal_power_on(struct generic_pm_domain *domain) +{ + struct zx_pm_domain *zpd = (struct zx_pm_domain *)domain; + unsigned long loop = 10000; + u32 tmp; + + tmp = readl_relaxed(pcubase + PCU_DM_PWRDN); + tmp &= ~BIT(zpd->bit); + writel_relaxed(tmp, pcubase + PCU_DM_PWRDN); + do { + tmp = readl_relaxed(pcubase + PCU_DM_ACK_SYNC) & BIT(zpd->bit); + } while (--loop && tmp); + + if (!loop) { + pr_err("Error: %s %s fail\n", __func__, domain->name); + return -EIO; + } + + tmp = readl_relaxed(pcubase + PCU_DM_RSTEN); + tmp &= ~BIT(zpd->bit); + writel_relaxed(tmp | BIT(zpd->bit), pcubase + PCU_DM_RSTEN); + udelay(5); + + tmp = readl_relaxed(pcubase + PCU_DM_ISOEN); + tmp &= ~BIT(zpd->bit); + writel_relaxed(tmp, pcubase + PCU_DM_ISOEN); + udelay(5); + + tmp = readl_relaxed(pcubase + PCU_DM_CLKEN); + tmp &= ~BIT(zpd->bit); + writel_relaxed(tmp | BIT(zpd->bit), pcubase + PCU_DM_CLKEN); + udelay(5); + return 0; +} + +static struct zx_pm_domain gpu_domain = { + .dm = { + .name = "gpu_domain", + .power_off = normal_power_off, + .power_on = normal_power_on, + }, + .bit = PCU_DM_GPU, +}; + +static struct zx_pm_domain decppu_domain = { + .dm = { + .name = "decppu_domain", + .power_off = normal_power_off, + .power_on = normal_power_on, + }, + .bit = PCU_DM_DECPPU, +}; + +static struct zx_pm_domain vou_domain = { + .dm = { + .name = "vou_domain", + .power_off = normal_power_off, + .power_on = normal_power_on, + }, + .bit = PCU_DM_VOU, +}; + +static struct zx_pm_domain r2d_domain = { + .dm = { + .name = "r2d_domain", + .power_off = normal_power_off, + .power_on = normal_power_on, + }, + .bit = PCU_DM_R2D, +}; + +static struct generic_pm_domain *zx296702_pm_domains[] = { + &vou_domain.dm, + &gpu_domain.dm, + &decppu_domain.dm, + &r2d_domain.dm, +}; + +static int zx296702_pd_probe(struct platform_device *pdev) +{ + struct genpd_onecell_data *genpd_data; + struct resource *res; + int i; + + genpd_data = devm_kzalloc(&pdev->dev, sizeof(*genpd_data), GFP_KERNEL); + if (!genpd_data) + return -ENOMEM; + + genpd_data->domains = zx296702_pm_domains; + genpd_data->num_domains = ARRAY_SIZE(zx296702_pm_domains); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "no memory resource defined\n"); + return -ENODEV; + } + + pcubase = devm_ioremap_resource(&pdev->dev, res); + if (!pcubase) { + dev_err(&pdev->dev, "ioremap fail.\n"); + return -EIO; + } + + for (i = 0; i < ARRAY_SIZE(zx296702_pm_domains); ++i) + pm_genpd_init(zx296702_pm_domains[i], NULL, false); + + of_genpd_add_provider_onecell(pdev->dev.of_node, genpd_data); + return 0; +} + +static const struct of_device_id zx296702_pm_domain_matches[] __initconst = { + { .compatible = "zte,zx296702-pcu", }, + { }, +}; + +static struct platform_driver zx296702_pd_driver __initdata = { + .driver = { + .name = "zx-powerdomain", + .owner = THIS_MODULE, + .of_match_table = zx296702_pm_domain_matches, + }, + .probe = zx296702_pd_probe, +}; + +static int __init zx296702_pd_init(void) +{ + return platform_driver_register(&zx296702_pd_driver); +} +subsys_initcall(zx296702_pd_init); -- cgit v0.10.2 From d6448b76ab260457d78e9d09465afaec2697e20d Mon Sep 17 00:00:00 2001 From: Soren Brinkmann Date: Fri, 26 Jun 2015 09:04:32 -0700 Subject: MAINTAINERS: Update Zynq git tree location The git tree for Zynq moved to Github. Update the MAINTAINERS record to reflect the change. Signed-off-by: Soren Brinkmann Signed-off-by: Michal Simek diff --git a/MAINTAINERS b/MAINTAINERS index 8133cef..9cde7e5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1672,7 +1672,7 @@ M: Michal Simek R: Sören Brinkmann L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) W: http://wiki.xilinx.com -T: git git://git.xilinx.com/linux-xlnx.git +T: git https://github.com/Xilinx/linux-xlnx.git S: Supported F: arch/arm/mach-zynq/ F: drivers/cpuidle/cpuidle-zynq.c -- cgit v0.10.2 From 07e4d3d9e281136fdd781e8c3b9146b97f2d28d6 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Mon, 27 Jul 2015 16:36:42 +0900 Subject: clk: zynq: remove redundant $(CONFIG_ARCH_ZYNQ) in Makefile Kbuild descends into drivers/clk/zynq/ only when CONFIG_ARCH_ZYNQ is enabled. (see drivers/clk/Makefile) $(CONFIG_ARCH_ZYNQ) in drivers/clk/zynq/Makefile always evaluates to 'y'. Signed-off-by: Masahiro Yamada Signed-off-by: Michal Simek diff --git a/drivers/clk/zynq/Makefile b/drivers/clk/zynq/Makefile index 156d923..0afc2e7 100644 --- a/drivers/clk/zynq/Makefile +++ b/drivers/clk/zynq/Makefile @@ -1,3 +1,3 @@ # Zynq clock specific Makefile -obj-$(CONFIG_ARCH_ZYNQ) += clkc.o pll.o +obj-y += clkc.o pll.o -- cgit v0.10.2 From e4a9288942392965bd5cfad93d9996b83c0dc4a6 Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Fri, 17 Jul 2015 16:01:02 -0500 Subject: ARM: zynq: reserve space for jump target in secondary trampoline Add a zero argument to the .word directive in zynq_secondary_trampoline. Without an expression the assembler emits nothing for the .word directive. This makes it so that the intended range is communicated to ioremap and outer_flush_range in zynq_cpun_start; e.g. for LE trampoline_code_size evaluates to 12 now instead of 8. Found by inspection. I'm not aware of any real problem this fixes. Tested by doing on online/offline loop on ZC702. Signed-off-by: Nathan Lynch Signed-off-by: Michal Simek diff --git a/arch/arm/mach-zynq/headsmp.S b/arch/arm/mach-zynq/headsmp.S index 045c727..f6d5de0 100644 --- a/arch/arm/mach-zynq/headsmp.S +++ b/arch/arm/mach-zynq/headsmp.S @@ -18,7 +18,7 @@ ARM_BE8(rev r0, r0) .globl zynq_secondary_trampoline_jump zynq_secondary_trampoline_jump: /* Space for jumping address */ - .word /* cpu 1 */ + .word 0 /* cpu 1 */ .globl zynq_secondary_trampoline_end zynq_secondary_trampoline_end: ENDPROC(zynq_secondary_trampoline) -- cgit v0.10.2 From c268a743103aebba8d81d3365107f7170653099e Mon Sep 17 00:00:00 2001 From: Nicolas Ferre Date: Thu, 30 Jul 2015 19:12:12 +0200 Subject: ARM: at91/soc: add basic support for new sama5d2 SoC Add Kconfig entries, header file changes and addition to the documentation. The early debug infrastructure is also added for easy development. Signed-off-by: Ludovic Desroches Signed-off-by: Nicolas Ferre Acked-by: Alexandre Belloni Signed-off-by: Olof Johansson diff --git a/Documentation/arm/Atmel/README b/Documentation/arm/Atmel/README index c53a19b..0931cf7 100644 --- a/Documentation/arm/Atmel/README +++ b/Documentation/arm/Atmel/README @@ -90,6 +90,11 @@ the Atmel website: http://www.atmel.com. + Datasheet http://www.atmel.com/Images/Atmel-11238-32-bit-Cortex-A5-Microcontroller-SAMA5D4_Datasheet.pdf + - sama5d2 family + - sama5d27 + + Datasheet + Coming soon + Linux kernel information ------------------------ diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt index 424ac8c..7f04b8a 100644 --- a/Documentation/devicetree/bindings/arm/atmel-at91.txt +++ b/Documentation/devicetree/bindings/arm/atmel-at91.txt @@ -27,6 +27,8 @@ compatible: must be one of: o "atmel,at91sam9xe" * "atmel,sama5" for SoCs using a Cortex-A5, shall be extended with the specific SoC family: + o "atmel,sama5d2" shall be extended with the specific SoC compatible: + - "atmel,sama5d27" o "atmel,sama5d3" shall be extended with the specific SoC compatible: - "atmel,sama5d31" - "atmel,sama5d33" diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index a2e16f9..946c8c0 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -141,6 +141,12 @@ choice depends on ARCH_AT91 depends on SOC_SAMA5 + config AT91_DEBUG_LL_DBGU3 + bool "Kernel low-level debugging on sama5d2" + select DEBUG_AT91_UART + depends on ARCH_AT91 + depends on SOC_SAMA5 + config DEBUG_BCM2835 bool "Kernel low-level debugging on BCM2835 PL011 UART" depends on ARCH_BCM2835 diff --git a/arch/arm/include/debug/at91.S b/arch/arm/include/debug/at91.S index c3c45e6..2556a88 100644 --- a/arch/arm/include/debug/at91.S +++ b/arch/arm/include/debug/at91.S @@ -13,9 +13,12 @@ #define AT91_DBGU 0xfffff200 /* AT91_BASE_DBGU0 */ #elif defined(CONFIG_AT91_DEBUG_LL_DBGU1) #define AT91_DBGU 0xffffee00 /* AT91_BASE_DBGU1 */ -#else +#elif defined(CONFIG_AT91_DEBUG_LL_DBGU2) /* On sama5d4, use USART3 as low level serial console */ #define AT91_DBGU 0xfc00c000 /* SAMA5D4_BASE_USART3 */ +#else +/* On sama5d2, use UART1 as low level serial console */ +#define AT91_DBGU 0xf8020000 #endif #ifdef CONFIG_MMU diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index fd95f34..89a755b 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -8,6 +8,18 @@ menuconfig ARCH_AT91 select SOC_BUS if ARCH_AT91 +config SOC_SAMA5D2 + bool "SAMA5D2 family" if ARCH_MULTI_V7 + select SOC_SAMA5 + select CACHE_L2X0 + select HAVE_FB_ATMEL + select HAVE_AT91_UTMI + select HAVE_AT91_USB_CLK + select HAVE_AT91_H32MX + select HAVE_AT91_GENERATED_CLK + help + Select this if ou are using one of Atmel's SAMA5D2 family SoC. + config SOC_SAMA5D3 bool "SAMA5D3 family" if ARCH_MULTI_V7 select SOC_SAMA5 diff --git a/arch/arm/mach-at91/sama5.c b/arch/arm/mach-at91/sama5.c index 41d829d..90c3c30 100644 --- a/arch/arm/mach-at91/sama5.c +++ b/arch/arm/mach-at91/sama5.c @@ -18,6 +18,8 @@ #include "soc.h" static const struct at91_soc sama5_socs[] = { + AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27_EXID_MATCH, + "sama5d27", "sama5d2"), AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D31_EXID_MATCH, "sama5d31", "sama5d3"), AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D33_EXID_MATCH, @@ -64,6 +66,7 @@ DT_MACHINE_START(sama5_dt, "Atmel SAMA5") MACHINE_END static const char *sama5_alt_dt_board_compat[] __initconst = { + "atmel,sama5d2", "atmel,sama5d4", NULL }; diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h index be23c40..8ede0ef 100644 --- a/arch/arm/mach-at91/soc.h +++ b/arch/arm/mach-at91/soc.h @@ -62,6 +62,9 @@ at91_soc_init(const struct at91_soc *socs); #define AT91SAM9XE256_CIDR_MATCH 0x329a93a0 #define AT91SAM9XE512_CIDR_MATCH 0x329aa3a0 +#define SAMA5D2_CIDR_MATCH 0x0a5c08c0 +#define SAMA5D27_EXID_MATCH 0x00000021 + #define SAMA5D3_CIDR_MATCH 0x0a5c07c0 #define SAMA5D31_EXID_MATCH 0x00444300 #define SAMA5D33_EXID_MATCH 0x00414300 -- cgit v0.10.2 From 9dd068a4b85a68733213c874d08ef768bbec8d01 Mon Sep 17 00:00:00 2001 From: Matthias Brugger Date: Fri, 31 Jul 2015 17:03:13 +0200 Subject: soc: mediatek: Fix SCPSYS compilation SCPSYS driver misses the module.h include which makes it fail when compiling with allmodconf. This patch fixes this. Signed-off-by: Matthias Brugger Acked-by: Sascha Hauer Signed-off-by: Olof Johansson diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c index 43a79ed..164a7d8 100644 --- a/drivers/soc/mediatek/mtk-scpsys.c +++ b/drivers/soc/mediatek/mtk-scpsys.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include -- cgit v0.10.2 From 3f86e570f26837d9f48d64b7ece85853cb45becd Mon Sep 17 00:00:00 2001 From: Sudeep Holla Date: Sat, 1 Aug 2015 21:03:56 +0530 Subject: ARM: davinci: cp_intc: use IRQCHIP_SKIP_SET_WAKE instead of irq_set_wake callback Commit 60f96b41f71d ("genirq: Add IRQCHIP_SKIP_SET_WAKE flag") introduced a new flag to skip the irq_set_wake callback in the irqchip core to avoid adding dummy irq_set_wake in the irqchip implementations. This patch removes the dummy callback and sets the IRQCHIP_SKIP_SET_WAKE flags. Cc: Sekhar Nori Cc: Kevin Hilman Signed-off-by: Sudeep Holla Signed-off-by: Sekhar Nori Signed-off-by: Olof Johansson diff --git a/arch/arm/mach-davinci/cp_intc.c b/arch/arm/mach-davinci/cp_intc.c index 006dae8..9fda75c 100644 --- a/arch/arm/mach-davinci/cp_intc.c +++ b/arch/arm/mach-davinci/cp_intc.c @@ -85,23 +85,13 @@ static int cp_intc_set_irq_type(struct irq_data *d, unsigned int flow_type) return 0; } -/* - * Faking this allows us to to work with suspend functions of - * generic drivers which call {enable|disable}_irq_wake for - * wake up interrupt sources (eg RTC on DA850). - */ -static int cp_intc_set_wake(struct irq_data *d, unsigned int on) -{ - return 0; -} - static struct irq_chip cp_intc_irq_chip = { .name = "cp_intc", .irq_ack = cp_intc_ack_irq, .irq_mask = cp_intc_mask_irq, .irq_unmask = cp_intc_unmask_irq, .irq_set_type = cp_intc_set_irq_type, - .irq_set_wake = cp_intc_set_wake, + .flags = IRQCHIP_SKIP_SET_WAKE, }; static struct irq_domain *cp_intc_domain; -- cgit v0.10.2 From 8f5fe77828e16ef6fd8e4931ab177b41449ce8fc Mon Sep 17 00:00:00 2001 From: Philippe Reynes Date: Sun, 26 Jul 2015 23:37:50 +0200 Subject: rtc: mxc: use a second rtc clock The mxc RTC needs two clocks, one for the input reference, and one for the IP. But this driver was only using one clock (for the reference). This patch add the second clock (for the IP). Acked-by: Alexandre Belloni Signed-off-by: Philippe Reynes Signed-off-by: Shawn Guo diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index 5fc292c..880d485 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c @@ -79,7 +79,8 @@ struct rtc_plat_data { struct rtc_device *rtc; void __iomem *ioaddr; int irq; - struct clk *clk; + struct clk *clk_ref; + struct clk *clk_ipg; struct rtc_time g_rtc_alarm; enum imx_rtc_type devtype; }; @@ -373,17 +374,28 @@ static int mxc_rtc_probe(struct platform_device *pdev) if (IS_ERR(pdata->ioaddr)) return PTR_ERR(pdata->ioaddr); - pdata->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(pdata->clk)) { - dev_err(&pdev->dev, "unable to get clock!\n"); - return PTR_ERR(pdata->clk); + pdata->clk_ipg = devm_clk_get(&pdev->dev, "ipg"); + if (IS_ERR(pdata->clk_ipg)) { + dev_err(&pdev->dev, "unable to get ipg clock!\n"); + return PTR_ERR(pdata->clk_ipg); } - ret = clk_prepare_enable(pdata->clk); + ret = clk_prepare_enable(pdata->clk_ipg); if (ret) return ret; - rate = clk_get_rate(pdata->clk); + pdata->clk_ref = devm_clk_get(&pdev->dev, "ref"); + if (IS_ERR(pdata->clk_ref)) { + dev_err(&pdev->dev, "unable to get ref clock!\n"); + ret = PTR_ERR(pdata->clk_ref); + goto exit_put_clk_ipg; + } + + ret = clk_prepare_enable(pdata->clk_ref); + if (ret) + goto exit_put_clk_ipg; + + rate = clk_get_rate(pdata->clk_ref); if (rate == 32768) reg = RTC_INPUT_CLK_32768HZ; @@ -394,7 +406,7 @@ static int mxc_rtc_probe(struct platform_device *pdev) else { dev_err(&pdev->dev, "rtc clock is not valid (%lu)\n", rate); ret = -EINVAL; - goto exit_put_clk; + goto exit_put_clk_ref; } reg |= RTC_ENABLE_BIT; @@ -402,7 +414,7 @@ static int mxc_rtc_probe(struct platform_device *pdev) if (((readw(pdata->ioaddr + RTC_RTCCTL)) & RTC_ENABLE_BIT) == 0) { dev_err(&pdev->dev, "hardware module can't be enabled!\n"); ret = -EIO; - goto exit_put_clk; + goto exit_put_clk_ref; } platform_set_drvdata(pdev, pdata); @@ -424,15 +436,17 @@ static int mxc_rtc_probe(struct platform_device *pdev) THIS_MODULE); if (IS_ERR(rtc)) { ret = PTR_ERR(rtc); - goto exit_put_clk; + goto exit_put_clk_ref; } pdata->rtc = rtc; return 0; -exit_put_clk: - clk_disable_unprepare(pdata->clk); +exit_put_clk_ref: + clk_disable_unprepare(pdata->clk_ref); +exit_put_clk_ipg: + clk_disable_unprepare(pdata->clk_ipg); return ret; } @@ -441,7 +455,8 @@ static int mxc_rtc_remove(struct platform_device *pdev) { struct rtc_plat_data *pdata = platform_get_drvdata(pdev); - clk_disable_unprepare(pdata->clk); + clk_disable_unprepare(pdata->clk_ref); + clk_disable_unprepare(pdata->clk_ipg); return 0; } -- cgit v0.10.2 From 61186371570e3ca62585e29e307f7a9c42ab789a Mon Sep 17 00:00:00 2001 From: Philippe Reynes Date: Sun, 26 Jul 2015 23:37:51 +0200 Subject: dt-binding: document the binding for mxc rtc This adds documentation of device tree bindings for the mxc rtc. Cc: Rob Herring Cc: Pawel Moll Cc: Mark Rutland Cc: Ian Campbell Cc: Kumar Gala Cc: devicetree@vger.kernel.org Signed-off-by: Philippe Reynes Signed-off-by: Shawn Guo diff --git a/Documentation/devicetree/bindings/rtc/rtc-mxc.txt b/Documentation/devicetree/bindings/rtc/rtc-mxc.txt new file mode 100644 index 0000000..5bcd31d --- /dev/null +++ b/Documentation/devicetree/bindings/rtc/rtc-mxc.txt @@ -0,0 +1,26 @@ +* Real Time Clock of the i.MX SoCs + +RTC controller for the i.MX SoCs + +Required properties: +- compatible: Should be "fsl,imx1-rtc" or "fsl,imx21-rtc". +- reg: physical base address of the controller and length of memory mapped + region. +- interrupts: IRQ line for the RTC. +- clocks: should contain two entries: + * one for the input reference + * one for the the SoC RTC +- clock-names: should contain: + * "ref" for the input reference clock + * "ipg" for the SoC RTC clock + +Example: + +rtc@10007000 { + compatible = "fsl,imx21-rtc"; + reg = <0x10007000 0x1000>; + interrupts = <22>; + clocks = <&clks IMX27_CLK_CKIL>, + <&clks IMX27_CLK_RTC_IPG_GATE>; + clock-names = "ref", "ipg"; +}; -- cgit v0.10.2 From cec13c26e90e53015360c09574a7a2cde8d29495 Mon Sep 17 00:00:00 2001 From: Philippe Reynes Date: Sun, 26 Jul 2015 23:37:52 +0200 Subject: rtc: mxc: add support of device tree Add device tree support for the mxc rtc driver. Acked-by: Alexandre Belloni Signed-off-by: Philippe Reynes Signed-off-by: Shawn Guo diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index 880d485..7bd89d9 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c @@ -16,6 +16,8 @@ #include #include #include +#include +#include #define RTC_INPUT_CLK_32768HZ (0x00 << 5) #define RTC_INPUT_CLK_32000HZ (0x01 << 5) @@ -98,6 +100,15 @@ static const struct platform_device_id imx_rtc_devtype[] = { }; MODULE_DEVICE_TABLE(platform, imx_rtc_devtype); +#ifdef CONFIG_OF +static const struct of_device_id imx_rtc_dt_ids[] = { + { .compatible = "fsl,imx1-rtc", .data = (const void *)IMX1_RTC }, + { .compatible = "fsl,imx21-rtc", .data = (const void *)IMX21_RTC }, + {} +}; +MODULE_DEVICE_TABLE(of, imx_rtc_dt_ids); +#endif + static inline int is_imx1_rtc(struct rtc_plat_data *data) { return data->devtype == IMX1_RTC; @@ -362,12 +373,17 @@ static int mxc_rtc_probe(struct platform_device *pdev) u32 reg; unsigned long rate; int ret; + const struct of_device_id *of_id; pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return -ENOMEM; - pdata->devtype = pdev->id_entry->driver_data; + of_id = of_match_device(imx_rtc_dt_ids, &pdev->dev); + if (of_id) + pdata->devtype = (enum imx_rtc_type)of_id->data; + else + pdata->devtype = pdev->id_entry->driver_data; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); pdata->ioaddr = devm_ioremap_resource(&pdev->dev, res); @@ -488,6 +504,7 @@ static SIMPLE_DEV_PM_OPS(mxc_rtc_pm_ops, mxc_rtc_suspend, mxc_rtc_resume); static struct platform_driver mxc_rtc_driver = { .driver = { .name = "mxc_rtc", + .of_match_table = of_match_ptr(imx_rtc_dt_ids), .pm = &mxc_rtc_pm_ops, }, .id_table = imx_rtc_devtype, -- cgit v0.10.2 From 9f55eb92441883a1afca48dc8d32bf62c4d8e833 Mon Sep 17 00:00:00 2001 From: Fugang Duan Date: Tue, 28 Jul 2015 15:30:39 +0800 Subject: ARM: imx6ul: add fec bits to GPR syscon definition FEC requires additional bits to select refrence clock. Signed-off-by: Fugang Duan Signed-off-by: Shawn Guo diff --git a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h index d16f4c8..558a485 100644 --- a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h +++ b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h @@ -435,4 +435,12 @@ #define IMX6SX_GPR5_DISP_MUX_DCIC1_LVDS (0x1 << 1) #define IMX6SX_GPR5_DISP_MUX_DCIC1_MASK (0x1 << 1) +/* For imx6ul iomux gpr register field define */ +#define IMX6UL_GPR1_ENET1_CLK_DIR (0x1 << 17) +#define IMX6UL_GPR1_ENET2_CLK_DIR (0x1 << 18) +#define IMX6UL_GPR1_ENET1_CLK_OUTPUT (0x1 << 17) +#define IMX6UL_GPR1_ENET2_CLK_OUTPUT (0x1 << 18) +#define IMX6UL_GPR1_ENET_CLK_DIR (0x3 << 17) +#define IMX6UL_GPR1_ENET_CLK_OUTPUT (0x3 << 17) + #endif /* __LINUX_IMX6Q_IOMUXC_GPR_H */ -- cgit v0.10.2 From 709bc0657fe6f9f55fdaab246135ff73ba7796e4 Mon Sep 17 00:00:00 2001 From: Fugang Duan Date: Tue, 28 Jul 2015 15:30:40 +0800 Subject: ARM: imx6ul: add fec MAC refrence clock and phy fixup init Add FEC MAC refrence clock init. Add phy fixup init for i.MX6ul 14x14 evk board that installs KSZ8081 phy. For the phy, there needs extra phy fixup for MII and RMII mode. Signed-off-by: Fugang Duan Signed-off-by: Shawn Guo diff --git a/arch/arm/mach-imx/mach-imx6ul.c b/arch/arm/mach-imx/mach-imx6ul.c index f206506..db74da5 100644 --- a/arch/arm/mach-imx/mach-imx6ul.c +++ b/arch/arm/mach-imx/mach-imx6ul.c @@ -6,12 +6,54 @@ * published by the Free Software Foundation. */ #include +#include +#include +#include #include +#include +#include #include #include #include "common.h" +static void __init imx6ul_enet_clk_init(void) +{ + struct regmap *gpr; + + gpr = syscon_regmap_lookup_by_compatible("fsl,imx6ul-iomuxc-gpr"); + if (!IS_ERR(gpr)) + regmap_update_bits(gpr, IOMUXC_GPR1, IMX6UL_GPR1_ENET_CLK_DIR, + IMX6UL_GPR1_ENET_CLK_OUTPUT); + else + pr_err("failed to find fsl,imx6ul-iomux-gpr regmap\n"); + +} + +static int ksz8081_phy_fixup(struct phy_device *dev) +{ + if (dev && dev->interface == PHY_INTERFACE_MODE_MII) { + phy_write(dev, 0x1f, 0x8110); + phy_write(dev, 0x16, 0x201); + } else if (dev && dev->interface == PHY_INTERFACE_MODE_RMII) { + phy_write(dev, 0x1f, 0x8190); + phy_write(dev, 0x16, 0x202); + } + + return 0; +} + +static void __init imx6ul_enet_phy_init(void) +{ + phy_register_fixup_for_uid(PHY_ID_KSZ8081, 0xffffffff, ksz8081_phy_fixup); +} + +static inline void imx6ul_enet_init(void) +{ + imx6ul_enet_clk_init(); + imx6ul_enet_phy_init(); +} + static void __init imx6ul_init_machine(void) { struct device *parent; @@ -21,6 +63,7 @@ static void __init imx6ul_init_machine(void) pr_warn("failed to initialize soc device\n"); of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); + imx6ul_enet_init(); imx_anatop_init(); } -- cgit v0.10.2 From 41fe6a01726b79b8531fed0a94b55d89a69ea5ee Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Wed, 5 Aug 2015 00:14:55 +0200 Subject: ARM: rockchip: rename osc_switch_to_32k variable The variable name is misleading, as the deep suspend mode always switches the main supplying clock to the 32kHz source. Additionally the main oscillator remains running in some cases, which this var indicates. So rename it to osc_disable to clarity. Signed-off-by: Heiko Stuebner Reviewed-by: Chris Zhong Tested-by: Chris Zhong Reviewed-by: Douglas Anderson diff --git a/arch/arm/mach-rockchip/pm.c b/arch/arm/mach-rockchip/pm.c index 892bace..2ca1170 100644 --- a/arch/arm/mach-rockchip/pm.c +++ b/arch/arm/mach-rockchip/pm.c @@ -96,7 +96,7 @@ static bool rk3288_slp_disable_osc(void) static void rk3288_slp_mode_set(int level) { u32 mode_set, mode_set1; - bool osc_switch_to_32k = rk3288_slp_disable_osc(); + bool osc_disable = rk3288_slp_disable_osc(); regmap_read(sgrf_regmap, RK3288_SGRF_CPU_CON0, &rk3288_sgrf_cpu_con0); regmap_read(sgrf_regmap, RK3288_SGRF_SOC_CON0, &rk3288_sgrf_soc_con0); @@ -140,7 +140,7 @@ static void rk3288_slp_mode_set(int level) BIT(PMU_DDR1IO_RET_EN) | BIT(PMU_DDR0IO_RET_EN) | BIT(PMU_ALIVE_USE_LF) | BIT(PMU_PLL_PD_EN); - if (osc_switch_to_32k) + if (osc_disable) mode_set |= BIT(PMU_OSC_24M_DIS); mode_set1 |= BIT(PMU_CLR_ALIVE) | BIT(PMU_CLR_BUS) | -- cgit v0.10.2 From d1d3a1a1d745095261d4a927c0c06588e5bc7f6f Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Wed, 22 Jul 2015 17:04:47 +0200 Subject: ARM: rockchip: set correct stabilization thresholds in suspend Currently the stabilization thresholds for the oscillator and external pmu are statically set to 30ms based on a 32kHz clock rate. This leaves out the case when we don't switch to the 32kHz clock when only entering the shallow suspend mode where the logic keeps running. So, set the correct threshold after we have determined if we switch to the 32kHz clock or stay with the 24MHz one. Also set the oscillator- stabilization to 0 if it is kept running during suspend, as it of course does not need to stabilize then. Reported-by: Chris Zhong Signed-off-by: Heiko Stuebner Reviewed-by: Chris Zhong Tested-by: Chris Zhong Reviewed-by: Douglas Anderson diff --git a/arch/arm/mach-rockchip/pm.c b/arch/arm/mach-rockchip/pm.c index 2ca1170..c11a30b 100644 --- a/arch/arm/mach-rockchip/pm.c +++ b/arch/arm/mach-rockchip/pm.c @@ -145,6 +145,19 @@ static void rk3288_slp_mode_set(int level) mode_set1 |= BIT(PMU_CLR_ALIVE) | BIT(PMU_CLR_BUS) | BIT(PMU_CLR_PERI) | BIT(PMU_CLR_DMA); + + /* + * In deep suspend we use PMU_PMU_USE_LF to let the rk3288 + * switch its main clock supply to the alternative 32kHz + * source. Therefore set 30ms on a 32kHz clock for pmic + * stabilization. Similar 30ms on 24MHz for the other + * mode below. + */ + regmap_write(pmu_regmap, RK3288_PMU_STABL_CNT, 32 * 30); + + /* only wait for stabilization, if we turned the osc off */ + regmap_write(pmu_regmap, RK3288_PMU_OSC_CNT, + osc_disable ? 32 * 30 : 0); } else { /* * arm off, logic normal @@ -152,6 +165,12 @@ static void rk3288_slp_mode_set(int level) * wakeup will be error */ mode_set |= BIT(PMU_CLK_CORE_SRC_GATE_EN); + + /* 30ms on a 24MHz clock for pmic stabilization */ + regmap_write(pmu_regmap, RK3288_PMU_STABL_CNT, 24000 * 30); + + /* oscillator is still running, so no need to wait */ + regmap_write(pmu_regmap, RK3288_PMU_OSC_CNT, 0); } regmap_write(pmu_regmap, RK3288_PMU_PWRMODE_CON, mode_set); @@ -262,9 +281,6 @@ static int rk3288_suspend_init(struct device_node *np) memcpy(rk3288_bootram_base, rockchip_slp_cpu_resume, rk3288_bootram_sz); - regmap_write(pmu_regmap, RK3288_PMU_OSC_CNT, OSC_STABL_CNT_THRESH); - regmap_write(pmu_regmap, RK3288_PMU_STABL_CNT, PMU_STABL_CNT_THRESH); - return 0; } diff --git a/arch/arm/mach-rockchip/pm.h b/arch/arm/mach-rockchip/pm.h index b6494c2..8a55ee2 100644 --- a/arch/arm/mach-rockchip/pm.h +++ b/arch/arm/mach-rockchip/pm.h @@ -62,10 +62,6 @@ static inline void rockchip_suspend_init(void) /* PMU_WAKEUP_CFG1 bits */ #define PMU_ARMINT_WAKEUP_EN BIT(0) -/* wait 30ms for OSC stable and 30ms for pmic stable */ -#define OSC_STABL_CNT_THRESH (32 * 30) -#define PMU_STABL_CNT_THRESH (32 * 30) - enum rk3288_pwr_mode_con { PMU_PWR_MODE_EN = 0, PMU_CLK_CORE_SRC_GATE_EN, -- cgit v0.10.2 From 9bb91ae970dd004393a3d7d09bdcc30dfe2f8693 Mon Sep 17 00:00:00 2001 From: Heiko Stuebner Date: Wed, 22 Jul 2015 17:18:03 +0200 Subject: ARM: rockchip: enable PMU_GPIOINT_WAKEUP_EN when entering shallow suspend PMU_GPIOINT_WAKEUP_EN seems needed when entering the shallow suspend (with logic staying on) but does not seem to be needed for the deep suspend for unknown reasons. Testing revealed that this setting really is necessary to reliably resume the veyron devices from suspend. Reported-by: Chris Zhong Signed-off-by: Heiko Stuebner Reviewed-by: Chris Zhong Tested-by: Chris Zhong Reviewed-by: Douglas Anderson diff --git a/arch/arm/mach-rockchip/pm.c b/arch/arm/mach-rockchip/pm.c index c11a30b..156cd23 100644 --- a/arch/arm/mach-rockchip/pm.c +++ b/arch/arm/mach-rockchip/pm.c @@ -123,9 +123,6 @@ static void rk3288_slp_mode_set(int level) regmap_write(sgrf_regmap, RK3288_SGRF_FAST_BOOT_ADDR, rk3288_bootram_phy); - regmap_write(pmu_regmap, RK3288_PMU_WAKEUP_CFG1, - PMU_ARMINT_WAKEUP_EN); - mode_set = BIT(PMU_GLOBAL_INT_DISABLE) | BIT(PMU_L2FLUSH_EN) | BIT(PMU_SREF0_ENTER_EN) | BIT(PMU_SREF1_ENTER_EN) | BIT(PMU_DDR0_GATING_EN) | BIT(PMU_DDR1_GATING_EN) | @@ -146,6 +143,9 @@ static void rk3288_slp_mode_set(int level) mode_set1 |= BIT(PMU_CLR_ALIVE) | BIT(PMU_CLR_BUS) | BIT(PMU_CLR_PERI) | BIT(PMU_CLR_DMA); + regmap_write(pmu_regmap, RK3288_PMU_WAKEUP_CFG1, + PMU_ARMINT_WAKEUP_EN); + /* * In deep suspend we use PMU_PMU_USE_LF to let the rk3288 * switch its main clock supply to the alternative 32kHz @@ -166,6 +166,9 @@ static void rk3288_slp_mode_set(int level) */ mode_set |= BIT(PMU_CLK_CORE_SRC_GATE_EN); + regmap_write(pmu_regmap, RK3288_PMU_WAKEUP_CFG1, + PMU_ARMINT_WAKEUP_EN | PMU_GPIOINT_WAKEUP_EN); + /* 30ms on a 24MHz clock for pmic stabilization */ regmap_write(pmu_regmap, RK3288_PMU_STABL_CNT, 24000 * 30); diff --git a/arch/arm/mach-rockchip/pm.h b/arch/arm/mach-rockchip/pm.h index 8a55ee2..b5af26f 100644 --- a/arch/arm/mach-rockchip/pm.h +++ b/arch/arm/mach-rockchip/pm.h @@ -61,6 +61,7 @@ static inline void rockchip_suspend_init(void) /* PMU_WAKEUP_CFG1 bits */ #define PMU_ARMINT_WAKEUP_EN BIT(0) +#define PMU_GPIOINT_WAKEUP_EN BIT(3) enum rk3288_pwr_mode_con { PMU_PWR_MODE_EN = 0, -- cgit v0.10.2 From 9610c8abd2d278a957b1b586390b8c928980e79b Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 6 Aug 2015 22:09:40 -0700 Subject: ARM: OMAP2+: Fix power domain operations regression caused by 81xx I managed to mess up omap3 power domain operations with commit 7c80a3f89c51 ("ARM: OMAP2+: Add custom prwdm_operations for 81xx to support dm814x"), by default we should keep on using the omap3_pwrdm_operations, only 81xx needs custom handling. This causes omap3 PM to break so we won't hit off mode any longer causing idle power consumption go up from less than 10mW to over 50 mW. Fixs: 7c80a3f89c51 ("ARM: OMAP2+: Add custom prwdm_operations for 81xx to support dm814x") Signed-off-by: Tony Lindgren diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c index 7829d27..d31c495 100644 --- a/arch/arm/mach-omap2/powerdomains3xxx_data.c +++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c @@ -580,7 +580,9 @@ void __init omap3xxx_powerdomains_init(void) if (!cpu_is_omap34xx() && !cpu_is_ti81xx()) return; - pwrdm_register_platform_funcs(&ti81xx_pwrdm_operations); + /* Only 81xx needs custom pwrdm_operations */ + if (!cpu_is_ti81xx()) + pwrdm_register_platform_funcs(&omap3_pwrdm_operations);; rev = omap_rev(); @@ -588,9 +590,11 @@ void __init omap3xxx_powerdomains_init(void) pwrdm_register_pwrdms(powerdomains_am35x); } else if (rev == TI8148_REV_ES1_0 || rev == TI8148_REV_ES2_0 || rev == TI8148_REV_ES2_1) { + pwrdm_register_platform_funcs(&ti81xx_pwrdm_operations); pwrdm_register_pwrdms(powerdomains_ti814x); } else if (rev == TI8168_REV_ES1_0 || rev == TI8168_REV_ES1_1 || rev == TI8168_REV_ES2_0 || rev == TI8168_REV_ES2_1) { + pwrdm_register_platform_funcs(&ti81xx_pwrdm_operations); pwrdm_register_pwrdms(powerdomains_ti816x); } else { pwrdm_register_pwrdms(powerdomains_omap3430_common); -- cgit v0.10.2 From aeaeba1b6f0988ad4d9773ba2f1312e3f1436efa Mon Sep 17 00:00:00 2001 From: Gregory Fong Date: Tue, 4 Aug 2015 18:43:28 -0700 Subject: ARM: BCM: Enable ARM erratum 798181 for BRCMSTB Commit 04fcab32d3fa1d3f6afe97e0ab431c5572e07a2c ("ARM: 8111/1: Enable erratum 798181 for Broadcom Brahma-B15") enables this erratum for affected Broadcom Brahma-B15 CPUs when CONFIG_ARM_ERRATA_798181=y. Let's make sure that config option is actually set. Signed-off-by: Gregory Fong Signed-off-by: Florian Fainelli Signed-off-by: Olof Johansson diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index 0ac9e4b3..eed8746 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig @@ -140,6 +140,7 @@ config ARCH_BCM_63XX config ARCH_BRCMSTB bool "Broadcom BCM7XXX based boards" if ARCH_MULTI_V7 select ARM_GIC + select ARM_ERRATA_798181 if SMP select HAVE_ARM_ARCH_TIMER select BRCMSTB_GISB_ARB select BRCMSTB_L2_IRQ -- cgit v0.10.2 From b78bda5fd8d04029ca3da512b83e8e636791db53 Mon Sep 17 00:00:00 2001 From: Gregory Fong Date: Thu, 6 Aug 2015 19:22:38 -0700 Subject: ARM: brcmstb: select ARCH_DMA_ADDR_T_64BIT for LPAE Broadcom STB (BRCMSTB) has some 64-bit capable DMA and therefore needs dma_addr_t to be a 64-bit size. One user is the Broadcom SATA3 AHCI controller driver. Signed-off-by: Gregory Fong Signed-off-by: Florian Fainelli Signed-off-by: Olof Johansson diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index eed8746..1319c3c 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig @@ -145,6 +145,7 @@ config ARCH_BRCMSTB select BRCMSTB_GISB_ARB select BRCMSTB_L2_IRQ select BCM7120_L2_IRQ + select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE select ARCH_WANT_OPTIONAL_GPIOLIB help Say Y if you intend to run the kernel on a Broadcom ARM-based STB -- cgit v0.10.2 From 8a0fa1843638c5078e6606114ed8bdf9ea56fab1 Mon Sep 17 00:00:00 2001 From: Shawn Guo Date: Mon, 13 Jul 2015 15:58:51 +0800 Subject: rtc: snvs: select option REGMAP_MMIO Select REGMAP_MMIO to fix the following build error seen with x86_64 randconfig. drivers/built-in.o: In function `snvs_rtc_probe': rtc-snvs.c:(.text+0x567730): undefined reference to `devm_regmap_init_mmio_clk' Reported-by: kbuild test robot Signed-off-by: Shawn Guo Acked-by: Frank Li Acked-by: Alexandre Belloni diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 83b4b89..533bfa3 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1523,6 +1523,7 @@ config RTC_DRV_MXC config RTC_DRV_SNVS tristate "Freescale SNVS RTC support" + select REGMAP_MMIO depends on HAS_IOMEM depends on OF help -- cgit v0.10.2 From ed293d1ad2b0c28b6abc3bd728b07754bc00f1cd Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Sun, 12 Jul 2015 09:26:45 -0500 Subject: memory: kill off set_irq_flags usage set_irq_flags is ARM specific with custom flags which have genirq equivalents. Convert drivers to use the genirq interfaces directly, so we can kill off set_irq_flags. The translation of flags is as follows: IRQF_VALID -> !IRQ_NOREQUEST IRQF_PROBE -> !IRQ_NOPROBE IRQF_NOAUTOEN -> IRQ_NOAUTOEN For IRQs managed by an irqdomain, the irqdomain core code handles clearing and setting IRQ_NOREQUEST already, so there is no need to do this in .map() functions and we can simply remove the set_irq_flags calls. Some users also set IRQ_NOPROBE and this has been maintained although it is not clear that is really needed. There appears to be a great deal of blind copy and paste of this code. Signed-off-by: Rob Herring Acked-by: Roger Quadros Cc: linux-omap@vger.kernel.org Signed-off-by: Tony Lindgren diff --git a/drivers/memory/omap-gpmc.c b/drivers/memory/omap-gpmc.c index 3a27a84..9722099 100644 --- a/drivers/memory/omap-gpmc.c +++ b/drivers/memory/omap-gpmc.c @@ -1176,8 +1176,8 @@ static int gpmc_setup_irq(void) gpmc_client_irq[i].irq = gpmc_irq_start + i; irq_set_chip_and_handler(gpmc_client_irq[i].irq, &gpmc_irq_chip, handle_simple_irq); - set_irq_flags(gpmc_client_irq[i].irq, - IRQF_VALID | IRQF_NOAUTOEN); + irq_modify_status(gpmc_client_irq[i].irq, IRQ_NOREQUEST, + IRQ_NOAUTOEN); } /* Disable interrupts */ @@ -1200,7 +1200,6 @@ static int gpmc_free_irq(void) for (i = 0; i < GPMC_NR_IRQ; i++) { irq_set_handler(gpmc_client_irq[i].irq, NULL); irq_set_chip(gpmc_client_irq[i].irq, &no_irq_chip); - irq_modify_status(gpmc_client_irq[i].irq, 0, 0); } irq_free_descs(gpmc_irq_start, GPMC_NR_IRQ); -- cgit v0.10.2 From fb3c44267684b76329b20317f2a62dacc452a09d Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Sat, 8 Aug 2015 21:13:44 +0900 Subject: ARM: uniphier: drop v7_invalidate_l1 call at secondary entry This is unnecessary since commit 02b4e2756e01 ("ARM: v7 setup function should invalidate L1 cache"). Signed-off-by: Masahiro Yamada Signed-off-by: Olof Johansson diff --git a/arch/arm/mach-uniphier/platsmp.c b/arch/arm/mach-uniphier/platsmp.c index 5943e1c..4b784f7 100644 --- a/arch/arm/mach-uniphier/platsmp.c +++ b/arch/arm/mach-uniphier/platsmp.c @@ -60,12 +60,6 @@ err: sbcm_regmap = NULL; } -static void __naked uniphier_secondary_startup(void) -{ - asm("bl v7_invalidate_l1\n" - "b secondary_startup\n"); -}; - static int uniphier_boot_secondary(unsigned int cpu, struct task_struct *idle) { @@ -75,7 +69,7 @@ static int uniphier_boot_secondary(unsigned int cpu, return -ENODEV; ret = regmap_write(sbcm_regmap, 0x1208, - virt_to_phys(uniphier_secondary_startup)); + virt_to_phys(secondary_startup)); if (!ret) asm("sev"); /* wake up secondary CPU */ -- cgit v0.10.2 From f9511a4fc47940c7b08ae51567bd9bddb54b8461 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Mon, 27 Jul 2015 14:11:17 +1000 Subject: clk: ti: fix for definition movement Signed-off-by: Stephen Rothwell Signed-off-by: Olof Johansson diff --git a/drivers/clk/ti/clk-814x.c b/drivers/clk/ti/clk-814x.c index d490d42..e172920 100644 --- a/drivers/clk/ti/clk-814x.c +++ b/drivers/clk/ti/clk-814x.c @@ -8,6 +8,8 @@ #include #include +#include "clock.h" + static struct ti_dt_clk dm814_clks[] = { DT_CLK(NULL, "devosc_ck", "devosc_ck"), DT_CLK(NULL, "mpu_ck", "mpu_ck"), -- cgit v0.10.2 From 6be4b0da4ecf1472cb4a064c752214dcb2ba4be2 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Wed, 19 Aug 2015 15:31:30 -0300 Subject: ARM: imx: mach-imx6ul: Fix allmodconfig build We should call phy_register_fixup_for_uid() only when CONFIG_PHYLIB is built-in, otherwise we get the following link error when building allmodconfig: arch/arm/mach-imx/built-in.o: In function `imx6ul_init_machine': :(.init.text+0xa714): undefined reference to `phy_register_fixup_for_uid' This is the same approach done in mach-imx6q.c and mach-imx6sx.c. Reported-by: Olof Johansson Signed-off-by: Fabio Estevam Acked-by: Shawn Guo Signed-off-by: Olof Johansson diff --git a/arch/arm/mach-imx/mach-imx6ul.c b/arch/arm/mach-imx/mach-imx6ul.c index db74da5..1b97fe1 100644 --- a/arch/arm/mach-imx/mach-imx6ul.c +++ b/arch/arm/mach-imx/mach-imx6ul.c @@ -45,7 +45,9 @@ static int ksz8081_phy_fixup(struct phy_device *dev) static void __init imx6ul_enet_phy_init(void) { - phy_register_fixup_for_uid(PHY_ID_KSZ8081, 0xffffffff, ksz8081_phy_fixup); + if (IS_BUILTIN(CONFIG_PHYLIB)) + phy_register_fixup_for_uid(PHY_ID_KSZ8081, 0xffffffff, + ksz8081_phy_fixup); } static inline void imx6ul_enet_init(void) -- cgit v0.10.2 From 2a03c025fdea25a491c359b31d8a8c8d452b06d0 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Thu, 13 Aug 2015 23:43:19 -0300 Subject: ARM: rockchip: pm: Fix PTR_ERR() argument PTR_ERR should access the value just tested by IS_ERR. The semantic patch that makes this change is available in scripts/coccinelle/tests/odd_ptr_err.cocci. Signed-off-by: Fabio Estevam Reviewed-by: Matthias Brugger Signed-off-by: Heiko Stuebner diff --git a/arch/arm/mach-rockchip/pm.c b/arch/arm/mach-rockchip/pm.c index 156cd23..bee8c80 100644 --- a/arch/arm/mach-rockchip/pm.c +++ b/arch/arm/mach-rockchip/pm.c @@ -246,14 +246,14 @@ static int rk3288_suspend_init(struct device_node *np) "rockchip,rk3288-sgrf"); if (IS_ERR(sgrf_regmap)) { pr_err("%s: could not find sgrf regmap\n", __func__); - return PTR_ERR(pmu_regmap); + return PTR_ERR(sgrf_regmap); } grf_regmap = syscon_regmap_lookup_by_compatible( "rockchip,rk3288-grf"); if (IS_ERR(grf_regmap)) { pr_err("%s: could not find grf regmap\n", __func__); - return PTR_ERR(pmu_regmap); + return PTR_ERR(grf_regmap); } sram_np = of_find_compatible_node(NULL, NULL, -- cgit v0.10.2