Commit 8ca302e9 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc

Pull ARM SoC platform updates from Arnd Bergmann:
 "SoC platform changes (arch/arm/mach-*). This merge window, the bulk is
  for a few platforms:

   - Andres Färber adds initial support for the Actions Semi S500 (aka
     'owl') platform, a close relative of the S900 platform he adds for
     arm64.

   - in mach-omap2, we remove more legacy code

   - Rockchips gains support for the RV1108 SoC designed for camera
     applications.

   - For Atmel, we gain support for MMU-less SoCs (SAME70/V71/S70/V70)

   - Minor updates for other platforms, including davinci, s3c64xx,
     prima2, stm32, broadcom nsp, amlogic, pxa, imx and renesas"

* tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (74 commits)
  ARM: owl: smp: Drop bogus holding pen
  ARM: owl: Drop custom machine
  ARM: owl: smp: Implement SPS power-gating for CPU2 and CPU3
  soc: actions: owl-sps: Factor out owl_sps_set_pg() for power-gating
  soc: actions: Add Owl SPS
  dt-bindings: power: Add Owl SPS power domains
  MAINTAINERS: Update Actions Semi section with SPS
  ARM: owl: Implement CPU enable-method for S500
  MAINTAINERS: Add Actions Semi Owl section
  ARM: Prepare Actions Semi S500
  ARM: socfpga: Increase max number of GPIOs
  ARM: stm32: Introduce MACH_STM32F469 flag
  ARM: prima2: remove redundant select CPU_V7
  ARM: davinci: fix const warnings
  ARM: shmobile: pm-rmobile: Use GENPD_FLAG_ALWAYS_ON
  ARM: OMAP4: hwmod_data: add SHAM crypto accelerator
  ARM: OMAP4: hwmod data: add des
  ARM: OMAP4: hwmod data: add aes2
  ARM: OMAP4: hwmod data: add aes1
  ARM: pxa: Delete an error message for a failed memory allocation in pxa3xx_u2d_probe()
  ...
