diff options
90 files changed, 1766 insertions, 1146 deletions
diff --git a/Documentation/arm/Atmel/README b/Documentation/arm/Atmel/README index 6ca78f818dbf..afb13c15389d 100644 --- a/Documentation/arm/Atmel/README +++ b/Documentation/arm/Atmel/README @@ -16,7 +16,7 @@ git branches/tags and email subject always contain this "at91" sub-string. AT91 SoCs --------- -Documentation and detailled datasheet for each product are available on +Documentation and detailed datasheet for each product are available on the Atmel website: http://www.atmel.com. Flavors: @@ -101,6 +101,42 @@ the Atmel website: http://www.atmel.com. + Datasheet http://www.atmel.com/Images/Atmel-11267-32-bit-Cortex-A5-Microcontroller-SAMA5D2_Datasheet.pdf + * ARM Cortex-M7 MCUs + - sams70 family + - sams70j19 + - sams70j20 + - sams70j21 + - sams70n19 + - sams70n20 + - sams70n21 + - sams70q19 + - sams70q20 + - sams70q21 + + Datasheet + http://www.atmel.com/Images/Atmel-11242-32-bit-Cortex-M7-Microcontroller-SAM-S70Q-SAM-S70N-SAM-S70J_Datasheet.pdf + + - samv70 family + - samv70j19 + - samv70j20 + - samv70n19 + - samv70n20 + - samv70q19 + - samv70q20 + + Datasheet + http://www.atmel.com/Images/Atmel-11297-32-bit-Cortex-M7-Microcontroller-SAM-V70Q-SAM-V70N-SAM-V70J_Datasheet.pdf + + - samv71 family + - samv71j19 + - samv71j20 + - samv71j21 + - samv71n19 + - samv71n20 + - samv71n21 + - samv71q19 + - samv71q20 + - samv71q21 + + Datasheet + http://www.atmel.com/Images/Atmel-44003-32-bit-Cortex-M7-Microcontroller-SAM-V71Q-SAM-V71N-SAM-V71J_Datasheet.pdf Linux kernel information ------------------------ diff --git a/Documentation/devicetree/bindings/arm/atmel-at91.txt b/Documentation/devicetree/bindings/arm/atmel-at91.txt index 799af90dd75b..91cb8e4f2a4f 100644 --- a/Documentation/devicetree/bindings/arm/atmel-at91.txt +++ b/Documentation/devicetree/bindings/arm/atmel-at91.txt @@ -41,6 +41,36 @@ compatible: must be one of: - "atmel,sama5d43" - "atmel,sama5d44" + * "atmel,samv7" for MCUs using a Cortex-M7, shall be extended with the specific + SoC family: + o "atmel,sams70" shall be extended with the specific MCU compatible: + - "atmel,sams70j19" + - "atmel,sams70j20" + - "atmel,sams70j21" + - "atmel,sams70n19" + - "atmel,sams70n20" + - "atmel,sams70n21" + - "atmel,sams70q19" + - "atmel,sams70q20" + - "atmel,sams70q21" + o "atmel,samv70" shall be extended with the specific MCU compatible: + - "atmel,samv70j19" + - "atmel,samv70j20" + - "atmel,samv70n19" + - "atmel,samv70n20" + - "atmel,samv70q19" + - "atmel,samv70q20" + o "atmel,samv71" shall be extended with the specific MCU compatible: + - "atmel,samv71j19" + - "atmel,samv71j20" + - "atmel,samv71j21" + - "atmel,samv71n19" + - "atmel,samv71n20" + - "atmel,samv71n21" + - "atmel,samv71q19" + - "atmel,samv71q20" + - "atmel,samv71q21" + Chipid required properties: - compatible: Should be "atmel,sama5d2-chipid" - reg : Should contain registers location and length diff --git a/Documentation/devicetree/bindings/power/actions,owl-sps.txt b/Documentation/devicetree/bindings/power/actions,owl-sps.txt new file mode 100644 index 000000000000..007b9a7ae723 --- /dev/null +++ b/Documentation/devicetree/bindings/power/actions,owl-sps.txt @@ -0,0 +1,17 @@ +Actions Semi Owl Smart Power System (SPS) + +Required properties: +- compatible : "actions,s500-sps" for S500 +- reg : Offset and length of the register set for the device. +- #power-domain-cells : Must be 1. + See macros in: + include/dt-bindings/power/owl-s500-powergate.h for S500 + + +Example: + + sps: power-controller@b01b0100 { + compatible = "actions,s500-sps"; + reg = <0xb01b0100 0x100>; + #power-domain-cells = <1>; + }; diff --git a/MAINTAINERS b/MAINTAINERS index b5a5ef1f5000..08e5e8f800e3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1036,6 +1036,22 @@ S: Maintained F: drivers/amba/ F: include/linux/amba/bus.h +ARM/ACTIONS SEMI ARCHITECTURE +M: Andreas Färber <afaerber@suse.de> +L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) +S: Maintained +N: owl +F: arch/arm/mach-actions/ +F: arch/arm/boot/dts/owl-* +F: arch/arm64/boot/dts/actions/ +F: drivers/clocksource/owl-* +F: drivers/soc/actions/ +F: include/dt-bindings/power/owl-* +F: include/linux/soc/actions/ +F: Documentation/devicetree/bindings/arm/actions.txt +F: Documentation/devicetree/bindings/power/actions,owl-sps.txt +F: Documentation/devicetree/bindings/timer/actions,owl-timer.txt + ARM/ADS SPHERE MACHINE SUPPORT M: Lennert Buytenhek <kernel@wantstofly.org> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 43f45d3b40e8..abd59fad1a34 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -712,6 +712,8 @@ config ARCH_VIRT # source "arch/arm/mach-mvebu/Kconfig" +source "arch/arm/mach-actions/Kconfig" + source "arch/arm/mach-alpine/Kconfig" source "arch/arm/mach-artpec/Kconfig" @@ -1462,6 +1464,7 @@ config ARM_PSCI # selected platforms. config ARCH_NR_GPIO int + default 2048 if ARCH_SOCFPGA default 1024 if ARCH_BRCMSTB || ARCH_SHMOBILE || ARCH_TEGRA || \ ARCH_ZYNQ default 512 if ARCH_EXYNOS || ARCH_KEYSTONE || SOC_OMAP5 || \ diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 426d2716f55d..447629d89884 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -145,6 +145,15 @@ choice Say Y here if you want kernel low-level debugging support on the USART3 port of sama5d4. + config DEBUG_AT91_SAMV7_USART1 + bool "Kernel low-level debugging via SAMV7 USART1" + select DEBUG_AT91_UART + depends on SOC_SAMV7 + help + Say Y here if you want the debug print routines to direct + their output to the USART1 port on SAMV7 based + machines. + config DEBUG_BCM2835 bool "Kernel low-level debugging on BCM2835 PL011 UART" depends on ARCH_BCM2835 && ARCH_MULTI_V6 @@ -751,6 +760,7 @@ choice ARCH DEBUG_UART_PHYS DEBUG_UART_VIRT APQ8064 0x16640000 0xf0040000 APQ8084 0xf995e000 0xfa75e000 + IPQ4019 0x078af000 0xf78af000 MSM8X60 0x19c40000 0xf0040000 MSM8960 0x16440000 0xf0040000 MSM8974 0xf991e000 0xfa71e000 @@ -776,6 +786,30 @@ choice their output to the standard serial port on the RealView PB1176 platform. + config DEBUG_RV1108_UART0 + bool "Kernel low-level debugging messages via Rockchip RV1108 UART0" + depends on ARCH_ROCKCHIP + select DEBUG_UART_8250 + help + Say Y here if you want kernel low-level debugging support + on Rockchip RV1108 based platforms. + + config DEBUG_RV1108_UART1 + bool "Kernel low-level debugging messages via Rockchip RV1108 UART1" + depends on ARCH_ROCKCHIP + select DEBUG_UART_8250 + help + Say Y here if you want kernel low-level debugging support + on Rockchip RV1108 based platforms. + + config DEBUG_RV1108_UART2 + bool "Kernel low-level debugging messages via Rockchip RV1108 UART2" + depends on ARCH_ROCKCHIP + select DEBUG_UART_8250 + help + Say Y here if you want kernel low-level debugging support + on Rockchip RV1108 based platforms. + config DEBUG_RK29_UART0 bool "Kernel low-level debugging messages via Rockchip RK29 UART0" depends on ARCH_ROCKCHIP @@ -1465,6 +1499,9 @@ config DEBUG_UART_PHYS default 0x10126000 if DEBUG_RK3X_UART1 default 0x101f1000 if DEBUG_VERSATILE default 0x101fb000 if DEBUG_NOMADIK_UART + default 0x10210000 if DEBUG_RV1108_UART2 + default 0x10220000 if DEBUG_RV1108_UART1 + default 0x10230000 if DEBUG_RV1108_UART0 default 0x11002000 if DEBUG_MT8127_UART0 default 0x11006000 if DEBUG_MT6589_UART0 default 0x11009000 if DEBUG_MT8135_UART3 @@ -1481,6 +1518,7 @@ config DEBUG_UART_PHYS default 0x3f201000 if DEBUG_BCM2836 default 0x3e000000 if DEBUG_BCM_KONA_UART default 0x4000e400 if DEBUG_LL_UART_EFM32 + default 0x40028000 if DEBUG_AT91_SAMV7_USART1 default 0x40081000 if DEBUG_LPC18XX_UART0 default 0x40090000 if DEBUG_LPC32XX default 0x40100000 if DEBUG_PXA_UART1 @@ -1563,6 +1601,9 @@ config DEBUG_UART_PHYS config DEBUG_UART_VIRT hex "Virtual base address of debug UART" + default 0xc881f000 if DEBUG_RV1108_UART2 + default 0xc8821000 if DEBUG_RV1108_UART1 + default 0xc8912000 if DEBUG_RV1108_UART0 default 0xe0000a00 if DEBUG_NETX_UART default 0xe0010fe0 if ARCH_RPC default 0xf0000be0 if ARCH_EBSA110 diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 65f4e2a4eb94..47d3a1ab08d2 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -151,6 +151,7 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000 # Machine directory name. This list is sorted alphanumerically # by CONFIG_* macro name. +machine-$(CONFIG_ARCH_ACTIONS) += actions machine-$(CONFIG_ARCH_ALPINE) += alpine machine-$(CONFIG_ARCH_ARTPEC) += artpec machine-$(CONFIG_ARCH_AT91) += at91 diff --git a/arch/arm/mach-actions/Kconfig b/arch/arm/mach-actions/Kconfig new file mode 100644 index 000000000000..ad9c5c89c683 --- /dev/null +++ b/arch/arm/mach-actions/Kconfig @@ -0,0 +1,16 @@ +menuconfig ARCH_ACTIONS + bool "Actions Semi SoCs" + depends on ARCH_MULTI_V7 + select ARM_AMBA + select ARM_GIC + select ARM_GLOBAL_TIMER + select CACHE_L2X0 + select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK + select COMMON_CLK + select GENERIC_IRQ_CHIP + select HAVE_ARM_SCU if SMP + select HAVE_ARM_TWD if SMP + select OWL_PM_DOMAINS_HELPER + select OWL_TIMER + help + This enables support for the Actions Semiconductor S500 SoC family. diff --git a/arch/arm/mach-actions/Makefile b/arch/arm/mach-actions/Makefile new file mode 100644 index 000000000000..c0f116241da7 --- /dev/null +++ b/arch/arm/mach-actions/Makefile @@ -0,0 +1,3 @@ +obj-${CONFIG_SMP} += platsmp.o headsmp.o + +AFLAGS_headsmp.o := -Wa,-march=armv7-a diff --git a/arch/arm/mach-actions/headsmp.S b/arch/arm/mach-actions/headsmp.S new file mode 100644 index 000000000000..65f53bdb69e7 --- /dev/null +++ b/arch/arm/mach-actions/headsmp.S @@ -0,0 +1,52 @@ +/* + * Copyright 2012 Actions Semi Inc. + * Author: Actions Semi, Inc. + * + * Copyright (c) 2017 Andreas Färber + * + * 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; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/linkage.h> +#include <linux/init.h> + +ENTRY(owl_v7_invalidate_l1) + mov r0, #0 + mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache + mcr p15, 2, r0, c0, c0, 0 + mrc p15, 1, r0, c0, c0, 0 + + ldr r1, =0x7fff + and r2, r1, r0, lsr #13 + + ldr r1, =0x3ff + + and r3, r1, r0, lsr #3 @ NumWays - 1 + add r2, r2, #1 @ NumSets + + and r0, r0, #0x7 + add r0, r0, #4 @ SetShift + + clz r1, r3 @ WayShift + add r4, r3, #1 @ NumWays +1: sub r2, r2, #1 @ NumSets-- + mov r3, r4 @ Temp = NumWays +2: subs r3, r3, #1 @ Temp-- + mov r5, r3, lsl r1 + mov r6, r2, lsl r0 + orr r5, r5, r6 @ Reg = (Temp<<WayShift)|(NumSets<<SetShift) + mcr p15, 0, r5, c7, c6, 2 + bgt 2b + cmp r2, #0 + bgt 1b + dsb + isb + mov pc, lr +ENDPROC(owl_v7_invalidate_l1) + +ENTRY(owl_secondary_startup) + bl owl_v7_invalidate_l1 + b secondary_startup diff --git a/arch/arm/mach-actions/platsmp.c b/arch/arm/mach-actions/platsmp.c new file mode 100644 index 000000000000..12a9e331b432 --- /dev/null +++ b/arch/arm/mach-actions/platsmp.c @@ -0,0 +1,171 @@ +/* + * Actions Semi Leopard + * + * This file is based on arm realview smp platform. + * + * Copyright 2012 Actions Semi Inc. + * Author: Actions Semi, Inc. + * + * Copyright (c) 2017 Andreas Färber + * + * 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; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/delay.h> +#include <linux/io.h> +#include <linux/of.h> +#include <linux/of_address.h> +#include <linux/smp.h> +#include <linux/soc/actions/owl-sps.h> +#include <asm/cacheflush.h> +#include <asm/smp_plat.h> +#include <asm/smp_scu.h> + +#define OWL_CPU1_ADDR 0x50 +#define OWL_CPU1_FLAG 0x5c + +#define OWL_CPUx_FLAG_BOOT 0x55aa + +#define OWL_SPS_PG_CTL_PWR_CPU2 BIT(5) +#define OWL_SPS_PG_CTL_PWR_CPU3 BIT(6) +#define OWL_SPS_PG_CTL_ACK_CPU2 BIT(21) +#define OWL_SPS_PG_CTL_ACK_CPU3 BIT(22) + +static void __iomem *scu_base_addr; +static void __iomem *sps_base_addr; +static void __iomem *timer_base_addr; +static int ncores; + +static DEFINE_SPINLOCK(boot_lock); + +void owl_secondary_startup(void); + +static int s500_wakeup_secondary(unsigned int cpu) +{ + int ret; + + if (cpu > 3) + return -EINVAL; + + /* The generic PM domain driver is not available this early. */ + switch (cpu) { + case 2: + ret = owl_sps_set_pg(sps_base_addr, + OWL_SPS_PG_CTL_PWR_CPU2, + OWL_SPS_PG_CTL_ACK_CPU2, true); + if (ret) + return ret; + break; + case 3: + ret = owl_sps_set_pg(sps_base_addr, + OWL_SPS_PG_CTL_PWR_CPU3, + OWL_SPS_PG_CTL_ACK_CPU3, true); + if (ret) + return ret; + break; + } + + /* wait for CPUx to run to WFE instruction */ + udelay(200); + + writel(virt_to_phys(owl_secondary_startup), + timer_base_addr + OWL_CPU1_ADDR + (cpu - 1) * 4); + writel(OWL_CPUx_FLAG_BOOT, + timer_base_addr + OWL_CPU1_FLAG + (cpu - 1) * 4); + + dsb_sev(); + mb(); + + return 0; +} + +static int s500_smp_boot_secondary(unsigned int cpu, struct task_struct *idle) +{ + unsigned long timeout; + int ret; + + ret = s500_wakeup_secondary(cpu); + if (ret) + return ret; + + udelay(10); + + spin_lock(&boot_lock); + + smp_send_reschedule(cpu); + + timeout = jiffies + (1 * HZ); + while (time_before(jiffies, timeout)) { + if (pen_release == -1) + break; + } + + writel(0, timer_base_addr + OWL_CPU1_ADDR + (cpu - 1) * 4); + writel(0, timer_base_addr + OWL_CPU1_FLAG + (cpu - 1) * 4); + + spin_unlock(&boot_lock); + + return 0; +} + +static void __init s500_smp_prepare_cpus(unsigned int max_cpus) +{ + struct device_node *node; + + node = of_find_compatible_node(NULL, NULL, "actions,s500-timer"); + if (!node) { + pr_err("%s: missing timer\n", __func__); + return; + } + + timer_base_addr = of_iomap(node, 0); + if (!timer_base_addr) { + pr_err("%s: could not map timer registers\n", __func__); + return; + } + + node = of_find_compatible_node(NULL, NULL, "actions,s500-sps"); + if (!node) { + pr_err("%s: missing sps\n", __func__); + return; + } + + sps_base_addr = of_iomap(node, 0); + if (!sps_base_addr) { + pr_err("%s: could not map sps registers\n", __func__); + return; + } + + if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) { + node = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu"); + if (!node) { + pr_err("%s: missing scu\n", __func__); + return; + } + + scu_base_addr = of_iomap(node, 0); + if (!scu_base_addr) { + pr_err("%s: could not map scu registers\n", __func__); + return; + } + + /* + * While the number of cpus is gathered from dt, also get the + * number of cores from the scu to verify this value when + * booting the cores. + */ + ncores = scu_get_core_count(scu_base_addr); + pr_debug("%s: ncores %d\n", __func__, ncores); + + scu_enable(scu_base_addr); + } +} + +static const struct smp_operations s500_smp_ops __initconst = { + .smp_prepare_cpus = s500_smp_prepare_cpus, + .smp_boot_secondary = s500_smp_boot_secondary, +}; +CPU_METHOD_OF_DECLARE(s500_smp, "actions,s500-smp", &s500_smp_ops); diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index cbd959b73654..d735e5fc4772 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -1,6 +1,6 @@ menuconfig ARCH_AT91 bool "Atmel SoCs" - depends on ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V7 + depends on ARCH_MULTI_V4T || ARCH_MULTI_V5 || ARCH_MULTI_V7 || ARM_SINGLE_ARMV7M select ARM_CPU_SUSPEND if PM select COMMON_CLK_AT91 select GPIOLIB @@ -8,6 +8,14 @@ menuconfig ARCH_AT91 select SOC_BUS if ARCH_AT91 +config SOC_SAMV7 + bool "SAM Cortex-M7 family" if ARM_SINGLE_ARMV7M + select COMMON_CLK_AT91 + select PINCTRL_AT91 + help + Select this if you are using an SoC from Atmel's SAME7, SAMS7 or SAMV7 + families. + config SOC_SAMA5D2 bool "SAMA5D2 family" depends on ARCH_MULTI_V7 @@ -53,6 +61,7 @@ config SOC_AT91RM9200 bool "AT91RM9200" depends on ARCH_MULTI_V4T select ATMEL_AIC_IRQ + select ATMEL_PM if PM select ATMEL_ST select CPU_ARM920T select HAVE_AT91_USB_CLK @@ -66,6 +75,7 @@ config SOC_AT91SAM9 bool "AT91SAM9" depends on ARCH_MULTI_V5 select ATMEL_AIC_IRQ + select ATMEL_PM if PM select ATMEL_SDRAMC select CPU_ARM926T select HAVE_AT91_SMD @@ -124,9 +134,13 @@ config SOC_SAM_V7 config SOC_SAMA5 bool select ATMEL_AIC5_IRQ + select ATMEL_PM if PM select ATMEL_SDRAMC select MEMORY select SOC_SAM_V7 select SRAM if PM +config ATMEL_PM + bool + endif diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index cfd8f60a9268..ee34aa34cc51 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -6,10 +6,10 @@ obj-$(CONFIG_SOC_AT91RM9200) += at91rm9200.o obj-$(CONFIG_SOC_AT91SAM9) += at91sam9.o obj-$(CONFIG_SOC_SAMA5) += sama5.o +obj-$(CONFIG_SOC_SAMV7) += samv7.o # Power Management -obj-$(CONFIG_PM) += pm.o -obj-$(CONFIG_PM) += pm_suspend.o +obj-$(CONFIG_ATMEL_PM) += pm.o pm_suspend.o ifeq ($(CONFIG_CPU_V7),y) AFLAGS_pm_suspend.o := -march=armv7-a diff --git a/arch/arm/mach-at91/Makefile.boot b/arch/arm/mach-at91/Makefile.boot new file mode 100644 index 000000000000..eacfc3f5c33e --- /dev/null +++ b/arch/arm/mach-at91/Makefile.boot @@ -0,0 +1,3 @@ +# Empty file waiting for deletion once Makefile.boot isn't needed any more. +# Patch waits for application at +# http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7889/1 . diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h index f1ead0f13c19..e2bd17237964 100644 --- a/arch/arm/mach-at91/generic.h +++ b/arch/arm/mach-at91/generic.h @@ -15,10 +15,12 @@ extern void __init at91rm9200_pm_init(void); extern void __init at91sam9_pm_init(void); extern void __init sama5_pm_init(void); +extern void __init sama5d2_pm_init(void); #else static inline void __init at91rm9200_pm_init(void) { } static inline void __init at91sam9_pm_init(void) { } static inline void __init sama5_pm_init(void) { } +static inline void __init sama5d2_pm_init(void) { } #endif #endif /* _AT91_GENERIC_H */ diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 283e79ab587d..667fddac3856 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -15,6 +15,7 @@ #include <linux/of_address.h> #include <linux/of.h> #include <linux/of_platform.h> +#include <linux/parser.h> #include <linux/suspend.h> #include <linux/clk/at91_pmc.h> @@ -22,6 +23,7 @@ #include <asm/cacheflush.h> #include <asm/fncpy.h> #include <asm/system_misc.h> +#include <asm/suspend.h> #include "generic.h" #include "pm.h" @@ -37,7 +39,17 @@ extern void at91_pinctrl_gpio_suspend(void); extern void at91_pinctrl_gpio_resume(void); #endif -static struct at91_pm_data pm_data; +static const match_table_t pm_modes __initconst = { + { 0, "standby" }, + { AT91_PM_SLOW_CLOCK, "ulp0" }, + { AT91_PM_BACKUP, "backup" }, + { -1, NULL }, +}; + +static struct at91_pm_data pm_data = { + .standby_mode = 0, + .suspend_mode = AT91_PM_SLOW_CLOCK, +}; #define at91_ramc_read(id, field) \ __raw_readl(pm_data.ramc[id] + field) @@ -58,15 +70,33 @@ static int at91_pm_valid_state(suspend_state_t state) } } +static int canary = 0xA5A5A5A5; -static suspend_state_t target_state; +static struct at91_pm_bu { + int suspended; + unsigned long reserved; + phys_addr_t canary; + phys_addr_t resume; +} *pm_bu; /* * Called after processes are frozen, but before we shutdown devices. */ static int at91_pm_begin(suspend_state_t state) { - target_state = state; + switch (state) { + case PM_SUSPEND_MEM: + pm_data.mode = pm_data.suspend_mode; + break; + + case PM_SUSPEND_STANDBY: + pm_data.mode = pm_data.standby_mode; + break; + + default: + pm_data.mode = -1; + } + return 0; } @@ -115,7 +145,7 @@ static int at91_pm_verify_clocks(void) */ int at91_suspend_entering_slow_clock(void) { - return (target_state == PM_SUSPEND_MEM); + return (pm_data.mode >= AT91_PM_SLOW_CLOCK); } EXPORT_SYMBOL(at91_suspend_entering_slow_clock); @@ -123,50 +153,65 @@ static void (*at91_suspend_sram_fn)(struct at91_pm_data *); extern void at91_pm_suspend_in_sram(struct at91_pm_data *pm_data); extern u32 at91_pm_suspend_in_sram_sz; -static void at91_pm_suspend(suspend_state_t state) +static int at91_suspend_finish(unsigned long val) { - pm_data.mode = (state == PM_SUSPEND_MEM) ? AT91_PM_SLOW_CLOCK : 0; - flush_cache_all(); outer_disable(); at91_suspend_sram_fn(&pm_data); + return 0; +} + +static void at91_pm_suspend(suspend_state_t state) +{ + if (pm_data.mode == AT91_PM_BACKUP) { + pm_bu->suspended = 1; + + cpu_suspend(0, at91_suspend_finish); + + /* The SRAM is lost between suspend cycles */ + at91_suspend_sram_fn = fncpy(at91_suspend_sram_fn, + &at91_pm_suspend_in_sram, + at91_pm_suspend_in_sram_sz); + } else { + at91_suspend_finish(0); + } + outer_resume(); } +/* + * STANDBY mode has *all* drivers suspended; ignores irqs not marked as 'wakeup' + * event sources; and reduces DRAM power. But otherwise it's identical to + * PM_SUSPEND_ON: cpu idle, and nothing fancy done with main or cpu clocks. + * + * AT91_PM_SLOW_CLOCK is like STANDBY plus slow clock mode, so drivers must + * suspend more deeply, the master clock switches to the clk32k and turns off + * the main oscillator + * + * AT91_PM_BACKUP turns off the whole SoC after placing the DDR in self refresh + */ static int at91_pm_enter(suspend_state_t state) { #ifdef CONFIG_PINCTRL_AT91 at91_pinctrl_gpio_suspend(); #endif + switch (state) { - /* - * Suspend-to-RAM is like STANDBY plus slow clock mode, so - * drivers must suspend more deeply, the master clock switches - * to the clk32k and turns off the main oscillator - */ case PM_SUSPEND_MEM: + case PM_SUSPEND_STANDBY: /* * Ensure that clocks are in a valid state. */ - if (!at91_pm_verify_clocks()) + if ((pm_data.mode >= AT91_PM_SLOW_CLOCK) && + !at91_pm_verify_clocks()) goto error; at91_pm_suspend(state); break; - /* - * STANDBY mode has *all* drivers suspended; ignores irqs not - * marked as 'wakeup' event sources; and reduces DRAM power. - * But otherwise it's identical to PM_SUSPEND_ON: cpu idle, and - * nothing fancy done with main or cpu clocks. - */ - case PM_SUSPEND_STANDBY: - at91_pm_suspend(state); - break; - case PM_SUSPEND_ON: cpu_do_idle(); break; @@ -177,8 +222,6 @@ static int at91_pm_enter(suspend_state_t state) } error: - target_state = PM_SUSPEND_ON; - #ifdef CONFIG_PINCTRL_AT91 at91_pinctrl_gpio_resume(); #endif @@ -190,7 +233,6 @@ error: */ static void at91_pm_end(void) { - target_state = PM_SUSPEND_ON; } @@ -436,6 +478,79 @@ static void __init at91_pm_sram_init(void) &at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz); } +static void __init at91_pm_backup_init(void) +{ + struct gen_pool *sram_pool; + struct device_node *np; + struct platform_device *pdev = NULL; + + if ((pm_data.standby_mode != AT91_PM_BACKUP) && + (pm_data.suspend_mode != AT91_PM_BACKUP)) + return; + + pm_bu = NULL; + + np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-shdwc"); + if (!np) { + pr_warn("%s: failed to find shdwc!\n", __func__); + return; + } + + pm_data.shdwc = of_iomap(np, 0); + of_node_put(np); + + np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-sfrbu"); + if (!np) { + pr_warn("%s: failed to find sfrbu!\n", __func__); + goto sfrbu_fail; + } + + pm_data.sfrbu = of_iomap(np, 0); + of_node_put(np); + pm_bu = NULL; + + np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-securam"); + if (!np) + goto securam_fail; + + pdev = of_find_device_by_node(np); + of_node_put(np); + if (!pdev) { + pr_warn("%s: failed to find securam device!\n", __func__); + goto securam_fail; + } + + sram_pool = gen_pool_get(&pdev->dev, NULL); + if (!sram_pool) { + pr_warn("%s: securam pool unavailable!\n", __func__); + goto securam_fail; + } + + pm_bu = (void *)gen_pool_alloc(sram_pool, sizeof(struct at91_pm_bu)); + if (!pm_bu) { + pr_warn("%s: unable to alloc securam!\n", __func__); + goto securam_fail; + } + + pm_bu->suspended = 0; + pm_bu->canary = virt_to_phys(&canary); + pm_bu->resume = virt_to_phys(cpu_resume); + + return; + +sfrbu_fail: + iounmap(pm_data.shdwc); + pm_data.shdwc = NULL; +securam_fail: + iounmap(pm_data.sfrbu); + pm_data.sfrbu = NULL; + + if (pm_data.standby_mode == AT91_PM_BACKUP) + pm_data.standby_mode = AT91_PM_SLOW_CLOCK; + if (pm_data.suspend_mode == AT91_PM_BACKUP) + pm_data.suspend_mode = AT91_PM_SLOW_CLOCK; +} + struct pmc_info { unsigned long uhp_udp_mask; }; @@ -481,10 +596,14 @@ static void __init at91_pm_init(void (*pm_idle)(void)) at91_pm_sram_init(); - if (at91_suspend_sram_fn) + if (at91_suspend_sram_fn) { suspend_set_ops(&at91_pm_ops); - else + pr_info("AT91: PM: standby: %s, suspend: %s\n", + pm_modes[pm_data.standby_mode].pattern, + pm_modes[pm_data.suspend_mode].pattern); + } else { pr_info("AT91: PM not supported, due to no SRAM allocated\n"); + } } void __init at91rm9200_pm_init(void) @@ -510,3 +629,34 @@ void __init sama5_pm_init(void) at91_dt_ramc(); at91_pm_init(NULL); } + +void __init sama5d2_pm_init(void) +{ + at91_pm_backup_init(); + sama5_pm_init(); +} + +static int __init at91_pm_modes_select(char *str) +{ + char *s; + substring_t args[MAX_OPT_ARGS]; + int standby, suspend; + + if (!str) + return 0; + + s = strsep(&str, ","); + standby = match_token(s, pm_modes, args); + if (standby < 0) + return 0; + + suspend = match_token(str, pm_modes, args); + if (suspend < 0) + return 0; + + pm_data.standby_mode = standby; + pm_data.suspend_mode = suspend; + + return 0; +} +early_param("atmel.pm_modes", at91_pm_modes_select); diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h index fc0f7d048187..f95d31496f08 100644 --- a/arch/arm/mach-at91/pm.h +++ b/arch/arm/mach-at91/pm.h @@ -22,6 +22,7 @@ #define AT91_MEMCTRL_DDRSDR 2 #define AT91_PM_SLOW_CLOCK 0x01 +#define AT91_PM_BACKUP 0x02 #ifndef __ASSEMBLY__ struct at91_pm_data { @@ -30,6 +31,10 @@ struct at91_pm_data { unsigned long uhp_udp_mask; unsigned int memctrl; unsigned int mode; + void __iomem *shdwc; + void __iomem *sfrbu; + unsigned int standby_mode; + unsigned int suspend_mode; }; #endif diff --git a/arch/arm/mach-at91/pm_data-offsets.c b/arch/arm/mach-at91/pm_data-offsets.c index 30302cb16df0..c0a73e62b725 100644 --- a/arch/arm/mach-at91/pm_data-offsets.c +++ b/arch/arm/mach-at91/pm_data-offsets.c @@ -9,5 +9,8 @@ int main(void) DEFINE(PM_DATA_RAMC1, offsetof(struct at91_pm_data, ramc[1])); DEFINE(PM_DATA_MEMCTRL, offsetof(struct at91_pm_data, memctrl)); DEFINE(PM_DATA_MODE, offsetof(struct at91_pm_data, mode)); + DEFINE(PM_DATA_SHDWC, offsetof(struct at91_pm_data, shdwc)); + DEFINE(PM_DATA_SFRBU, offsetof(struct at91_pm_data, sfrbu)); + return 0; } diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S index 96781daa671a..daca91feea6a 100644 --- a/arch/arm/mach-at91/pm_suspend.S +++ b/arch/arm/mach-at91/pm_suspend.S @@ -97,15 +97,61 @@ ENTRY(at91_pm_suspend_in_sram) str tmp1, .memtype ldr tmp1, [r0, #PM_DATA_MODE] str tmp1, .pm_mode + /* Both ldrne below are here to preload their address in the TLB */ + ldr tmp1, [r0, #PM_DATA_SHDWC] + str tmp1, .shdwc + cmp tmp1, #0 + ldrne tmp2, [tmp1, #0] + ldr tmp1, [r0, #PM_DATA_SFRBU] + str tmp1, .sfr + cmp tmp1, #0 + ldrne tmp2, [tmp1, #0x10] /* Active the self-refresh mode */ mov r0, #SRAMC_SELF_FRESH_ACTIVE bl at91_sramc_self_refresh ldr r0, .pm_mode - tst r0, #AT91_PM_SLOW_CLOCK - beq skip_disable_main_clock + cmp r0, #AT91_PM_SLOW_CLOCK + beq slow_clock + cmp r0, #AT91_PM_BACKUP + beq backup_mode + /* Wait for interrupt */ + ldr pmc, .pmc_base + at91_cpu_idle + b exit_suspend + +slow_clock: + bl at91_slowck_mode + b exit_suspend +backup_mode: + bl at91_backup_mode + b exit_suspend + +exit_suspend: + /* Exit the self-refresh mode */ + mov r0, #SRAMC_SELF_FRESH_EXIT + bl at91_sramc_self_refresh + + /* Restore registers, and return */ + ldmfd sp!, {r4 - r12, pc} +ENDPROC(at91_pm_suspend_in_sram) + +ENTRY(at91_backup_mode) + /*BUMEN*/ + ldr r0, .sfr + mov tmp1, #0x1 + str tmp1, [r0, #0x10] + + /* Shutdown */ + ldr r0, .shdwc + mov tmp1, #0xA5000000 + add tmp1, tmp1, #0x1 + str tmp1, [r0, #0] +ENDPROC(at91_backup_mode) + +ENTRY(at91_slowck_mode) ldr pmc, .pmc_base /* Save Master clock setting */ @@ -134,18 +180,9 @@ ENTRY(at91_pm_suspend_in_sram) orr tmp1, tmp1, #AT91_PMC_KEY str tmp1, [pmc, #AT91_CKGR_MOR] -skip_disable_main_clock: - ldr pmc, .pmc_base - /* Wait for interrupt */ at91_cpu_idle - ldr r0, .pm_mode - tst r0, #AT91_PM_SLOW_CLOCK - beq skip_enable_main_clock - - ldr pmc, .pmc_base - /* Turn on the main oscillator */ ldr tmp1, [pmc, #AT91_CKGR_MOR] orr tmp1, tmp1, #AT91_PMC_MOSCEN @@ -174,14 +211,8 @@ skip_disable_main_clock: wait_mckrdy -skip_enable_main_clock: - /* Exit the self-refresh mode */ - mov r0, #SRAMC_SELF_FRESH_EXIT - bl at91_sramc_self_refresh - - /* Restore registers, and return */ - ldmfd sp!, {r4 - r12, pc} -ENDPROC(at91_pm_suspend_in_sram) + mov pc, lr +ENDPROC(at91_slowck_mode) /* * void at91_sramc_self_refresh(unsigned int is_active) @@ -314,6 +345,10 @@ ENDPROC(at91_sramc_self_refresh) .word 0 .sramc1_base: .word 0 +.shdwc: + .word 0 +.sfr: + .word 0 .memtype: .word 0 .pm_mode: diff --git a/arch/arm/mach-at91/sama5.c b/arch/arm/mach-at91/sama5.c index 6d157d0ead8e..3d0bf95a56ae 100644 --- a/arch/arm/mach-at91/sama5.c +++ b/arch/arm/mach-at91/sama5.c @@ -34,7 +34,6 @@ DT_MACHINE_START(sama5_dt, "Atmel SAMA5") MACHINE_END static const char *const sama5_alt_dt_board_compat[] __initconst = { - "atmel,sama5d2", "atmel,sama5d4", NULL }; @@ -45,3 +44,21 @@ DT_MACHINE_START(sama5_alt_dt, "Atmel SAMA5") .dt_compat = sama5_alt_dt_board_compat, .l2c_aux_mask = ~0UL, MACHINE_END + +static void __init sama5d2_init(void) +{ + of_platform_default_populate(NULL, NULL, NULL); + sama5d2_pm_init(); +} + +static const char *const sama5d2_compat[] __initconst = { + "atmel,sama5d2", + NULL +}; + +DT_MACHINE_START(sama5d2, "Atmel SAMA5") + /* Maintainer: Atmel */ + .init_machine = sama5d2_init, + .dt_compat = sama5d2_compat, + .l2c_aux_mask = ~0UL, +MACHINE_END diff --git a/arch/arm/mach-at91/samv7.c b/arch/arm/mach-at91/samv7.c new file mode 100644 index 000000000000..11386f190c83 --- /dev/null +++ b/arch/arm/mach-at91/samv7.c @@ -0,0 +1,25 @@ +/* + * Setup code for SAMv7x + * + * Copyright (C) 2013 Atmel, + * 2016 Andras Szemzo <szemzo.andras@gmail.com> + * + * Licensed under GPLv2 or later. + */ +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/of_address.h> +#include <linux/slab.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/system_misc.h> +#include "generic.h" + +static const char *const samv7_dt_board_compat[] __initconst = { + "atmel,samv7", + NULL +}; + +DT_MACHINE_START(samv7_dt, "Atmel SAMV7") + .dt_compat = samv7_dt_board_compat, +MACHINE_END diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index f23a23934162..73be3d578851 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig @@ -44,6 +44,8 @@ config ARCH_BCM_NSP select ARM_ERRATA_775420 select ARM_ERRATA_764369 if SMP select HAVE_SMP + select THERMAL + select THERMAL_OF help Support for Broadcom Northstar Plus SoC. Broadcom Northstar Plus family of SoCs are used for switching control diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c index cb176826d1cb..055e947a6a39 100644 --- a/arch/arm/mach-davinci/board-dm646x-evm.c +++ b/arch/arm/mach-davinci/board-dm646x-evm.c @@ -641,7 +641,7 @@ static struct vpif_subdev_info vpif_capture_sdev_info[] = { }, }; -static const struct vpif_input dm6467_ch0_inputs[] = { +static struct vpif_input dm6467_ch0_inputs[] = { { .input = { .index = 0, @@ -656,7 +656,7 @@ static const struct vpif_input dm6467_ch0_inputs[] = { }, }; -static const struct vpif_input dm6467_ch1_inputs[] = { +static struct vpif_input dm6467_ch1_inputs[] = { { .input = { .index = 0, diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c index 7cf529ffbe5a..22440c05d66a 100644 --- a/arch/arm/mach-davinci/devices-da8xx.c +++ b/arch/arm/mach-davinci/devices-da8xx.c @@ -789,15 +789,35 @@ int __init da850_register_mmcsd1(struct davinci_mmc_config *config) static struct resource da8xx_rproc_resources[] = { { /* DSP boot address */ + .name = "host1cfg", .start = DA8XX_SYSCFG0_BASE + DA8XX_HOST1CFG_REG, .end = DA8XX_SYSCFG0_BASE + DA8XX_HOST1CFG_REG + 3, .flags = IORESOURCE_MEM, }, { /* DSP interrupt registers */ + .name = "chipsig", .start = DA8XX_SYSCFG0_BASE + DA8XX_CHIPSIG_REG, .end = DA8XX_SYSCFG0_BASE + DA8XX_CHIPSIG_REG + 7, .flags = IORESOURCE_MEM, }, + { /* DSP L2 RAM */ + .name = "l2sram", + .start = DA8XX_DSP_L2_RAM_BASE, + .end = DA8XX_DSP_L2_RAM_BASE + SZ_256K - 1, + .flags = IORESOURCE_MEM, + }, + { /* DSP L1P RAM */ + .name = "l1pram", + .start = DA8XX_DSP_L1P_RAM_BASE, + .end = DA8XX_DSP_L1P_RAM_BASE + SZ_32K - 1, + .flags = IORESOURCE_MEM, + }, + { /* DSP L1D RAM */ + .name = "l1dram", + .start = DA8XX_DSP_L1D_RAM_BASE, + .end = DA8XX_DSP_L1D_RAM_BASE + SZ_32K - 1, + .flags = IORESOURCE_MEM, + }, { /* dsp irq */ .start = IRQ_DA8XX_CHIPINT0, .end = IRQ_DA8XX_CHIPINT0, @@ -814,6 +834,8 @@ static struct platform_device da8xx_dsp = { .resource = da8xx_rproc_resources, }; +static bool rproc_mem_inited __initdata; + #if IS_ENABLED(CONFIG_DA8XX_REMOTEPROC) static phys_addr_t rproc_base __initdata; @@ -852,6 +874,8 @@ void __init da8xx_rproc_reserve_cma(void) ret = dma_declare_contiguous(&da8xx_dsp.dev, rproc_size, rproc_base, 0); if (ret) pr_err("%s: dma_declare_contiguous failed %d\n", __func__, ret); + else + rproc_mem_inited = true; } #else @@ -866,6 +890,12 @@ int __init da8xx_register_rproc(void) { int ret; + if (!rproc_mem_inited) { + pr_warn("%s: memory not reserved for DSP, not registering DSP device\n", + __func__); + return -ENOMEM; + } + ret = platform_device_register(&da8xx_dsp); if (ret) pr_err("%s: can't register DSP device: %d\n", __func__, ret); diff --git a/arch/arm/mach-davinci/include/mach/da8xx.h b/arch/arm/mach-davinci/include/mach/da8xx.h index 7e464228948b..93ff1569cee5 100644 --- a/arch/arm/mach-davinci/include/mach/da8xx.h +++ b/arch/arm/mach-davinci/include/mach/da8xx.h @@ -75,6 +75,11 @@ extern unsigned int da850_max_speed; #define DA8XX_VPIF_BASE 0x01e17000 #define DA8XX_GPIO_BASE 0x01e26000 #define DA8XX_PSC1_BASE 0x01e27000 + +#define DA8XX_DSP_L2_RAM_BASE 0x11800000 +#define DA8XX_DSP_L1P_RAM_BASE (DA8XX_DSP_L2_RAM_BASE + 0x600000) +#define DA8XX_DSP_L1D_RAM_BASE (DA8XX_DSP_L2_RAM_BASE + 0x700000) + #define DA8XX_AEMIF_CS2_BASE 0x60000000 #define DA8XX_AEMIF_CS3_BASE 0x62000000 #define DA8XX_AEMIF_CTL_BASE 0x68000000 diff --git a/arch/arm/mach-davinci/pdata-quirks.c b/arch/arm/mach-davinci/pdata-quirks.c index 329f5402ad1d..4858b1cdf31b 100644 --- a/arch/arm/mach-davinci/pdata-quirks.c +++ b/arch/arm/mach-davinci/pdata-quirks.c @@ -33,7 +33,7 @@ static struct tvp514x_platform_data tvp5146_pdata = { #define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL) -static const struct vpif_input da850_ch0_inputs[] = { +static struct vpif_input da850_ch0_inputs[] = { { .input = { .index = 0, @@ -48,7 +48,7 @@ static const struct vpif_input da850_ch0_inputs[] = { }, }; -static const struct vpif_input da850_ch1_inputs[] = { +static struct vpif_input da850_ch1_inputs[] = { { .input = { .index = 0, diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 936c59d0e18b..782699e67600 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -536,6 +536,7 @@ config SOC_IMX7D select HAVE_IMX_ANATOP select HAVE_IMX_MMDC select HAVE_IMX_SRC + select IMX_GPCV2 help This enables support for Freescale i.MX7 Dual processor. diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index b3347d32349f..94906ed49392 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -131,6 +131,9 @@ struct device * __init imx_soc_device_init(void) case MXC_CPU_IMX6UL: soc_id = "i.MX6UL"; break; + case MXC_CPU_IMX6ULL: + soc_id = "i.MX6ULL"; + break; case MXC_CPU_IMX7D: soc_id = "i.MX7D"; break; diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h index 34f2ff62583c..e00d6260c3df 100644 --- a/arch/arm/mach-imx/mxc.h +++ b/arch/arm/mach-imx/mxc.h @@ -39,6 +39,7 @@ #define MXC_CPU_IMX6SX 0x62 #define MXC_CPU_IMX6Q 0x63 #define MXC_CPU_IMX6UL 0x64 +#define MXC_CPU_IMX6ULL 0x65 #define MXC_CPU_IMX7D 0x72 #define IMX_DDR_TYPE_LPDDR2 1 @@ -73,6 +74,11 @@ static inline bool cpu_is_imx6ul(void) return __mxc_cpu_type == MXC_CPU_IMX6UL; } +static inline bool cpu_is_imx6ull(void) +{ + return __mxc_cpu_type == MXC_CPU_IMX6ULL; +} + static inline bool cpu_is_imx6q(void) { return __mxc_cpu_type == MXC_CPU_IMX6Q; diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c index e61b1d1027e1..ecdf071653d4 100644 --- a/arch/arm/mach-imx/pm-imx6.c +++ b/arch/arm/mach-imx/pm-imx6.c @@ -295,7 +295,8 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode) val &= ~BM_CLPCR_SBYOS; if (cpu_is_imx6sl()) val |= BM_CLPCR_BYPASS_PMIC_READY; - if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul()) + if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() || + cpu_is_imx6ull()) val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS; else val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS; @@ -312,7 +313,8 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode) val |= BM_CLPCR_SBYOS; if (cpu_is_imx6sl() || cpu_is_imx6sx()) val |= BM_CLPCR_BYPASS_PMIC_READY; - if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul()) + if (cpu_is_imx6sl() || cpu_is_imx6sx() || cpu_is_imx6ul() || + cpu_is_imx6ull()) val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS; else val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS; diff --git a/arch/arm/mach-meson/Kconfig b/arch/arm/mach-meson/Kconfig index b6e3acc63e14..ee30511849ca 100644 --- a/arch/arm/mach-meson/Kconfig +++ b/arch/arm/mach-meson/Kconfig @@ -21,6 +21,7 @@ config MACH_MESON8 bool "Amlogic Meson8 SoCs support" default ARCH_MESON select MESON6_TIMER + select COMMON_CLK_MESON8B config MACH_MESON8B bool "Amlogic Meson8b SoCs support" diff --git a/arch/arm/mach-omap1/dma.c b/arch/arm/mach-omap1/dma.c index c821c1d5610e..52d7eda1adec 100644 --- a/arch/arm/mach-omap1/dma.c +++ b/arch/arm/mach-omap1/dma.c @@ -240,7 +240,6 @@ static void omap1_show_dma_caps(void) w |= 1 << 3; dma_write(w, GSCR, 0); } - return; } static unsigned configure_dma_errata(void) @@ -339,10 +338,8 @@ static int __init omap1_system_dma_init(void) goto exit_iounmap; } - d = kzalloc(sizeof(struct omap_dma_dev_attr), GFP_KERNEL); + d = kzalloc(sizeof(*d), GFP_KERNEL); if (!d) { - dev_err(&pdev->dev, "%s: Unable to allocate 'd' for %s\n", - __func__, pdev->name); ret = -ENOMEM; goto exit_iounmap; } diff --git a/arch/arm/mach-omap1/timer.c b/arch/arm/mach-omap1/timer.c index 06c5ba7574a5..8fb1ec6fa999 100644 --- a/arch/arm/mach-omap1/timer.c +++ b/arch/arm/mach-omap1/timer.c @@ -3,7 +3,7 @@ * * Contains first level initialization routines which internally * generates timer device information and registers with linux - * device model. It also has low level function to chnage the timer + * device model. It also has a low level function to change the timer * input clock source. * * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ @@ -134,8 +134,6 @@ static int __init omap1_dm_timer_init(void) pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) { - dev_err(&pdev->dev, "%s: Failed to allocate pdata.\n", - __func__); ret = -ENOMEM; goto err_free_pdata; } diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index c89757abb0ae..779fb1f680b3 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -69,7 +69,6 @@ obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o # OPP table initialization ifeq ($(CONFIG_PM_OPP),y) -obj-y += opp.o obj-$(CONFIG_ARCH_OMAP3) += opp3xxx_data.o obj-$(CONFIG_ARCH_OMAP4) += opp4xxx_data.o endif @@ -220,9 +219,6 @@ obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o obj-$(CONFIG_SOC_OMAP5) += omap_hwmod_54xx_data.o obj-$(CONFIG_SOC_DRA7XX) += omap_hwmod_7xx_data.o -# EMU peripherals -obj-$(CONFIG_HW_PERF_EVENTS) += pmu.o - # OMAP2420 MSDI controller integration support ("MMC") obj-$(CONFIG_SOC_OMAP2420) += msdi.o diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c index 91272db09fa3..20f25539d572 100644 --- a/arch/arm/mach-omap2/board-n8x0.c +++ b/arch/arm/mach-omap2/board-n8x0.c @@ -53,14 +53,12 @@ static u32 board_caps; static void board_check_revision(void) { - if (of_have_populated_dt()) { - if (of_machine_is_compatible("nokia,n800")) - board_caps = NOKIA_N800; - else if (of_machine_is_compatible("nokia,n810")) - board_caps = NOKIA_N810; - else if (of_machine_is_compatible("nokia,n810-wimax")) - board_caps = NOKIA_N810_WIMAX; - } + if (of_machine_is_compatible("nokia,n800")) + board_caps = NOKIA_N800; + else if (of_machine_is_compatible("nokia,n810")) + board_caps = NOKIA_N810; + else if (of_machine_is_compatible("nokia,n810-wimax")) + board_caps = NOKIA_N810_WIMAX; if (!board_caps) pr_err("Unknown board\n"); diff --git a/arch/arm/mach-omap2/clockdomain.c b/arch/arm/mach-omap2/clockdomain.c index b79b1ca9aee9..518926410b62 100644 --- a/arch/arm/mach-omap2/clockdomain.c +++ b/arch/arm/mach-omap2/clockdomain.c @@ -1224,6 +1224,14 @@ ccd_exit: return 0; } +u32 clkdm_xlate_address(struct clockdomain *clkdm) +{ + if (arch_clkdm->clkdm_xlate_address) + return arch_clkdm->clkdm_xlate_address(clkdm); + + return 0; +} + /** * clkdm_hwmod_enable - add an enabled downstream hwmod to this clkdm * @clkdm: struct clockdomain * diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h index 24667a5a9dc0..827f01e2d0af 100644 --- a/arch/arm/mach-omap2/clockdomain.h +++ b/arch/arm/mach-omap2/clockdomain.h @@ -175,6 +175,7 @@ struct clkdm_ops { void (*clkdm_deny_idle)(struct clockdomain *clkdm); int (*clkdm_clk_enable)(struct clockdomain *clkdm); int (*clkdm_clk_disable)(struct clockdomain *clkdm); + u32 (*clkdm_xlate_address)(struct clockdomain *clkdm); }; int clkdm_register_platform_funcs(struct clkdm_ops *co); @@ -213,6 +214,7 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk); int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk); int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh); int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh); +u32 clkdm_xlate_address(struct clockdomain *clkdm); extern void __init omap242x_clockdomains_init(void); extern void __init omap243x_clockdomains_init(void); diff --git a/arch/arm/mach-omap2/cm.h b/arch/arm/mach-omap2/cm.h index de75cbcdc9d1..e833984cc85e 100644 --- a/arch/arm/mach-omap2/cm.h +++ b/arch/arm/mach-omap2/cm.h @@ -24,8 +24,11 @@ # ifndef __ASSEMBLER__ #include <linux/clk/ti.h> -extern void __iomem *cm_base; -extern void __iomem *cm2_base; + +#include "prcm-common.h" + +extern struct omap_domain_base cm_base; +extern struct omap_domain_base cm2_base; extern void omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2); # endif diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.h b/arch/arm/mach-omap2/cm2xxx_3xxx.h index 72928a3ce2aa..aa148cd57cc1 100644 --- a/arch/arm/mach-omap2/cm2xxx_3xxx.h +++ b/arch/arm/mach-omap2/cm2xxx_3xxx.h @@ -52,12 +52,12 @@ static inline u32 omap2_cm_read_mod_reg(s16 module, u16 idx) { - return readl_relaxed(cm_base + module + idx); + return readl_relaxed(cm_base.va + module + idx); } static inline void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx) { - writel_relaxed(val, cm_base + module + idx); + writel_relaxed(val, cm_base.va + module + idx); } /* Read-modify-write a register in a CM module. Caller must lock */ diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c index 6f2d0aec0513..a9e08d89104e 100644 --- a/arch/arm/mach-omap2/cm33xx.c +++ b/arch/arm/mach-omap2/cm33xx.c @@ -50,13 +50,13 @@ /* Read a register in a CM instance */ static inline u32 am33xx_cm_read_reg(u16 inst, u16 idx) { - return readl_relaxed(cm_base + inst + idx); + return readl_relaxed(cm_base.va + inst + idx); } /* Write into a register in a CM */ static inline void am33xx_cm_write_reg(u32 val, u16 inst, u16 idx) { - writel_relaxed(val, cm_base + inst + idx); + writel_relaxed(val, cm_base.va + inst + idx); } /* Read-modify-write a register in CM */ diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c index 55b046a719dc..961bc478b9de 100644 --- a/arch/arm/mach-omap2/cm3xxx.c +++ b/arch/arm/mach-omap2/cm3xxx.c @@ -669,7 +669,8 @@ static struct cm_ll_data omap3xxx_cm_ll_data = { int __init omap3xxx_cm_init(const struct omap_prcm_init_data *data) { - omap2_clk_legacy_provider_init(TI_CLKM_CM, cm_base + OMAP3430_IVA2_MOD); + omap2_clk_legacy_provider_init(TI_CLKM_CM, cm_base.va + + OMAP3430_IVA2_MOD); return cm_register(&omap3xxx_cm_ll_data); } diff --git a/arch/arm/mach-omap2/cm_common.c b/arch/arm/mach-omap2/cm_common.c index bbe41f4c9dc8..d555791cf349 100644 --- a/arch/arm/mach-omap2/cm_common.c +++ b/arch/arm/mach-omap2/cm_common.c @@ -32,10 +32,10 @@ static struct cm_ll_data null_cm_ll_data; static struct cm_ll_data *cm_ll_data = &null_cm_ll_data; /* cm_base: base virtual address of the CM IP block */ -void __iomem *cm_base; +struct omap_domain_base cm_base; /* cm2_base: base virtual address of the CM2 IP block (OMAP44xx only) */ -void __iomem *cm2_base; +struct omap_domain_base cm2_base; #define CM_NO_CLOCKS 0x1 #define CM_SINGLE_INSTANCE 0x2 @@ -49,8 +49,8 @@ void __iomem *cm2_base; */ void __init omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2) { - cm_base = cm; - cm2_base = cm2; + cm_base.va = cm; + cm2_base.va = cm2; } /** @@ -315,27 +315,34 @@ int __init omap2_cm_base_init(void) struct device_node *np; const struct of_device_id *match; struct omap_prcm_init_data *data; - void __iomem *mem; + struct resource res; + int ret; + struct omap_domain_base *mem = NULL; for_each_matching_node_and_match(np, omap_cm_dt_match_table, &match) { data = (struct omap_prcm_init_data *)match->data; - mem = of_iomap(np, 0); - if (!mem) - return -ENOMEM; + ret = of_address_to_resource(np, 0, &res); + if (ret) + return ret; if (data->index == TI_CLKM_CM) - cm_base = mem + data->offset; + mem = &cm_base; if (data->index == TI_CLKM_CM2) - cm2_base = mem + data->offset; + mem = &cm2_base; + + data->mem = ioremap(res.start, resource_size(&res)); - data->mem = mem; + if (mem) { + mem->pa = res.start + data->offset; + mem->va = data->mem + data->offset; + } data->np = np; if (data->init && (data->flags & CM_SINGLE_INSTANCE || - (cm_base && cm2_base))) + (cm_base.va && cm2_base.va))) data->init(data); } diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c index 2ab27ade136a..8774e983bea1 100644 --- a/arch/arm/mach-omap2/cminst44xx.c +++ b/arch/arm/mach-omap2/cminst44xx.c @@ -55,7 +55,7 @@ #define CLKCTRL_IDLEST_INTERFACE_IDLE 0x2 #define CLKCTRL_IDLEST_DISABLED 0x3 -static void __iomem *_cm_bases[OMAP4_MAX_PRCM_PARTITIONS]; +static struct omap_domain_base _cm_bases[OMAP4_MAX_PRCM_PARTITIONS]; /** * omap_cm_base_init - Populates the cm partitions @@ -65,10 +65,11 @@ static void __iomem *_cm_bases[OMAP4_MAX_PRCM_PARTITIONS]; */ static void omap_cm_base_init(void) { - _cm_bases[OMAP4430_PRM_PARTITION] = prm_base; - _cm_bases[OMAP4430_CM1_PARTITION] = cm_base; - _cm_bases[OMAP4430_CM2_PARTITION] = cm2_base; - _cm_bases[OMAP4430_PRCM_MPU_PARTITION] = prcm_mpu_base; + memcpy(&_cm_bases[OMAP4430_PRM_PARTITION], &prm_base, sizeof(prm_base)); + memcpy(&_cm_bases[OMAP4430_CM1_PARTITION], &cm_base, sizeof(cm_base)); + memcpy(&_cm_bases[OMAP4430_CM2_PARTITION], &cm2_base, sizeof(cm2_base)); + memcpy(&_cm_bases[OMAP4430_PRCM_MPU_PARTITION], &prcm_mpu_base, + sizeof(prcm_mpu_base)); } /* Private functions */ @@ -116,8 +117,8 @@ static u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx) { BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || part == OMAP4430_INVALID_PRCM_PARTITION || - !_cm_bases[part]); - return readl_relaxed(_cm_bases[part] + inst + idx); + !_cm_bases[part].va); + return readl_relaxed(_cm_bases[part].va + inst + idx); } /* Write into a register in a CM instance */ @@ -125,8 +126,8 @@ static void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx) { BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || part == OMAP4430_INVALID_PRCM_PARTITION || - !_cm_bases[part]); - writel_relaxed(val, _cm_bases[part] + inst + idx); + !_cm_bases[part].va); + writel_relaxed(val, _cm_bases[part].va + inst + idx); } /* Read-modify-write a register in CM1. Caller must lock */ @@ -475,6 +476,14 @@ static int omap4_clkdm_clk_disable(struct clockdomain *clkdm) return 0; } +static u32 omap4_clkdm_xlate_address(struct clockdomain *clkdm) +{ + u32 addr = _cm_bases[clkdm->prcm_partition].pa + clkdm->cm_inst + + clkdm->clkdm_offs; + + return addr; +} + struct clkdm_ops omap4_clkdm_operations = { .clkdm_add_wkdep = omap4_clkdm_add_wkup_sleep_dep, .clkdm_del_wkdep = omap4_clkdm_del_wkup_sleep_dep, @@ -490,6 +499,7 @@ struct clkdm_ops omap4_clkdm_operations = { .clkdm_deny_idle = omap4_clkdm_deny_idle, .clkdm_clk_enable = omap4_clkdm_clk_enable, .clkdm_clk_disable = omap4_clkdm_clk_disable, + .clkdm_xlate_address = omap4_clkdm_xlate_address, }; struct clkdm_ops am43xx_clkdm_operations = { @@ -499,6 +509,7 @@ struct clkdm_ops am43xx_clkdm_operations = { .clkdm_deny_idle = omap4_clkdm_deny_idle, .clkdm_clk_enable = omap4_clkdm_clk_enable, .clkdm_clk_disable = omap4_clkdm_clk_disable, + .clkdm_xlate_address = omap4_clkdm_xlate_address, }; static struct cm_ll_data omap4xxx_cm_ll_data = { diff --git a/arch/arm/mach-omap2/devices.c b/arch/arm/mach-omap2/devices.c index 473951203104..93057fb65f44 100644 --- a/arch/arm/mach-omap2/devices.c +++ b/arch/arm/mach-omap2/devices.c @@ -36,130 +36,6 @@ #define L3_MODULES_MAX_LEN 12 #define L3_MODULES 3 -static int __init omap3_l3_init(void) -{ - struct omap_hwmod *oh; - struct platform_device *pdev; - char oh_name[L3_MODULES_MAX_LEN]; - - /* - * To avoid code running on other OMAPs in - * multi-omap builds - */ - if (!(cpu_is_omap34xx()) || of_have_populated_dt()) - return -ENODEV; - - snprintf(oh_name, L3_MODULES_MAX_LEN, "l3_main"); - - oh = omap_hwmod_lookup(oh_name); - - if (!oh) - pr_err("could not look up %s\n", oh_name); - - pdev = omap_device_build("omap_l3_smx", 0, oh, NULL, 0); - - WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); - - return PTR_ERR_OR_ZERO(pdev); -} -omap_postcore_initcall(omap3_l3_init); - -static inline void omap_init_sti(void) {} - -#if IS_ENABLED(CONFIG_SPI_OMAP24XX) - -#include <linux/platform_data/spi-omap2-mcspi.h> - -static int __init omap_mcspi_init(struct omap_hwmod *oh, void *unused) -{ - struct platform_device *pdev; - char *name = "omap2_mcspi"; - struct omap2_mcspi_platform_config *pdata; - static int spi_num; - struct omap2_mcspi_dev_attr *mcspi_attrib = oh->dev_attr; - - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); - if (!pdata) { - pr_err("Memory allocation for McSPI device failed\n"); - return -ENOMEM; - } - - pdata->num_cs = mcspi_attrib->num_chipselect; - switch (oh->class->rev) { - case OMAP2_MCSPI_REV: - case OMAP3_MCSPI_REV: - pdata->regs_offset = 0; - break; - case OMAP4_MCSPI_REV: - pdata->regs_offset = OMAP4_MCSPI_REG_OFFSET; - break; - default: - pr_err("Invalid McSPI Revision value\n"); - kfree(pdata); - return -EINVAL; - } - - spi_num++; - pdev = omap_device_build(name, spi_num, oh, pdata, sizeof(*pdata)); - WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s\n", - name, oh->name); - kfree(pdata); - return 0; -} - -static void omap_init_mcspi(void) -{ - omap_hwmod_for_each_by_class("mcspi", omap_mcspi_init, NULL); -} - -#else -static inline void omap_init_mcspi(void) {} -#endif - -/** - * omap_init_rng - bind the RNG hwmod to the RNG omap_device - * - * Bind the RNG hwmod to the RNG omap_device. No return value. - */ -static void __init omap_init_rng(void) -{ - struct omap_hwmod *oh; - struct platform_device *pdev; - - oh = omap_hwmod_lookup("rng"); - if (!oh) - return; - - pdev = omap_device_build("omap_rng", -1, oh, NULL, 0); - WARN(IS_ERR(pdev), "Can't build omap_device for omap_rng\n"); -} - -static void __init omap_init_sham(void) -{ - struct omap_hwmod *oh; - struct platform_device *pdev; - - oh = omap_hwmod_lookup("sham"); - if (!oh) - return; - - pdev = omap_device_build("omap-sham", -1, oh, NULL, 0); - WARN(IS_ERR(pdev), "Can't build omap_device for omap-sham\n"); -} - -static void __init omap_init_aes(void) -{ - struct omap_hwmod *oh; - struct platform_device *pdev; - - oh = omap_hwmod_lookup("aes"); - if (!oh) - return; - - pdev = omap_device_build("omap-aes", -1, oh, NULL, 0); - WARN(IS_ERR(pdev), "Can't build omap_device for omap-aes\n"); -} - /*-------------------------------------------------------------------------*/ #if IS_ENABLED(CONFIG_VIDEO_OMAP2_VOUT) @@ -185,54 +61,3 @@ int __init omap_init_vout(void) #else int __init omap_init_vout(void) { return 0; } #endif - -/*-------------------------------------------------------------------------*/ - -static int __init omap2_init_devices(void) -{ - /* Enable dummy states for those platforms without pinctrl support */ - if (!of_have_populated_dt()) - pinctrl_provide_dummies(); - - /* If dtb is there, the devices will be created dynamically */ - if (!of_have_populated_dt()) { - /* - * please keep these calls, and their implementations above, - * in alphabetical order so they're easier to sort through. - */ - omap_init_mcspi(); - omap_init_sham(); - omap_init_aes(); - omap_init_rng(); - } - omap_init_sti(); - - return 0; -} -omap_arch_initcall(omap2_init_devices); - -static int __init omap_gpmc_init(void) -{ - struct omap_hwmod *oh; - struct platform_device *pdev; - char *oh_name = "gpmc"; - - /* - * if the board boots up with a populated DT, do not - * manually add the device from this initcall - */ - if (of_have_populated_dt()) - return -ENODEV; - - oh = omap_hwmod_lookup(oh_name); - if (!oh) { - pr_err("Could not look up %s\n", oh_name); - return -ENODEV; - } - - pdev = omap_device_build("omap-gpmc", -1, oh, NULL, 0); - WARN(IS_ERR(pdev), "could not build omap_device for %s\n", oh_name); - - return PTR_ERR_OR_ZERO(pdev); -} -omap_postcore_initcall(omap_gpmc_init); diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c index cb754c46747e..be517b048762 100644 --- a/arch/arm/mach-omap2/hsmmc.c +++ b/arch/arm/mach-omap2/hsmmc.c @@ -153,7 +153,6 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c, hc_name = kzalloc(sizeof(char) * (HSMMC_NAME_LEN + 1), GFP_KERNEL); if (!hc_name) { - pr_err("Cannot allocate memory for controller slot name\n"); kfree(hc_name); return -ENOMEM; } @@ -315,10 +314,8 @@ static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo, int res; mmc_data = kzalloc(sizeof(*mmc_data), GFP_KERNEL); - if (!mmc_data) { - pr_err("Cannot allocate memory for mmc device!\n"); + if (!mmc_data) return; - } res = omap_hsmmc_pdata_init(hsmmcinfo, mmc_data); if (res < 0) diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 5aafb8449c40..1d739d1a0a65 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -493,67 +493,39 @@ void __init omap3_init_early(void) omap2_set_globals_tap(OMAP343X_CLASS, OMAP2_L4_IO_ADDRESS(0x4830A000)); omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP343X_SDRC_BASE), OMAP2_L3_IO_ADDRESS(OMAP343X_SMS_BASE)); - /* XXX: remove these once OMAP3 is DT only */ - if (!of_have_populated_dt()) { - omap2_set_globals_control( - OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE)); - omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(OMAP3430_PRM_BASE)); - omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(OMAP3430_CM_BASE), - NULL); - } omap2_control_base_init(); omap3xxx_check_revision(); omap3xxx_check_features(); omap2_prcm_base_init(); - /* XXX: remove these once OMAP3 is DT only */ - if (!of_have_populated_dt()) { - omap3xxx_prm_init(NULL); - omap3xxx_cm_init(NULL); - } omap3xxx_voltagedomains_init(); omap3xxx_powerdomains_init(); omap3xxx_clockdomains_init(); omap3xxx_hwmod_init(); omap_hwmod_init_postsetup(); - if (!of_have_populated_dt()) { - omap3_control_legacy_iomap_init(); - if (soc_is_am35xx()) - omap_clk_soc_init = am35xx_clk_legacy_init; - else if (cpu_is_omap3630()) - omap_clk_soc_init = omap36xx_clk_legacy_init; - else if (omap_rev() == OMAP3430_REV_ES1_0) - omap_clk_soc_init = omap3430es1_clk_legacy_init; - else - omap_clk_soc_init = omap3430_clk_legacy_init; - } } void __init omap3430_init_early(void) { omap3_init_early(); - if (of_have_populated_dt()) - omap_clk_soc_init = omap3430_dt_clk_init; + omap_clk_soc_init = omap3430_dt_clk_init; } void __init omap35xx_init_early(void) { omap3_init_early(); - if (of_have_populated_dt()) - omap_clk_soc_init = omap3430_dt_clk_init; + omap_clk_soc_init = omap3430_dt_clk_init; } void __init omap3630_init_early(void) { omap3_init_early(); - if (of_have_populated_dt()) - omap_clk_soc_init = omap3630_dt_clk_init; + omap_clk_soc_init = omap3630_dt_clk_init; } void __init am35xx_init_early(void) { omap3_init_early(); - if (of_have_populated_dt()) - omap_clk_soc_init = am35xx_dt_clk_init; + omap_clk_soc_init = am35xx_dt_clk_init; } void __init omap3_init_late(void) @@ -628,8 +600,7 @@ void __init ti816x_init_early(void) ti816x_clockdomains_init(); dm816x_hwmod_init(); omap_hwmod_init_postsetup(); - if (of_have_populated_dt()) - omap_clk_soc_init = dm816x_dt_clk_init; + omap_clk_soc_init = dm816x_dt_clk_init; } #endif @@ -785,21 +756,19 @@ int __init omap_clk_init(void) omap2_clk_setup_ll_ops(); - if (of_have_populated_dt()) { - ret = omap_control_init(); - if (ret) - return ret; + ret = omap_control_init(); + if (ret) + return ret; - ret = omap_prcm_init(); - if (ret) - return ret; + ret = omap_prcm_init(); + if (ret) + return ret; - of_clk_init(NULL); + of_clk_init(NULL); - ti_dt_clk_init_retry_clks(); + ti_dt_clk_init_retry_clks(); - ti_dt_clockdomains_setup(); - } + ti_dt_clockdomains_setup(); ret = omap_clk_soc_init(); diff --git a/arch/arm/mach-omap2/mcbsp.c b/arch/arm/mach-omap2/mcbsp.c index fc04be74e064..4acc0dae27e0 100644 --- a/arch/arm/mach-omap2/mcbsp.c +++ b/arch/arm/mach-omap2/mcbsp.c @@ -53,73 +53,3 @@ void __init omap3_mcbsp_init_pdata_callback( pdata->force_ick_on = omap3_mcbsp_force_ick_on; } - -static int __init omap_init_mcbsp(struct omap_hwmod *oh, void *unused) -{ - int id, count = 1; - char *name = "omap-mcbsp"; - struct omap_hwmod *oh_device[2]; - struct omap_mcbsp_platform_data *pdata = NULL; - struct platform_device *pdev; - - sscanf(oh->name, "mcbsp%d", &id); - - pdata = kzalloc(sizeof(struct omap_mcbsp_platform_data), GFP_KERNEL); - if (!pdata) { - pr_err("%s: No memory for mcbsp\n", __func__); - return -ENOMEM; - } - - pdata->reg_step = 4; - if (oh->class->rev < MCBSP_CONFIG_TYPE2) { - pdata->reg_size = 2; - } else { - pdata->reg_size = 4; - pdata->has_ccr = true; - } - - if (oh->class->rev == MCBSP_CONFIG_TYPE2) { - /* The FIFO has 128 locations */ - pdata->buffer_size = 0x80; - } else if (oh->class->rev == MCBSP_CONFIG_TYPE3) { - if (id == 2) - /* The FIFO has 1024 + 256 locations */ - pdata->buffer_size = 0x500; - else - /* The FIFO has 128 locations */ - pdata->buffer_size = 0x80; - } else if (oh->class->rev == MCBSP_CONFIG_TYPE4) { - /* The FIFO has 128 locations for all instances */ - pdata->buffer_size = 0x80; - } - - if (oh->class->rev >= MCBSP_CONFIG_TYPE3) - pdata->has_wakeup = true; - - oh_device[0] = oh; - - if (oh->dev_attr) { - oh_device[1] = omap_hwmod_lookup(( - (struct omap_mcbsp_dev_attr *)(oh->dev_attr))->sidetone); - pdata->force_ick_on = omap3_mcbsp_force_ick_on; - count++; - } - pdev = omap_device_build_ss(name, id, oh_device, count, pdata, - sizeof(*pdata)); - kfree(pdata); - if (IS_ERR(pdev)) { - pr_err("%s: Can't build omap_device for %s:%s.\n", __func__, - name, oh->name); - return PTR_ERR(pdev); - } - return 0; -} - -static int __init omap2_mcbsp_init(void) -{ - if (!of_have_populated_dt()) - omap_hwmod_for_each_by_class("mcbsp", omap_init_mcbsp, NULL); - - return 0; -} -omap_arch_initcall(omap2_mcbsp_init); diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index 369f95a703ac..33ed5d53fa45 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c @@ -58,6 +58,17 @@ static unsigned int irq_banks = DEFAULT_NR_REG_BANKS; static unsigned int max_irqs = DEFAULT_IRQS; static unsigned int omap_secure_apis; +#ifdef CONFIG_CPU_PM +static unsigned int wakeupgen_context[MAX_NR_REG_BANKS]; +#endif + +struct omap_wakeupgen_ops { + void (*save_context)(void); + void (*restore_context)(void); +}; + +static struct omap_wakeupgen_ops *wakeupgen_ops; + /* * Static helper functions. */ @@ -264,6 +275,16 @@ static inline void omap5_irq_save_context(void) } +static inline void am43xx_irq_save_context(void) +{ + u32 i; + + for (i = 0; i < irq_banks; i++) { + wakeupgen_context[i] = wakeupgen_readl(i, 0); + wakeupgen_writel(0, i, CPU0_ID); + } +} + /* * Save WakeupGen interrupt context in SAR BANK3. Restore is done by * ROM code. WakeupGen IP is integrated along with GIC to manage the @@ -280,11 +301,8 @@ static void irq_save_context(void) if (!sar_base) sar_base = omap4_get_sar_ram_base(); - - if (soc_is_omap54xx()) - omap5_irq_save_context(); - else - omap4_irq_save_context(); + if (wakeupgen_ops && wakeupgen_ops->save_context) + wakeupgen_ops->save_context(); } /* @@ -306,6 +324,20 @@ static void irq_sar_clear(void) writel_relaxed(val, sar_base + offset); } +static void am43xx_irq_restore_context(void) +{ + u32 i; + + for (i = 0; i < irq_banks; i++) + wakeupgen_writel(wakeupgen_context[i], i, CPU0_ID); +} + +static void irq_restore_context(void) +{ + if (wakeupgen_ops && wakeupgen_ops->restore_context) + wakeupgen_ops->restore_context(); +} + /* * Save GIC and Wakeupgen interrupt context using secure API * for HS/EMU devices. @@ -319,6 +351,26 @@ static void irq_save_secure_context(void) if (ret != API_HAL_RET_VALUE_OK) pr_err("GIC and Wakeupgen context save failed\n"); } + +/* Define ops for context save and restore for each SoC */ +static struct omap_wakeupgen_ops omap4_wakeupgen_ops = { + .save_context = omap4_irq_save_context, + .restore_context = irq_sar_clear, +}; + +static struct omap_wakeupgen_ops omap5_wakeupgen_ops = { + .save_context = omap5_irq_save_context, + .restore_context = irq_sar_clear, +}; + +static struct omap_wakeupgen_ops am43xx_wakeupgen_ops = { + .save_context = am43xx_irq_save_context, + .restore_context = am43xx_irq_restore_context, +}; +#else +static struct omap_wakeupgen_ops omap4_wakeupgen_ops = {}; +static struct omap_wakeupgen_ops omap5_wakeupgen_ops = {}; +static struct omap_wakeupgen_ops am43xx_wakeupgen_ops = {}; #endif #ifdef CONFIG_HOTPLUG_CPU @@ -359,7 +411,7 @@ static int irq_notifier(struct notifier_block *self, unsigned long cmd, void *v) break; case CPU_CLUSTER_PM_EXIT: if (omap_type() == OMAP2_DEVICE_TYPE_GP) - irq_sar_clear(); + irq_restore_context(); break; } return NOTIFY_OK; @@ -494,9 +546,13 @@ static int __init wakeupgen_init(struct device_node *node, irq_banks = OMAP4_NR_BANKS; max_irqs = OMAP4_NR_IRQS; omap_secure_apis = 1; + wakeupgen_ops = &omap4_wakeupgen_ops; + } else if (soc_is_omap54xx()) { + wakeupgen_ops = &omap5_wakeupgen_ops; } else if (soc_is_am43xx()) { irq_banks = AM43XX_NR_REG_BANKS; max_irqs = AM43XX_IRQS; + wakeupgen_ops = &am43xx_wakeupgen_ops; } domain = irq_domain_add_hierarchy(parent_domain, 0, max_irqs, diff --git a/arch/arm/mach-omap2/omap_device.c b/arch/arm/mach-omap2/omap_device.c index f989145480c8..ef9ffb8ac912 100644 --- a/arch/arm/mach-omap2/omap_device.c +++ b/arch/arm/mach-omap2/omap_device.c @@ -65,7 +65,7 @@ static void _add_clkdev(struct omap_device *od, const char *clk_alias, r = clk_get_sys(NULL, clk_name); - if (IS_ERR(r) && of_have_populated_dt()) { + if (IS_ERR(r)) { struct of_phandle_args clkspec; clkspec.np = of_find_node_by_name(NULL, clk_name); @@ -953,9 +953,6 @@ static int __init omap_device_late_init(void) { bus_for_each_dev(&platform_bus_type, NULL, NULL, omap_device_late_idle); - WARN(!of_have_populated_dt(), - "legacy booting deprecated, please update to boot with .dts\n"); - return 0; } omap_late_initcall_sync(omap_device_late_init); diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 8bcea0d83fa0..3b47ded5fa0c 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c @@ -141,6 +141,7 @@ #include <linux/cpu.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/bootmem.h> #include <asm/system_misc.h> @@ -182,6 +183,24 @@ #define MOD_CLK_MAX_NAME_LEN 32 /** + * struct clkctrl_provider - clkctrl provider mapping data + * @addr: base address for the provider + * @offset: base offset for the provider + * @clkdm: base clockdomain for provider + * @node: device node associated with the provider + * @link: list link + */ +struct clkctrl_provider { + u32 addr; + u16 offset; + struct clockdomain *clkdm; + struct device_node *node; + struct list_head link; +}; + +static LIST_HEAD(clkctrl_providers); + +/** * struct omap_hwmod_soc_ops - fn ptrs for some SoC-specific operations * @enable_module: function to enable a module (via MODULEMODE) * @disable_module: function to disable a module (via MODULEMODE) @@ -204,6 +223,8 @@ struct omap_hwmod_soc_ops { void (*update_context_lost)(struct omap_hwmod *oh); int (*get_context_lost)(struct omap_hwmod *oh); int (*disable_direct_prcm)(struct omap_hwmod *oh); + u32 (*xlate_clkctrl)(struct omap_hwmod *oh, + struct clkctrl_provider *provider); }; /* soc_ops: adapts the omap_hwmod code to the currently-booted SoC */ @@ -690,6 +711,103 @@ static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) return clkdm_del_sleepdep(clkdm, init_clkdm); } +static const struct of_device_id ti_clkctrl_match_table[] __initconst = { + { .compatible = "ti,clkctrl" }, + { } +}; + +static int _match_clkdm(struct clockdomain *clkdm, void *user) +{ + struct clkctrl_provider *provider = user; + + if (clkdm_xlate_address(clkdm) == provider->addr) { + pr_debug("%s: Matched clkdm %s for addr %x (%s)\n", __func__, + clkdm->name, provider->addr, + provider->node->parent->name); + provider->clkdm = clkdm; + + return -1; + } + + return 0; +} + +static int _setup_clkctrl_provider(struct device_node *np) +{ + const __be32 *addrp; + struct clkctrl_provider *provider; + + provider = memblock_virt_alloc(sizeof(*provider), 0); + if (!provider) + return -ENOMEM; + + addrp = of_get_address(np, 0, NULL, NULL); + provider->addr = (u32)of_translate_address(np, addrp); + provider->offset = provider->addr & 0xff; + provider->addr &= ~0xff; + provider->node = np; + + clkdm_for_each(_match_clkdm, provider); + + if (!provider->clkdm) { + pr_err("%s: nothing matched for node %s (%x)\n", + __func__, np->parent->name, provider->addr); + memblock_free_early(__pa(provider), sizeof(*provider)); + return -EINVAL; + } + + list_add(&provider->link, &clkctrl_providers); + + return 0; +} + +static int _init_clkctrl_providers(void) +{ + struct device_node *np; + int ret = 0; + + for_each_matching_node(np, ti_clkctrl_match_table) { + ret = _setup_clkctrl_provider(np); + if (ret) + break; + } + + return ret; +} + +static u32 _omap4_xlate_clkctrl(struct omap_hwmod *oh, + struct clkctrl_provider *provider) +{ + return oh->prcm.omap4.clkctrl_offs - + provider->offset - provider->clkdm->clkdm_offs; +} + +static struct clk *_lookup_clkctrl_clk(struct omap_hwmod *oh) +{ + struct clkctrl_provider *provider; + struct clk *clk; + + if (!soc_ops.xlate_clkctrl) + return NULL; + + list_for_each_entry(provider, &clkctrl_providers, link) { + if (provider->clkdm == oh->clkdm) { + struct of_phandle_args clkspec; + + clkspec.np = provider->node; + clkspec.args_count = 2; + clkspec.args[0] = soc_ops.xlate_clkctrl(oh, provider); + clkspec.args[1] = 0; + + clk = of_clk_get_from_provider(&clkspec); + + return clk; + } + } + + return NULL; +} + /** * _init_main_clk - get a struct clk * for the the hwmod's main functional clk * @oh: struct omap_hwmod * @@ -701,22 +819,16 @@ static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) static int _init_main_clk(struct omap_hwmod *oh) { int ret = 0; - char name[MOD_CLK_MAX_NAME_LEN]; - struct clk *clk; - static const char modck[] = "_mod_ck"; + struct clk *clk = NULL; - if (strlen(oh->name) >= MOD_CLK_MAX_NAME_LEN - strlen(modck)) - pr_warn("%s: warning: cropping name for %s\n", __func__, - oh->name); - - strlcpy(name, oh->name, MOD_CLK_MAX_NAME_LEN - strlen(modck)); - strlcat(name, modck, MOD_CLK_MAX_NAME_LEN); + clk = _lookup_clkctrl_clk(oh); - clk = clk_get(NULL, name); - if (!IS_ERR(clk)) { + if (!IS_ERR_OR_NULL(clk)) { + pr_debug("%s: mapped main_clk %s for %s\n", __func__, + __clk_get_name(clk), oh->name); + oh->main_clk = __clk_get_name(clk); oh->_clk = clk; soc_ops.disable_direct_prcm(oh); - oh->main_clk = kstrdup(name, GFP_KERNEL); } else { if (!oh->main_clk) return 0; @@ -1482,13 +1594,13 @@ static int _init_clkdm(struct omap_hwmod *oh) * _init_clocks - clk_get() all clocks associated with this hwmod. Retrieve as * well the clockdomain. * @oh: struct omap_hwmod * - * @data: not used; pass NULL + * @np: device_node mapped to this hwmod * * Called by omap_hwmod_setup_*() (after omap2_clk_init()). * Resolves all clock names embedded in the hwmod. Returns 0 on * success, or a negative error code on failure. */ -static int _init_clocks(struct omap_hwmod *oh, void *data) +static int _init_clocks(struct omap_hwmod *oh, struct device_node *np) { int ret = 0; @@ -2334,24 +2446,21 @@ static int __init _init(struct omap_hwmod *oh, void *data) { int r, index; struct device_node *np = NULL; + struct device_node *bus; if (oh->_state != _HWMOD_STATE_REGISTERED) return 0; - if (of_have_populated_dt()) { - struct device_node *bus; + bus = of_find_node_by_name(NULL, "ocp"); + if (!bus) + return -ENODEV; - bus = of_find_node_by_name(NULL, "ocp"); - if (!bus) - return -ENODEV; - - r = of_dev_hwmod_lookup(bus, oh, &index, &np); - if (r) - pr_debug("omap_hwmod: %s missing dt data\n", oh->name); - else if (np && index) - pr_warn("omap_hwmod: %s using broken dt data from %s\n", - oh->name, np->name); - } + r = of_dev_hwmod_lookup(bus, oh, &index, &np); + if (r) + pr_debug("omap_hwmod: %s missing dt data\n", oh->name); + else if (np && index) + pr_warn("omap_hwmod: %s using broken dt data from %s\n", + oh->name, np->name); r = _init_mpu_rt_base(oh, NULL, index, np); if (r < 0) { @@ -2360,7 +2469,7 @@ static int __init _init(struct omap_hwmod *oh, void *data) return 0; } - r = _init_clocks(oh, NULL); + r = _init_clocks(oh, np); if (r < 0) { WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh->name); return -EINVAL; @@ -3722,6 +3831,7 @@ void __init omap_hwmod_init(void) soc_ops.update_context_lost = _omap4_update_context_lost; soc_ops.get_context_lost = _omap4_get_context_lost; soc_ops.disable_direct_prcm = _omap4_disable_direct_prcm; + soc_ops.xlate_clkctrl = _omap4_xlate_clkctrl; } else if (cpu_is_ti814x() || cpu_is_ti816x() || soc_is_am33xx() || soc_is_am43xx()) { soc_ops.enable_module = _omap4_enable_module; @@ -3736,6 +3846,8 @@ void __init omap_hwmod_init(void) WARN(1, "omap_hwmod: unknown SoC type\n"); } + _init_clkctrl_providers(); + inited = true; } diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c index 1c6ca4d5fa2d..c3276436b0ae 100644 --- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c @@ -3204,8 +3204,7 @@ int __init omap3xxx_hwmod_init(void) * If DT information is missing, enable them only for GP devices. */ - if (of_have_populated_dt()) - bus = of_find_node_by_name(NULL, "ocp"); + bus = of_find_node_by_name(NULL, "ocp"); if (h_sham && omap3xxx_hwmod_is_hs_ip_block_usable(bus, "sham")) { r = omap_hwmod_register_links(h_sham); diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c index 94f09c720f29..3e2d792fd9df 100644 --- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c @@ -775,6 +775,7 @@ static struct omap_hwmod_dma_info omap44xx_dss_hdmi_sdma_reqs[] = { static struct omap_hwmod_opt_clk dss_hdmi_opt_clks[] = { { .role = "sys_clk", .clk = "dss_sys_clk" }, + { .role = "hdmi_clk", .clk = "dss_48mhz_clk" }, }; static struct omap_hwmod omap44xx_dss_hdmi_hwmod = { @@ -785,7 +786,7 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = { * HDMI audio requires to use no-idle mode. Hence, * set idle mode by software. */ - .flags = HWMOD_SWSUP_SIDLE, + .flags = HWMOD_SWSUP_SIDLE | HWMOD_OPT_CLKS_NEEDED, .mpu_irqs = omap44xx_dss_hdmi_irqs, .xlate_irq = omap4_xlate_irq, .sdma_reqs = omap44xx_dss_hdmi_sdma_reqs, @@ -858,11 +859,16 @@ static struct omap_hwmod_class omap44xx_venc_hwmod_class = { }; /* dss_venc */ +static struct omap_hwmod_opt_clk dss_venc_opt_clks[] = { + { .role = "tv_clk", .clk = "dss_tv_clk" }, +}; + static struct omap_hwmod omap44xx_dss_venc_hwmod = { .name = "dss_venc", .class = &omap44xx_venc_hwmod_class, .clkdm_name = "l3_dss_clkdm", .main_clk = "dss_tv_clk", + .flags = HWMOD_OPT_CLKS_NEEDED, .prcm = { .omap4 = { .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, @@ -870,6 +876,35 @@ static struct omap_hwmod omap44xx_dss_venc_hwmod = { }, }, .parent_hwmod = &omap44xx_dss_hwmod, + .opt_clks = dss_venc_opt_clks, + .opt_clks_cnt = ARRAY_SIZE(dss_venc_opt_clks), +}; + +/* sha0 HIB2 (the 'P' (public) device) */ +static struct omap_hwmod_class_sysconfig omap44xx_sha0_sysc = { + .rev_offs = 0x100, + .sysc_offs = 0x110, + .syss_offs = 0x114, + .sysc_flags = SYSS_HAS_RESET_STATUS, +}; + +static struct omap_hwmod_class omap44xx_sha0_hwmod_class = { + .name = "sham", + .sysc = &omap44xx_sha0_sysc, +}; + +struct omap_hwmod omap44xx_sha0_hwmod = { + .name = "sham", + .class = &omap44xx_sha0_hwmod_class, + .clkdm_name = "l4_secure_clkdm", + .main_clk = "l3_div_ck", + .prcm = { + .omap4 = { + .clkctrl_offs = OMAP4_CM_L4SEC_SHA2MD51_CLKCTRL_OFFSET, + .context_offs = OMAP4_RM_L4SEC_SHA2MD51_CONTEXT_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, }; /* @@ -953,6 +988,103 @@ static struct omap_hwmod omap44xx_emif2_hwmod = { }; /* + Crypto modules AES0/1 belong to: + PD_L4_PER power domain + CD_L4_SEC clock domain + On the L3, the AES modules are mapped to + L3_CLK2: Peripherals and multimedia sub clock domain +*/ +static struct omap_hwmod_class_sysconfig omap44xx_aes_sysc = { + .rev_offs = 0x80, + .sysc_offs = 0x84, + .syss_offs = 0x88, + .sysc_flags = SYSS_HAS_RESET_STATUS, +}; + +static struct omap_hwmod_class omap44xx_aes_hwmod_class = { + .name = "aes", + .sysc = &omap44xx_aes_sysc, +}; + +static struct omap_hwmod omap44xx_aes1_hwmod = { + .name = "aes1", + .class = &omap44xx_aes_hwmod_class, + .clkdm_name = "l4_secure_clkdm", + .main_clk = "l3_div_ck", + .prcm = { + .omap4 = { + .context_offs = OMAP4_RM_L4SEC_AES1_CONTEXT_OFFSET, + .clkctrl_offs = OMAP4_CM_L4SEC_AES1_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__aes1 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_aes1_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +static struct omap_hwmod omap44xx_aes2_hwmod = { + .name = "aes2", + .class = &omap44xx_aes_hwmod_class, + .clkdm_name = "l4_secure_clkdm", + .main_clk = "l3_div_ck", + .prcm = { + .omap4 = { + .context_offs = OMAP4_RM_L4SEC_AES2_CONTEXT_OFFSET, + .clkctrl_offs = OMAP4_CM_L4SEC_AES2_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__aes2 = { + .master = &omap44xx_l4_per_hwmod, + .slave = &omap44xx_aes2_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* + * 'des' class for DES3DES module + */ +static struct omap_hwmod_class_sysconfig omap44xx_des_sysc = { + .rev_offs = 0x30, + .sysc_offs = 0x34, + .syss_offs = 0x38, + .sysc_flags = SYSS_HAS_RESET_STATUS, +}; + +static struct omap_hwmod_class omap44xx_des_hwmod_class = { + .name = "des", + .sysc = &omap44xx_des_sysc, +}; + +static struct omap_hwmod omap44xx_des_hwmod = { + .name = "des", + .class = &omap44xx_des_hwmod_class, + .clkdm_name = "l4_secure_clkdm", + .main_clk = "l3_div_ck", + .prcm = { + .omap4 = { + .context_offs = OMAP4_RM_L4SEC_DES3DES_CONTEXT_OFFSET, + .clkctrl_offs = OMAP4_CM_L4SEC_DES3DES_CLKCTRL_OFFSET, + .modulemode = MODULEMODE_SWCTRL, + }, + }, +}; + +struct omap_hwmod_ocp_if omap44xx_l3_main_2__des = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_des_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + +/* * 'fdif' class * face detection hw accelerator module */ @@ -3882,6 +4014,14 @@ static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_venc = { .user = OCP_USER_MPU, }; +/* l3_main_2 -> sham */ +static struct omap_hwmod_ocp_if omap44xx_l3_main_2__sha0 = { + .master = &omap44xx_l3_main_2_hwmod, + .slave = &omap44xx_sha0_hwmod, + .clk = "l3_div_ck", + .user = OCP_USER_MPU | OCP_USER_SDMA, +}; + /* l4_per -> elm */ static struct omap_hwmod_ocp_if omap44xx_l4_per__elm = { .master = &omap44xx_l4_per_hwmod, @@ -4793,6 +4933,10 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { &omap44xx_l4_abe__wd_timer3_dma, &omap44xx_mpu__emif1, &omap44xx_mpu__emif2, + &omap44xx_l3_main_2__aes1, + &omap44xx_l3_main_2__aes2, + &omap44xx_l3_main_2__des, + &omap44xx_l3_main_2__sha0, NULL, }; diff --git a/arch/arm/mach-omap2/opp.c b/arch/arm/mach-omap2/opp.c deleted file mode 100644 index a358a07e18f2..000000000000 --- a/arch/arm/mach-omap2/opp.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * OMAP SoC specific OPP wrapper function - * - * Copyright (C) 2009-2010 Texas Instruments Incorporated - http://www.ti.com/ - * Nishanth Menon - * Kevin Hilman - * Copyright (C) 2010 Nokia Corporation. - * Eduardo Valentin - * - * 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 "as is" WITHOUT ANY WARRANTY of any - * kind, whether express or implied; without even the implied warranty - * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include <linux/module.h> -#include <linux/of.h> -#include <linux/pm_opp.h> -#include <linux/cpu.h> - -#include "omap_device.h" - -#include "omap_opp_data.h" - -/* Temp variable to allow multiple calls */ -static u8 __initdata omap_table_init; - -/** - * omap_init_opp_table() - Initialize opp table as per the CPU type - * @opp_def: opp default list for this silicon - * @opp_def_size: number of opp entries for this silicon - * - * Register the initial OPP table with the OPP library based on the CPU - * type. This is meant to be used only by SoC specific registration. - */ -int __init omap_init_opp_table(struct omap_opp_def *opp_def, - u32 opp_def_size) -{ - int i, r; - - if (of_have_populated_dt()) - return -EINVAL; - - if (!opp_def || !opp_def_size) { - pr_err("%s: invalid params!\n", __func__); - return -EINVAL; - } - - /* - * Initialize only if not already initialized even if the previous - * call failed, because, no reason we'd succeed again. - */ - if (omap_table_init) - return -EEXIST; - omap_table_init = 1; - - /* Lets now register with OPP library */ - for (i = 0; i < opp_def_size; i++, opp_def++) { - struct omap_hwmod *oh; - struct device *dev; - - if (!opp_def->hwmod_name) { - pr_err("%s: NULL name of omap_hwmod, failing [%d].\n", - __func__, i); - return -EINVAL; - } - - if (!strncmp(opp_def->hwmod_name, "mpu", 3)) { - /* - * All current OMAPs share voltage rail and - * clock source, so CPU0 is used to represent - * the MPU-SS. - */ - dev = get_cpu_device(0); - } else { - oh = omap_hwmod_lookup(opp_def->hwmod_name); - if (!oh || !oh->od) { - pr_debug("%s: no hwmod or odev for %s, [%d] cannot add OPPs.\n", - __func__, opp_def->hwmod_name, i); - continue; - } - dev = &oh->od->pdev->dev; - } - - r = dev_pm_opp_add(dev, opp_def->freq, opp_def->u_volt); - if (r) { - dev_err(dev, "%s: add OPP %ld failed for %s [%d] result=%d\n", - __func__, opp_def->freq, - opp_def->hwmod_name, i, r); - } else { - if (!opp_def->default_available) - r = dev_pm_opp_disable(dev, opp_def->freq); - if (r) - dev_err(dev, "%s: disable %ld failed for %s [%d] result=%d\n", - __func__, opp_def->freq, - opp_def->hwmod_name, i, r); - } - } - - return 0; -} diff --git a/arch/arm/mach-omap2/opp3xxx_data.c b/arch/arm/mach-omap2/opp3xxx_data.c index fc67add76444..c2d459f5b0da 100644 --- a/arch/arm/mach-omap2/opp3xxx_data.c +++ b/arch/arm/mach-omap2/opp3xxx_data.c @@ -83,89 +83,3 @@ struct omap_volt_data omap36xx_vddcore_volt_data[] = { VOLT_DATA_DEFINE(OMAP3630_VDD_CORE_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD2, 0xf9, 0x16), VOLT_DATA_DEFINE(0, 0, 0, 0), }; - -/* OPP data */ - -static struct omap_opp_def __initdata omap34xx_opp_def_list[] = { - /* MPU OPP1 */ - OPP_INITIALIZER("mpu", true, 125000000, OMAP3430_VDD_MPU_OPP1_UV), - /* MPU OPP2 */ - OPP_INITIALIZER("mpu", true, 250000000, OMAP3430_VDD_MPU_OPP2_UV), - /* MPU OPP3 */ - OPP_INITIALIZER("mpu", true, 500000000, OMAP3430_VDD_MPU_OPP3_UV), - /* MPU OPP4 */ - OPP_INITIALIZER("mpu", true, 550000000, OMAP3430_VDD_MPU_OPP4_UV), - /* MPU OPP5 */ - OPP_INITIALIZER("mpu", true, 600000000, OMAP3430_VDD_MPU_OPP5_UV), - - /* - * L3 OPP1 - 41.5 MHz is disabled because: The voltage for that OPP is - * almost the same than the one at 83MHz thus providing very little - * gain for the power point of view. In term of energy it will even - * increase the consumption due to the very negative performance - * impact that frequency will do to the MPU and the whole system in - * general. - */ - OPP_INITIALIZER("l3_main", false, 41500000, OMAP3430_VDD_CORE_OPP1_UV), - /* L3 OPP2 */ - OPP_INITIALIZER("l3_main", true, 83000000, OMAP3430_VDD_CORE_OPP2_UV), - /* L3 OPP3 */ - OPP_INITIALIZER("l3_main", true, 166000000, OMAP3430_VDD_CORE_OPP3_UV), - - /* DSP OPP1 */ - OPP_INITIALIZER("iva", true, 90000000, OMAP3430_VDD_MPU_OPP1_UV), - /* DSP OPP2 */ - OPP_INITIALIZER("iva", true, 180000000, OMAP3430_VDD_MPU_OPP2_UV), - /* DSP OPP3 */ - OPP_INITIALIZER("iva", true, 360000000, OMAP3430_VDD_MPU_OPP3_UV), - /* DSP OPP4 */ - OPP_INITIALIZER("iva", true, 400000000, OMAP3430_VDD_MPU_OPP4_UV), - /* DSP OPP5 */ - OPP_INITIALIZER("iva", true, 430000000, OMAP3430_VDD_MPU_OPP5_UV), -}; - -static struct omap_opp_def __initdata omap36xx_opp_def_list[] = { - /* MPU OPP1 - OPP50 */ - OPP_INITIALIZER("mpu", true, 300000000, OMAP3630_VDD_MPU_OPP50_UV), - /* MPU OPP2 - OPP100 */ - OPP_INITIALIZER("mpu", true, 600000000, OMAP3630_VDD_MPU_OPP100_UV), - /* MPU OPP3 - OPP-Turbo */ - OPP_INITIALIZER("mpu", false, 800000000, OMAP3630_VDD_MPU_OPP120_UV), - /* MPU OPP4 - OPP-SB */ - OPP_INITIALIZER("mpu", false, 1000000000, OMAP3630_VDD_MPU_OPP1G_UV), - - /* L3 OPP1 - OPP50 */ - OPP_INITIALIZER("l3_main", true, 100000000, OMAP3630_VDD_CORE_OPP50_UV), - /* L3 OPP2 - OPP100, OPP-Turbo, OPP-SB */ - OPP_INITIALIZER("l3_main", true, 200000000, OMAP3630_VDD_CORE_OPP100_UV), - - /* DSP OPP1 - OPP50 */ - OPP_INITIALIZER("iva", true, 260000000, OMAP3630_VDD_MPU_OPP50_UV), - /* DSP OPP2 - OPP100 */ - OPP_INITIALIZER("iva", true, 520000000, OMAP3630_VDD_MPU_OPP100_UV), - /* DSP OPP3 - OPP-Turbo */ - OPP_INITIALIZER("iva", false, 660000000, OMAP3630_VDD_MPU_OPP120_UV), - /* DSP OPP4 - OPP-SB */ - OPP_INITIALIZER("iva", false, 800000000, OMAP3630_VDD_MPU_OPP1G_UV), -}; - -/** - * omap3_opp_init() - initialize omap3 opp table - */ -int __init omap3_opp_init(void) -{ - int r = -ENODEV; - - if (!cpu_is_omap34xx()) - return r; - - if (cpu_is_omap3630()) - r = omap_init_opp_table(omap36xx_opp_def_list, - ARRAY_SIZE(omap36xx_opp_def_list)); - else - r = omap_init_opp_table(omap34xx_opp_def_list, - ARRAY_SIZE(omap34xx_opp_def_list)); - - return r; -} -omap_device_initcall(omap3_opp_init); diff --git a/arch/arm/mach-omap2/opp4xxx_data.c b/arch/arm/mach-omap2/opp4xxx_data.c index 1ef7a3e5ce4a..adea43ea1c60 100644 --- a/arch/arm/mach-omap2/opp4xxx_data.c +++ b/arch/arm/mach-omap2/opp4xxx_data.c @@ -63,29 +63,6 @@ struct omap_volt_data omap443x_vdd_core_volt_data[] = { VOLT_DATA_DEFINE(0, 0, 0, 0), }; - -static struct omap_opp_def __initdata omap443x_opp_def_list[] = { - /* MPU OPP1 - OPP50 */ - OPP_INITIALIZER("mpu", true, 300000000, OMAP4430_VDD_MPU_OPP50_UV), - /* MPU OPP2 - OPP100 */ - OPP_INITIALIZER("mpu", true, 600000000, OMAP4430_VDD_MPU_OPP100_UV), - /* MPU OPP3 - OPP-Turbo */ - OPP_INITIALIZER("mpu", true, 800000000, OMAP4430_VDD_MPU_OPPTURBO_UV), - /* MPU OPP4 - OPP-SB */ - OPP_INITIALIZER("mpu", true, 1008000000, OMAP4430_VDD_MPU_OPPNITRO_UV), - /* L3 OPP1 - OPP50 */ - OPP_INITIALIZER("l3_main_1", true, 100000000, OMAP4430_VDD_CORE_OPP50_UV), - /* L3 OPP2 - OPP100, OPP-Turbo, OPP-SB */ - OPP_INITIALIZER("l3_main_1", true, 200000000, OMAP4430_VDD_CORE_OPP100_UV), - /* IVA OPP1 - OPP50 */ - OPP_INITIALIZER("iva", true, 133000000, OMAP4430_VDD_IVA_OPP50_UV), - /* IVA OPP2 - OPP100 */ - OPP_INITIALIZER("iva", true, 266100000, OMAP4430_VDD_IVA_OPP100_UV), - /* IVA OPP3 - OPP-Turbo */ - OPP_INITIALIZER("iva", false, 332000000, OMAP4430_VDD_IVA_OPPTURBO_UV), - /* TODO: add DSP, aess, fdif, gpu */ -}; - #define OMAP4460_VDD_MPU_OPP50_UV 1025000 #define OMAP4460_VDD_MPU_OPP100_UV 1200000 #define OMAP4460_VDD_MPU_OPPTURBO_UV 1313000 @@ -122,59 +99,3 @@ struct omap_volt_data omap446x_vdd_core_volt_data[] = { VOLT_DATA_DEFINE(OMAP4460_VDD_CORE_OPP100_OV_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100OV, 0xf9, 0x16), VOLT_DATA_DEFINE(0, 0, 0, 0), }; - -static struct omap_opp_def __initdata omap446x_opp_def_list[] = { - /* MPU OPP1 - OPP50 */ - OPP_INITIALIZER("mpu", true, 350000000, OMAP4460_VDD_MPU_OPP50_UV), - /* MPU OPP2 - OPP100 */ - OPP_INITIALIZER("mpu", true, 700000000, OMAP4460_VDD_MPU_OPP100_UV), - /* MPU OPP3 - OPP-Turbo */ - OPP_INITIALIZER("mpu", true, 920000000, OMAP4460_VDD_MPU_OPPTURBO_UV), - /* - * MPU OPP4 - OPP-Nitro + Disabled as the reference schematics - * recommends TPS623631 - confirm and enable the opp in board file - * XXX: May be we should enable these based on mpu capability and - * Exception board files disable it... - */ - OPP_INITIALIZER("mpu", false, 1200000000, OMAP4460_VDD_MPU_OPPNITRO_UV), - /* MPU OPP4 - OPP-Nitro SpeedBin */ - OPP_INITIALIZER("mpu", false, 1500000000, OMAP4460_VDD_MPU_OPPNITRO_UV), - /* L3 OPP1 - OPP50 */ - OPP_INITIALIZER("l3_main_1", true, 100000000, OMAP4460_VDD_CORE_OPP50_UV), - /* L3 OPP2 - OPP100 */ - OPP_INITIALIZER("l3_main_1", true, 200000000, OMAP4460_VDD_CORE_OPP100_UV), - /* IVA OPP1 - OPP50 */ - OPP_INITIALIZER("iva", true, 133000000, OMAP4460_VDD_IVA_OPP50_UV), - /* IVA OPP2 - OPP100 */ - OPP_INITIALIZER("iva", true, 266100000, OMAP4460_VDD_IVA_OPP100_UV), - /* - * IVA OPP3 - OPP-Turbo + Disabled as the reference schematics - * recommends Phoenix VCORE2 which can supply only 600mA - so the ones - * above this OPP frequency, even though OMAP is capable, should be - * enabled by board file which is sure of the chip power capability - */ - OPP_INITIALIZER("iva", false, 332000000, OMAP4460_VDD_IVA_OPPTURBO_UV), - /* IVA OPP4 - OPP-Nitro */ - OPP_INITIALIZER("iva", false, 430000000, OMAP4460_VDD_IVA_OPPNITRO_UV), - /* IVA OPP5 - OPP-Nitro SpeedBin*/ - OPP_INITIALIZER("iva", false, 500000000, OMAP4460_VDD_IVA_OPPNITRO_UV), - - /* TODO: add DSP, aess, fdif, gpu */ -}; - -/** - * omap4_opp_init() - initialize omap4 opp table - */ -int __init omap4_opp_init(void) -{ - int r = -ENODEV; - - if (cpu_is_omap443x()) - r = omap_init_opp_table(omap443x_opp_def_list, - ARRAY_SIZE(omap443x_opp_def_list)); - else if (cpu_is_omap446x()) - r = omap_init_opp_table(omap446x_opp_def_list, - ARRAY_SIZE(omap446x_opp_def_list)); - return r; -} -omap_device_initcall(omap4_opp_init); diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c index 63027e60cc20..366158a54fcd 100644 --- a/arch/arm/mach-omap2/pm.c +++ b/arch/arm/mach-omap2/pm.c @@ -71,7 +71,7 @@ void omap_pm_get_oscillator(u32 *tstart, u32 *tshut) } #endif -int __init omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused) +int omap_pm_clkdms_setup(struct clockdomain *clkdm, void *unused) { clkdm_allow_idle(clkdm); return 0; diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c deleted file mode 100644 index d2adfebd3b3f..000000000000 --- a/arch/arm/mach-omap2/pmu.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * OMAP2 ARM Performance Monitoring Unit (PMU) Support - * - * Copyright (C) 2012 Texas Instruments, Inc. - * - * Contacts: - * Jon Hunter <jon-hunter@ti.com> - * - * 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; either version 2 of the License, or - * (at your option) any later version. - */ -#include <linux/of.h> - -#include <asm/system_info.h> - -#include "soc.h" -#include "omap_hwmod.h" -#include "omap_device.h" - -static char *omap2_pmu_oh_names[] = {"mpu"}; -static char *omap3_pmu_oh_names[] = {"mpu", "debugss"}; -static char *omap4430_pmu_oh_names[] = {"l3_main_3", "l3_instr", "debugss"}; -static struct platform_device *omap_pmu_dev; - -/** - * omap2_init_pmu - creates and registers PMU platform device - * @oh_num: Number of OMAP HWMODs required to create PMU device - * @oh_names: Array of OMAP HWMODS names required to create PMU device - * - * Uses OMAP HWMOD framework to create and register an ARM PMU device - * from a list of HWMOD names passed. Currently supports OMAP2, OMAP3 - * and OMAP4 devices. - */ -static int __init omap2_init_pmu(unsigned oh_num, char *oh_names[]) -{ - int i; - struct omap_hwmod *oh[3]; - char *dev_name = cpu_architecture() == CPU_ARCH_ARMv6 ? - "armv6-pmu" : "armv7-pmu"; - - if ((!oh_num) || (oh_num > 3)) - return -EINVAL; - - for (i = 0; i < oh_num; i++) { - oh[i] = omap_hwmod_lookup(oh_names[i]); - if (!oh[i]) { - pr_err("Could not look up %s hwmod\n", oh_names[i]); - return -ENODEV; - } - } - - omap_pmu_dev = omap_device_build_ss(dev_name, -1, oh, oh_num, NULL, 0); - WARN(IS_ERR(omap_pmu_dev), "Can't build omap_device for %s.\n", - dev_name); - - return PTR_ERR_OR_ZERO(omap_pmu_dev); -} - -static int __init omap_init_pmu(void) -{ - unsigned oh_num; - char **oh_names; - - /* XXX Remove this check when the CTI driver is available */ - if (cpu_is_omap443x()) { - pr_info("ARM PMU: not yet supported on OMAP4430 due to missing CTI driver\n"); - return 0; - } - - if (of_have_populated_dt()) - return 0; - - /* - * To create an ARM-PMU device the following HWMODs - * are required for the various OMAP2+ devices. - * - * OMAP24xx: mpu - * OMAP3xxx: mpu, debugss - * OMAP4430: l3_main_3, l3_instr, debugss - * OMAP4460/70: mpu, debugss - */ - if (cpu_is_omap443x()) { - oh_num = ARRAY_SIZE(omap4430_pmu_oh_names); - oh_names = omap4430_pmu_oh_names; - } else if (cpu_is_omap34xx() || cpu_is_omap44xx()) { - oh_num = ARRAY_SIZE(omap3_pmu_oh_names); - oh_names = omap3_pmu_oh_names; - } else { - oh_num = ARRAY_SIZE(omap2_pmu_oh_names); - oh_names = omap2_pmu_oh_names; - } - - return omap2_init_pmu(oh_num, oh_names); -} -omap_subsys_initcall(omap_init_pmu); diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index c8f590b7c32d..ee7041d523cf 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h @@ -526,10 +526,16 @@ struct omap_prcm_irq_setup { .priority = _priority \ } +struct omap_domain_base { + u32 pa; + void __iomem *va; +}; + /** * struct omap_prcm_init_data - PRCM driver init data * @index: clock memory mapping index to be used * @mem: IO mem pointer for this module + * @phys: IO mem physical base address for this module * @offset: module base address offset from the IO base * @flags: PRCM module init flags * @device_inst_offset: device instance offset within the module address space @@ -539,6 +545,7 @@ struct omap_prcm_irq_setup { struct omap_prcm_init_data { int index; void __iomem *mem; + u32 phys; s16 offset; u16 flags; s32 device_inst_offset; diff --git a/arch/arm/mach-omap2/prcm_mpu44xx.c b/arch/arm/mach-omap2/prcm_mpu44xx.c index cdbee6326d29..9c782f5c3f94 100644 --- a/arch/arm/mach-omap2/prcm_mpu44xx.c +++ b/arch/arm/mach-omap2/prcm_mpu44xx.c @@ -24,7 +24,7 @@ * prcm_mpu_base: the virtual address of the start of the PRCM_MPU IP * block registers */ -void __iomem *prcm_mpu_base; +struct omap_domain_base prcm_mpu_base; /* PRCM_MPU low-level functions */ @@ -58,5 +58,5 @@ u32 omap4_prcm_mpu_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg) */ void __init omap2_set_globals_prcm_mpu(void __iomem *prcm_mpu) { - prcm_mpu_base = prcm_mpu; + prcm_mpu_base.va = prcm_mpu; } diff --git a/arch/arm/mach-omap2/prcm_mpu_44xx_54xx.h b/arch/arm/mach-omap2/prcm_mpu_44xx_54xx.h index ca149e70bed0..f565f7f73175 100644 --- a/arch/arm/mach-omap2/prcm_mpu_44xx_54xx.h +++ b/arch/arm/mach-omap2/prcm_mpu_44xx_54xx.h @@ -24,7 +24,9 @@ #define __ARCH_ARM_MACH_OMAP2_PRCM_MPU_44XX_54XX_H #ifndef __ASSEMBLER__ -extern void __iomem *prcm_mpu_base; +#include "prcm-common.h" + +extern struct omap_domain_base prcm_mpu_base; extern u32 omap4_prcm_mpu_read_inst_reg(s16 inst, u16 idx); extern void omap4_prcm_mpu_write_inst_reg(u32 val, s16 inst, u16 idx); diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h index 233bc84fbc0e..94dc3565add8 100644 --- a/arch/arm/mach-omap2/prm.h +++ b/arch/arm/mach-omap2/prm.h @@ -16,7 +16,7 @@ #include "prcm-common.h" # ifndef __ASSEMBLER__ -extern void __iomem *prm_base; +extern struct omap_domain_base prm_base; extern u16 prm_features; extern void omap2_set_globals_prm(void __iomem *prm); int omap_prcm_init(void); diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h index f57e29b0e041..6775e10883fb 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.h +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h @@ -55,12 +55,12 @@ /* Power/reset management domain register get/set */ static inline u32 omap2_prm_read_mod_reg(s16 module, u16 idx) { - return readl_relaxed(prm_base + module + idx); + return readl_relaxed(prm_base.va + module + idx); } static inline void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx) { - writel_relaxed(val, prm_base + module + idx); + writel_relaxed(val, prm_base.va + module + idx); } /* Read-modify-write a register in a PRM module. Caller must lock */ diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c index dcb5001d77da..d2c5bcabdbeb 100644 --- a/arch/arm/mach-omap2/prm33xx.c +++ b/arch/arm/mach-omap2/prm33xx.c @@ -30,13 +30,13 @@ /* Read a register in a PRM instance */ static u32 am33xx_prm_read_reg(s16 inst, u16 idx) { - return readl_relaxed(prm_base + inst + idx); + return readl_relaxed(prm_base.va + inst + idx); } /* Write into a register in a PRM instance */ static void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx) { - writel_relaxed(val, prm_base + inst + idx); + writel_relaxed(val, prm_base.va + inst + idx); } /* Read-modify-write a register in PRM. Caller must lock */ diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c index 718981bb80cd..382e236fbfd9 100644 --- a/arch/arm/mach-omap2/prm3xxx.c +++ b/arch/arm/mach-omap2/prm3xxx.c @@ -676,7 +676,7 @@ static struct prm_ll_data omap3xxx_prm_ll_data = { int __init omap3xxx_prm_init(const struct omap_prcm_init_data *data) { omap2_clk_legacy_provider_init(TI_CLKM_PRM, - prm_base + OMAP3430_IVA2_MOD); + prm_base.va + OMAP3430_IVA2_MOD); if (omap3_has_io_wakeup()) prm_features |= PRM_HAS_IO_WAKEUP; @@ -690,6 +690,8 @@ static const struct of_device_id omap3_prm_dt_match_table[] = { static int omap3xxx_prm_late_init(void) { + struct device_node *np; + int irq_num; int ret; if (!(prm_features & PRM_HAS_IO_WAKEUP)) @@ -702,16 +704,11 @@ static int omap3xxx_prm_late_init(void) omap3_prcm_irq_setup.reconfigure_io_chain = omap3430_pre_es3_1_reconfigure_io_chain; - if (of_have_populated_dt()) { - struct device_node *np; - int irq_num; - - np = of_find_matching_node(NULL, omap3_prm_dt_match_table); - if (np) { - irq_num = of_irq_get(np, 0); - if (irq_num >= 0) - omap3_prcm_irq_setup.irq = irq_num; - } + np = of_find_matching_node(NULL, omap3_prm_dt_match_table); + if (np) { + irq_num = of_irq_get(np, 0); + if (irq_num >= 0) + omap3_prcm_irq_setup.irq = irq_num; } omap3xxx_prm_enable_io_wakeup(); diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index 30768003f854..87e86a4a9ead 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c @@ -91,13 +91,13 @@ static struct prm_reset_src_map omap44xx_prm_reset_src_map[] = { /* Read a register in a CM/PRM instance in the PRM module */ static u32 omap4_prm_read_inst_reg(s16 inst, u16 reg) { - return readl_relaxed(prm_base + inst + reg); + return readl_relaxed(prm_base.va + inst + reg); } /* Write into a register in a CM/PRM instance in the PRM module */ static void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg) { - writel_relaxed(val, prm_base + inst + reg); + writel_relaxed(val, prm_base.va + inst + reg); } /* Read-modify-write a register in a PRM module. Caller must lock */ @@ -337,27 +337,6 @@ static void omap44xx_prm_reconfigure_io_chain(void) } /** - * omap44xx_prm_enable_io_wakeup - enable wakeup events from I/O wakeup latches - * - * Activates the I/O wakeup event latches and allows events logged by - * those latches to signal a wakeup event to the PRCM. For I/O wakeups - * to occur, WAKEUPENABLE bits must be set in the pad mux registers, and - * omap44xx_prm_reconfigure_io_chain() must be called. No return value. - */ -static void __init omap44xx_prm_enable_io_wakeup(void) -{ - s32 inst = omap4_prmst_get_prm_dev_inst(); - - if (inst == PRM_INSTANCE_UNKNOWN) - return; - - omap4_prm_rmw_inst_reg_bits(OMAP4430_GLOBAL_WUEN_MASK, - OMAP4430_GLOBAL_WUEN_MASK, - inst, - omap4_prcm_irq_setup.pm_ctrl); -} - -/** * omap44xx_prm_read_reset_sources - return the last SoC reset source * * Return a u32 representing the last reset sources of the SoC. The @@ -689,8 +668,6 @@ struct pwrdm_ops omap4_pwrdm_operations = { .pwrdm_has_voltdm = omap4_check_vcvp, }; -static int omap44xx_prm_late_init(void); - /* * XXX document */ @@ -698,7 +675,6 @@ static struct prm_ll_data omap44xx_prm_ll_data = { .read_reset_sources = &omap44xx_prm_read_reset_sources, .was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old, .clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old, - .late_init = &omap44xx_prm_late_init, .assert_hardreset = omap4_prminst_assert_hardreset, .deassert_hardreset = omap4_prminst_deassert_hardreset, .is_hardreset_asserted = omap4_prminst_is_hardreset_asserted, @@ -735,41 +711,6 @@ int __init omap44xx_prm_init(const struct omap_prcm_init_data *data) return prm_register(&omap44xx_prm_ll_data); } -static int omap44xx_prm_late_init(void) -{ - int irq_num; - - if (!(prm_features & PRM_HAS_IO_WAKEUP)) - return 0; - - /* OMAP4+ is DT only now */ - if (!of_have_populated_dt()) - return 0; - - irq_num = of_irq_get(prm_init_data->np, 0); - /* - * Already have OMAP4 IRQ num. For all other platforms, we need - * IRQ numbers from DT - */ - if (irq_num < 0 && !(prm_init_data->flags & PRM_IRQ_DEFAULT)) { - if (irq_num == -EPROBE_DEFER) - return irq_num; - - /* Have nothing to do */ - return 0; - } - - /* Once OMAP4 DT is filled as well */ - if (irq_num >= 0) { - omap4_prcm_irq_setup.irq = irq_num; - omap4_prcm_irq_setup.xlate_irq = NULL; - } - - omap44xx_prm_enable_io_wakeup(); - - return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup); -} - static void __exit omap44xx_prm_exit(void) { prm_unregister(&omap44xx_prm_ll_data); diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index dc11841ca334..09180a59b1c9 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -66,7 +66,7 @@ static struct irq_chip_generic **prcm_irq_chips; static struct omap_prcm_irq_setup *prcm_irq_setup; /* prm_base: base virtual address of the PRM IP block */ -void __iomem *prm_base; +struct omap_domain_base prm_base; u16 prm_features; @@ -267,10 +267,9 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) { int nr_regs; u32 mask[OMAP_PRCM_MAX_NR_PENDING_REG]; - int offset, i; + int offset, i, irq; struct irq_chip_generic *gc; struct irq_chip_type *ct; - unsigned int irq; if (!irq_setup) return -EINVAL; @@ -325,7 +324,7 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) for (i = 0; i < irq_setup->nr_regs; i++) { gc = irq_alloc_generic_chip("PRCM", 1, - irq_setup->base_irq + i * 32, prm_base, + irq_setup->base_irq + i * 32, prm_base.va, handle_level_irq); if (!gc) { @@ -344,10 +343,8 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) prcm_irq_chips[i] = gc; } - if (of_have_populated_dt()) { - int irq = omap_prcm_event_to_irq("io"); - omap_pcs_legacy_init(irq, irq_setup->reconfigure_io_chain); - } + irq = omap_prcm_event_to_irq("io"); + omap_pcs_legacy_init(irq, irq_setup->reconfigure_io_chain); return 0; @@ -364,7 +361,7 @@ err: */ void __init omap2_set_globals_prm(void __iomem *prm) { - prm_base = prm; + prm_base.va = prm; } /** @@ -755,19 +752,22 @@ int __init omap2_prm_base_init(void) struct device_node *np; const struct of_device_id *match; struct omap_prcm_init_data *data; - void __iomem *mem; + struct resource res; + int ret; for_each_matching_node_and_match(np, omap_prcm_dt_match_table, &match) { data = (struct omap_prcm_init_data *)match->data; - mem = of_iomap(np, 0); - if (!mem) - return -ENOMEM; + ret = of_address_to_resource(np, 0, &res); + if (ret) + return ret; - if (data->index == TI_CLKM_PRM) - prm_base = mem + data->offset; + data->mem = ioremap(res.start, resource_size(&res)); - data->mem = mem; + if (data->index == TI_CLKM_PRM) { + prm_base.va = data->mem + data->offset; + prm_base.pa = res.start + data->offset; + } data->np = np; diff --git a/arch/arm/mach-omap2/prminst44xx.c b/arch/arm/mach-omap2/prminst44xx.c index d0b15dbafa2e..48b8127b4e99 100644 --- a/arch/arm/mach-omap2/prminst44xx.c +++ b/arch/arm/mach-omap2/prminst44xx.c @@ -29,7 +29,7 @@ #include "prcm_mpu44xx.h" #include "soc.h" -static void __iomem *_prm_bases[OMAP4_MAX_PRCM_PARTITIONS]; +static struct omap_domain_base _prm_bases[OMAP4_MAX_PRCM_PARTITIONS]; static s32 prm_dev_inst = PRM_INSTANCE_UNKNOWN; @@ -41,8 +41,10 @@ static s32 prm_dev_inst = PRM_INSTANCE_UNKNOWN; */ void omap_prm_base_init(void) { - _prm_bases[OMAP4430_PRM_PARTITION] = prm_base; - _prm_bases[OMAP4430_PRCM_MPU_PARTITION] = prcm_mpu_base; + memcpy(&_prm_bases[OMAP4430_PRM_PARTITION], &prm_base, + sizeof(prm_base)); + memcpy(&_prm_bases[OMAP4430_PRCM_MPU_PARTITION], &prcm_mpu_base, + sizeof(prcm_mpu_base)); } s32 omap4_prmst_get_prm_dev_inst(void) @@ -60,8 +62,8 @@ u32 omap4_prminst_read_inst_reg(u8 part, s16 inst, u16 idx) { BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || part == OMAP4430_INVALID_PRCM_PARTITION || - !_prm_bases[part]); - return readl_relaxed(_prm_bases[part] + inst + idx); + !_prm_bases[part].va); + return readl_relaxed(_prm_bases[part].va + inst + idx); } /* Write into a register in a PRM instance */ @@ -69,8 +71,8 @@ void omap4_prminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx) { BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || part == OMAP4430_INVALID_PRCM_PARTITION || - !_prm_bases[part]); - writel_relaxed(val, _prm_bases[part] + inst + idx); + !_prm_bases[part].va); + writel_relaxed(val, _prm_bases[part].va + inst + idx); } /* Read-modify-write a register in PRM. Caller must lock */ diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c index d7cff2632d1e..eef6935e0403 100644 --- a/arch/arm/mach-omap2/sr_device.c +++ b/arch/arm/mach-omap2/sr_device.c @@ -44,13 +44,9 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data, while (volt_data[count].volt_nominal) count++; - nvalue_table = kzalloc(sizeof(struct omap_sr_nvalue_table)*count, - GFP_KERNEL); - - if (!nvalue_table) { - pr_err("OMAP: SmartReflex: cannot allocate memory for n-value table\n"); + nvalue_table = kcalloc(count, sizeof(*nvalue_table), GFP_KERNEL); + if (!nvalue_table) return; - } for (i = 0, j = 0; i < count; i++) { u32 v; @@ -102,12 +98,9 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user) char *name = "smartreflex"; static int i; - sr_data = kzalloc(sizeof(struct omap_sr_data), GFP_KERNEL); - if (!sr_data) { - pr_err("%s: Unable to allocate memory for %s sr_data\n", - __func__, oh->name); + sr_data = kzalloc(sizeof(*sr_data), GFP_KERNEL); + if (!sr_data) return -ENOMEM; - } sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr; if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) { diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index ae4bb9fdc483..ece09c9461f7 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -68,6 +68,9 @@ static struct omap_dm_timer clkev; static struct clock_event_device clockevent_gpt; +/* Clockevent hwmod for am335x and am437x suspend */ +static struct omap_hwmod *clockevent_gpt_hwmod; + #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER static unsigned long arch_timer_freq; @@ -125,6 +128,23 @@ static int omap2_gp_timer_set_periodic(struct clock_event_device *evt) return 0; } +static void omap_clkevt_idle(struct clock_event_device *unused) +{ + if (!clockevent_gpt_hwmod) + return; + + omap_hwmod_idle(clockevent_gpt_hwmod); +} + +static void omap_clkevt_unidle(struct clock_event_device *unused) +{ + if (!clockevent_gpt_hwmod) + return; + + omap_hwmod_enable(clockevent_gpt_hwmod); + __omap_dm_timer_int_enable(&clkev, OMAP_TIMER_INT_OVERFLOW); +} + static struct clock_event_device clockevent_gpt = { .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, @@ -232,37 +252,29 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, const char **timer_name, int posted) { - char name[10]; /* 10 = sizeof("gptXX_Xck0") */ const char *oh_name = NULL; struct device_node *np; struct omap_hwmod *oh; - struct resource irq, mem; struct clk *src; int r = 0; - if (of_have_populated_dt()) { - np = omap_get_timer_dt(omap_timer_match, property); - if (!np) - return -ENODEV; + np = omap_get_timer_dt(omap_timer_match, property); + if (!np) + return -ENODEV; - of_property_read_string_index(np, "ti,hwmods", 0, &oh_name); - if (!oh_name) - return -ENODEV; + of_property_read_string_index(np, "ti,hwmods", 0, &oh_name); + if (!oh_name) + return -ENODEV; - timer->irq = irq_of_parse_and_map(np, 0); - if (!timer->irq) - return -ENXIO; + timer->irq = irq_of_parse_and_map(np, 0); + if (!timer->irq) + return -ENXIO; - timer->io_base = of_iomap(np, 0); + timer->io_base = of_iomap(np, 0); - of_node_put(np); - } else { - if (omap_dm_timer_reserve_systimer(timer->id)) - return -ENODEV; + timer->fclk = of_clk_get_by_name(np, "fck"); - sprintf(name, "timer%d", timer->id); - oh_name = name; - } + of_node_put(np); oh = omap_hwmod_lookup(oh_name); if (!oh) @@ -270,29 +282,14 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, *timer_name = oh->name; - if (!of_have_populated_dt()) { - r = omap_hwmod_get_resource_byname(oh, IORESOURCE_IRQ, NULL, - &irq); - if (r) - return -ENXIO; - timer->irq = irq.start; - - r = omap_hwmod_get_resource_byname(oh, IORESOURCE_MEM, NULL, - &mem); - if (r) - return -ENXIO; - - /* Static mapping, never released */ - timer->io_base = ioremap(mem.start, mem.end - mem.start); - } - if (!timer->io_base) return -ENXIO; omap_hwmod_setup_one(oh_name); /* After the dmtimer is using hwmod these clocks won't be needed */ - timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh)); + if (IS_ERR_OR_NULL(timer->fclk)) + timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh)); if (IS_ERR(timer->fclk)) return PTR_ERR(timer->fclk); @@ -358,6 +355,14 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, 3, /* Timer internal resynch latency */ 0xffffffff); + if (soc_is_am33xx() || soc_is_am43xx()) { + clockevent_gpt.suspend = omap_clkevt_idle; + clockevent_gpt.resume = omap_clkevt_unidle; + + clockevent_gpt_hwmod = + omap_hwmod_lookup(clockevent_gpt.name); + } + pr_info("OMAP clockevent source: %s at %lu Hz\n", clockevent_gpt.name, clkev.rate); } @@ -405,18 +410,15 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void) const char *oh_name = "counter_32k"; /* - * If device-tree is present, then search the DT blob - * to see if the 32kHz counter is supported. + * See if the 32kHz counter is supported. */ - if (of_have_populated_dt()) { - np = omap_get_timer_dt(omap_counter_match, NULL); - if (!np) - return -ENODEV; - - of_property_read_string_index(np, "ti,hwmods", 0, &oh_name); - if (!oh_name) - return -ENODEV; - } + np = omap_get_timer_dt(omap_counter_match, NULL); + if (!np) + return -ENODEV; + + of_property_read_string_index(np, "ti,hwmods", 0, &oh_name); + if (!oh_name) + return -ENODEV; /* * First check hwmod data is available for sync32k counter @@ -434,18 +436,6 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void) return ret; } - if (!of_have_populated_dt()) { - void __iomem *vbase; - - vbase = omap_hwmod_get_mpu_rt_va(oh); - - ret = omap_init_clocksource_32k(vbase); - if (ret) { - pr_warn("%s: failed to initialize counter_32k as a clocksource (%d)\n", - __func__, ret); - omap_hwmod_idle(oh); - } - } return ret; } @@ -661,96 +651,6 @@ void __init omap5_realtime_timer_init(void) #endif /* CONFIG_SOC_OMAP5 || CONFIG_SOC_DRA7XX */ /** - * omap_timer_init - build and register timer device with an - * associated timer hwmod - * @oh: timer hwmod pointer to be used to build timer device - * @user: parameter that can be passed from calling hwmod API - * - * Called by omap_hwmod_for_each_by_class to register each of the timer - * devices present in the system. The number of timer devices is known - * by parsing through the hwmod database for a given class name. At the - * end of function call memory is allocated for timer device and it is - * registered to the framework ready to be proved by the driver. - */ -static int __init omap_timer_init(struct omap_hwmod *oh, void *unused) -{ - int id; - int ret = 0; - char *name = "omap_timer"; - struct dmtimer_platform_data *pdata; - struct platform_device *pdev; - struct omap_timer_capability_dev_attr *timer_dev_attr; - - pr_debug("%s: %s\n", __func__, oh->name); - - /* on secure device, do not register secure timer */ - timer_dev_attr = oh->dev_attr; - if (omap_type() != OMAP2_DEVICE_TYPE_GP && timer_dev_attr) - if (timer_dev_attr->timer_capability == OMAP_TIMER_SECURE) - return ret; - - pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); - if (!pdata) { - pr_err("%s: No memory for [%s]\n", __func__, oh->name); - return -ENOMEM; - } - - /* - * Extract the IDs from name field in hwmod database - * and use the same for constructing ids' for the - * timer devices. In a way, we are avoiding usage of - * static variable witin the function to do the same. - * CAUTION: We have to be careful and make sure the - * name in hwmod database does not change in which case - * we might either make corresponding change here or - * switch back static variable mechanism. - */ - sscanf(oh->name, "timer%2d", &id); - - if (timer_dev_attr) - pdata->timer_capability = timer_dev_attr->timer_capability; - - pdata->timer_errata = omap_dm_timer_get_errata(); - pdata->get_context_loss_count = omap_pm_get_dev_context_loss_count; - - pdev = omap_device_build(name, id, oh, pdata, sizeof(*pdata)); - - if (IS_ERR(pdev)) { - pr_err("%s: Can't build omap_device for %s: %s.\n", - __func__, name, oh->name); - ret = -EINVAL; - } - - kfree(pdata); - - return ret; -} - -/** - * omap2_dm_timer_init - top level regular device initialization - * - * Uses dedicated hwmod api to parse through hwmod database for - * given class name and then build and register the timer device. - */ -static int __init omap2_dm_timer_init(void) -{ - int ret; - - /* If dtb is there, the devices will be created dynamically */ - if (of_have_populated_dt()) - return -ENODEV; - - ret = omap_hwmod_for_each_by_class("timer", omap_timer_init, NULL); - if (unlikely(ret)) { - pr_err("%s: device registration failed.\n", __func__); - return -EINVAL; - } - - return 0; -} -omap_arch_initcall(omap2_dm_timer_init); - -/** * omap2_override_clocksource - clocksource override with user configuration * * Allows user to override default clocksource, using kernel parameter diff --git a/arch/arm/mach-omap2/wd_timer.c b/arch/arm/mach-omap2/wd_timer.c index ff0a68cf7439..0084b6c77cf1 100644 --- a/arch/arm/mach-omap2/wd_timer.c +++ b/arch/arm/mach-omap2/wd_timer.c @@ -102,31 +102,3 @@ int omap2_wd_timer_reset(struct omap_hwmod *oh) return (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : omap2_wd_timer_disable(oh); } - -static int __init omap_init_wdt(void) -{ - int id = -1; - struct platform_device *pdev; - struct omap_hwmod *oh; - char *oh_name = "wd_timer2"; - char *dev_name = "omap_wdt"; - struct omap_wd_timer_platform_data pdata; - - if (!cpu_class_is_omap2() || of_have_populated_dt()) - return 0; - - oh = omap_hwmod_lookup(oh_name); - if (!oh) { - pr_err("Could not look up wd_timer%d hwmod\n", id); - return -EINVAL; - } - - pdata.read_reset_sources = prm_read_reset_sources; - - pdev = omap_device_build(dev_name, id, oh, &pdata, - sizeof(struct omap_wd_timer_platform_data)); - WARN(IS_ERR(pdev), "Can't build omap_device for %s:%s.\n", - dev_name, oh->name); - return 0; -} -omap_subsys_initcall(omap_init_wdt); diff --git a/arch/arm/mach-prima2/Kconfig b/arch/arm/mach-prima2/Kconfig index 85e874a97337..7426211bddaf 100644 --- a/arch/arm/mach-prima2/Kconfig +++ b/arch/arm/mach-prima2/Kconfig @@ -27,7 +27,6 @@ config ARCH_ATLAS7 bool "CSR SiRFSoC ATLAS7 ARM Cortex A7 Platform" default y select ARM_GIC - select CPU_V7 select ATLAS7_TIMER select HAVE_ARM_SCU if SMP select HAVE_SMP diff --git a/arch/arm/mach-pxa/include/mach/magician.h b/arch/arm/mach-pxa/include/mach/magician.h index 5f6b850ebe33..c48b54d0f331 100644 --- a/arch/arm/mach-pxa/include/mach/magician.h +++ b/arch/arm/mach-pxa/include/mach/magician.h @@ -24,6 +24,7 @@ #define GPIO10_MAGICIAN_GSM_IRQ 10 #define GPIO11_MAGICIAN_GSM_OUT1 11 #define GPIO13_MAGICIAN_CPLD_IRQ 13 +#define GPIO14_MAGICIAN_TSC2046_CS 14 #define GPIO18_MAGICIAN_UNKNOWN 18 #define GPIO22_MAGICIAN_VIBRA_EN 22 #define GPIO26_MAGICIAN_GSM_POWER 26 diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index b413e36506af..7f3566c93733 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -54,6 +54,10 @@ #include "devices.h" #include "generic.h" +#include <linux/spi/spi.h> +#include <linux/spi/pxa2xx_spi.h> +#include <linux/spi/ads7846.h> + static unsigned long magician_pin_config[] __initdata = { /* SDRAM and Static Memory I/O Signals */ @@ -85,7 +89,7 @@ static unsigned long magician_pin_config[] __initdata = { /* SSP 2 TSC2046 touchscreen */ GPIO19_SSP2_SCLK, - GPIO14_SSP2_SFRM, + MFP_CFG_OUT(GPIO14, AF0, DRIVE_HIGH), /* frame as GPIO */ GPIO89_SSP2_TXD, GPIO88_SSP2_RXD, @@ -675,6 +679,37 @@ static struct platform_device bq24022 = { }; /* + * fixed regulator for ads7846 + */ + +static struct regulator_consumer_supply ads7846_supply = + REGULATOR_SUPPLY("vcc", "spi2.0"); + +static struct regulator_init_data vads7846_regulator = { + .constraints = { + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &ads7846_supply, +}; + +static struct fixed_voltage_config vads7846 = { + .supply_name = "vads7846", + .microvolts = 3300000, /* probably */ + .gpio = -EINVAL, + .startup_delay = 0, + .init_data = &vads7846_regulator, +}; + +static struct platform_device vads7846_device = { + .name = "reg-fixed-voltage", + .id = -1, + .dev = { + .platform_data = &vads7846, + }, +}; + +/* * Vcore regulator MAX1587A */ @@ -852,6 +887,49 @@ static struct i2c_pxa_platform_data magician_i2c_power_info = { }; /* + * Touchscreen + */ + +static struct ads7846_platform_data ads7846_pdata = { + .model = 7846, + .x_plate_ohms = 317, + .y_plate_ohms = 500, + .pressure_max = 1023, /* with x plate ohms it will overflow 255 */ + .debounce_max = 3, /* first readout is always bad */ + .debounce_tol = 30, + .debounce_rep = 0, + .gpio_pendown = GPIO115_MAGICIAN_nPEN_IRQ, + .keep_vref_on = 1, + .wakeup = true, + .vref_delay_usecs = 100, + .penirq_recheck_delay_usecs = 100, +}; + +struct pxa2xx_spi_chip tsc2046_chip_info = { + .tx_threshold = 1, + .rx_threshold = 2, + .timeout = 64, + /* NOTICE must be GPIO, incompatibility with hw PXA SPI framing */ + .gpio_cs = GPIO14_MAGICIAN_TSC2046_CS, +}; + +static struct pxa2xx_spi_master magician_spi_info = { + .num_chipselect = 1, + .enable_dma = 1, +}; + +static struct spi_board_info ads7846_spi_board_info[] __initdata = { + { + .modalias = "ads7846", + .bus_num = 2, + .max_speed_hz = 2500000, + .platform_data = &ads7846_pdata, + .controller_data = &tsc2046_chip_info, + .irq = PXA_GPIO_TO_IRQ(GPIO115_MAGICIAN_nPEN_IRQ), + }, +}; + +/* * Platform devices */ @@ -865,6 +943,7 @@ static struct platform_device *devices[] __initdata = { &power_supply, &strataflash, &leds_gpio, + &vads7846_device, }; static struct gpio magician_global_gpios[] = { @@ -922,6 +1001,9 @@ static void __init magician_init(void) } else pr_err("LCD detection: CPLD mapping failed\n"); + pxa2xx_set_spi_info(2, &magician_spi_info); + spi_register_board_info(ARRAY_AND_SIZE(ads7846_spi_board_info)); + regulator_register_always_on(0, "power", pwm_backlight_supply, ARRAY_SIZE(pwm_backlight_supply), 5000000); diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index e7450fb49d24..f2237f471750 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c @@ -107,10 +107,8 @@ static int __init pxa_pm_init(void) sleep_save = kmalloc_array(pxa_cpu_pm_fns->save_count, sizeof(*sleep_save), GFP_KERNEL); - if (!sleep_save) { - printk(KERN_ERR "failed to alloc memory for pm save\n"); + if (!sleep_save) return -ENOMEM; - } suspend_set_ops(&pxa_pm_ops); return 0; diff --git a/arch/arm/mach-pxa/pxa3xx-ulpi.c b/arch/arm/mach-pxa/pxa3xx-ulpi.c index eba595fac8ca..60cb59a7ebd1 100644 --- a/arch/arm/mach-pxa/pxa3xx-ulpi.c +++ b/arch/arm/mach-pxa/pxa3xx-ulpi.c @@ -286,11 +286,9 @@ static int pxa3xx_u2d_probe(struct platform_device *pdev) struct resource *r; int err; - u2d = kzalloc(sizeof(struct pxa3xx_u2d_ulpi), GFP_KERNEL); - if (!u2d) { - dev_err(&pdev->dev, "failed to allocate memory\n"); + u2d = kzalloc(sizeof(*u2d), GFP_KERNEL); + if (!u2d) return -ENOMEM; - } u2d->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(u2d->clk)) { diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c index 5ab834ebcb49..e41cabc4dc2b 100644 --- a/arch/arm/mach-rockchip/rockchip.c +++ b/arch/arm/mach-rockchip/rockchip.c @@ -70,6 +70,7 @@ static const char * const rockchip_board_dt_compat[] = { "rockchip,rk3188", "rockchip,rk3228", "rockchip,rk3288", + "rockchip,rv1108", NULL, }; diff --git a/arch/arm/mach-s3c64xx/Kconfig b/arch/arm/mach-s3c64xx/Kconfig index 71a49343d711..afd1f20be49e 100644 --- a/arch/arm/mach-s3c64xx/Kconfig +++ b/arch/arm/mach-s3c64xx/Kconfig @@ -40,7 +40,6 @@ config CPU_S3C6410 config S3C64XX_PL080 def_bool DMADEVICES - select ARM_AMBA select AMBA_PL08X config S3C64XX_SETUP_SDHCI diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c index 45a195501b78..699429f28b73 100644 --- a/arch/arm/mach-shmobile/pm-rmobile.c +++ b/arch/arm/mach-shmobile/pm-rmobile.c @@ -130,7 +130,7 @@ static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) struct generic_pm_domain *genpd = &rmobile_pd->genpd; struct dev_power_governor *gov = rmobile_pd->gov; - genpd->flags = GENPD_FLAG_PM_CLK; + genpd->flags |= GENPD_FLAG_PM_CLK; genpd->dev_ops.active_wakeup = rmobile_pd_active_wakeup; genpd->power_off = rmobile_pd_power_down; genpd->power_on = rmobile_pd_power_up; @@ -140,14 +140,6 @@ static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) pm_genpd_init(genpd, gov ? : &simple_qos_governor, false); } -static int rmobile_pd_suspend_busy(void) -{ - /* - * This domain should not be turned off. - */ - return -EBUSY; -} - static int rmobile_pd_suspend_console(void) { /* @@ -260,8 +252,7 @@ static void __init rmobile_setup_pm_domain(struct device_node *np, * only be turned off if the CPU is not in use. */ pr_debug("PM domain %s contains CPU\n", name); - pd->gov = &pm_domain_always_on_gov; - pd->suspend = rmobile_pd_suspend_busy; + pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON; break; case PD_CONSOLE: @@ -277,8 +268,7 @@ static void __init rmobile_setup_pm_domain(struct device_node *np, * is not in use. */ pr_debug("PM domain %s contains Coresight-ETM\n", name); - pd->gov = &pm_domain_always_on_gov; - pd->suspend = rmobile_pd_suspend_busy; + pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON; break; case PD_MEMCTL: @@ -287,8 +277,7 @@ static void __init rmobile_setup_pm_domain(struct device_node *np, * should only be turned off if memory is not in use. */ pr_debug("PM domain %s contains MEMCTL\n", name); - pd->gov = &pm_domain_always_on_gov; - pd->suspend = rmobile_pd_suspend_busy; + pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON; break; case PD_NORMAL: diff --git a/arch/arm/mach-stm32/Kconfig b/arch/arm/mach-stm32/Kconfig index 2d1419eb0896..0d1889bbde58 100644 --- a/arch/arm/mach-stm32/Kconfig +++ b/arch/arm/mach-stm32/Kconfig @@ -15,6 +15,11 @@ config MACH_STM32F429 depends on ARCH_STM32 default y +config MACH_STM32F469 + bool "STMicrolectronics STM32F469" + depends on ARCH_STM32 + default y + config MACH_STM32F746 bool "STMicrolectronics STM32F746" depends on ARCH_STM32 diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index 309643fe35f9..a63eb0ffba98 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -1,5 +1,6 @@ menu "SOC (System On Chip) specific Drivers" +source "drivers/soc/actions/Kconfig" source "drivers/soc/atmel/Kconfig" source "drivers/soc/bcm/Kconfig" source "drivers/soc/fsl/Kconfig" diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index 824b44281efa..a3b27a33c309 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -2,6 +2,7 @@ # Makefile for the Linux Kernel SOC specific device drivers. # +obj-$(CONFIG_ARCH_ACTIONS) += actions/ obj-$(CONFIG_ARCH_AT91) += atmel/ obj-y += bcm/ obj-$(CONFIG_ARCH_DOVE) += dove/ diff --git a/drivers/soc/actions/Kconfig b/drivers/soc/actions/Kconfig new file mode 100644 index 000000000000..9d68b5a771c3 --- /dev/null +++ b/drivers/soc/actions/Kconfig @@ -0,0 +1,16 @@ +if ARCH_ACTIONS || COMPILE_TEST + +config OWL_PM_DOMAINS_HELPER + bool + +config OWL_PM_DOMAINS + bool "Actions Semi SPS power domains" + depends on PM + select OWL_PM_DOMAINS_HELPER + select PM_GENERIC_DOMAINS + help + Say 'y' here to enable support for Smart Power System (SPS) + power-gating on Actions Semiconductor S500 SoC. + If unsure, say 'n'. + +endif diff --git a/drivers/soc/actions/Makefile b/drivers/soc/actions/Makefile new file mode 100644 index 000000000000..1e101b06bab1 --- /dev/null +++ b/drivers/soc/actions/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_OWL_PM_DOMAINS_HELPER) += owl-sps-helper.o +obj-$(CONFIG_OWL_PM_DOMAINS) += owl-sps.o diff --git a/drivers/soc/actions/owl-sps-helper.c b/drivers/soc/actions/owl-sps-helper.c new file mode 100644 index 000000000000..9d7a2c2b44ec --- /dev/null +++ b/drivers/soc/actions/owl-sps-helper.c @@ -0,0 +1,51 @@ +/* + * Actions Semi Owl Smart Power System (SPS) shared helpers + * + * Copyright 2012 Actions Semi Inc. + * Author: Actions Semi, Inc. + * + * Copyright (c) 2017 Andreas Färber + * + * 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; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/delay.h> +#include <linux/io.h> + +#define OWL_SPS_PG_CTL 0x0 + +int owl_sps_set_pg(void __iomem *base, u32 pwr_mask, u32 ack_mask, bool enable) +{ + u32 val; + bool ack; + int timeout; + + val = readl(base + OWL_SPS_PG_CTL); + ack = val & ack_mask; + if (ack == enable) + return 0; + + if (enable) + val |= pwr_mask; + else + val &= ~pwr_mask; + + writel(val, base + OWL_SPS_PG_CTL); + + for (timeout = 5000; timeout > 0; timeout -= 50) { + val = readl(base + OWL_SPS_PG_CTL); + if ((val & ack_mask) == (enable ? ack_mask : 0)) + break; + udelay(50); + } + if (timeout <= 0) + return -ETIMEDOUT; + + udelay(10); + + return 0; +} +EXPORT_SYMBOL_GPL(owl_sps_set_pg); diff --git a/drivers/soc/actions/owl-sps.c b/drivers/soc/actions/owl-sps.c new file mode 100644 index 000000000000..875225bfa21c --- /dev/null +++ b/drivers/soc/actions/owl-sps.c @@ -0,0 +1,224 @@ +/* + * Actions Semi Owl Smart Power System (SPS) + * + * Copyright 2012 Actions Semi Inc. + * Author: Actions Semi, Inc. + * + * Copyright (c) 2017 Andreas Färber + * + * 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; either version 2 of the License, or (at your + * option) any later version. + */ + +#include <linux/of_address.h> +#include <linux/of_platform.h> +#include <linux/pm_domain.h> +#include <linux/soc/actions/owl-sps.h> +#include <dt-bindings/power/owl-s500-powergate.h> + +struct owl_sps_domain_info { + const char *name; + int pwr_bit; + int ack_bit; + unsigned int genpd_flags; +}; + +struct owl_sps_info { + unsigned num_domains; + const struct owl_sps_domain_info *domains; +}; + +struct owl_sps { + struct device *dev; + const struct owl_sps_info *info; + void __iomem *base; + struct genpd_onecell_data genpd_data; + struct generic_pm_domain *domains[]; +}; + +#define to_owl_pd(gpd) container_of(gpd, struct owl_sps_domain, genpd) + +struct owl_sps_domain { + struct generic_pm_domain genpd; + const struct owl_sps_domain_info *info; + struct owl_sps *sps; +}; + +static int owl_sps_set_power(struct owl_sps_domain *pd, bool enable) +{ + u32 pwr_mask, ack_mask; + + ack_mask = BIT(pd->info->ack_bit); + pwr_mask = BIT(pd->info->pwr_bit); + + return owl_sps_set_pg(pd->sps->base, pwr_mask, ack_mask, enable); +} + +static int owl_sps_power_on(struct generic_pm_domain *domain) +{ + struct owl_sps_domain *pd = to_owl_pd(domain); + + dev_dbg(pd->sps->dev, "%s power on", pd->info->name); + + return owl_sps_set_power(pd, true); +} + +static int owl_sps_power_off(struct generic_pm_domain *domain) +{ + struct owl_sps_domain *pd = to_owl_pd(domain); + + dev_dbg(pd->sps->dev, "%s power off", pd->info->name); + + return owl_sps_set_power(pd, false); +} + +static int owl_sps_init_domain(struct owl_sps *sps, int index) +{ + struct owl_sps_domain *pd; + + pd = devm_kzalloc(sps->dev, sizeof(*pd), GFP_KERNEL); + if (!pd) + return -ENOMEM; + + pd->info = &sps->info->domains[index]; + pd->sps = sps; + + pd->genpd.name = pd->info->name; + pd->genpd.power_on = owl_sps_power_on; + pd->genpd.power_off = owl_sps_power_off; + pd->genpd.flags = pd->info->genpd_flags; + pm_genpd_init(&pd->genpd, NULL, false); + + sps->genpd_data.domains[index] = &pd->genpd; + + return 0; +} + +static int owl_sps_probe(struct platform_device *pdev) +{ + const struct of_device_id *match; + const struct owl_sps_info *sps_info; + struct owl_sps *sps; + int i, ret; + + if (!pdev->dev.of_node) { + dev_err(&pdev->dev, "no device node\n"); + return -ENODEV; + } + + match = of_match_device(pdev->dev.driver->of_match_table, &pdev->dev); + if (!match || !match->data) { + dev_err(&pdev->dev, "unknown compatible or missing data\n"); + return -EINVAL; + } + + sps_info = match->data; + + sps = devm_kzalloc(&pdev->dev, sizeof(*sps) + + sps_info->num_domains * sizeof(sps->domains[0]), + GFP_KERNEL); + if (!sps) + return -ENOMEM; + + sps->base = of_io_request_and_map(pdev->dev.of_node, 0, "owl-sps"); + if (IS_ERR(sps->base)) { + dev_err(&pdev->dev, "failed to map sps registers\n"); + return PTR_ERR(sps->base); + } + + sps->dev = &pdev->dev; + sps->info = sps_info; + sps->genpd_data.domains = sps->domains; + sps->genpd_data.num_domains = sps_info->num_domains; + + for (i = 0; i < sps_info->num_domains; i++) { + ret = owl_sps_init_domain(sps, i); + if (ret) + return ret; + } + + ret = of_genpd_add_provider_onecell(pdev->dev.of_node, &sps->genpd_data); + if (ret) { + dev_err(&pdev->dev, "failed to add provider (%d)", ret); + return ret; + } + + return 0; +} + +static const struct owl_sps_domain_info s500_sps_domains[] = { + [S500_PD_VDE] = { + .name = "VDE", + .pwr_bit = 0, + .ack_bit = 16, + }, + [S500_PD_VCE_SI] = { + .name = "VCE_SI", + .pwr_bit = 1, + .ack_bit = 17, + }, + [S500_PD_USB2_1] = { + .name = "USB2_1", + .pwr_bit = 2, + .ack_bit = 18, + }, + [S500_PD_CPU2] = { + .name = "CPU2", + .pwr_bit = 5, + .ack_bit = 21, + .genpd_flags = GENPD_FLAG_ALWAYS_ON, + }, + [S500_PD_CPU3] = { + .name = "CPU3", + .pwr_bit = 6, + .ack_bit = 22, + .genpd_flags = GENPD_FLAG_ALWAYS_ON, + }, + [S500_PD_DMA] = { + .name = "DMA", + .pwr_bit = 8, + .ack_bit = 12, + }, + [S500_PD_DS] = { + .name = "DS", + .pwr_bit = 9, + .ack_bit = 13, + }, + [S500_PD_USB3] = { + .name = "USB3", + .pwr_bit = 10, + .ack_bit = 14, + }, + [S500_PD_USB2_0] = { + .name = "USB2_0", + .pwr_bit = 11, + .ack_bit = 15, + }, +}; + +static const struct owl_sps_info s500_sps_info = { + .num_domains = ARRAY_SIZE(s500_sps_domains), + .domains = s500_sps_domains, +}; + +static const struct of_device_id owl_sps_of_matches[] = { + { .compatible = "actions,s500-sps", .data = &s500_sps_info }, + { } +}; + +static struct platform_driver owl_sps_platform_driver = { + .probe = owl_sps_probe, + .driver = { + .name = "owl-sps", + .of_match_table = owl_sps_of_matches, + .suppress_bind_attrs = true, + }, +}; + +static int __init owl_sps_init(void) +{ + return platform_driver_register(&owl_sps_platform_driver); +} +postcore_initcall(owl_sps_init); diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c index 4790094b498e..c1363c83c352 100644 --- a/drivers/soc/atmel/soc.c +++ b/drivers/soc/atmel/soc.c @@ -107,6 +107,30 @@ static const struct at91_soc __initconst socs[] = { AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D44_EXID_MATCH, "sama5d44", "sama5d4"), #endif +#ifdef CONFIG_SOC_SAMV7 + AT91_SOC(SAME70Q21_CIDR_MATCH, SAME70Q21_EXID_MATCH, + "same70q21", "same7"), + AT91_SOC(SAME70Q20_CIDR_MATCH, SAME70Q20_EXID_MATCH, + "same70q20", "same7"), + AT91_SOC(SAME70Q19_CIDR_MATCH, SAME70Q19_EXID_MATCH, + "same70q19", "same7"), + AT91_SOC(SAMS70Q21_CIDR_MATCH, SAMS70Q21_EXID_MATCH, + "sams70q21", "sams7"), + AT91_SOC(SAMS70Q20_CIDR_MATCH, SAMS70Q20_EXID_MATCH, + "sams70q20", "sams7"), + AT91_SOC(SAMS70Q19_CIDR_MATCH, SAMS70Q19_EXID_MATCH, + "sams70q19", "sams7"), + AT91_SOC(SAMV71Q21_CIDR_MATCH, SAMV71Q21_EXID_MATCH, + "samv71q21", "samv7"), + AT91_SOC(SAMV71Q20_CIDR_MATCH, SAMV71Q20_EXID_MATCH, + "samv71q20", "samv7"), + AT91_SOC(SAMV71Q19_CIDR_MATCH, SAMV71Q19_EXID_MATCH, + "samv71q19", "samv7"), + AT91_SOC(SAMV70Q20_CIDR_MATCH, SAMV70Q20_EXID_MATCH, + "samv70q20", "samv7"), + AT91_SOC(SAMV70Q19_CIDR_MATCH, SAMV70Q19_EXID_MATCH, + "samv70q19", "samv7"), +#endif { /* sentinel */ }, }; diff --git a/drivers/soc/atmel/soc.h b/drivers/soc/atmel/soc.h index 228efded5085..a90bd5b0ef8f 100644 --- a/drivers/soc/atmel/soc.h +++ b/drivers/soc/atmel/soc.h @@ -88,4 +88,30 @@ at91_soc_init(const struct at91_soc *socs); #define SAMA5D43_EXID_MATCH 0x00000003 #define SAMA5D44_EXID_MATCH 0x00000004 +#define SAME70Q21_CIDR_MATCH 0x21020e00 +#define SAME70Q21_EXID_MATCH 0x00000002 +#define SAME70Q20_CIDR_MATCH 0x21020c00 +#define SAME70Q20_EXID_MATCH 0x00000002 +#define SAME70Q19_CIDR_MATCH 0x210d0a00 +#define SAME70Q19_EXID_MATCH 0x00000002 + +#define SAMS70Q21_CIDR_MATCH 0x21120e00 +#define SAMS70Q21_EXID_MATCH 0x00000002 +#define SAMS70Q20_CIDR_MATCH 0x21120c00 +#define SAMS70Q20_EXID_MATCH 0x00000002 +#define SAMS70Q19_CIDR_MATCH 0x211d0a00 +#define SAMS70Q19_EXID_MATCH 0x00000002 + +#define SAMV71Q21_CIDR_MATCH 0x21220e00 +#define SAMV71Q21_EXID_MATCH 0x00000002 +#define SAMV71Q20_CIDR_MATCH 0x21220c00 +#define SAMV71Q20_EXID_MATCH 0x00000002 +#define SAMV71Q19_CIDR_MATCH 0x212d0a00 +#define SAMV71Q19_EXID_MATCH 0x00000002 + +#define SAMV70Q20_CIDR_MATCH 0x21320c00 +#define SAMV70Q20_EXID_MATCH 0x00000002 +#define SAMV70Q19_CIDR_MATCH 0x213d0a00 +#define SAMV70Q19_EXID_MATCH 0x00000002 + #endif /* __AT91_SOC_H */ diff --git a/include/dt-bindings/power/owl-s500-powergate.h b/include/dt-bindings/power/owl-s500-powergate.h new file mode 100644 index 000000000000..0a1c451865ea --- /dev/null +++ b/include/dt-bindings/power/owl-s500-powergate.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2017 Andreas Färber + * + * SPDX-License-Identifier: (GPL-2.0+ OR MIT) + */ +#ifndef DT_BINDINGS_POWER_OWL_S500_POWERGATE_H +#define DT_BINDINGS_POWER_OWL_S500_POWERGATE_H + +#define S500_PD_VDE 0 +#define S500_PD_VCE_SI 1 +#define S500_PD_USB2_1 2 +#define S500_PD_CPU2 3 +#define S500_PD_CPU3 4 +#define S500_PD_DMA 5 +#define S500_PD_DS 6 +#define S500_PD_USB3 7 +#define S500_PD_USB2_0 8 + +#endif diff --git a/include/linux/platform_data/atmel.h b/include/linux/platform_data/atmel.h index d36bc8d17e97..cdceb4d4ef9d 100644 --- a/include/linux/platform_data/atmel.h +++ b/include/linux/platform_data/atmel.h @@ -7,9 +7,6 @@ #ifndef __ATMEL_H__ #define __ATMEL_H__ -#include <linux/mtd/nand.h> -#include <linux/mtd/partitions.h> - /* Compact Flash */ struct at91_cf_data { int irq_pin; /* I/O IRQ */ @@ -22,26 +19,14 @@ struct at91_cf_data { #define AT91_IDE_SWAP_A0_A2 0x02 }; - /* NAND / SmartMedia */ -struct atmel_nand_data { - int enable_pin; /* chip enable */ - int det_pin; /* card detect */ - int rdy_pin; /* ready/busy */ - u8 rdy_pin_active_low; /* rdy_pin value is inverted */ - u8 ale; /* address line number connected to ALE */ - u8 cle; /* address line number connected to CLE */ - u8 bus_width_16; /* buswidth is 16 bit */ - u8 ecc_mode; /* ecc mode */ - u8 on_flash_bbt; /* bbt on flash */ - struct mtd_partition *parts; - unsigned int num_parts; - bool has_dma; /* support dma transfer */ - - /* default is false, only for at32ap7000 chip is true */ - bool need_reset_workaround; -}; - /* FIXME: this needs a better location, but gets stuff building again */ +#ifdef CONFIG_ATMEL_PM extern int at91_suspend_entering_slow_clock(void); +#else +static inline int at91_suspend_entering_slow_clock(void) +{ + return 0; +} +#endif #endif /* __ATMEL_H__ */ diff --git a/include/linux/soc/actions/owl-sps.h b/include/linux/soc/actions/owl-sps.h new file mode 100644 index 000000000000..33d0dbeceb55 --- /dev/null +++ b/include/linux/soc/actions/owl-sps.h @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2017 Andreas Färber + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef SOC_ACTIONS_OWL_SPS_H +#define SOC_ACTIONS_OWL_SPS_H + +int owl_sps_set_pg(void __iomem *base, u32 pwr_mask, u32 ack_mask, bool enable); + +#endif |