parents 612341bd 18cfd942
...@@ -16,7 +16,7 @@ git branches/tags and email subject always contain this "at91" sub-string. ...@@ -16,7 +16,7 @@ git branches/tags and email subject always contain this "at91" sub-string.
AT91 SoCs 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. the Atmel website: http://www.atmel.com.
Flavors: Flavors:
...@@ -101,6 +101,42 @@ the Atmel website: http://www.atmel.com. ...@@ -101,6 +101,42 @@ the Atmel website: http://www.atmel.com.
+ Datasheet + Datasheet
http://www.atmel.com/Images/Atmel-11267-32-bit-Cortex-A5-Microcontroller-SAMA5D2_Datasheet.pdf 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 Linux kernel information
------------------------ ------------------------
......
...@@ -41,6 +41,36 @@ compatible: must be one of: ...@@ -41,6 +41,36 @@ compatible: must be one of:
- "atmel,sama5d43" - "atmel,sama5d43"
- "atmel,sama5d44" - "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: Chipid required properties:
- compatible: Should be "atmel,sama5d2-chipid" - compatible: Should be "atmel,sama5d2-chipid"
- reg : Should contain registers location and length - reg : Should contain registers location and length
......
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>;
};
...@@ -1036,6 +1036,22 @@ S: Maintained ...@@ -1036,6 +1036,22 @@ S: Maintained
F: drivers/amba/ F: drivers/amba/
F: include/linux/amba/bus.h 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 ARM/ADS SPHERE MACHINE SUPPORT
M: Lennert Buytenhek <kernel@wantstofly.org> M: Lennert Buytenhek <kernel@wantstofly.org>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
......
...@@ -712,6 +712,8 @@ config ARCH_VIRT ...@@ -712,6 +712,8 @@ config ARCH_VIRT
# #
source "arch/arm/mach-mvebu/Kconfig" source "arch/arm/mach-mvebu/Kconfig"
source "arch/arm/mach-actions/Kconfig"
source "arch/arm/mach-alpine/Kconfig" source "arch/arm/mach-alpine/Kconfig"
source "arch/arm/mach-artpec/Kconfig" source "arch/arm/mach-artpec/Kconfig"
...@@ -1462,6 +1464,7 @@ config ARM_PSCI ...@@ -1462,6 +1464,7 @@ config ARM_PSCI
# selected platforms. # selected platforms.
config ARCH_NR_GPIO config ARCH_NR_GPIO
int int
default 2048 if ARCH_SOCFPGA
default 1024 if ARCH_BRCMSTB || ARCH_SHMOBILE || ARCH_TEGRA || \ default 1024 if ARCH_BRCMSTB || ARCH_SHMOBILE || ARCH_TEGRA || \
ARCH_ZYNQ ARCH_ZYNQ
default 512 if ARCH_EXYNOS || ARCH_KEYSTONE || SOC_OMAP5 || \ default 512 if ARCH_EXYNOS || ARCH_KEYSTONE || SOC_OMAP5 || \
......
...@@ -145,6 +145,15 @@ choice ...@@ -145,6 +145,15 @@ choice
Say Y here if you want kernel low-level debugging support Say Y here if you want kernel low-level debugging support
on the USART3 port of sama5d4. 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 config DEBUG_BCM2835
bool "Kernel low-level debugging on BCM2835 PL011 UART" bool "Kernel low-level debugging on BCM2835 PL011 UART"
depends on ARCH_BCM2835 && ARCH_MULTI_V6 depends on ARCH_BCM2835 && ARCH_MULTI_V6
...@@ -751,6 +760,7 @@ choice ...@@ -751,6 +760,7 @@ choice
ARCH DEBUG_UART_PHYS DEBUG_UART_VIRT ARCH DEBUG_UART_PHYS DEBUG_UART_VIRT
APQ8064 0x16640000 0xf0040000 APQ8064 0x16640000 0xf0040000
APQ8084 0xf995e000 0xfa75e000 APQ8084 0xf995e000 0xfa75e000
IPQ4019 0x078af000 0xf78af000
MSM8X60 0x19c40000 0xf0040000 MSM8X60 0x19c40000 0xf0040000
MSM8960 0x16440000 0xf0040000 MSM8960 0x16440000 0xf0040000
MSM8974 0xf991e000 0xfa71e000 MSM8974 0xf991e000 0xfa71e000
...@@ -776,6 +786,30 @@ choice ...@@ -776,6 +786,30 @@ choice
their output to the standard serial port on the RealView their output to the standard serial port on the RealView
PB1176 platform. 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 config DEBUG_RK29_UART0
bool "Kernel low-level debugging messages via Rockchip RK29 UART0" bool "Kernel low-level debugging messages via Rockchip RK29 UART0"
depends on ARCH_ROCKCHIP depends on ARCH_ROCKCHIP
...@@ -1465,6 +1499,9 @@ config DEBUG_UART_PHYS ...@@ -1465,6 +1499,9 @@ config DEBUG_UART_PHYS
default 0x10126000 if DEBUG_RK3X_UART1 default 0x10126000 if DEBUG_RK3X_UART1
default 0x101f1000 if DEBUG_VERSATILE default 0x101f1000 if DEBUG_VERSATILE
default 0x101fb000 if DEBUG_NOMADIK_UART 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 0x11002000 if DEBUG_MT8127_UART0
default 0x11006000 if DEBUG_MT6589_UART0 default 0x11006000 if DEBUG_MT6589_UART0
default 0x11009000 if DEBUG_MT8135_UART3 default 0x11009000 if DEBUG_MT8135_UART3
...@@ -1481,6 +1518,7 @@ config DEBUG_UART_PHYS ...@@ -1481,6 +1518,7 @@ config DEBUG_UART_PHYS
default 0x3f201000 if DEBUG_BCM2836 default 0x3f201000 if DEBUG_BCM2836
default 0x3e000000 if DEBUG_BCM_KONA_UART default 0x3e000000 if DEBUG_BCM_KONA_UART
default 0x4000e400 if DEBUG_LL_UART_EFM32 default 0x4000e400 if DEBUG_LL_UART_EFM32
default 0x40028000 if DEBUG_AT91_SAMV7_USART1
default 0x40081000 if DEBUG_LPC18XX_UART0 default 0x40081000 if DEBUG_LPC18XX_UART0
default 0x40090000 if DEBUG_LPC32XX default 0x40090000 if DEBUG_LPC32XX
default 0x40100000 if DEBUG_PXA_UART1 default 0x40100000 if DEBUG_PXA_UART1
...@@ -1563,6 +1601,9 @@ config DEBUG_UART_PHYS ...@@ -1563,6 +1601,9 @@ config DEBUG_UART_PHYS
config DEBUG_UART_VIRT config DEBUG_UART_VIRT
hex "Virtual base address of debug UART" 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 0xe0000a00 if DEBUG_NETX_UART
default 0xe0010fe0 if ARCH_RPC default 0xe0010fe0 if ARCH_RPC
default 0xf0000be0 if ARCH_EBSA110 default 0xf0000be0 if ARCH_EBSA110
......
...@@ -151,6 +151,7 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000 ...@@ -151,6 +151,7 @@ textofs-$(CONFIG_ARCH_AXXIA) := 0x00308000
# Machine directory name. This list is sorted alphanumerically # Machine directory name. This list is sorted alphanumerically
# by CONFIG_* macro name. # by CONFIG_* macro name.
machine-$(CONFIG_ARCH_ACTIONS) += actions
machine-$(CONFIG_ARCH_ALPINE) += alpine machine-$(CONFIG_ARCH_ALPINE) += alpine
machine-$(CONFIG_ARCH_ARTPEC) += artpec machine-$(CONFIG_ARCH_ARTPEC) += artpec
machine-$(CONFIG_ARCH_AT91) += at91 machine-$(CONFIG_ARCH_AT91) += at91
......
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.
obj-${CONFIG_SMP} += platsmp.o headsmp.o
AFLAGS_headsmp.o := -Wa,-march=armv7-a
/*
* 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
/*
* 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);
menuconfig ARCH_AT91 menuconfig ARCH_AT91
bool "Atmel SoCs" 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 ARM_CPU_SUSPEND if PM
select COMMON_CLK_AT91 select COMMON_CLK_AT91
select GPIOLIB select GPIOLIB
...@@ -8,6 +8,14 @@ menuconfig ARCH_AT91 ...@@ -8,6 +8,14 @@ menuconfig ARCH_AT91
select SOC_BUS select SOC_BUS
if ARCH_AT91 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 config SOC_SAMA5D2
bool "SAMA5D2 family" bool "SAMA5D2 family"
depends on ARCH_MULTI_V7 depends on ARCH_MULTI_V7
...@@ -53,6 +61,7 @@ config SOC_AT91RM9200 ...@@ -53,6 +61,7 @@ config SOC_AT91RM9200
bool "AT91RM9200" bool "AT91RM9200"
depends on ARCH_MULTI_V4T depends on ARCH_MULTI_V4T
select ATMEL_AIC_IRQ select ATMEL_AIC_IRQ
select ATMEL_PM if PM
select ATMEL_ST select ATMEL_ST
select CPU_ARM920T select CPU_ARM920T
select HAVE_AT91_USB_CLK select HAVE_AT91_USB_CLK
...@@ -66,6 +75,7 @@ config SOC_AT91SAM9 ...@@ -66,6 +75,7 @@ config SOC_AT91SAM9
bool "AT91SAM9" bool "AT91SAM9"
depends on ARCH_MULTI_V5 depends on ARCH_MULTI_V5
select ATMEL_AIC_IRQ select ATMEL_AIC_IRQ
select ATMEL_PM if PM
select ATMEL_SDRAMC select ATMEL_SDRAMC
select CPU_ARM926T select CPU_ARM926T
select HAVE_AT91_SMD select HAVE_AT91_SMD
...@@ -124,9 +134,13 @@ config SOC_SAM_V7 ...@@ -124,9 +134,13 @@ config SOC_SAM_V7
config SOC_SAMA5 config SOC_SAMA5
bool bool
select ATMEL_AIC5_IRQ select ATMEL_AIC5_IRQ
select ATMEL_PM if PM
select ATMEL_SDRAMC select ATMEL_SDRAMC
select MEMORY select MEMORY
select SOC_SAM_V7 select SOC_SAM_V7
select SRAM if PM select SRAM if PM
config ATMEL_PM
bool
endif endif
...@@ -6,10 +6,10 @@ ...@@ -6,10 +6,10 @@
obj-$(CONFIG_SOC_AT91RM9200) += at91rm9200.o obj-$(CONFIG_SOC_AT91RM9200) += at91rm9200.o
obj-$(CONFIG_SOC_AT91SAM9) += at91sam9.o obj-$(CONFIG_SOC_AT91SAM9) += at91sam9.o
obj-$(CONFIG_SOC_SAMA5) += sama5.o obj-$(CONFIG_SOC_SAMA5) += sama5.o
obj-$(CONFIG_SOC_SAMV7) += samv7.o
# Power Management # Power Management
obj-$(CONFIG_PM) += pm.o obj-$(CONFIG_ATMEL_PM) += pm.o pm_suspend.o
obj-$(CONFIG_PM) += pm_suspend.o
ifeq ($(CONFIG_CPU_V7),y) ifeq ($(CONFIG_CPU_V7),y)
AFLAGS_pm_suspend.o := -march=armv7-a AFLAGS_pm_suspend.o := -march=armv7-a
......
# 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 .
...@@ -15,10 +15,12 @@ ...@@ -15,10 +15,12 @@
extern void __init at91rm9200_pm_init(void); extern void __init at91rm9200_pm_init(void);
extern void __init at91sam9_pm_init(void); extern void __init at91sam9_pm_init(void);
extern void __init sama5_pm_init(void); extern void __init sama5_pm_init(void);
extern void __init sama5d2_pm_init(void);
#else #else
static inline void __init at91rm9200_pm_init(void) { } static inline void __init at91rm9200_pm_init(void) { }
static inline void __init at91sam9_pm_init(void) { } static inline void __init at91sam9_pm_init(void) { }
static inline void __init sama5_pm_init(void) { } static inline void __init sama5_pm_init(void) { }
static inline void __init sama5d2_pm_init(void) { }
#endif #endif
#endif /* _AT91_GENERIC_H */ #endif /* _AT91_GENERIC_H */
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/parser.h>
#include <linux/suspend.h> #include <linux/suspend.h>
#include <linux/clk/at91_pmc.h> #include <linux/clk/at91_pmc.h>
...@@ -22,6 +23,7 @@ ...@@ -22,6 +23,7 @@
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
#include <asm/fncpy.h> #include <asm/fncpy.h>
#include <asm/system_misc.h> #include <asm/system_misc.h>
#include <asm/suspend.h>
#include "generic.h" #include "generic.h"
#include "pm.h" #include "pm.h"
...@@ -37,7 +39,17 @@ extern void at91_pinctrl_gpio_suspend(void); ...@@ -37,7 +39,17 @@ extern void at91_pinctrl_gpio_suspend(void);
extern void at91_pinctrl_gpio_resume(void); extern void at91_pinctrl_gpio_resume(void);
#endif #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) \ #define at91_ramc_read(id, field) \
__raw_readl(pm_data.ramc[id] + field) __raw_readl(pm_data.ramc[id] + field)
...@@ -58,15 +70,33 @@ static int at91_pm_valid_state(suspend_state_t state) ...@@ -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. * Called after processes are frozen, but before we shutdown devices.
*/ */
static int at91_pm_begin(suspend_state_t state) 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; return 0;
} }
...@@ -115,7 +145,7 @@ static int at91_pm_verify_clocks(void) ...@@ -115,7 +145,7 @@ static int at91_pm_verify_clocks(void)
*/ */
int at91_suspend_entering_slow_clock(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); EXPORT_SYMBOL(at91_suspend_entering_slow_clock);
...@@ -123,50 +153,65 @@ static void (*at91_suspend_sram_fn)(struct at91_pm_data *); ...@@ -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 void at91_pm_suspend_in_sram(struct at91_pm_data *pm_data);
extern u32 at91_pm_suspend_in_sram_sz; 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(); flush_cache_all();
outer_disable(); outer_disable();
at91_suspend_sram_fn(&pm_data); 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(); 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) static int at91_pm_enter(suspend_state_t state)
{ {
#ifdef CONFIG_PINCTRL_AT91 #ifdef CONFIG_PINCTRL_AT91
at91_pinctrl_gpio_suspend(); at91_pinctrl_gpio_suspend();
#endif #endif
switch (state) { 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_MEM:
case PM_SUSPEND_STANDBY:
/* /*
* Ensure that clocks are in a valid state. * 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; goto error;
at91_pm_suspend(state); at91_pm_suspend(state);
break; 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: case PM_SUSPEND_ON:
cpu_do_idle(); cpu_do_idle();
break; break;
...@@ -177,8 +222,6 @@ static int at91_pm_enter(suspend_state_t state) ...@@ -177,8 +222,6 @@ static int at91_pm_enter(suspend_state_t state)
} }
error: error:
target_state = PM_SUSPEND_ON;
#ifdef CONFIG_PINCTRL_AT91 #ifdef CONFIG_PINCTRL_AT91
at91_pinctrl_gpio_resume(); at91_pinctrl_gpio_resume();
#endif #endif
...@@ -190,7 +233,6 @@ static int at91_pm_enter(suspend_state_t state) ...@@ -190,7 +233,6 @@ static int at91_pm_enter(suspend_state_t state)
*/ */
static void at91_pm_end(void) static void at91_pm_end(void)
{ {
target_state = PM_SUSPEND_ON;
} }
...@@ -436,6 +478,79 @@ static void __init at91_pm_sram_init(void) ...@@ -436,6 +478,79 @@ static void __init at91_pm_sram_init(void)
&at91_pm_suspend_in_sram, at91_pm_suspend_in_sram_sz); &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 { struct pmc_info {
unsigned long uhp_udp_mask; unsigned long uhp_udp_mask;
}; };
...@@ -481,10 +596,14 @@ static void __init at91_pm_init(void (*pm_idle)(void)) ...@@ -481,10 +596,14 @@ static void __init at91_pm_init(void (*pm_idle)(void))
at91_pm_sram_init(); at91_pm_sram_init();
if (at91_suspend_sram_fn) if (at91_suspend_sram_fn) {
suspend_set_ops(&at91_pm_ops); 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"); pr_info("AT91: PM not supported, due to no SRAM allocated\n");
}
} }
void __init at91rm9200_pm_init(void) void __init at91rm9200_pm_init(void)
...@@ -510,3 +629,34 @@ void __init sama5_pm_init(void) ...@@ -510,3 +629,34 @@ void __init sama5_pm_init(void)
at91_dt_ramc(); at91_dt_ramc();
at91_pm_init(NULL); 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);
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#define AT91_MEMCTRL_DDRSDR 2 #define AT91_MEMCTRL_DDRSDR 2
#define AT91_PM_SLOW_CLOCK 0x01 #define AT91_PM_SLOW_CLOCK 0x01
#define AT91_PM_BACKUP 0x02
#ifndef __ASSEMBLY__ #ifndef __ASSEMBLY__
struct at91_pm_data { struct at91_pm_data {
...@@ -30,6 +31,10 @@ struct at91_pm_data { ...@@ -30,6 +31,10 @@ struct at91_pm_data {
unsigned long uhp_udp_mask; unsigned long uhp_udp_mask;
unsigned int memctrl; unsigned int memctrl;
unsigned int mode; unsigned int mode;
void __iomem *shdwc;
void __iomem *sfrbu;
unsigned int standby_mode;
unsigned int suspend_mode;
}; };
#endif #endif
......
...@@ -9,5 +9,8 @@ int main(void) ...@@ -9,5 +9,8 @@ int main(void)
DEFINE(PM_DATA_RAMC1, offsetof(struct at91_pm_data, ramc[1])); DEFINE(PM_DATA_RAMC1, offsetof(struct at91_pm_data, ramc[1]));
DEFINE(PM_DATA_MEMCTRL, offsetof(struct at91_pm_data, memctrl)); DEFINE(PM_DATA_MEMCTRL, offsetof(struct at91_pm_data, memctrl));
DEFINE(PM_DATA_MODE, offsetof(struct at91_pm_data, mode)); 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; return 0;
} }
...@@ -97,15 +97,61 @@ ENTRY(at91_pm_suspend_in_sram) ...@@ -97,15 +97,61 @@ ENTRY(at91_pm_suspend_in_sram)
str tmp1, .memtype str tmp1, .memtype
ldr tmp1, [r0, #PM_DATA_MODE] ldr tmp1, [r0, #PM_DATA_MODE]
str tmp1, .pm_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 */ /* Active the self-refresh mode */
mov r0, #SRAMC_SELF_FRESH_ACTIVE mov r0, #SRAMC_SELF_FRESH_ACTIVE
bl at91_sramc_self_refresh bl at91_sramc_self_refresh
ldr r0, .pm_mode ldr r0, .pm_mode
tst r0, #AT91_PM_SLOW_CLOCK cmp r0, #AT91_PM_SLOW_CLOCK
beq skip_disable_main_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 ldr pmc, .pmc_base
/* Save Master clock setting */ /* Save Master clock setting */
...@@ -134,18 +180,9 @@ ENTRY(at91_pm_suspend_in_sram) ...@@ -134,18 +180,9 @@ ENTRY(at91_pm_suspend_in_sram)
orr tmp1, tmp1, #AT91_PMC_KEY orr tmp1, tmp1, #AT91_PMC_KEY
str tmp1, [pmc, #AT91_CKGR_MOR] str tmp1, [pmc, #AT91_CKGR_MOR]
skip_disable_main_clock:
ldr pmc, .pmc_base
/* Wait for interrupt */ /* Wait for interrupt */
at91_cpu_idle 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 */ /* Turn on the main oscillator */
ldr tmp1, [pmc, #AT91_CKGR_MOR] ldr tmp1, [pmc, #AT91_CKGR_MOR]
orr tmp1, tmp1, #AT91_PMC_MOSCEN orr tmp1, tmp1, #AT91_PMC_MOSCEN
...@@ -174,14 +211,8 @@ skip_disable_main_clock: ...@@ -174,14 +211,8 @@ skip_disable_main_clock:
wait_mckrdy wait_mckrdy
skip_enable_main_clock: mov pc, lr
/* Exit the self-refresh mode */ ENDPROC(at91_slowck_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)
/* /*
* void at91_sramc_self_refresh(unsigned int is_active) * void at91_sramc_self_refresh(unsigned int is_active)
...@@ -314,6 +345,10 @@ ENDPROC(at91_sramc_self_refresh) ...@@ -314,6 +345,10 @@ ENDPROC(at91_sramc_self_refresh)
.word 0 .word 0
.sramc1_base: .sramc1_base:
.word 0 .word 0
.shdwc:
.word 0
.sfr:
.word 0
.memtype: .memtype:
.word 0 .word 0
.pm_mode: .pm_mode:
......
...@@ -34,7 +34,6 @@ DT_MACHINE_START(sama5_dt, "Atmel SAMA5") ...@@ -34,7 +34,6 @@ DT_MACHINE_START(sama5_dt, "Atmel SAMA5")
MACHINE_END MACHINE_END
static const char *const sama5_alt_dt_board_compat[] __initconst = { static const char *const sama5_alt_dt_board_compat[] __initconst = {
"atmel,sama5d2",
"atmel,sama5d4", "atmel,sama5d4",
NULL NULL
}; };
...@@ -45,3 +44,21 @@ DT_MACHINE_START(sama5_alt_dt, "Atmel SAMA5") ...@@ -45,3 +44,21 @@ DT_MACHINE_START(sama5_alt_dt, "Atmel SAMA5")
.dt_compat = sama5_alt_dt_board_compat, .dt_compat = sama5_alt_dt_board_compat,
.l2c_aux_mask = ~0UL, .l2c_aux_mask = ~0UL,
MACHINE_END 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
/*
* 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
...@@ -44,6 +44,8 @@ config ARCH_BCM_NSP ...@@ -44,6 +44,8 @@ config ARCH_BCM_NSP
select ARM_ERRATA_775420 select ARM_ERRATA_775420
select ARM_ERRATA_764369 if SMP select ARM_ERRATA_764369 if SMP
select HAVE_SMP select HAVE_SMP
select THERMAL
select THERMAL_OF
help help
Support for Broadcom Northstar Plus SoC. Support for Broadcom Northstar Plus SoC.
Broadcom Northstar Plus family of SoCs are used for switching control Broadcom Northstar Plus family of SoCs are used for switching control
......
...@@ -641,7 +641,7 @@ static struct vpif_subdev_info vpif_capture_sdev_info[] = { ...@@ -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 = { .input = {
.index = 0, .index = 0,
...@@ -656,7 +656,7 @@ static const struct vpif_input dm6467_ch0_inputs[] = { ...@@ -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 = { .input = {
.index = 0, .index = 0,
......
...@@ -789,15 +789,35 @@ int __init da850_register_mmcsd1(struct davinci_mmc_config *config) ...@@ -789,15 +789,35 @@ int __init da850_register_mmcsd1(struct davinci_mmc_config *config)
static struct resource da8xx_rproc_resources[] = { static struct resource da8xx_rproc_resources[] = {
{ /* DSP boot address */ { /* DSP boot address */
.name = "host1cfg",
.start = DA8XX_SYSCFG0_BASE + DA8XX_HOST1CFG_REG, .start = DA8XX_SYSCFG0_BASE + DA8XX_HOST1CFG_REG,
.end = DA8XX_SYSCFG0_BASE + DA8XX_HOST1CFG_REG + 3, .end = DA8XX_SYSCFG0_BASE + DA8XX_HOST1CFG_REG + 3,
.flags = IORESOURCE_MEM, .flags = IORESOURCE_MEM,
}, },
{ /* DSP interrupt registers */ { /* DSP interrupt registers */
.name = "chipsig",
.start = DA8XX_SYSCFG0_BASE + DA8XX_CHIPSIG_REG, .start = DA8XX_SYSCFG0_BASE + DA8XX_CHIPSIG_REG,
.end = DA8XX_SYSCFG0_BASE + DA8XX_CHIPSIG_REG + 7, .end = DA8XX_SYSCFG0_BASE + DA8XX_CHIPSIG_REG + 7,
.flags = IORESOURCE_MEM, .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 */ { /* dsp irq */
.start = IRQ_DA8XX_CHIPINT0, .start = IRQ_DA8XX_CHIPINT0,
.end = IRQ_DA8XX_CHIPINT0, .end = IRQ_DA8XX_CHIPINT0,
...@@ -814,6 +834,8 @@ static struct platform_device da8xx_dsp = { ...@@ -814,6 +834,8 @@ static struct platform_device da8xx_dsp = {
.resource = da8xx_rproc_resources, .resource = da8xx_rproc_resources,
}; };
static bool rproc_mem_inited __initdata;
#if IS_ENABLED(CONFIG_DA8XX_REMOTEPROC) #if IS_ENABLED(CONFIG_DA8XX_REMOTEPROC)
static phys_addr_t rproc_base __initdata; static phys_addr_t rproc_base __initdata;
...@@ -852,6 +874,8 @@ void __init da8xx_rproc_reserve_cma(void) ...@@ -852,6 +874,8 @@ void __init da8xx_rproc_reserve_cma(void)
ret = dma_declare_contiguous(&da8xx_dsp.dev, rproc_size, rproc_base, 0); ret = dma_declare_contiguous(&da8xx_dsp.dev, rproc_size, rproc_base, 0);
if (ret) if (ret)
pr_err("%s: dma_declare_contiguous failed %d\n", __func__, ret); pr_err("%s: dma_declare_contiguous failed %d\n", __func__, ret);
else
rproc_mem_inited = true;
} }
#else #else
...@@ -866,6 +890,12 @@ int __init da8xx_register_rproc(void) ...@@ -866,6 +890,12 @@ int __init da8xx_register_rproc(void)
{ {
int ret; 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); ret = platform_device_register(&da8xx_dsp);
if (ret) if (ret)
pr_err("%s: can't register DSP device: %d\n", __func__, ret); pr_err("%s: can't register DSP device: %d\n", __func__, ret);
......
...@@ -75,6 +75,11 @@ extern unsigned int da850_max_speed; ...@@ -75,6 +75,11 @@ extern unsigned int da850_max_speed;
#define DA8XX_VPIF_BASE 0x01e17000 #define DA8XX_VPIF_BASE 0x01e17000
#define DA8XX_GPIO_BASE 0x01e26000 #define DA8XX_GPIO_BASE 0x01e26000
#define DA8XX_PSC1_BASE 0x01e27000 #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_CS2_BASE 0x60000000
#define DA8XX_AEMIF_CS3_BASE 0x62000000 #define DA8XX_AEMIF_CS3_BASE 0x62000000
#define DA8XX_AEMIF_CTL_BASE 0x68000000 #define DA8XX_AEMIF_CTL_BASE 0x68000000
......
...@@ -33,7 +33,7 @@ static struct tvp514x_platform_data tvp5146_pdata = { ...@@ -33,7 +33,7 @@ static struct tvp514x_platform_data tvp5146_pdata = {
#define TVP514X_STD_ALL (V4L2_STD_NTSC | V4L2_STD_PAL) #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 = { .input = {
.index = 0, .index = 0,
...@@ -48,7 +48,7 @@ static const struct vpif_input da850_ch0_inputs[] = { ...@@ -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 = { .input = {
.index = 0, .index = 0,
......
...@@ -536,6 +536,7 @@ config SOC_IMX7D ...@@ -536,6 +536,7 @@ config SOC_IMX7D
select HAVE_IMX_ANATOP select HAVE_IMX_ANATOP
select HAVE_IMX_MMDC select HAVE_IMX_MMDC
select HAVE_IMX_SRC select HAVE_IMX_SRC
select IMX_GPCV2
help help
This enables support for Freescale i.MX7 Dual processor. This enables support for Freescale i.MX7 Dual processor.
......
...@@ -131,6 +131,9 @@ struct device * __init imx_soc_device_init(void) ...@@ -131,6 +131,9 @@ struct device * __init imx_soc_device_init(void)
case MXC_CPU_IMX6UL: case MXC_CPU_IMX6UL:
soc_id = "i.MX6UL"; soc_id = "i.MX6UL";
break; break;
case MXC_CPU_IMX6ULL:
soc_id = "i.MX6ULL";
break;
case MXC_CPU_IMX7D: case MXC_CPU_IMX7D:
soc_id = "i.MX7D"; soc_id = "i.MX7D";
break; break;
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#define MXC_CPU_IMX6SX 0x62 #define MXC_CPU_IMX6SX 0x62
#define MXC_CPU_IMX6Q 0x63 #define MXC_CPU_IMX6Q 0x63
#define MXC_CPU_IMX6UL 0x64 #define MXC_CPU_IMX6UL 0x64
#define MXC_CPU_IMX6ULL 0x65
#define MXC_CPU_IMX7D 0x72 #define MXC_CPU_IMX7D 0x72
#define IMX_DDR_TYPE_LPDDR2 1 #define IMX_DDR_TYPE_LPDDR2 1
...@@ -73,6 +74,11 @@ static inline bool cpu_is_imx6ul(void) ...@@ -73,6 +74,11 @@ static inline bool cpu_is_imx6ul(void)
return __mxc_cpu_type == MXC_CPU_IMX6UL; 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) static inline bool cpu_is_imx6q(void)
{ {
return __mxc_cpu_type == MXC_CPU_IMX6Q; return __mxc_cpu_type == MXC_CPU_IMX6Q;
......
...@@ -295,7 +295,8 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode) ...@@ -295,7 +295,8 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
val &= ~BM_CLPCR_SBYOS; val &= ~BM_CLPCR_SBYOS;
if (cpu_is_imx6sl()) if (cpu_is_imx6sl())
val |= BM_CLPCR_BYPASS_PMIC_READY; 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; val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
else else
val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS; val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
...@@ -312,7 +313,8 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode) ...@@ -312,7 +313,8 @@ int imx6_set_lpm(enum mxc_cpu_pwr_mode mode)
val |= BM_CLPCR_SBYOS; val |= BM_CLPCR_SBYOS;
if (cpu_is_imx6sl() || cpu_is_imx6sx()) if (cpu_is_imx6sl() || cpu_is_imx6sx())
val |= BM_CLPCR_BYPASS_PMIC_READY; 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; val |= BM_CLPCR_BYP_MMDC_CH0_LPM_HS;
else else
val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS; val |= BM_CLPCR_BYP_MMDC_CH1_LPM_HS;
......
...@@ -21,6 +21,7 @@ config MACH_MESON8 ...@@ -21,6 +21,7 @@ config MACH_MESON8
bool "Amlogic Meson8 SoCs support" bool "Amlogic Meson8 SoCs support"
default ARCH_MESON default ARCH_MESON
select MESON6_TIMER select MESON6_TIMER
select COMMON_CLK_MESON8B
config MACH_MESON8B config MACH_MESON8B
bool "Amlogic Meson8b SoCs support" bool "Amlogic Meson8b SoCs support"
......
...@@ -240,7 +240,6 @@ static void omap1_show_dma_caps(void) ...@@ -240,7 +240,6 @@ static void omap1_show_dma_caps(void)
w |= 1 << 3; w |= 1 << 3;
dma_write(w, GSCR, 0); dma_write(w, GSCR, 0);
} }
return;
} }
static unsigned configure_dma_errata(void) static unsigned configure_dma_errata(void)
...@@ -339,10 +338,8 @@ static int __init omap1_system_dma_init(void) ...@@ -339,10 +338,8 @@ static int __init omap1_system_dma_init(void)
goto exit_iounmap; goto exit_iounmap;
} }
d = kzalloc(sizeof(struct omap_dma_dev_attr), GFP_KERNEL); d = kzalloc(sizeof(*d), GFP_KERNEL);
if (!d) { if (!d) {
dev_err(&pdev->dev, "%s: Unable to allocate 'd' for %s\n",
__func__, pdev->name);
ret = -ENOMEM; ret = -ENOMEM;
goto exit_iounmap; goto exit_iounmap;
} }
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Contains first level initialization routines which internally * Contains first level initialization routines which internally
* generates timer device information and registers with linux * 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. * input clock source.
* *
* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
...@@ -134,8 +134,6 @@ static int __init omap1_dm_timer_init(void) ...@@ -134,8 +134,6 @@ static int __init omap1_dm_timer_init(void)
pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
if (!pdata) { if (!pdata) {
dev_err(&pdev->dev, "%s: Failed to allocate pdata.\n",
__func__);
ret = -ENOMEM; ret = -ENOMEM;
goto err_free_pdata; goto err_free_pdata;
} }
......
...@@ -69,7 +69,6 @@ obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o ...@@ -69,7 +69,6 @@ obj-$(CONFIG_ARCH_OMAP2) += sdrc2xxx.o
# OPP table initialization # OPP table initialization
ifeq ($(CONFIG_PM_OPP),y) ifeq ($(CONFIG_PM_OPP),y)
obj-y += opp.o
obj-$(CONFIG_ARCH_OMAP3) += opp3xxx_data.o obj-$(CONFIG_ARCH_OMAP3) += opp3xxx_data.o
obj-$(CONFIG_ARCH_OMAP4) += opp4xxx_data.o obj-$(CONFIG_ARCH_OMAP4) += opp4xxx_data.o
endif endif
...@@ -220,9 +219,6 @@ obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o ...@@ -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_OMAP5) += omap_hwmod_54xx_data.o
obj-$(CONFIG_SOC_DRA7XX) += omap_hwmod_7xx_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") # OMAP2420 MSDI controller integration support ("MMC")
obj-$(CONFIG_SOC_OMAP2420) += msdi.o obj-$(CONFIG_SOC_OMAP2420) += msdi.o
......
...@@ -53,14 +53,12 @@ static u32 board_caps; ...@@ -53,14 +53,12 @@ static u32 board_caps;
static void board_check_revision(void) static void board_check_revision(void)
{ {
if (of_have_populated_dt()) {
if (of_machine_is_compatible("nokia,n800")) if (of_machine_is_compatible("nokia,n800"))
board_caps = NOKIA_N800; board_caps = NOKIA_N800;
else if (of_machine_is_compatible("nokia,n810")) else if (of_machine_is_compatible("nokia,n810"))
board_caps = NOKIA_N810; board_caps = NOKIA_N810;
else if (of_machine_is_compatible("nokia,n810-wimax")) else if (of_machine_is_compatible("nokia,n810-wimax"))
board_caps = NOKIA_N810_WIMAX; board_caps = NOKIA_N810_WIMAX;
}
if (!board_caps) if (!board_caps)
pr_err("Unknown board\n"); pr_err("Unknown board\n");
......
...@@ -1224,6 +1224,14 @@ int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk) ...@@ -1224,6 +1224,14 @@ int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk)
return 0; 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_hwmod_enable - add an enabled downstream hwmod to this clkdm
* @clkdm: struct clockdomain * * @clkdm: struct clockdomain *
......
...@@ -175,6 +175,7 @@ struct clkdm_ops { ...@@ -175,6 +175,7 @@ struct clkdm_ops {
void (*clkdm_deny_idle)(struct clockdomain *clkdm); void (*clkdm_deny_idle)(struct clockdomain *clkdm);
int (*clkdm_clk_enable)(struct clockdomain *clkdm); int (*clkdm_clk_enable)(struct clockdomain *clkdm);
int (*clkdm_clk_disable)(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); int clkdm_register_platform_funcs(struct clkdm_ops *co);
...@@ -213,6 +214,7 @@ int clkdm_clk_enable(struct clockdomain *clkdm, struct clk *clk); ...@@ -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_clk_disable(struct clockdomain *clkdm, struct clk *clk);
int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh); int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh);
int clkdm_hwmod_disable(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 omap242x_clockdomains_init(void);
extern void __init omap243x_clockdomains_init(void); extern void __init omap243x_clockdomains_init(void);
......
...@@ -24,8 +24,11 @@ ...@@ -24,8 +24,11 @@
# ifndef __ASSEMBLER__ # ifndef __ASSEMBLER__
#include <linux/clk/ti.h> #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); extern void omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2);
# endif # endif
......
...@@ -52,12 +52,12 @@ ...@@ -52,12 +52,12 @@
static inline u32 omap2_cm_read_mod_reg(s16 module, u16 idx) 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) 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 */ /* Read-modify-write a register in a CM module. Caller must lock */
......
...@@ -50,13 +50,13 @@ ...@@ -50,13 +50,13 @@
/* Read a register in a CM instance */ /* Read a register in a CM instance */
static inline u32 am33xx_cm_read_reg(u16 inst, u16 idx) 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 */ /* Write into a register in a CM */
static inline void am33xx_cm_write_reg(u32 val, u16 inst, u16 idx) 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 */ /* Read-modify-write a register in CM */
......
...@@ -669,7 +669,8 @@ static struct cm_ll_data omap3xxx_cm_ll_data = { ...@@ -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) 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); return cm_register(&omap3xxx_cm_ll_data);
} }
......
...@@ -32,10 +32,10 @@ static struct cm_ll_data null_cm_ll_data; ...@@ -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; static struct cm_ll_data *cm_ll_data = &null_cm_ll_data;
/* cm_base: base virtual address of the CM IP block */ /* 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) */ /* 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_NO_CLOCKS 0x1
#define CM_SINGLE_INSTANCE 0x2 #define CM_SINGLE_INSTANCE 0x2
...@@ -49,8 +49,8 @@ void __iomem *cm2_base; ...@@ -49,8 +49,8 @@ void __iomem *cm2_base;
*/ */
void __init omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2) void __init omap2_set_globals_cm(void __iomem *cm, void __iomem *cm2)
{ {
cm_base = cm; cm_base.va = cm;
cm2_base = cm2; cm2_base.va = cm2;
} }
/** /**
...@@ -315,27 +315,34 @@ int __init omap2_cm_base_init(void) ...@@ -315,27 +315,34 @@ int __init omap2_cm_base_init(void)
struct device_node *np; struct device_node *np;
const struct of_device_id *match; const struct of_device_id *match;
struct omap_prcm_init_data *data; 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) { for_each_matching_node_and_match(np, omap_cm_dt_match_table, &match) {
data = (struct omap_prcm_init_data *)match->data; data = (struct omap_prcm_init_data *)match->data;
mem = of_iomap(np, 0); ret = of_address_to_resource(np, 0, &res);
if (!mem) if (ret)
return -ENOMEM; return ret;
if (data->index == TI_CLKM_CM) if (data->index == TI_CLKM_CM)
cm_base = mem + data->offset; mem = &cm_base;
if (data->index == TI_CLKM_CM2) if (data->index == TI_CLKM_CM2)
cm2_base = mem + data->offset; mem = &cm2_base;
data->mem = mem; data->mem = ioremap(res.start, resource_size(&res));
if (mem) {
mem->pa = res.start + data->offset;
mem->va = data->mem + data->offset;
}
data->np = np; data->np = np;
if (data->init && (data->flags & CM_SINGLE_INSTANCE || if (data->init && (data->flags & CM_SINGLE_INSTANCE ||
(cm_base && cm2_base))) (cm_base.va && cm2_base.va)))
data->init(data); data->init(data);
} }
......
...@@ -55,7 +55,7 @@ ...@@ -55,7 +55,7 @@
#define CLKCTRL_IDLEST_INTERFACE_IDLE 0x2 #define CLKCTRL_IDLEST_INTERFACE_IDLE 0x2
#define CLKCTRL_IDLEST_DISABLED 0x3 #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 * omap_cm_base_init - Populates the cm partitions
...@@ -65,10 +65,11 @@ static void __iomem *_cm_bases[OMAP4_MAX_PRCM_PARTITIONS]; ...@@ -65,10 +65,11 @@ static void __iomem *_cm_bases[OMAP4_MAX_PRCM_PARTITIONS];
*/ */
static void omap_cm_base_init(void) static void omap_cm_base_init(void)
{ {
_cm_bases[OMAP4430_PRM_PARTITION] = prm_base; memcpy(&_cm_bases[OMAP4430_PRM_PARTITION], &prm_base, sizeof(prm_base));
_cm_bases[OMAP4430_CM1_PARTITION] = cm_base; memcpy(&_cm_bases[OMAP4430_CM1_PARTITION], &cm_base, sizeof(cm_base));
_cm_bases[OMAP4430_CM2_PARTITION] = cm2_base; memcpy(&_cm_bases[OMAP4430_CM2_PARTITION], &cm2_base, sizeof(cm2_base));
_cm_bases[OMAP4430_PRCM_MPU_PARTITION] = prcm_mpu_base; memcpy(&_cm_bases[OMAP4430_PRCM_MPU_PARTITION], &prcm_mpu_base,
sizeof(prcm_mpu_base));
} }
/* Private functions */ /* Private functions */
...@@ -116,8 +117,8 @@ static u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx) ...@@ -116,8 +117,8 @@ static u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx)
{ {
BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
part == OMAP4430_INVALID_PRCM_PARTITION || part == OMAP4430_INVALID_PRCM_PARTITION ||
!_cm_bases[part]); !_cm_bases[part].va);
return readl_relaxed(_cm_bases[part] + inst + idx); return readl_relaxed(_cm_bases[part].va + inst + idx);
} }
/* Write into a register in a CM instance */ /* 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) ...@@ -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 || BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
part == OMAP4430_INVALID_PRCM_PARTITION || part == OMAP4430_INVALID_PRCM_PARTITION ||
!_cm_bases[part]); !_cm_bases[part].va);
writel_relaxed(val, _cm_bases[part] + inst + idx); writel_relaxed(val, _cm_bases[part].va + inst + idx);
} }
/* Read-modify-write a register in CM1. Caller must lock */ /* Read-modify-write a register in CM1. Caller must lock */
...@@ -475,6 +476,14 @@ static int omap4_clkdm_clk_disable(struct clockdomain *clkdm) ...@@ -475,6 +476,14 @@ static int omap4_clkdm_clk_disable(struct clockdomain *clkdm)
return 0; 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 = { struct clkdm_ops omap4_clkdm_operations = {
.clkdm_add_wkdep = omap4_clkdm_add_wkup_sleep_dep, .clkdm_add_wkdep = omap4_clkdm_add_wkup_sleep_dep,
.clkdm_del_wkdep = omap4_clkdm_del_wkup_sleep_dep, .clkdm_del_wkdep = omap4_clkdm_del_wkup_sleep_dep,
...@@ -490,6 +499,7 @@ struct clkdm_ops omap4_clkdm_operations = { ...@@ -490,6 +499,7 @@ struct clkdm_ops omap4_clkdm_operations = {
.clkdm_deny_idle = omap4_clkdm_deny_idle, .clkdm_deny_idle = omap4_clkdm_deny_idle,
.clkdm_clk_enable = omap4_clkdm_clk_enable, .clkdm_clk_enable = omap4_clkdm_clk_enable,
.clkdm_clk_disable = omap4_clkdm_clk_disable, .clkdm_clk_disable = omap4_clkdm_clk_disable,
.clkdm_xlate_address = omap4_clkdm_xlate_address,
}; };
struct clkdm_ops am43xx_clkdm_operations = { struct clkdm_ops am43xx_clkdm_operations = {
...@@ -499,6 +509,7 @@ struct clkdm_ops am43xx_clkdm_operations = { ...@@ -499,6 +509,7 @@ struct clkdm_ops am43xx_clkdm_operations = {
.clkdm_deny_idle = omap4_clkdm_deny_idle, .clkdm_deny_idle = omap4_clkdm_deny_idle,
.clkdm_clk_enable = omap4_clkdm_clk_enable, .clkdm_clk_enable = omap4_clkdm_clk_enable,
.clkdm_clk_disable = omap4_clkdm_clk_disable, .clkdm_clk_disable = omap4_clkdm_clk_disable,
.clkdm_xlate_address = omap4_clkdm_xlate_address,
}; };
static struct cm_ll_data omap4xxx_cm_ll_data = { static struct cm_ll_data omap4xxx_cm_ll_data = {
......
...@@ -36,130 +36,6 @@ ...@@ -36,130 +36,6 @@
#define L3_MODULES_MAX_LEN 12 #define L3_MODULES_MAX_LEN 12
#define L3_MODULES 3 #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) #if IS_ENABLED(CONFIG_VIDEO_OMAP2_VOUT)
...@@ -185,54 +61,3 @@ int __init omap_init_vout(void) ...@@ -185,54 +61,3 @@ int __init omap_init_vout(void)
#else #else
int __init omap_init_vout(void) { return 0; } int __init omap_init_vout(void) { return 0; }
#endif #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);
...@@ -153,7 +153,6 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *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); hc_name = kzalloc(sizeof(char) * (HSMMC_NAME_LEN + 1), GFP_KERNEL);
if (!hc_name) { if (!hc_name) {
pr_err("Cannot allocate memory for controller slot name\n");
kfree(hc_name); kfree(hc_name);
return -ENOMEM; return -ENOMEM;
} }
...@@ -315,10 +314,8 @@ static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo, ...@@ -315,10 +314,8 @@ static void __init omap_hsmmc_init_one(struct omap2_hsmmc_info *hsmmcinfo,
int res; int res;
mmc_data = kzalloc(sizeof(*mmc_data), GFP_KERNEL); mmc_data = kzalloc(sizeof(*mmc_data), GFP_KERNEL);
if (!mmc_data) { if (!mmc_data)
pr_err("Cannot allocate memory for mmc device!\n");
return; return;
}
res = omap_hsmmc_pdata_init(hsmmcinfo, mmc_data); res = omap_hsmmc_pdata_init(hsmmcinfo, mmc_data);
if (res < 0) if (res < 0)
......
...@@ -493,66 +493,38 @@ void __init omap3_init_early(void) ...@@ -493,66 +493,38 @@ void __init omap3_init_early(void)
omap2_set_globals_tap(OMAP343X_CLASS, OMAP2_L4_IO_ADDRESS(0x4830A000)); omap2_set_globals_tap(OMAP343X_CLASS, OMAP2_L4_IO_ADDRESS(0x4830A000));
omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP343X_SDRC_BASE), omap2_set_globals_sdrc(OMAP2_L3_IO_ADDRESS(OMAP343X_SDRC_BASE),
OMAP2_L3_IO_ADDRESS(OMAP343X_SMS_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(); omap2_control_base_init();
omap3xxx_check_revision(); omap3xxx_check_revision();
omap3xxx_check_features(); omap3xxx_check_features();
omap2_prcm_base_init(); 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_voltagedomains_init();
omap3xxx_powerdomains_init(); omap3xxx_powerdomains_init();
omap3xxx_clockdomains_init(); omap3xxx_clockdomains_init();
omap3xxx_hwmod_init(); omap3xxx_hwmod_init();
omap_hwmod_init_postsetup(); 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) void __init omap3430_init_early(void)
{ {
omap3_init_early(); 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) void __init omap35xx_init_early(void)
{ {
omap3_init_early(); 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) void __init omap3630_init_early(void)
{ {
omap3_init_early(); 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) void __init am35xx_init_early(void)
{ {
omap3_init_early(); omap3_init_early();
if (of_have_populated_dt())
omap_clk_soc_init = am35xx_dt_clk_init; omap_clk_soc_init = am35xx_dt_clk_init;
} }
...@@ -628,7 +600,6 @@ void __init ti816x_init_early(void) ...@@ -628,7 +600,6 @@ void __init ti816x_init_early(void)
ti816x_clockdomains_init(); ti816x_clockdomains_init();
dm816x_hwmod_init(); dm816x_hwmod_init();
omap_hwmod_init_postsetup(); 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 #endif
...@@ -785,7 +756,6 @@ int __init omap_clk_init(void) ...@@ -785,7 +756,6 @@ int __init omap_clk_init(void)
omap2_clk_setup_ll_ops(); omap2_clk_setup_ll_ops();
if (of_have_populated_dt()) {
ret = omap_control_init(); ret = omap_control_init();
if (ret) if (ret)
return ret; return ret;
...@@ -799,7 +769,6 @@ int __init omap_clk_init(void) ...@@ -799,7 +769,6 @@ int __init omap_clk_init(void)
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(); ret = omap_clk_soc_init();
......
...@@ -53,73 +53,3 @@ void __init omap3_mcbsp_init_pdata_callback( ...@@ -53,73 +53,3 @@ void __init omap3_mcbsp_init_pdata_callback(
pdata->force_ick_on = omap3_mcbsp_force_ick_on; 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);
...@@ -58,6 +58,17 @@ static unsigned int irq_banks = DEFAULT_NR_REG_BANKS; ...@@ -58,6 +58,17 @@ static unsigned int irq_banks = DEFAULT_NR_REG_BANKS;
static unsigned int max_irqs = DEFAULT_IRQS; static unsigned int max_irqs = DEFAULT_IRQS;
static unsigned int omap_secure_apis; 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. * Static helper functions.
*/ */
...@@ -264,6 +275,16 @@ static inline void omap5_irq_save_context(void) ...@@ -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 * Save WakeupGen interrupt context in SAR BANK3. Restore is done by
* ROM code. WakeupGen IP is integrated along with GIC to manage the * ROM code. WakeupGen IP is integrated along with GIC to manage the
...@@ -280,11 +301,8 @@ static void irq_save_context(void) ...@@ -280,11 +301,8 @@ static void irq_save_context(void)
if (!sar_base) if (!sar_base)
sar_base = omap4_get_sar_ram_base(); sar_base = omap4_get_sar_ram_base();
if (wakeupgen_ops && wakeupgen_ops->save_context)
if (soc_is_omap54xx()) wakeupgen_ops->save_context();
omap5_irq_save_context();
else
omap4_irq_save_context();
} }
/* /*
...@@ -306,6 +324,20 @@ static void irq_sar_clear(void) ...@@ -306,6 +324,20 @@ static void irq_sar_clear(void)
writel_relaxed(val, sar_base + offset); 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 * Save GIC and Wakeupgen interrupt context using secure API
* for HS/EMU devices. * for HS/EMU devices.
...@@ -319,6 +351,26 @@ static void irq_save_secure_context(void) ...@@ -319,6 +351,26 @@ static void irq_save_secure_context(void)
if (ret != API_HAL_RET_VALUE_OK) if (ret != API_HAL_RET_VALUE_OK)
pr_err("GIC and Wakeupgen context save failed\n"); 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 #endif
#ifdef CONFIG_HOTPLUG_CPU #ifdef CONFIG_HOTPLUG_CPU
...@@ -359,7 +411,7 @@ static int irq_notifier(struct notifier_block *self, unsigned long cmd, void *v) ...@@ -359,7 +411,7 @@ static int irq_notifier(struct notifier_block *self, unsigned long cmd, void *v)
break; break;
case CPU_CLUSTER_PM_EXIT: case CPU_CLUSTER_PM_EXIT:
if (omap_type() == OMAP2_DEVICE_TYPE_GP) if (omap_type() == OMAP2_DEVICE_TYPE_GP)
irq_sar_clear(); irq_restore_context();
break; break;
} }
return NOTIFY_OK; return NOTIFY_OK;
...@@ -494,9 +546,13 @@ static int __init wakeupgen_init(struct device_node *node, ...@@ -494,9 +546,13 @@ static int __init wakeupgen_init(struct device_node *node,
irq_banks = OMAP4_NR_BANKS; irq_banks = OMAP4_NR_BANKS;
max_irqs = OMAP4_NR_IRQS; max_irqs = OMAP4_NR_IRQS;
omap_secure_apis = 1; omap_secure_apis = 1;
wakeupgen_ops = &omap4_wakeupgen_ops;
} else if (soc_is_omap54xx()) {
wakeupgen_ops = &omap5_wakeupgen_ops;
} else if (soc_is_am43xx()) { } else if (soc_is_am43xx()) {
irq_banks = AM43XX_NR_REG_BANKS; irq_banks = AM43XX_NR_REG_BANKS;
max_irqs = AM43XX_IRQS; max_irqs = AM43XX_IRQS;
wakeupgen_ops = &am43xx_wakeupgen_ops;
} }
domain = irq_domain_add_hierarchy(parent_domain, 0, max_irqs, domain = irq_domain_add_hierarchy(parent_domain, 0, max_irqs,
......
...@@ -65,7 +65,7 @@ static void _add_clkdev(struct omap_device *od, const char *clk_alias, ...@@ -65,7 +65,7 @@ static void _add_clkdev(struct omap_device *od, const char *clk_alias,
r = clk_get_sys(NULL, clk_name); r = clk_get_sys(NULL, clk_name);
if (IS_ERR(r) && of_have_populated_dt()) { if (IS_ERR(r)) {
struct of_phandle_args clkspec; struct of_phandle_args clkspec;
clkspec.np = of_find_node_by_name(NULL, clk_name); clkspec.np = of_find_node_by_name(NULL, clk_name);
...@@ -953,9 +953,6 @@ static int __init omap_device_late_init(void) ...@@ -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); 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; return 0;
} }
omap_late_initcall_sync(omap_device_late_init); omap_late_initcall_sync(omap_device_late_init);
...@@ -141,6 +141,7 @@ ...@@ -141,6 +141,7 @@
#include <linux/cpu.h> #include <linux/cpu.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/bootmem.h>
#include <asm/system_misc.h> #include <asm/system_misc.h>
...@@ -181,6 +182,24 @@ ...@@ -181,6 +182,24 @@
*/ */
#define MOD_CLK_MAX_NAME_LEN 32 #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 * struct omap_hwmod_soc_ops - fn ptrs for some SoC-specific operations
* @enable_module: function to enable a module (via MODULEMODE) * @enable_module: function to enable a module (via MODULEMODE)
...@@ -204,6 +223,8 @@ struct omap_hwmod_soc_ops { ...@@ -204,6 +223,8 @@ struct omap_hwmod_soc_ops {
void (*update_context_lost)(struct omap_hwmod *oh); void (*update_context_lost)(struct omap_hwmod *oh);
int (*get_context_lost)(struct omap_hwmod *oh); int (*get_context_lost)(struct omap_hwmod *oh);
int (*disable_direct_prcm)(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 */ /* 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) ...@@ -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); 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 * _init_main_clk - get a struct clk * for the the hwmod's main functional clk
* @oh: struct omap_hwmod * * @oh: struct omap_hwmod *
...@@ -701,22 +819,16 @@ static int _del_initiator_dep(struct omap_hwmod *oh, struct omap_hwmod *init_oh) ...@@ -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) static int _init_main_clk(struct omap_hwmod *oh)
{ {
int ret = 0; int ret = 0;
char name[MOD_CLK_MAX_NAME_LEN]; struct clk *clk = NULL;
struct clk *clk;
static const char modck[] = "_mod_ck";
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)); clk = _lookup_clkctrl_clk(oh);
strlcat(name, modck, MOD_CLK_MAX_NAME_LEN);
clk = clk_get(NULL, name); if (!IS_ERR_OR_NULL(clk)) {
if (!IS_ERR(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; oh->_clk = clk;
soc_ops.disable_direct_prcm(oh); soc_ops.disable_direct_prcm(oh);
oh->main_clk = kstrdup(name, GFP_KERNEL);
} else { } else {
if (!oh->main_clk) if (!oh->main_clk)
return 0; return 0;
...@@ -1482,13 +1594,13 @@ static int _init_clkdm(struct omap_hwmod *oh) ...@@ -1482,13 +1594,13 @@ static int _init_clkdm(struct omap_hwmod *oh)
* _init_clocks - clk_get() all clocks associated with this hwmod. Retrieve as * _init_clocks - clk_get() all clocks associated with this hwmod. Retrieve as
* well the clockdomain. * well the clockdomain.
* @oh: struct omap_hwmod * * @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()). * Called by omap_hwmod_setup_*() (after omap2_clk_init()).
* Resolves all clock names embedded in the hwmod. Returns 0 on * Resolves all clock names embedded in the hwmod. Returns 0 on
* success, or a negative error code on failure. * 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; int ret = 0;
...@@ -2334,13 +2446,11 @@ static int __init _init(struct omap_hwmod *oh, void *data) ...@@ -2334,13 +2446,11 @@ static int __init _init(struct omap_hwmod *oh, void *data)
{ {
int r, index; int r, index;
struct device_node *np = NULL; struct device_node *np = NULL;
struct device_node *bus;
if (oh->_state != _HWMOD_STATE_REGISTERED) if (oh->_state != _HWMOD_STATE_REGISTERED)
return 0; return 0;
if (of_have_populated_dt()) {
struct device_node *bus;
bus = of_find_node_by_name(NULL, "ocp"); bus = of_find_node_by_name(NULL, "ocp");
if (!bus) if (!bus)
return -ENODEV; return -ENODEV;
...@@ -2351,7 +2461,6 @@ static int __init _init(struct omap_hwmod *oh, void *data) ...@@ -2351,7 +2461,6 @@ static int __init _init(struct omap_hwmod *oh, void *data)
else if (np && index) else if (np && index)
pr_warn("omap_hwmod: %s using broken dt data from %s\n", pr_warn("omap_hwmod: %s using broken dt data from %s\n",
oh->name, np->name); oh->name, np->name);
}
r = _init_mpu_rt_base(oh, NULL, index, np); r = _init_mpu_rt_base(oh, NULL, index, np);
if (r < 0) { if (r < 0) {
...@@ -2360,7 +2469,7 @@ static int __init _init(struct omap_hwmod *oh, void *data) ...@@ -2360,7 +2469,7 @@ static int __init _init(struct omap_hwmod *oh, void *data)
return 0; return 0;
} }
r = _init_clocks(oh, NULL); r = _init_clocks(oh, np);
if (r < 0) { if (r < 0) {
WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh->name); WARN(1, "omap_hwmod: %s: couldn't init clocks\n", oh->name);
return -EINVAL; return -EINVAL;
...@@ -3722,6 +3831,7 @@ void __init omap_hwmod_init(void) ...@@ -3722,6 +3831,7 @@ void __init omap_hwmod_init(void)
soc_ops.update_context_lost = _omap4_update_context_lost; soc_ops.update_context_lost = _omap4_update_context_lost;
soc_ops.get_context_lost = _omap4_get_context_lost; soc_ops.get_context_lost = _omap4_get_context_lost;
soc_ops.disable_direct_prcm = _omap4_disable_direct_prcm; 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() || } else if (cpu_is_ti814x() || cpu_is_ti816x() || soc_is_am33xx() ||
soc_is_am43xx()) { soc_is_am43xx()) {
soc_ops.enable_module = _omap4_enable_module; soc_ops.enable_module = _omap4_enable_module;
...@@ -3736,6 +3846,8 @@ void __init omap_hwmod_init(void) ...@@ -3736,6 +3846,8 @@ void __init omap_hwmod_init(void)
WARN(1, "omap_hwmod: unknown SoC type\n"); WARN(1, "omap_hwmod: unknown SoC type\n");
} }
_init_clkctrl_providers();
inited = true; inited = true;
} }
......
...@@ -3204,7 +3204,6 @@ int __init omap3xxx_hwmod_init(void) ...@@ -3204,7 +3204,6 @@ int __init omap3xxx_hwmod_init(void)
* If DT information is missing, enable them only for GP devices. * 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")) { if (h_sham && omap3xxx_hwmod_is_hs_ip_block_usable(bus, "sham")) {
......
...@@ -775,6 +775,7 @@ static struct omap_hwmod_dma_info omap44xx_dss_hdmi_sdma_reqs[] = { ...@@ -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[] = { static struct omap_hwmod_opt_clk dss_hdmi_opt_clks[] = {
{ .role = "sys_clk", .clk = "dss_sys_clk" }, { .role = "sys_clk", .clk = "dss_sys_clk" },
{ .role = "hdmi_clk", .clk = "dss_48mhz_clk" },
}; };
static struct omap_hwmod omap44xx_dss_hdmi_hwmod = { static struct omap_hwmod omap44xx_dss_hdmi_hwmod = {
...@@ -785,7 +786,7 @@ 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, * HDMI audio requires to use no-idle mode. Hence,
* set idle mode by software. * set idle mode by software.
*/ */
.flags = HWMOD_SWSUP_SIDLE, .flags = HWMOD_SWSUP_SIDLE | HWMOD_OPT_CLKS_NEEDED,
.mpu_irqs = omap44xx_dss_hdmi_irqs, .mpu_irqs = omap44xx_dss_hdmi_irqs,
.xlate_irq = omap4_xlate_irq, .xlate_irq = omap4_xlate_irq,
.sdma_reqs = omap44xx_dss_hdmi_sdma_reqs, .sdma_reqs = omap44xx_dss_hdmi_sdma_reqs,
...@@ -858,11 +859,16 @@ static struct omap_hwmod_class omap44xx_venc_hwmod_class = { ...@@ -858,11 +859,16 @@ static struct omap_hwmod_class omap44xx_venc_hwmod_class = {
}; };
/* dss_venc */ /* 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 = { static struct omap_hwmod omap44xx_dss_venc_hwmod = {
.name = "dss_venc", .name = "dss_venc",
.class = &omap44xx_venc_hwmod_class, .class = &omap44xx_venc_hwmod_class,
.clkdm_name = "l3_dss_clkdm", .clkdm_name = "l3_dss_clkdm",
.main_clk = "dss_tv_clk", .main_clk = "dss_tv_clk",
.flags = HWMOD_OPT_CLKS_NEEDED,
.prcm = { .prcm = {
.omap4 = { .omap4 = {
.clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET, .clkctrl_offs = OMAP4_CM_DSS_DSS_CLKCTRL_OFFSET,
...@@ -870,6 +876,35 @@ static struct omap_hwmod omap44xx_dss_venc_hwmod = { ...@@ -870,6 +876,35 @@ static struct omap_hwmod omap44xx_dss_venc_hwmod = {
}, },
}, },
.parent_hwmod = &omap44xx_dss_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,
},
},
}; };
/* /*
...@@ -952,6 +987,103 @@ static struct omap_hwmod omap44xx_emif2_hwmod = { ...@@ -952,6 +987,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 * 'fdif' class
* face detection hw accelerator module * face detection hw accelerator module
...@@ -3882,6 +4014,14 @@ static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_venc = { ...@@ -3882,6 +4014,14 @@ static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_venc = {
.user = OCP_USER_MPU, .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 */ /* l4_per -> elm */
static struct omap_hwmod_ocp_if omap44xx_l4_per__elm = { static struct omap_hwmod_ocp_if omap44xx_l4_per__elm = {
.master = &omap44xx_l4_per_hwmod, .master = &omap44xx_l4_per_hwmod,
...@@ -4793,6 +4933,10 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = { ...@@ -4793,6 +4933,10 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
&omap44xx_l4_abe__wd_timer3_dma, &omap44xx_l4_abe__wd_timer3_dma,
&omap44xx_mpu__emif1, &omap44xx_mpu__emif1,
&omap44xx_mpu__emif2, &omap44xx_mpu__emif2,
&omap44xx_l3_main_2__aes1,
&omap44xx_l3_main_2__aes2,
&omap44xx_l3_main_2__des,
&omap44xx_l3_main_2__sha0,
NULL, NULL,
}; };
......
/*
* 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;
}
...@@ -83,89 +83,3 @@ struct omap_volt_data omap36xx_vddcore_volt_data[] = { ...@@ -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(OMAP3630_VDD_CORE_OPP100_UV, OMAP3630_CONTROL_FUSE_OPP100_VDD2, 0xf9, 0x16),
VOLT_DATA_DEFINE(0, 0, 0, 0), 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);
...@@ -63,29 +63,6 @@ struct omap_volt_data omap443x_vdd_core_volt_data[] = { ...@@ -63,29 +63,6 @@ struct omap_volt_data omap443x_vdd_core_volt_data[] = {
VOLT_DATA_DEFINE(0, 0, 0, 0), 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_OPP50_UV 1025000
#define OMAP4460_VDD_MPU_OPP100_UV 1200000 #define OMAP4460_VDD_MPU_OPP100_UV 1200000
#define OMAP4460_VDD_MPU_OPPTURBO_UV 1313000 #define OMAP4460_VDD_MPU_OPPTURBO_UV 1313000
...@@ -122,59 +99,3 @@ struct omap_volt_data omap446x_vdd_core_volt_data[] = { ...@@ -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(OMAP4460_VDD_CORE_OPP100_OV_UV, OMAP44XX_CONTROL_FUSE_CORE_OPP100OV, 0xf9, 0x16),
VOLT_DATA_DEFINE(0, 0, 0, 0), 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);
...@@ -71,7 +71,7 @@ void omap_pm_get_oscillator(u32 *tstart, u32 *tshut) ...@@ -71,7 +71,7 @@ void omap_pm_get_oscillator(u32 *tstart, u32 *tshut)
} }
#endif #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); clkdm_allow_idle(clkdm);
return 0; return 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);
...@@ -526,10 +526,16 @@ struct omap_prcm_irq_setup { ...@@ -526,10 +526,16 @@ struct omap_prcm_irq_setup {
.priority = _priority \ .priority = _priority \
} }
struct omap_domain_base {
u32 pa;
void __iomem *va;
};
/** /**
* struct omap_prcm_init_data - PRCM driver init data * struct omap_prcm_init_data - PRCM driver init data
* @index: clock memory mapping index to be used * @index: clock memory mapping index to be used
* @mem: IO mem pointer for this module * @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 * @offset: module base address offset from the IO base
* @flags: PRCM module init flags * @flags: PRCM module init flags
* @device_inst_offset: device instance offset within the module address space * @device_inst_offset: device instance offset within the module address space
...@@ -539,6 +545,7 @@ struct omap_prcm_irq_setup { ...@@ -539,6 +545,7 @@ struct omap_prcm_irq_setup {
struct omap_prcm_init_data { struct omap_prcm_init_data {
int index; int index;
void __iomem *mem; void __iomem *mem;
u32 phys;
s16 offset; s16 offset;
u16 flags; u16 flags;
s32 device_inst_offset; s32 device_inst_offset;
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
* prcm_mpu_base: the virtual address of the start of the PRCM_MPU IP * prcm_mpu_base: the virtual address of the start of the PRCM_MPU IP
* block registers * block registers
*/ */
void __iomem *prcm_mpu_base; struct omap_domain_base prcm_mpu_base;
/* PRCM_MPU low-level functions */ /* 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) ...@@ -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) void __init omap2_set_globals_prcm_mpu(void __iomem *prcm_mpu)
{ {
prcm_mpu_base = prcm_mpu; prcm_mpu_base.va = prcm_mpu;
} }
...@@ -24,7 +24,9 @@ ...@@ -24,7 +24,9 @@
#define __ARCH_ARM_MACH_OMAP2_PRCM_MPU_44XX_54XX_H #define __ARCH_ARM_MACH_OMAP2_PRCM_MPU_44XX_54XX_H
#ifndef __ASSEMBLER__ #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 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); extern void omap4_prcm_mpu_write_inst_reg(u32 val, s16 inst, u16 idx);
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
#include "prcm-common.h" #include "prcm-common.h"
# ifndef __ASSEMBLER__ # ifndef __ASSEMBLER__
extern void __iomem *prm_base; extern struct omap_domain_base prm_base;
extern u16 prm_features; extern u16 prm_features;
extern void omap2_set_globals_prm(void __iomem *prm); extern void omap2_set_globals_prm(void __iomem *prm);
int omap_prcm_init(void); int omap_prcm_init(void);
......
...@@ -55,12 +55,12 @@ ...@@ -55,12 +55,12 @@
/* Power/reset management domain register get/set */ /* Power/reset management domain register get/set */
static inline u32 omap2_prm_read_mod_reg(s16 module, u16 idx) 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) 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 */ /* Read-modify-write a register in a PRM module. Caller must lock */
......
...@@ -30,13 +30,13 @@ ...@@ -30,13 +30,13 @@
/* Read a register in a PRM instance */ /* Read a register in a PRM instance */
static u32 am33xx_prm_read_reg(s16 inst, u16 idx) 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 */ /* Write into a register in a PRM instance */
static void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx) 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 */ /* Read-modify-write a register in PRM. Caller must lock */
......
...@@ -676,7 +676,7 @@ static struct prm_ll_data omap3xxx_prm_ll_data = { ...@@ -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) int __init omap3xxx_prm_init(const struct omap_prcm_init_data *data)
{ {
omap2_clk_legacy_provider_init(TI_CLKM_PRM, omap2_clk_legacy_provider_init(TI_CLKM_PRM,
prm_base + OMAP3430_IVA2_MOD); prm_base.va + OMAP3430_IVA2_MOD);
if (omap3_has_io_wakeup()) if (omap3_has_io_wakeup())
prm_features |= PRM_HAS_IO_WAKEUP; prm_features |= PRM_HAS_IO_WAKEUP;
...@@ -690,6 +690,8 @@ static const struct of_device_id omap3_prm_dt_match_table[] = { ...@@ -690,6 +690,8 @@ static const struct of_device_id omap3_prm_dt_match_table[] = {
static int omap3xxx_prm_late_init(void) static int omap3xxx_prm_late_init(void)
{ {
struct device_node *np;
int irq_num;
int ret; int ret;
if (!(prm_features & PRM_HAS_IO_WAKEUP)) if (!(prm_features & PRM_HAS_IO_WAKEUP))
...@@ -702,17 +704,12 @@ static int omap3xxx_prm_late_init(void) ...@@ -702,17 +704,12 @@ static int omap3xxx_prm_late_init(void)
omap3_prcm_irq_setup.reconfigure_io_chain = omap3_prcm_irq_setup.reconfigure_io_chain =
omap3430_pre_es3_1_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); np = of_find_matching_node(NULL, omap3_prm_dt_match_table);
if (np) { if (np) {
irq_num = of_irq_get(np, 0); irq_num = of_irq_get(np, 0);
if (irq_num >= 0) if (irq_num >= 0)
omap3_prcm_irq_setup.irq = irq_num; omap3_prcm_irq_setup.irq = irq_num;
} }
}
omap3xxx_prm_enable_io_wakeup(); omap3xxx_prm_enable_io_wakeup();
ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup); ret = omap_prcm_register_chain_handler(&omap3_prcm_irq_setup);
......
...@@ -91,13 +91,13 @@ static struct prm_reset_src_map omap44xx_prm_reset_src_map[] = { ...@@ -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 */ /* Read a register in a CM/PRM instance in the PRM module */
static u32 omap4_prm_read_inst_reg(s16 inst, u16 reg) 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 */ /* 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) 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 */ /* Read-modify-write a register in a PRM module. Caller must lock */
...@@ -336,27 +336,6 @@ static void omap44xx_prm_reconfigure_io_chain(void) ...@@ -336,27 +336,6 @@ static void omap44xx_prm_reconfigure_io_chain(void)
return; return;
} }
/**
* 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 * omap44xx_prm_read_reset_sources - return the last SoC reset source
* *
...@@ -689,8 +668,6 @@ struct pwrdm_ops omap4_pwrdm_operations = { ...@@ -689,8 +668,6 @@ struct pwrdm_ops omap4_pwrdm_operations = {
.pwrdm_has_voltdm = omap4_check_vcvp, .pwrdm_has_voltdm = omap4_check_vcvp,
}; };
static int omap44xx_prm_late_init(void);
/* /*
* XXX document * XXX document
*/ */
...@@ -698,7 +675,6 @@ static struct prm_ll_data omap44xx_prm_ll_data = { ...@@ -698,7 +675,6 @@ static struct prm_ll_data omap44xx_prm_ll_data = {
.read_reset_sources = &omap44xx_prm_read_reset_sources, .read_reset_sources = &omap44xx_prm_read_reset_sources,
.was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old, .was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old,
.clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_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, .assert_hardreset = omap4_prminst_assert_hardreset,
.deassert_hardreset = omap4_prminst_deassert_hardreset, .deassert_hardreset = omap4_prminst_deassert_hardreset,
.is_hardreset_asserted = omap4_prminst_is_hardreset_asserted, .is_hardreset_asserted = omap4_prminst_is_hardreset_asserted,
...@@ -735,41 +711,6 @@ int __init omap44xx_prm_init(const struct omap_prcm_init_data *data) ...@@ -735,41 +711,6 @@ int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
return prm_register(&omap44xx_prm_ll_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) static void __exit omap44xx_prm_exit(void)
{ {
prm_unregister(&omap44xx_prm_ll_data); prm_unregister(&omap44xx_prm_ll_data);
......
...@@ -66,7 +66,7 @@ static struct irq_chip_generic **prcm_irq_chips; ...@@ -66,7 +66,7 @@ static struct irq_chip_generic **prcm_irq_chips;
static struct omap_prcm_irq_setup *prcm_irq_setup; static struct omap_prcm_irq_setup *prcm_irq_setup;
/* prm_base: base virtual address of the PRM IP block */ /* prm_base: base virtual address of the PRM IP block */
void __iomem *prm_base; struct omap_domain_base prm_base;
u16 prm_features; u16 prm_features;
...@@ -267,10 +267,9 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) ...@@ -267,10 +267,9 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
{ {
int nr_regs; int nr_regs;
u32 mask[OMAP_PRCM_MAX_NR_PENDING_REG]; u32 mask[OMAP_PRCM_MAX_NR_PENDING_REG];
int offset, i; int offset, i, irq;
struct irq_chip_generic *gc; struct irq_chip_generic *gc;
struct irq_chip_type *ct; struct irq_chip_type *ct;
unsigned int irq;
if (!irq_setup) if (!irq_setup)
return -EINVAL; return -EINVAL;
...@@ -325,7 +324,7 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) ...@@ -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++) { for (i = 0; i < irq_setup->nr_regs; i++) {
gc = irq_alloc_generic_chip("PRCM", 1, 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); handle_level_irq);
if (!gc) { if (!gc) {
...@@ -344,10 +343,8 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) ...@@ -344,10 +343,8 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
prcm_irq_chips[i] = gc; prcm_irq_chips[i] = gc;
} }
if (of_have_populated_dt()) { irq = omap_prcm_event_to_irq("io");
int irq = omap_prcm_event_to_irq("io");
omap_pcs_legacy_init(irq, irq_setup->reconfigure_io_chain); omap_pcs_legacy_init(irq, irq_setup->reconfigure_io_chain);
}
return 0; return 0;
...@@ -364,7 +361,7 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) ...@@ -364,7 +361,7 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
*/ */
void __init omap2_set_globals_prm(void __iomem *prm) 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) ...@@ -755,19 +752,22 @@ int __init omap2_prm_base_init(void)
struct device_node *np; struct device_node *np;
const struct of_device_id *match; const struct of_device_id *match;
struct omap_prcm_init_data *data; 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) { for_each_matching_node_and_match(np, omap_prcm_dt_match_table, &match) {
data = (struct omap_prcm_init_data *)match->data; data = (struct omap_prcm_init_data *)match->data;
mem = of_iomap(np, 0); ret = of_address_to_resource(np, 0, &res);
if (!mem) if (ret)
return -ENOMEM; return ret;
if (data->index == TI_CLKM_PRM) data->mem = ioremap(res.start, resource_size(&res));
prm_base = mem + data->offset;
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; data->np = np;
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include "prcm_mpu44xx.h" #include "prcm_mpu44xx.h"
#include "soc.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; static s32 prm_dev_inst = PRM_INSTANCE_UNKNOWN;
...@@ -41,8 +41,10 @@ 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) void omap_prm_base_init(void)
{ {
_prm_bases[OMAP4430_PRM_PARTITION] = prm_base; memcpy(&_prm_bases[OMAP4430_PRM_PARTITION], &prm_base,
_prm_bases[OMAP4430_PRCM_MPU_PARTITION] = prcm_mpu_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) s32 omap4_prmst_get_prm_dev_inst(void)
...@@ -60,8 +62,8 @@ u32 omap4_prminst_read_inst_reg(u8 part, s16 inst, u16 idx) ...@@ -60,8 +62,8 @@ u32 omap4_prminst_read_inst_reg(u8 part, s16 inst, u16 idx)
{ {
BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
part == OMAP4430_INVALID_PRCM_PARTITION || part == OMAP4430_INVALID_PRCM_PARTITION ||
!_prm_bases[part]); !_prm_bases[part].va);
return readl_relaxed(_prm_bases[part] + inst + idx); return readl_relaxed(_prm_bases[part].va + inst + idx);
} }
/* Write into a register in a PRM instance */ /* 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) ...@@ -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 || BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS ||
part == OMAP4430_INVALID_PRCM_PARTITION || part == OMAP4430_INVALID_PRCM_PARTITION ||
!_prm_bases[part]); !_prm_bases[part].va);
writel_relaxed(val, _prm_bases[part] + inst + idx); writel_relaxed(val, _prm_bases[part].va + inst + idx);
} }
/* Read-modify-write a register in PRM. Caller must lock */ /* Read-modify-write a register in PRM. Caller must lock */
......
...@@ -44,13 +44,9 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data, ...@@ -44,13 +44,9 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data,
while (volt_data[count].volt_nominal) while (volt_data[count].volt_nominal)
count++; count++;
nvalue_table = kzalloc(sizeof(struct omap_sr_nvalue_table)*count, nvalue_table = kcalloc(count, sizeof(*nvalue_table), GFP_KERNEL);
GFP_KERNEL); if (!nvalue_table)
if (!nvalue_table) {
pr_err("OMAP: SmartReflex: cannot allocate memory for n-value table\n");
return; return;
}
for (i = 0, j = 0; i < count; i++) { for (i = 0, j = 0; i < count; i++) {
u32 v; u32 v;
...@@ -102,12 +98,9 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user) ...@@ -102,12 +98,9 @@ static int __init sr_dev_init(struct omap_hwmod *oh, void *user)
char *name = "smartreflex"; char *name = "smartreflex";
static int i; static int i;
sr_data = kzalloc(sizeof(struct omap_sr_data), GFP_KERNEL); sr_data = kzalloc(sizeof(*sr_data), GFP_KERNEL);
if (!sr_data) { if (!sr_data)
pr_err("%s: Unable to allocate memory for %s sr_data\n",
__func__, oh->name);
return -ENOMEM; return -ENOMEM;
}
sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr; sr_dev_attr = (struct omap_smartreflex_dev_attr *)oh->dev_attr;
if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) { if (!sr_dev_attr || !sr_dev_attr->sensor_voltdm_name) {
......
...@@ -68,6 +68,9 @@ ...@@ -68,6 +68,9 @@
static struct omap_dm_timer clkev; static struct omap_dm_timer clkev;
static struct clock_event_device clockevent_gpt; 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 #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
static unsigned long arch_timer_freq; static unsigned long arch_timer_freq;
...@@ -125,6 +128,23 @@ static int omap2_gp_timer_set_periodic(struct clock_event_device *evt) ...@@ -125,6 +128,23 @@ static int omap2_gp_timer_set_periodic(struct clock_event_device *evt)
return 0; 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 = { static struct clock_event_device clockevent_gpt = {
.features = CLOCK_EVT_FEAT_PERIODIC | .features = CLOCK_EVT_FEAT_PERIODIC |
CLOCK_EVT_FEAT_ONESHOT, CLOCK_EVT_FEAT_ONESHOT,
...@@ -232,15 +252,12 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, ...@@ -232,15 +252,12 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
const char **timer_name, const char **timer_name,
int posted) int posted)
{ {
char name[10]; /* 10 = sizeof("gptXX_Xck0") */
const char *oh_name = NULL; const char *oh_name = NULL;
struct device_node *np; struct device_node *np;
struct omap_hwmod *oh; struct omap_hwmod *oh;
struct resource irq, mem;
struct clk *src; struct clk *src;
int r = 0; int r = 0;
if (of_have_populated_dt()) {
np = omap_get_timer_dt(omap_timer_match, property); np = omap_get_timer_dt(omap_timer_match, property);
if (!np) if (!np)
return -ENODEV; return -ENODEV;
...@@ -255,14 +272,9 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, ...@@ -255,14 +272,9 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
timer->io_base = of_iomap(np, 0); timer->io_base = of_iomap(np, 0);
of_node_put(np); timer->fclk = of_clk_get_by_name(np, "fck");
} else {
if (omap_dm_timer_reserve_systimer(timer->id))
return -ENODEV;
sprintf(name, "timer%d", timer->id); of_node_put(np);
oh_name = name;
}
oh = omap_hwmod_lookup(oh_name); oh = omap_hwmod_lookup(oh_name);
if (!oh) if (!oh)
...@@ -270,28 +282,13 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer, ...@@ -270,28 +282,13 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
*timer_name = oh->name; *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) if (!timer->io_base)
return -ENXIO; return -ENXIO;
omap_hwmod_setup_one(oh_name); omap_hwmod_setup_one(oh_name);
/* After the dmtimer is using hwmod these clocks won't be needed */ /* After the dmtimer is using hwmod these clocks won't be needed */
if (IS_ERR_OR_NULL(timer->fclk))
timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh)); timer->fclk = clk_get(NULL, omap_hwmod_get_main_clk(oh));
if (IS_ERR(timer->fclk)) if (IS_ERR(timer->fclk))
return PTR_ERR(timer->fclk); return PTR_ERR(timer->fclk);
...@@ -358,6 +355,14 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, ...@@ -358,6 +355,14 @@ static void __init omap2_gp_clockevent_init(int gptimer_id,
3, /* Timer internal resynch latency */ 3, /* Timer internal resynch latency */
0xffffffff); 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, pr_info("OMAP clockevent source: %s at %lu Hz\n", clockevent_gpt.name,
clkev.rate); clkev.rate);
} }
...@@ -405,10 +410,8 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void) ...@@ -405,10 +410,8 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void)
const char *oh_name = "counter_32k"; const char *oh_name = "counter_32k";
/* /*
* If device-tree is present, then search the DT blob * See if the 32kHz counter is supported.
* to see if the 32kHz counter is supported.
*/ */
if (of_have_populated_dt()) {
np = omap_get_timer_dt(omap_counter_match, NULL); np = omap_get_timer_dt(omap_counter_match, NULL);
if (!np) if (!np)
return -ENODEV; return -ENODEV;
...@@ -416,7 +419,6 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void) ...@@ -416,7 +419,6 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void)
of_property_read_string_index(np, "ti,hwmods", 0, &oh_name); of_property_read_string_index(np, "ti,hwmods", 0, &oh_name);
if (!oh_name) if (!oh_name)
return -ENODEV; return -ENODEV;
}
/* /*
* First check hwmod data is available for sync32k counter * First check hwmod data is available for sync32k counter
...@@ -434,18 +436,6 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void) ...@@ -434,18 +436,6 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void)
return ret; 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; return ret;
} }
...@@ -660,96 +650,6 @@ void __init omap5_realtime_timer_init(void) ...@@ -660,96 +650,6 @@ void __init omap5_realtime_timer_init(void)
} }
#endif /* CONFIG_SOC_OMAP5 || CONFIG_SOC_DRA7XX */ #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 * omap2_override_clocksource - clocksource override with user configuration
* *
......
...@@ -102,31 +102,3 @@ int omap2_wd_timer_reset(struct omap_hwmod *oh) ...@@ -102,31 +102,3 @@ int omap2_wd_timer_reset(struct omap_hwmod *oh)
return (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT : return (c == MAX_MODULE_SOFTRESET_WAIT) ? -ETIMEDOUT :
omap2_wd_timer_disable(oh); 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);
...@@ -27,7 +27,6 @@ config ARCH_ATLAS7 ...@@ -27,7 +27,6 @@ config ARCH_ATLAS7
bool "CSR SiRFSoC ATLAS7 ARM Cortex A7 Platform" bool "CSR SiRFSoC ATLAS7 ARM Cortex A7 Platform"
default y default y
select ARM_GIC select ARM_GIC
select CPU_V7
select ATLAS7_TIMER select ATLAS7_TIMER
select HAVE_ARM_SCU if SMP select HAVE_ARM_SCU if SMP
select HAVE_SMP select HAVE_SMP
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#define GPIO10_MAGICIAN_GSM_IRQ 10 #define GPIO10_MAGICIAN_GSM_IRQ 10
#define GPIO11_MAGICIAN_GSM_OUT1 11 #define GPIO11_MAGICIAN_GSM_OUT1 11
#define GPIO13_MAGICIAN_CPLD_IRQ 13 #define GPIO13_MAGICIAN_CPLD_IRQ 13
#define GPIO14_MAGICIAN_TSC2046_CS 14
#define GPIO18_MAGICIAN_UNKNOWN 18 #define GPIO18_MAGICIAN_UNKNOWN 18
#define GPIO22_MAGICIAN_VIBRA_EN 22 #define GPIO22_MAGICIAN_VIBRA_EN 22
#define GPIO26_MAGICIAN_GSM_POWER 26 #define GPIO26_MAGICIAN_GSM_POWER 26
......
...@@ -54,6 +54,10 @@ ...@@ -54,6 +54,10 @@
#include "devices.h" #include "devices.h"
#include "generic.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 = { static unsigned long magician_pin_config[] __initdata = {
/* SDRAM and Static Memory I/O Signals */ /* SDRAM and Static Memory I/O Signals */
...@@ -85,7 +89,7 @@ static unsigned long magician_pin_config[] __initdata = { ...@@ -85,7 +89,7 @@ static unsigned long magician_pin_config[] __initdata = {
/* SSP 2 TSC2046 touchscreen */ /* SSP 2 TSC2046 touchscreen */
GPIO19_SSP2_SCLK, GPIO19_SSP2_SCLK,
GPIO14_SSP2_SFRM, MFP_CFG_OUT(GPIO14, AF0, DRIVE_HIGH), /* frame as GPIO */
GPIO89_SSP2_TXD, GPIO89_SSP2_TXD,
GPIO88_SSP2_RXD, GPIO88_SSP2_RXD,
...@@ -674,6 +678,37 @@ static struct platform_device bq24022 = { ...@@ -674,6 +678,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 * Vcore regulator MAX1587A
*/ */
...@@ -851,6 +886,49 @@ static struct i2c_pxa_platform_data magician_i2c_power_info = { ...@@ -851,6 +886,49 @@ static struct i2c_pxa_platform_data magician_i2c_power_info = {
.fast_mode = 1, .fast_mode = 1,
}; };
/*
* 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 * Platform devices
*/ */
...@@ -865,6 +943,7 @@ static struct platform_device *devices[] __initdata = { ...@@ -865,6 +943,7 @@ static struct platform_device *devices[] __initdata = {
&power_supply, &power_supply,
&strataflash, &strataflash,
&leds_gpio, &leds_gpio,
&vads7846_device,
}; };
static struct gpio magician_global_gpios[] = { static struct gpio magician_global_gpios[] = {
...@@ -922,6 +1001,9 @@ static void __init magician_init(void) ...@@ -922,6 +1001,9 @@ static void __init magician_init(void)
} else } else
pr_err("LCD detection: CPLD mapping failed\n"); 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, regulator_register_always_on(0, "power", pwm_backlight_supply,
ARRAY_SIZE(pwm_backlight_supply), 5000000); ARRAY_SIZE(pwm_backlight_supply), 5000000);
......
...@@ -107,10 +107,8 @@ static int __init pxa_pm_init(void) ...@@ -107,10 +107,8 @@ static int __init pxa_pm_init(void)
sleep_save = kmalloc_array(pxa_cpu_pm_fns->save_count, sleep_save = kmalloc_array(pxa_cpu_pm_fns->save_count,
sizeof(*sleep_save), sizeof(*sleep_save),
GFP_KERNEL); GFP_KERNEL);
if (!sleep_save) { if (!sleep_save)
printk(KERN_ERR "failed to alloc memory for pm save\n");
return -ENOMEM; return -ENOMEM;
}
suspend_set_ops(&pxa_pm_ops); suspend_set_ops(&pxa_pm_ops);
return 0; return 0;
......
...@@ -286,11 +286,9 @@ static int pxa3xx_u2d_probe(struct platform_device *pdev) ...@@ -286,11 +286,9 @@ static int pxa3xx_u2d_probe(struct platform_device *pdev)
struct resource *r; struct resource *r;
int err; int err;
u2d = kzalloc(sizeof(struct pxa3xx_u2d_ulpi), GFP_KERNEL); u2d = kzalloc(sizeof(*u2d), GFP_KERNEL);
if (!u2d) { if (!u2d)
dev_err(&pdev->dev, "failed to allocate memory\n");
return -ENOMEM; return -ENOMEM;
}
u2d->clk = clk_get(&pdev->dev, NULL); u2d->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(u2d->clk)) { if (IS_ERR(u2d->clk)) {
......
...@@ -70,6 +70,7 @@ static const char * const rockchip_board_dt_compat[] = { ...@@ -70,6 +70,7 @@ static const char * const rockchip_board_dt_compat[] = {
"rockchip,rk3188", "rockchip,rk3188",
"rockchip,rk3228", "rockchip,rk3228",
"rockchip,rk3288", "rockchip,rk3288",
"rockchip,rv1108",
NULL, NULL,
}; };
......
...@@ -40,7 +40,6 @@ config CPU_S3C6410 ...@@ -40,7 +40,6 @@ config CPU_S3C6410
config S3C64XX_PL080 config S3C64XX_PL080
def_bool DMADEVICES def_bool DMADEVICES
select ARM_AMBA
select AMBA_PL08X select AMBA_PL08X
config S3C64XX_SETUP_SDHCI config S3C64XX_SETUP_SDHCI
......
...@@ -130,7 +130,7 @@ static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) ...@@ -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 generic_pm_domain *genpd = &rmobile_pd->genpd;
struct dev_power_governor *gov = rmobile_pd->gov; 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->dev_ops.active_wakeup = rmobile_pd_active_wakeup;
genpd->power_off = rmobile_pd_power_down; genpd->power_off = rmobile_pd_power_down;
genpd->power_on = rmobile_pd_power_up; genpd->power_on = rmobile_pd_power_up;
...@@ -140,14 +140,6 @@ static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd) ...@@ -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); 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) static int rmobile_pd_suspend_console(void)
{ {
/* /*
...@@ -260,8 +252,7 @@ static void __init rmobile_setup_pm_domain(struct device_node *np, ...@@ -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. * only be turned off if the CPU is not in use.
*/ */
pr_debug("PM domain %s contains CPU\n", name); pr_debug("PM domain %s contains CPU\n", name);
pd->gov = &pm_domain_always_on_gov; pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON;
pd->suspend = rmobile_pd_suspend_busy;
break; break;
case PD_CONSOLE: case PD_CONSOLE:
...@@ -277,8 +268,7 @@ static void __init rmobile_setup_pm_domain(struct device_node *np, ...@@ -277,8 +268,7 @@ static void __init rmobile_setup_pm_domain(struct device_node *np,
* is not in use. * is not in use.
*/ */
pr_debug("PM domain %s contains Coresight-ETM\n", name); pr_debug("PM domain %s contains Coresight-ETM\n", name);
pd->gov = &pm_domain_always_on_gov; pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON;
pd->suspend = rmobile_pd_suspend_busy;
break; break;
case PD_MEMCTL: case PD_MEMCTL:
...@@ -287,8 +277,7 @@ static void __init rmobile_setup_pm_domain(struct device_node *np, ...@@ -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. * should only be turned off if memory is not in use.
*/ */
pr_debug("PM domain %s contains MEMCTL\n", name); pr_debug("PM domain %s contains MEMCTL\n", name);
pd->gov = &pm_domain_always_on_gov; pd->genpd.flags |= GENPD_FLAG_ALWAYS_ON;
pd->suspend = rmobile_pd_suspend_busy;
break; break;
case PD_NORMAL: case PD_NORMAL:
......
...@@ -15,6 +15,11 @@ config MACH_STM32F429 ...@@ -15,6 +15,11 @@ config MACH_STM32F429
depends on ARCH_STM32 depends on ARCH_STM32
default y default y
config MACH_STM32F469
bool "STMicrolectronics STM32F469"
depends on ARCH_STM32
default y
config MACH_STM32F746 config MACH_STM32F746
bool "STMicrolectronics STM32F746" bool "STMicrolectronics STM32F746"
depends on ARCH_STM32 depends on ARCH_STM32
......
menu "SOC (System On Chip) specific Drivers" menu "SOC (System On Chip) specific Drivers"
source "drivers/soc/actions/Kconfig"
source "drivers/soc/atmel/Kconfig" source "drivers/soc/atmel/Kconfig"
source "drivers/soc/bcm/Kconfig" source "drivers/soc/bcm/Kconfig"
source "drivers/soc/fsl/Kconfig" source "drivers/soc/fsl/Kconfig"
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
# Makefile for the Linux Kernel SOC specific device drivers. # Makefile for the Linux Kernel SOC specific device drivers.
# #
obj-$(CONFIG_ARCH_ACTIONS) += actions/
obj-$(CONFIG_ARCH_AT91) += atmel/ obj-$(CONFIG_ARCH_AT91) += atmel/
obj-y += bcm/ obj-y += bcm/
obj-$(CONFIG_ARCH_DOVE) += dove/ obj-$(CONFIG_ARCH_DOVE) += dove/
......
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
obj-$(CONFIG_OWL_PM_DOMAINS_HELPER) += owl-sps-helper.o
obj-$(CONFIG_OWL_PM_DOMAINS) += owl-sps.o
/*
* 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);
/*
* 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);
...@@ -106,6 +106,30 @@ static const struct at91_soc __initconst socs[] = { ...@@ -106,6 +106,30 @@ static const struct at91_soc __initconst socs[] = {
"sama5d43", "sama5d4"), "sama5d43", "sama5d4"),
AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D44_EXID_MATCH, AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D44_EXID_MATCH,
"sama5d44", "sama5d4"), "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 #endif
{ /* sentinel */ }, { /* sentinel */ },
}; };
......
...@@ -88,4 +88,30 @@ at91_soc_init(const struct at91_soc *socs); ...@@ -88,4 +88,30 @@ at91_soc_init(const struct at91_soc *socs);
#define SAMA5D43_EXID_MATCH 0x00000003 #define SAMA5D43_EXID_MATCH 0x00000003
#define SAMA5D44_EXID_MATCH 0x00000004 #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 */ #endif /* __AT91_SOC_H */
/*
* 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
...@@ -7,9 +7,6 @@ ...@@ -7,9 +7,6 @@
#ifndef __ATMEL_H__ #ifndef __ATMEL_H__
#define __ATMEL_H__ #define __ATMEL_H__
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
/* Compact Flash */ /* Compact Flash */
struct at91_cf_data { struct at91_cf_data {
int irq_pin; /* I/O IRQ */ int irq_pin; /* I/O IRQ */
...@@ -22,26 +19,14 @@ struct at91_cf_data { ...@@ -22,26 +19,14 @@ struct at91_cf_data {
#define AT91_IDE_SWAP_A0_A2 0x02 #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 */ /* FIXME: this needs a better location, but gets stuff building again */
#ifdef CONFIG_ATMEL_PM
extern int at91_suspend_entering_slow_clock(void); extern int at91_suspend_entering_slow_clock(void);
#else
static inline int at91_suspend_entering_slow_clock(void)
{
return 0;
}
#endif
#endif /* __ATMEL_H__ */ #endif /* __ATMEL_H__ */
/*
* 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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment