Commit 7c00e8ae 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 Olof Johansson:
 "Here are the main updates for SoC support (besides DT additions) for
  ARM 32- and 64-bit platforms. The branch also contains defconfig
  updates to turn on drivers and options as needed on the various
  platforms.

  The largest parts of the delta are from cleanups moving platform data
  and board file setup of TI platforms to ti-sysc bus drivers. There are
  also some sweeping changes of eeprom and nand setup on Davinci, i.MX
  and other platforms.

  Samsung is removing support for Exynos5440, which was an oddball SoC
  that hasn't been seen much use in designs.

  Renesas is adding support for new SoCs (R-Car E3, RZ/G1C and RZ/N1D).

  Linus Walleij is also removing support for ux500 (Sony Ericsson)
  U8540/9540 SoCs that never made it to significant mass production and
  products"

* tag 'armsoc-soc' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (133 commits)
  MAINTAINERS: add NXP linux team maillist as i.MX reviewer
  ARM: stm32: Don't select DMA unconditionally on STM32MP157C
  arm64: defconfig: Enable PCIe on msm8996 and db820c
  ARM: pxa3xx: enable external wakeup pins
  ARM: pxa: stargate2: use device properties for at24 eeprom
  arm64: defconfig: Enable HISILICON_LPC
  arm64: defconfig: enable drivers for Poplar support
  arm64: defconfig: Enable UFS on msm8996
  ARM: berlin: switch to SPDX license identifier
  arm: berlin: remove non-necessary flush_cache_all()
  ARM: berlin: extend BG2CD Kconfig entry
  OMAP: CLK: CLKSRC: Add suspend resume hooks
  ARM: AM43XX: Add functions to save/restore am43xx control registers
  ASoC: ams_delta: use GPIO lookup table
  ARM: OMAP1: ams-delta: add GPIO lookup tables
  bus: ti-sysc: Fix optional clocks array access
  ARM: OMAP2+: Make sure LOGICRETSTATE bits are not cleared
  ARM: OMAP2+: prm44xx: Inroduce cpu_pm notifiers for context save/restore
  ARM: OMAP2+: prm44xx: Introduce context save/restore for am43 PRCM IO
  ARM: OMAP2+: powerdomain: Introduce cpu_pm notifiers for context save/restore
  ...
parents a2b7ab45 958da6e3
......@@ -21,6 +21,8 @@ SoCs:
compatible = "renesas,r8a7744"
- RZ/G1E (R8A77450)
compatible = "renesas,r8a7745"
- RZ/G1C (R8A77470)
compatible = "renesas,r8a77470"
- R-Car M1A (R8A77781)
compatible = "renesas,r8a7778"
- R-Car H1 (R8A77790)
......
......@@ -79,7 +79,11 @@ Optional properties:
mode as for example omap4 L4_CFG_CLKCTRL
- clock-names should contain at least "fck", and optionally also "ick"
depending on the SoC and the interconnect target module
depending on the SoC and the interconnect target module,
some interconnect target modules also need additional
optional clocks that can be specified as listed in TRM
for the related CLKCTRL register bits 8 to 15 such as
"dbclk" or "clk32k" depending on their role
- ti,hwmods optional TI interconnect module name to use legacy
hwmod platform data
......
......@@ -9,6 +9,7 @@ Required properties:
- compatible: Must contain exactly one of the following:
- "renesas,r8a7743-sysc" (RZ/G1M)
- "renesas,r8a7745-sysc" (RZ/G1E)
- "renesas,r8a77470-sysc" (RZ/G1C)
- "renesas,r8a7779-sysc" (R-Car H1)
- "renesas,r8a7790-sysc" (R-Car H2)
- "renesas,r8a7791-sysc" (R-Car M2-W)
......@@ -20,6 +21,7 @@ Required properties:
- "renesas,r8a77965-sysc" (R-Car M3-N)
- "renesas,r8a77970-sysc" (R-Car V3M)
- "renesas,r8a77980-sysc" (R-Car V3H)
- "renesas,r8a77990-sysc" (R-Car E3)
- "renesas,r8a77995-sysc" (R-Car D3)
- reg: Address start and address range for the device.
- #power-domain-cells: Must be 1.
......
......@@ -17,6 +17,7 @@ Required properties:
Examples with soctypes are:
- "renesas,r8a7743-rst" (RZ/G1M)
- "renesas,r8a7745-rst" (RZ/G1E)
- "renesas,r8a77470-rst" (RZ/G1C)
- "renesas,r8a7778-reset-wdt" (R-Car M1A)
- "renesas,r8a7779-reset-wdt" (R-Car H1)
- "renesas,r8a7790-rst" (R-Car H2)
......@@ -29,6 +30,7 @@ Required properties:
- "renesas,r8a77965-rst" (R-Car M3-N)
- "renesas,r8a77970-rst" (R-Car V3M)
- "renesas,r8a77980-rst" (R-Car V3H)
- "renesas,r8a77990-rst" (R-Car E3)
- "renesas,r8a77995-rst" (R-Car D3)
- reg: Address start and address range for the device.
......
......@@ -1419,6 +1419,7 @@ M: Shawn Guo <shawnguo@kernel.org>
M: Sascha Hauer <s.hauer@pengutronix.de>
R: Pengutronix Kernel Team <kernel@pengutronix.de>
R: Fabio Estevam <fabio.estevam@nxp.com>
R: NXP Linux Team <linux-imx@nxp.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/shawnguo/linux.git
......
......@@ -1463,7 +1463,7 @@ config ARM_PSCI
config ARCH_NR_GPIO
int
default 2048 if ARCH_SOCFPGA
default 1024 if ARCH_BRCMSTB || ARCH_SHMOBILE || ARCH_TEGRA || \
default 1024 if ARCH_BRCMSTB || ARCH_RENESAS || ARCH_TEGRA || \
ARCH_ZYNQ
default 512 if ARCH_EXYNOS || ARCH_KEYSTONE || SOC_OMAP5 || \
SOC_DRA7XX || ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5PV210
......
......@@ -942,6 +942,13 @@ choice
via SCIF0 on Renesas RZ/G1M (R8A7743), R-Car H2 (R8A7790),
M2-W (R8A7791), V2H (R8A7792), or M2-N (R8A7793).
config DEBUG_RCAR_GEN2_SCIF1
bool "Kernel low-level debugging messages via SCIF1 on R8A77470"
depends on ARCH_R8A77470
help
Say Y here if you want kernel low-level debugging support
via SCIF1 on Renesas RZ/G1C (R8A77470).
config DEBUG_RCAR_GEN2_SCIF2
bool "Kernel low-level debugging messages via SCIF2 on R8A7794"
depends on ARCH_R8A7794
......@@ -1495,6 +1502,7 @@ config DEBUG_LL_INCLUDE
default "debug/renesas-scif.S" if DEBUG_RCAR_GEN1_SCIF0
default "debug/renesas-scif.S" if DEBUG_RCAR_GEN1_SCIF2
default "debug/renesas-scif.S" if DEBUG_RCAR_GEN2_SCIF0
default "debug/renesas-scif.S" if DEBUG_RCAR_GEN2_SCIF1
default "debug/renesas-scif.S" if DEBUG_RCAR_GEN2_SCIF2
default "debug/renesas-scif.S" if DEBUG_RCAR_GEN2_SCIF4
default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA0
......@@ -1617,6 +1625,7 @@ config DEBUG_UART_PHYS
default 0xe6c80000 if DEBUG_RMOBILE_SCIFA4
default 0xe6e58000 if DEBUG_RCAR_GEN2_SCIF2
default 0xe6e60000 if DEBUG_RCAR_GEN2_SCIF0
default 0xe6e68000 if DEBUG_RCAR_GEN2_SCIF1
default 0xe6ee0000 if DEBUG_RCAR_GEN2_SCIF4
default 0xe8008000 if DEBUG_R7S72100_SCIF2
default 0xf0000be0 if ARCH_EBSA110
......@@ -1651,8 +1660,8 @@ config DEBUG_UART_PHYS
DEBUG_NETX_UART || \
DEBUG_QCOM_UARTDM || DEBUG_R7S72100_SCIF2 || \
DEBUG_RCAR_GEN1_SCIF0 || DEBUG_RCAR_GEN1_SCIF2 || \
DEBUG_RCAR_GEN2_SCIF0 || DEBUG_RCAR_GEN2_SCIF2 || \
DEBUG_RCAR_GEN2_SCIF4 || \
DEBUG_RCAR_GEN2_SCIF0 || DEBUG_RCAR_GEN2_SCIF1 || \
DEBUG_RCAR_GEN2_SCIF2 || DEBUG_RCAR_GEN2_SCIF4 || \
DEBUG_RMOBILE_SCIFA0 || DEBUG_RMOBILE_SCIFA1 || \
DEBUG_RMOBILE_SCIFA4 || DEBUG_S3C24XX_UART || \
DEBUG_S3C64XX_UART || \
......
......@@ -212,7 +212,7 @@ machine-$(CONFIG_ARCH_S3C24XX) += s3c24xx
machine-$(CONFIG_ARCH_S3C64XX) += s3c64xx
machine-$(CONFIG_ARCH_S5PV210) += s5pv210
machine-$(CONFIG_ARCH_SA1100) += sa1100
machine-$(CONFIG_ARCH_SHMOBILE) += shmobile
machine-$(CONFIG_ARCH_RENESAS) += shmobile
machine-$(CONFIG_ARCH_SIRF) += prima2
machine-$(CONFIG_ARCH_SOCFPGA) += socfpga
machine-$(CONFIG_ARCH_STI) += sti
......
......@@ -10,6 +10,7 @@ obj-$(CONFIG_DMABOUNCE) += dmabounce.o
obj-$(CONFIG_SHARP_LOCOMO) += locomo.o
obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o
obj-$(CONFIG_SHARP_SCOOP) += scoop.o
obj-$(CONFIG_SMP) += secure_cntvoff.o
obj-$(CONFIG_PCI_HOST_ITE8152) += it8152.o
obj-$(CONFIG_MCPM) += mcpm_head.o mcpm_entry.o mcpm_platsmp.o vlock.o
CFLAGS_REMOVE_mcpm_entry.o = -pg
......
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2014 Renesas Electronics Corporation
*
* Initialization of CNTVOFF register from secure mode
*
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
ENTRY(secure_cntvoff_init)
.arch armv7-a
/*
* CNTVOFF has to be initialized either from non-secure Hypervisor
* mode or secure Monitor mode with SCR.NS==1. If TrustZone is enabled
* then it should be handled by the secure code. The CPU must implement
* the virtualization extensions.
*/
cps #MON_MODE
mrc p15, 0, r1, c1, c1, 0 /* Get Secure Config */
orr r0, r1, #1
mcr p15, 0, r0, c1, c1, 0 /* Set Non Secure bit */
isb
mov r0, #0
mcrr p15, 4, r0, r0, c14 /* CNTVOFF = 0 */
isb
mcr p15, 0, r1, c1, c1, 0 /* Set Secure bit */
isb
cps #SVC_MODE
ret lr
ENDPROC(secure_cntvoff_init)
......@@ -64,6 +64,7 @@ CONFIG_BLK_DEV_SD=y
CONFIG_SCSI_CONSTANTS=y
CONFIG_SCSI_SCAN_ASYNC=y
CONFIG_NETDEVICES=y
CONFIG_USB_LAN78XX=y
CONFIG_USB_USBNET=y
CONFIG_USB_NET_SMSC95XX=y
CONFIG_BRCMFMAC=m
......@@ -127,6 +128,7 @@ CONFIG_LEDS_TRIGGER_CAMERA=y
CONFIG_DMADEVICES=y
CONFIG_DMA_BCM2835=y
CONFIG_STAGING=y
CONFIG_BCM2835_VCHIQ=m
CONFIG_MAILBOX=y
CONFIG_BCM2835_MBOX=y
# CONFIG_IOMMU_SUPPORT is not set
......
......@@ -56,7 +56,7 @@ CONFIG_IP_PNP_DHCP=y
CONFIG_NETFILTER=y
CONFIG_DEVTMPFS=y
CONFIG_DEVTMPFS_MOUNT=y
# CONFIG_FW_LOADER is not set
CONFIG_FW_LOADER=m
CONFIG_DMA_CMA=y
CONFIG_DA8XX_MSTPRI=y
CONFIG_MTD=m
......@@ -212,6 +212,8 @@ CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_OMAP=m
CONFIG_DMADEVICES=y
CONFIG_TI_EDMA=y
CONFIG_REMOTEPROC=m
CONFIG_DA8XX_REMOTEPROC=m
CONFIG_MEMORY=y
CONFIG_TI_AEMIF=m
CONFIG_DA8XX_DDRCTL=y
......
......@@ -208,6 +208,7 @@ CONFIG_DRM_EXYNOS_DSI=y
CONFIG_DRM_EXYNOS_HDMI=y
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_PANEL_SAMSUNG_LD9040=y
CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=y
CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=y
CONFIG_DRM_NXP_PTN3460=y
CONFIG_DRM_PARADE_PS8622=y
......
......@@ -38,6 +38,7 @@ CONFIG_SOC_IMX51=y
CONFIG_SOC_IMX53=y
CONFIG_SOC_IMX6Q=y
CONFIG_SOC_IMX6SL=y
CONFIG_SOC_IMX6SLL=y
CONFIG_SOC_IMX6SX=y
CONFIG_SOC_IMX6UL=y
CONFIG_SOC_IMX7D=y
......@@ -153,6 +154,9 @@ CONFIG_USB_RTL8152=m
CONFIG_USB_USBNET=y
CONFIG_USB_NET_CDC_EEM=m
CONFIG_BRCMFMAC=m
CONFIG_MWIFIEX=m
CONFIG_MWIFIEX_SDIO=m
CONFIG_MWIFIEX_PCIE=m
CONFIG_WL12XX=m
CONFIG_WL18XX=m
CONFIG_WLCORE_SDIO=m
......@@ -199,6 +203,7 @@ CONFIG_SPI_GPIO=y
CONFIG_SPI_IMX=y
CONFIG_SPI_FSL_DSPI=y
CONFIG_GPIO_SYSFS=y
CONFIG_GPIO_MAX732X=y
CONFIG_GPIO_MC9S08DZ60=y
CONFIG_GPIO_PCA953X=y
CONFIG_GPIO_STMPE=y
......@@ -214,11 +219,13 @@ CONFIG_CPU_THERMAL=y
CONFIG_IMX_THERMAL=y
CONFIG_WATCHDOG=y
CONFIG_DA9062_WATCHDOG=y
CONFIG_RN5T618_WATCHDOG=y
CONFIG_IMX2_WDT=y
CONFIG_MFD_DA9052_I2C=y
CONFIG_MFD_DA9062=y
CONFIG_MFD_MC13XXX_SPI=y
CONFIG_MFD_MC13XXX_I2C=y
CONFIG_MFD_RN5T618=y
CONFIG_MFD_STMPE=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
......@@ -229,6 +236,7 @@ CONFIG_REGULATOR_GPIO=y
CONFIG_REGULATOR_MC13783=y
CONFIG_REGULATOR_MC13892=y
CONFIG_REGULATOR_PFUZE100=y
CONFIG_REGULATOR_RN5T618=y
CONFIG_RC_CORE=y
CONFIG_RC_DEVICES=y
CONFIG_IR_GPIO_CIR=y
......@@ -374,6 +382,7 @@ CONFIG_PWM=y
CONFIG_PWM_FSL_FTM=y
CONFIG_PWM_IMX=y
CONFIG_NVMEM_IMX_OCOTP=y
CONFIG_NVMEM_VF610_OCOTP=y
CONFIG_TEE=y
CONFIG_OPTEE=y
CONFIG_MUX_MMIO=y
......
......@@ -90,6 +90,7 @@ CONFIG_ARCH_R8A73A4=y
CONFIG_ARCH_R8A7740=y
CONFIG_ARCH_R8A7743=y
CONFIG_ARCH_R8A7745=y
CONFIG_ARCH_R8A77470=y
CONFIG_ARCH_R8A7778=y
CONFIG_ARCH_R8A7779=y
CONFIG_ARCH_R8A7790=y
......@@ -187,6 +188,8 @@ CONFIG_B53_MMAP_DRIVER=m
CONFIG_B53_SRAB_DRIVER=m
CONFIG_CAN_SUN4I=y
CONFIG_BT=m
CONFIG_BT_HCIUART=m
CONFIG_BT_HCIUART_BCM=y
CONFIG_BT_MRVL=m
CONFIG_BT_MRVL_SDIO=m
CONFIG_CFG80211=m
......@@ -280,6 +283,7 @@ CONFIG_FIXED_PHY=y
CONFIG_ROCKCHIP_PHY=y
CONFIG_USB_PEGASUS=y
CONFIG_USB_RTL8152=m
CONFIG_USB_LAN78XX=m
CONFIG_USB_USBNET=y
CONFIG_USB_NET_SMSC75XX=y
CONFIG_USB_NET_SMSC95XX=y
......@@ -360,10 +364,12 @@ CONFIG_SERIAL_ST_ASC=y
CONFIG_SERIAL_ST_ASC_CONSOLE=y
CONFIG_SERIAL_STM32=y
CONFIG_SERIAL_STM32_CONSOLE=y
CONFIG_SERIAL_DEV_BUS=y
CONFIG_HVC_DRIVER=y
CONFIG_VIRTIO_CONSOLE=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_DAVINCI=y
CONFIG_I2C_MESON=y
CONFIG_I2C_MUX=y
CONFIG_I2C_ARB_GPIO_CHALLENGE=m
CONFIG_I2C_MUX_PCA954x=y
......@@ -385,6 +391,7 @@ CONFIG_I2C_S3C2410=y
CONFIG_I2C_SH_MOBILE=y
CONFIG_I2C_SIRF=y
CONFIG_I2C_ST=y
CONFIG_I2C_STM32F7=y
CONFIG_I2C_SUN6I_P2WI=y
CONFIG_I2C_TEGRA=y
CONFIG_I2C_UNIPHIER=y
......@@ -497,6 +504,7 @@ CONFIG_TEGRA_WATCHDOG=m
CONFIG_MESON_WATCHDOG=y
CONFIG_DW_WATCHDOG=y
CONFIG_DIGICOLOR_WATCHDOG=y
CONFIG_RENESAS_WDT=m
CONFIG_BCM2835_WDT=y
CONFIG_BCM47XX_WDT=y
CONFIG_BCM7038_WDT=m
......@@ -638,6 +646,7 @@ CONFIG_DRM_SUN4I=m
CONFIG_DRM_FSL_DCU=m
CONFIG_DRM_TEGRA=y
CONFIG_DRM_PANEL_SAMSUNG_LD9040=m
CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03=m
CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0=m
CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_DRM_SII9234=m
......@@ -650,7 +659,6 @@ CONFIG_FB_EFI=y
CONFIG_FB_WM8505=y
CONFIG_FB_SH_MOBILE_LCDC=y
CONFIG_FB_SIMPLE=y
CONFIG_FB_SH_MOBILE_MERAM=y
CONFIG_BACKLIGHT_LCD_SUPPORT=y
CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_LCD_PLATFORM=m
......@@ -947,6 +955,7 @@ CONFIG_PWM_ATMEL=m
CONFIG_PWM_ATMEL_HLCDC_PWM=m
CONFIG_PWM_ATMEL_TCB=m
CONFIG_PWM_FSL_FTM=m
CONFIG_PWM_MESON=m
CONFIG_PWM_RCAR=m
CONFIG_PWM_RENESAS_TPU=y
CONFIG_PWM_ROCKCHIP=m
......@@ -972,6 +981,7 @@ CONFIG_PHY_QCOM_APQ8064_SATA=m
CONFIG_PHY_MIPHY28LP=y
CONFIG_PHY_RCAR_GEN2=m
CONFIG_PHY_STIH407_USB=y
CONFIG_PHY_STM32_USBPHYC=y
CONFIG_PHY_SUN4I_USB=y
CONFIG_PHY_SUN9I_USB=y
CONFIG_PHY_SAMSUNG_USB2=m
......
......@@ -14,6 +14,7 @@ CONFIG_ARCH_R8A73A4=y
CONFIG_ARCH_R8A7740=y
CONFIG_ARCH_R8A7743=y
CONFIG_ARCH_R8A7745=y
CONFIG_ARCH_R8A77470=y
CONFIG_ARCH_R8A7778=y
CONFIG_ARCH_R8A7779=y
CONFIG_ARCH_R8A7790=y
......@@ -127,6 +128,7 @@ CONFIG_CPU_THERMAL=y
CONFIG_RCAR_THERMAL=y
CONFIG_WATCHDOG=y
CONFIG_DA9063_WATCHDOG=y
CONFIG_RENESAS_WDT=y
CONFIG_MFD_AS3711=y
CONFIG_MFD_DA9063=y
CONFIG_REGULATOR_FIXED_VOLTAGE=y
......@@ -156,7 +158,6 @@ CONFIG_DRM_DUMB_VGA_DAC=y
CONFIG_DRM_I2C_ADV7511=y
CONFIG_DRM_I2C_ADV7511_AUDIO=y
CONFIG_FB_SH_MOBILE_LCDC=y
CONFIG_FB_SH_MOBILE_MERAM=y
# CONFIG_LCD_CLASS_DEVICE is not set
# CONFIG_BACKLIGHT_GENERIC is not set
CONFIG_BACKLIGHT_PWM=y
......
......@@ -2,9 +2,6 @@
#ifndef __ASM_ARM_CPUTYPE_H
#define __ASM_ARM_CPUTYPE_H
#include <linux/stringify.h>
#include <linux/kernel.h>
#define CPUID_ID 0
#define CPUID_CACHETYPE 1
#define CPUID_TCM 2
......@@ -62,6 +59,7 @@
((mpidr >> (MPIDR_LEVEL_BITS * level)) & MPIDR_LEVEL_MASK)
#define ARM_CPU_IMP_ARM 0x41
#define ARM_CPU_IMP_BRCM 0x42
#define ARM_CPU_IMP_DEC 0x44
#define ARM_CPU_IMP_INTEL 0x69
......@@ -84,8 +82,9 @@
#define ARM_CPU_PART_CORTEX_A75 0x4100d0a0
#define ARM_CPU_PART_MASK 0xff00fff0
/* Broadcom cores */
/* Broadcom implemented processors */
#define ARM_CPU_PART_BRAHMA_B15 0x420000f0
#define ARM_CPU_PART_BRAHMA_B53 0x42001000
/* DEC implemented cores */
#define ARM_CPU_PART_SA1100 0x4400a110
......@@ -106,6 +105,11 @@
/* Qualcomm implemented cores */
#define ARM_CPU_PART_SCORPION 0x510002d0
#ifndef __ASSEMBLY__
#include <linux/stringify.h>
#include <linux/kernel.h>
extern unsigned int processor_id;
#ifdef CONFIG_CPU_CP15
......@@ -334,4 +338,6 @@ static inline int __attribute_const__ cpuid_feature_extract_field(u32 features,
#define cpuid_feature_extract(reg, field) \
cpuid_feature_extract_field(read_cpuid_ext(reg), field)
#endif /* __ASSEMBLY__ */
#endif
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASMARM_ARCH_CNTVOFF_H
#define __ASMARM_ARCH_CNTVOFF_H
extern void secure_cntvoff_init(void);
#endif
......@@ -11,20 +11,25 @@
* GNU General Public License for more details.
*/
#include <linux/serial_reg.h>
#include <asm/cputype.h>
/* Physical register offset and virtual register offset */
#define REG_PHYS_BASE 0xf0000000
#define REG_PHYS_BASE_V7 0x08000000
#define REG_VIRT_BASE 0xfc000000
#define REG_PHYS_ADDR(x) ((x) + REG_PHYS_BASE)
#define REG_PHYS_ADDR_V7(x) ((x) + REG_PHYS_BASE_V7)
/* Product id can be read from here */
#define SUN_TOP_CTRL_BASE REG_PHYS_ADDR(0x404000)
#define SUN_TOP_CTRL_BASE_V7 REG_PHYS_ADDR_V7(0x404000)
#define UARTA_3390 REG_PHYS_ADDR(0x40a900)
#define UARTA_7250 REG_PHYS_ADDR(0x40b400)
#define UARTA_7260 REG_PHYS_ADDR(0x40c000)
#define UARTA_7268 UARTA_7260
#define UARTA_7271 UARTA_7268
#define UARTA_7278 REG_PHYS_ADDR_V7(0x40c000)
#define UARTA_7364 REG_PHYS_ADDR(0x40b000)
#define UARTA_7366 UARTA_7364
#define UARTA_74371 REG_PHYS_ADDR(0x406b00)
......@@ -55,8 +60,21 @@
mov \rv, #0 @ yes; record init is done
str \rv, [\tmp]
/* Check for V7 memory map if B53 */
mrc p15, 0, \rv, c0, c0, 0 @ get Main ID register
ldr \rp, =ARM_CPU_PART_MASK
and \rv, \rv, \rp
ldr \rp, =ARM_CPU_PART_BRAHMA_B53 @ check for B53 CPU
cmp \rv, \rp
bne 10f
/* if PERIPHBASE doesn't overlap REG_PHYS_BASE use V7 map */
mrc p15, 1, \rv, c15, c3, 0 @ get PERIPHBASE from CBAR
ands \rv, \rv, #REG_PHYS_BASE
ldreq \rp, =SUN_TOP_CTRL_BASE_V7
/* Check SUN_TOP_CTRL base */
ldr \rp, =SUN_TOP_CTRL_BASE @ load SUN_TOP_CTRL PA
10: ldrne \rp, =SUN_TOP_CTRL_BASE @ load SUN_TOP_CTRL PA
ldr \rv, [\rp, #0] @ get register contents
ARM_BE8( rev \rv, \rv )
and \rv, \rv, #0xffffff00 @ strip revision bits [7:0]
......@@ -72,6 +90,7 @@ ARM_BE8( rev \rv, \rv )
27: checkuart(\rp, \rv, 0x07437100, 74371)
28: checkuart(\rp, \rv, 0x74390000, 7439)
29: checkuart(\rp, \rv, 0x74450000, 7445)
30: checkuart(\rp, \rv, 0x72780000, 7278)
/* No valid UART found */
90: mov \rp, #0
......
......@@ -23,8 +23,12 @@ config MACH_BERLIN_BG2
config MACH_BERLIN_BG2CD
bool "Marvell Armada 1500-mini (BG2CD)"
select ARM_ERRATA_754322
select ARM_ERRATA_775420
select ARM_GLOBAL_TIMER
select CACHE_L2X0
select HAVE_ARM_TWD if SMP
select HAVE_ARM_SCU
select HAVE_ARM_TWD
select PINCTRL_BERLIN_BG2CD
config MACH_BERLIN_BG2Q
......
// SPDX-License-Identifier: GPL-2.0
/*
* Device Tree support for Marvell Berlin SoCs.
*
......@@ -5,10 +6,6 @@
*
* based on GPL'ed 2.6 kernel sources
* (c) Marvell International Ltd.
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
* warranty of any kind, whether express or implied.
*/
#include <linux/init.h>
......
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 2014 Marvell Technology Group Ltd.
*
* Antoine Ténart <antoine.tenart@free-electrons.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/linkage.h>
......
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2014 Marvell Technology Group Ltd.
*
* Antoine Ténart <antoine.tenart@free-electrons.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/io.h>
......@@ -81,7 +78,6 @@ static void __init berlin_smp_prepare_cpus(unsigned int max_cpus)
goto unmap_scu;
scu_enable(scu_base);
flush_cache_all();
/*
* Write the first instruction the CPU will execute after being reset
......
......@@ -189,7 +189,7 @@ int davinci_aemif_setup(struct platform_device *pdev)
* Setup Async configuration register in case we did not boot
* from NAND and so bootloader did not bother to set it up.
*/
val = davinci_aemif_readl(base, A1CR_OFFSET + pdev->id * 4);
val = davinci_aemif_readl(base, A1CR_OFFSET + pdata->core_chipsel * 4);
/*
* Extended Wait is not valid and Select Strobe mode is not
* used
......@@ -198,13 +198,13 @@ int davinci_aemif_setup(struct platform_device *pdev)
if (pdata->options & NAND_BUSWIDTH_16)
val |= 0x1;
davinci_aemif_writel(base, A1CR_OFFSET + pdev->id * 4, val);
davinci_aemif_writel(base, A1CR_OFFSET + pdata->core_chipsel * 4, val);
clkrate = clk_get_rate(clk);
if (pdata->timing)
ret = davinci_aemif_setup_timing(pdata->timing, base, pdev->id,
clkrate);
ret = davinci_aemif_setup_timing(pdata->timing, base,
pdata->core_chipsel, clkrate);
if (ret < 0)
dev_dbg(&pdev->dev, "NAND timing values setup fail\n");
......
......@@ -315,6 +315,7 @@ static struct davinci_aemif_timing da830_evm_nandflash_timing = {
};
static struct davinci_nand_pdata da830_evm_nand_pdata = {
.core_chipsel = 1,
.parts = da830_evm_nand_partitions,
.nr_parts = ARRAY_SIZE(da830_evm_nand_partitions),
.ecc_mode = NAND_ECC_HW,
......
......@@ -244,6 +244,7 @@ static struct davinci_aemif_timing da850_evm_nandflash_timing = {
};
static struct davinci_nand_pdata da850_evm_nandflash_data = {
.core_chipsel = 1,
.parts = da850_evm_nandflash_partition,
.nr_parts = ARRAY_SIZE(da850_evm_nandflash_partition),
.ecc_mode = NAND_ECC_HW,
......
......@@ -78,6 +78,7 @@ static struct mtd_partition davinci_nand_partitions[] = {
};
static struct davinci_nand_pdata davinci_nand_data = {
.core_chipsel = 0,
.mask_chipsel = BIT(14),
.parts = davinci_nand_partitions,
.nr_parts = ARRAY_SIZE(davinci_nand_partitions),
......
......@@ -72,6 +72,7 @@ static struct mtd_partition davinci_nand_partitions[] = {
};
static struct davinci_nand_pdata davinci_nand_data = {
.core_chipsel = 0,
.mask_chipsel = BIT(14),
.parts = davinci_nand_partitions,
.nr_parts = ARRAY_SIZE(davinci_nand_partitions),
......
......@@ -138,6 +138,7 @@ static struct mtd_partition davinci_nand_partitions[] = {
};
static struct davinci_nand_pdata davinci_nand_data = {
.core_chipsel = 0,
.mask_chipsel = BIT(14),
.parts = davinci_nand_partitions,
.nr_parts = ARRAY_SIZE(davinci_nand_partitions),
......
......@@ -153,6 +153,7 @@ static struct davinci_aemif_timing davinci_evm_nandflash_timing = {
};
static struct davinci_nand_pdata davinci_evm_nandflash_data = {
.core_chipsel = 0,
.parts = davinci_evm_nandflash_partition,
.nr_parts = ARRAY_SIZE(davinci_evm_nandflash_partition),
.ecc_mode = NAND_ECC_HW,
......@@ -772,6 +773,8 @@ static __init void davinci_evm_init(void)
struct clk *aemif_clk;
struct davinci_soc_info *soc_info = &davinci_soc_info;
dm644x_init_devices();
ret = dm644x_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
......
......@@ -84,6 +84,7 @@ static struct davinci_aemif_timing dm6467tevm_nandflash_timing = {
};
static struct davinci_nand_pdata davinci_nand_data = {
.core_chipsel = 0,
.mask_cle = 0x80000,
.mask_ale = 0x40000,
.parts = davinci_nand_partitions,
......
......@@ -400,6 +400,7 @@ static struct mtd_partition mityomapl138_nandflash_partition[] = {
};
static struct davinci_nand_pdata mityomapl138_nandflash_data = {
.core_chipsel = 1,
.parts = mityomapl138_nandflash_partition,
.nr_parts = ARRAY_SIZE(mityomapl138_nandflash_partition),
.ecc_mode = NAND_ECC_HW,
......
......@@ -87,6 +87,7 @@ static struct mtd_partition davinci_ntosd2_nandflash_partition[] = {
};
static struct davinci_nand_pdata davinci_ntosd2_nandflash_data = {
.core_chipsel = 0,
.parts = davinci_ntosd2_nandflash_partition,
.nr_parts = ARRAY_SIZE(davinci_ntosd2_nandflash_partition),
.ecc_mode = NAND_ECC_HW,
......@@ -174,6 +175,8 @@ static __init void davinci_ntosd2_init(void)
struct clk *aemif_clk;
struct davinci_soc_info *soc_info = &davinci_soc_info;
dm644x_init_devices();
ret = dm644x_gpio_register();
if (ret)
pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
......
......@@ -134,6 +134,8 @@ static __init void davinci_sffsdr_init(void)
{
struct davinci_soc_info *soc_info = &davinci_soc_info;
dm644x_init_devices();
platform_add_devices(davinci_sffsdr_devices,
ARRAY_SIZE(davinci_sffsdr_devices));
sffsdr_init_i2c();
......
......@@ -104,6 +104,7 @@ int dm365_gpio_register(void);
/* DM644x function declarations */
void dm644x_init(void);
void dm644x_init_devices(void);
void dm644x_init_time(void);
void dm644x_init_asp(void);
int dm644x_init_video(struct vpfe_config *, struct vpbe_config *);
......
......@@ -961,19 +961,14 @@ int __init dm644x_init_video(struct vpfe_config *vpfe_cfg,
return 0;
}
static int __init dm644x_init_devices(void)
void __init dm644x_init_devices(void)
{
struct platform_device *edma_pdev;
int ret = 0;
if (!cpu_is_davinci_dm644x())
return 0;
int ret;
edma_pdev = platform_device_register_full(&dm644x_edma_device);
if (IS_ERR(edma_pdev)) {
if (IS_ERR(edma_pdev))
pr_warn("%s: Failed to register eDMA\n", __func__);
return PTR_ERR(edma_pdev);
}
platform_device_register(&dm644x_mdio_device);
platform_device_register(&dm644x_emac_device);
......@@ -982,6 +977,4 @@ static int __init dm644x_init_devices(void)
if (ret)
pr_warn("%s: watchdog init failed: %d\n", __func__, ret);
return ret;
}
postcore_initcall(dm644x_init_devices);
......@@ -8,7 +8,6 @@
menuconfig ARCH_EXYNOS
bool "Samsung EXYNOS"
depends on ARCH_MULTI_V7
select ARCH_HAS_BANDGAP
select ARCH_HAS_HOLES_MEMORYMODEL
select ARCH_SUPPORTS_BIG_ENDIAN
select ARM_AMBA
......@@ -108,17 +107,6 @@ config SOC_EXYNOS5420
default y
depends on ARCH_EXYNOS5
config SOC_EXYNOS5440
bool "SAMSUNG EXYNOS5440"
default y
depends on ARCH_EXYNOS5
select HAVE_ARM_ARCH_TIMER
select AUTO_ZRELADDR
select PINCTRL_EXYNOS5440
select PM_OPP
help
Enable EXYNOS5440 SoC support
config SOC_EXYNOS5800
bool "SAMSUNG EXYNOS5800"
default y
......
......@@ -21,7 +21,6 @@
#define EXYNOS5250_SOC_ID 0x43520000
#define EXYNOS5410_SOC_ID 0xE5410000
#define EXYNOS5420_SOC_ID 0xE5420000
#define EXYNOS5440_SOC_ID 0xE5440000
#define EXYNOS5800_SOC_ID 0xE5422000
#define EXYNOS5_SOC_MASK 0xFFFFF000
......@@ -39,7 +38,6 @@ IS_SAMSUNG_CPU(exynos4412, EXYNOS4412_CPU_ID, EXYNOS4_CPU_MASK)
IS_SAMSUNG_CPU(exynos5250, EXYNOS5250_SOC_ID, EXYNOS5_SOC_MASK)
IS_SAMSUNG_CPU(exynos5410, EXYNOS5410_SOC_ID, EXYNOS5_SOC_MASK)
IS_SAMSUNG_CPU(exynos5420, EXYNOS5420_SOC_ID, EXYNOS5_SOC_MASK)
IS_SAMSUNG_CPU(exynos5440, EXYNOS5440_SOC_ID, EXYNOS5_SOC_MASK)
IS_SAMSUNG_CPU(exynos5800, EXYNOS5800_SOC_ID, EXYNOS5_SOC_MASK)
#if defined(CONFIG_SOC_EXYNOS3250)
......@@ -82,22 +80,12 @@ IS_SAMSUNG_CPU(exynos5800, EXYNOS5800_SOC_ID, EXYNOS5_SOC_MASK)
# define soc_is_exynos5420() 0
#endif
#if defined(CONFIG_SOC_EXYNOS5440)
# define soc_is_exynos5440() is_samsung_exynos5440()
#else
# define soc_is_exynos5440() 0
#endif
#if defined(CONFIG_SOC_EXYNOS5800)
# define soc_is_exynos5800() is_samsung_exynos5800()
#else
# define soc_is_exynos5800() 0
#endif
#define soc_is_exynos4() (soc_is_exynos4210() || soc_is_exynos4412())
#define soc_is_exynos5() (soc_is_exynos5250() || soc_is_exynos5410() || \
soc_is_exynos5420() || soc_is_exynos5800())
extern u32 cp15_save_diag;
extern u32 cp15_save_power;
......@@ -149,6 +137,11 @@ extern void exynos_cpu_restore_register(void);
extern void exynos_pm_central_suspend(void);
extern int exynos_pm_central_resume(void);
extern void exynos_enter_aftr(void);
#ifdef CONFIG_SMP
extern void exynos_scu_enable(void);
#else
static inline void exynos_scu_enable(void) { }
#endif
extern struct cpuidle_exynos_data cpuidle_coupled_exynos_data;
......
......@@ -24,15 +24,6 @@
#include "common.h"
static struct map_desc exynos4_iodesc[] __initdata = {
{
.virtual = (unsigned long)S5P_VA_COREPERI_BASE,
.pfn = __phys_to_pfn(EXYNOS4_PA_COREPERI),
.length = SZ_8K,
.type = MT_DEVICE,
},
};
static struct platform_device exynos_cpuidle = {
.name = "exynos_cpuidle",
#ifdef CONFIG_ARM_EXYNOS_CPUIDLE
......@@ -63,15 +54,6 @@ void __init exynos_sysram_init(void)
}
}
static void __init exynos_init_late(void)
{
if (of_machine_is_compatible("samsung,exynos5440"))
/* to be supported later */
return;
exynos_pm_init();
}
static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
int depth, void *data)
{
......@@ -79,8 +61,7 @@ static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
const __be32 *reg;
int len;
if (!of_flat_dt_is_compatible(node, "samsung,exynos4210-chipid") &&
!of_flat_dt_is_compatible(node, "samsung,exynos5440-clock"))
if (!of_flat_dt_is_compatible(node, "samsung,exynos4210-chipid"))
return 0;
reg = of_get_flat_dt_prop(node, "reg", &len);
......@@ -95,17 +76,6 @@ static int __init exynos_fdt_map_chipid(unsigned long node, const char *uname,
return 1;
}
/*
* exynos_map_io
*
* register the standard cpu IO areas
*/
static void __init exynos_map_io(void)
{
if (soc_is_exynos4())
iotable_init(exynos4_iodesc, ARRAY_SIZE(exynos4_iodesc));
}
static void __init exynos_init_io(void)
{
debug_ll_io_init();
......@@ -114,8 +84,6 @@ static void __init exynos_init_io(void)
/* detect cpu id and rev. */
s5p_init_cpu(S5P_VA_CHIPID);
exynos_map_io();
}
/*
......@@ -209,7 +177,6 @@ static char const *const exynos_dt_compat[] __initconst = {
"samsung,exynos5250",
"samsung,exynos5260",
"samsung,exynos5420",
"samsung,exynos5440",
NULL
};
......@@ -232,7 +199,7 @@ DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)")
.init_early = exynos_firmware_init,
.init_irq = exynos_init_irq,
.init_machine = exynos_dt_machine_init,
.init_late = exynos_init_late,
.init_late = exynos_pm_init,
.dt_compat = exynos_dt_compat,
.dt_fixup = exynos_dt_fixup,
MACHINE_END
......@@ -15,6 +15,4 @@
#define EXYNOS_PA_CHIPID 0x10000000
#define EXYNOS4_PA_COREPERI 0x10500000
#endif /* __ASM_ARCH_MAP_H */
......@@ -163,6 +163,26 @@ int exynos_cluster_power_state(int cluster)
S5P_CORE_LOCAL_PWR_EN);
}
/**
* exynos_scu_enable : enables SCU for Cortex-A9 based system
*/
void exynos_scu_enable(void)
{
struct device_node *np;
static void __iomem *scu_base;
if (!scu_base) {
np = of_find_compatible_node(NULL, NULL, "arm,cortex-a9-scu");
if (np) {
scu_base = of_iomap(np, 0);
of_node_put(np);
} else {
scu_base = ioremap(scu_a9_get_base(), SZ_4K);
}
}
scu_enable(scu_base);
}
static void __iomem *cpu_boot_reg_base(void)
{
if (soc_is_exynos4210() && samsung_rev() == EXYNOS4210_REV_1_1)
......@@ -219,11 +239,6 @@ static void write_pen_release(int val)
sync_cache_w(&pen_release);
}
static void __iomem *scu_base_addr(void)
{
return (void __iomem *)(S5P_VA_SCU);
}
static DEFINE_SPINLOCK(boot_lock);
static void exynos_secondary_init(unsigned int cpu)
......@@ -389,7 +404,7 @@ static void __init exynos_smp_prepare_cpus(unsigned int max_cpus)
exynos_set_delayed_reset_assertion(true);
if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9)
scu_enable(scu_base_addr());
exynos_scu_enable();
/*
* Write the address of secondary startup into the
......
......@@ -22,8 +22,6 @@
#include <asm/suspend.h>
#include <asm/cacheflush.h>
#include <mach/map.h>
#include "common.h"
static inline void __iomem *exynos_boot_vector_addr(void)
......@@ -172,7 +170,7 @@ void exynos_enter_aftr(void)
cpu_suspend(0, exynos_aftr_finisher);
if (read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
scu_enable(S5P_VA_SCU);
exynos_scu_enable();
if (call_firmware_op(resume) == -ENOSYS)
exynos_cpu_restore_register();
}
......
......@@ -30,8 +30,6 @@
#include <asm/smp_scu.h>
#include <asm/suspend.h>
#include <mach/map.h>
#include <plat/pm-common.h>
#include "common.h"
......@@ -401,7 +399,7 @@ static void exynos_pm_resume(void)
goto early_wakeup;
if (cpuid == ARM_CPU_PART_CORTEX_A9)
scu_enable(S5P_VA_SCU);
exynos_scu_enable();
if (call_firmware_op(resume) == -ENOSYS
&& cpuid == ARM_CPU_PART_CORTEX_A9)
......
......@@ -501,6 +501,7 @@ config SOC_IMX6SL
config SOC_IMX6SLL
bool "i.MX6 SoloLiteLite support"
select PINCTRL_IMX6SLL
select SOC_IMX6
help
......
......@@ -374,26 +374,12 @@ static struct imx_ssi_platform_data mx31_3ds_ssi_pdata = {
};
/* SPI */
static int spi0_internal_chipselect[] = {
MXC_SPI_CS(0),
MXC_SPI_CS(1),
MXC_SPI_CS(2),
};
static const struct spi_imx_master spi0_pdata __initconst = {
.chipselect = spi0_internal_chipselect,
.num_chipselect = ARRAY_SIZE(spi0_internal_chipselect),
};
static int spi1_internal_chipselect[] = {
MXC_SPI_CS(0),
MXC_SPI_CS(1),
MXC_SPI_CS(2),
.num_chipselect = 3,
};
static const struct spi_imx_master spi1_pdata __initconst = {
.chipselect = spi1_internal_chipselect,
.num_chipselect = ARRAY_SIZE(spi1_internal_chipselect),
.num_chipselect = 3,
};
static struct spi_board_info mx31_3ds_spi_devs[] __initdata = {
......
......@@ -226,20 +226,12 @@ static void __init lilly1131_usb_init(void)
/* SPI */
static int spi_internal_chipselect[] = {
MXC_SPI_CS(0),
MXC_SPI_CS(1),
MXC_SPI_CS(2),
};
static const struct spi_imx_master spi0_pdata __initconst = {
.chipselect = spi_internal_chipselect,
.num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
.num_chipselect = 3,
};
static const struct spi_imx_master spi1_pdata __initconst = {
.chipselect = spi_internal_chipselect,
.num_chipselect = ARRAY_SIZE(spi_internal_chipselect),
.num_chipselect = 3,
};
static struct mc13xxx_platform_data mc13783_pdata __initdata = {
......
......@@ -83,15 +83,8 @@ static const struct imxuart_platform_data uart_pdata __initconst = {
};
/* SPI */
static int spi0_internal_chipselect[] = {
MXC_SPI_CS(0),
MXC_SPI_CS(1),
MXC_SPI_CS(2),
};
static const struct spi_imx_master spi0_pdata __initconst = {
.chipselect = spi0_internal_chipselect,
.num_chipselect = ARRAY_SIZE(spi0_internal_chipselect),
.num_chipselect = 3,
};
static const struct mxc_nand_platform_data
......@@ -133,13 +126,8 @@ static struct platform_device smsc911x_device = {
* The MC13783 is the only hard-wired SPI device on the module.
*/
static int spi1_internal_chipselect[] = {
MXC_SPI_CS(0),
};
static const struct spi_imx_master spi1_pdata __initconst = {
.chipselect = spi1_internal_chipselect,
.num_chipselect = ARRAY_SIZE(spi1_internal_chipselect),
.num_chipselect = 1,
};
static struct mc13xxx_platform_data mc13783_pdata __initdata = {
......
......@@ -152,14 +152,8 @@ static const struct imxi2c_platform_data moboard_i2c1_data __initconst = {
.bitrate = 100000,
};
static int moboard_spi1_cs[] = {
MXC_SPI_CS(0),
MXC_SPI_CS(2),
};
static const struct spi_imx_master moboard_spi1_pdata __initconst = {
.chipselect = moboard_spi1_cs,
.num_chipselect = ARRAY_SIZE(moboard_spi1_cs),
.num_chipselect = 3,
};
static struct regulator_consumer_supply sdhc_consumers[] = {
......@@ -296,19 +290,14 @@ static struct spi_board_info moboard_spi_board_info[] __initdata = {
/* irq number is run-time assigned */
.max_speed_hz = 300000,
.bus_num = 1,
.chip_select = 1,
.chip_select = 0,
.platform_data = &moboard_pmic,
.mode = SPI_CS_HIGH,
},
};
static int moboard_spi2_cs[] = {
MXC_SPI_CS(0), MXC_SPI_CS(1),
};
static const struct spi_imx_master moboard_spi2_pdata __initconst = {
.chipselect = moboard_spi2_cs,
.num_chipselect = ARRAY_SIZE(moboard_spi2_cs),
.num_chipselect = 2,
};
#define SDHC1_CD IOMUX_TO_GPIO(MX31_PIN_ATA_CS0)
......
......@@ -20,7 +20,7 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/i2c.h>
#include <linux/platform_data/at24.h>
#include <linux/property.h>
#include <linux/dma-mapping.h>
#include <linux/spi/spi.h>
#include <linux/spi/eeprom.h>
......@@ -168,16 +168,15 @@ static const struct imxi2c_platform_data pca100_i2c1_data __initconst = {
.bitrate = 100000,
};
static struct at24_platform_data board_eeprom = {
.byte_len = 4096,
.page_size = 32,
.flags = AT24_FLAG_ADDR16,
static const struct property_entry board_eeprom_properties[] = {
PROPERTY_ENTRY_U32("pagesize", 32),
{ }
};
static struct i2c_board_info pca100_i2c_devices[] = {
{
I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
.platform_data = &board_eeprom,
I2C_BOARD_INFO("24c32", 0x52), /* E0=0, E1=1, E2=0 */
.properties = board_eeprom_properties,
}, {
I2C_BOARD_INFO("pcf8563", 0x51),
}, {
......
......@@ -23,7 +23,7 @@
#include <linux/smsc911x.h>
#include <linux/interrupt.h>
#include <linux/i2c.h>
#include <linux/platform_data/at24.h>
#include <linux/property.h>
#include <linux/delay.h>
#include <linux/spi/spi.h>
#include <linux/irq.h>
......@@ -263,16 +263,15 @@ static const struct imxi2c_platform_data pcm037_i2c2_data __initconst = {
.bitrate = 20000,
};
static struct at24_platform_data board_eeprom = {
.byte_len = 4096,
.page_size = 32,
.flags = AT24_FLAG_ADDR16,
static const struct property_entry board_eeprom_properties[] = {
PROPERTY_ENTRY_U32("pagesize", 32),
{ }
};
static struct i2c_board_info pcm037_i2c_devices[] = {
{
I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
.platform_data = &board_eeprom,
I2C_BOARD_INFO("24c32", 0x52), /* E0=0, E1=1, E2=0 */
.properties = board_eeprom_properties,
}, {
I2C_BOARD_INFO("pcf8563", 0x51),
}
......
......@@ -56,11 +56,8 @@ static struct spi_board_info pcm037_spi_dev[] = {
};
/* Platform Data for MXC CSPI */
static int pcm037_spi1_cs[] = { MXC_SPI_CS(0), MXC_SPI_CS(1), };
static const struct spi_imx_master pcm037_spi1_pdata __initconst = {
.chipselect = pcm037_spi1_cs,
.num_chipselect = ARRAY_SIZE(pcm037_spi1_cs),
.num_chipselect = 2,
};
/* GPIO-keys input device */
......
......@@ -24,7 +24,7 @@
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/platform_data/at24.h>
#include <linux/property.h>
#include <linux/usb/otg.h>
#include <linux/usb/ulpi.h>
......@@ -110,16 +110,15 @@ static const struct imxi2c_platform_data pcm043_i2c0_data __initconst = {
.bitrate = 50000,
};
static struct at24_platform_data board_eeprom = {
.byte_len = 4096,
.page_size = 32,
.flags = AT24_FLAG_ADDR16,
static const struct property_entry board_eeprom_properties[] = {
PROPERTY_ENTRY_U32("pagesize", 32),
{ }
};
static struct i2c_board_info pcm043_i2c_devices[] = {
{
I2C_BOARD_INFO("at24", 0x52), /* E0=0, E1=1, E2=0 */
.platform_data = &board_eeprom,
I2C_BOARD_INFO("24c32", 0x52), /* E0=0, E1=1, E2=0 */
.properties = board_eeprom_properties,
}, {
I2C_BOARD_INFO("pcf8563", 0x51),
},
......
......@@ -29,7 +29,6 @@
#include <asm/mach/time.h>
#include <linux/i2c.h>
#include <linux/platform_data/at24.h>
#include <linux/mfd/mc13xxx.h>
#include "common.h"
......@@ -145,15 +144,9 @@ static const struct imxi2c_platform_data vpr200_i2c0_data __initconst = {
.bitrate = 50000,
};
static struct at24_platform_data vpr200_eeprom = {
.byte_len = 2048 / 8,
.page_size = 1,
};
static struct i2c_board_info vpr200_i2c_devices[] = {
{
I2C_BOARD_INFO("at24", 0x50), /* E0=0, E1=0, E2=0 */
.platform_data = &vpr200_eeprom,
I2C_BOARD_INFO("24c02", 0x50), /* E0=0, E1=0, E2=0 */
}, {
I2C_BOARD_INFO("mc13892", 0x08),
.platform_data = &vpr200_pmic,
......
......@@ -12,6 +12,7 @@
* published by the Free Software Foundation.
*/
#include <linux/gpio/driver.h>
#include <linux/gpio/machine.h>
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <linux/init.h>
......@@ -202,7 +203,10 @@ static struct resource latch2_resources[] = {
},
};
#define LATCH2_LABEL "latch2"
static struct bgpio_pdata latch2_pdata = {
.label = LATCH2_LABEL,
.base = AMS_DELTA_LATCH2_GPIO_BASE,
.ngpio = AMS_DELTA_LATCH2_NGPIO,
};
......@@ -217,6 +221,23 @@ static struct platform_device latch2_gpio_device = {
},
};
#define LATCH2_PIN_LCD_VBLEN 0
#define LATCH2_PIN_LCD_NDISP 1
#define LATCH2_PIN_NAND_NCE 2
#define LATCH2_PIN_NAND_NRE 3
#define LATCH2_PIN_NAND_NWP 4
#define LATCH2_PIN_NAND_NWE 5
#define LATCH2_PIN_NAND_ALE 6
#define LATCH2_PIN_NAND_CLE 7
#define LATCH2_PIN_KEYBRD_PWR 8
#define LATCH2_PIN_KEYBRD_DATAOUT 9
#define LATCH2_PIN_SCARD_RSTIN 10
#define LATCH2_PIN_SCARD_CMDVCC 11
#define LATCH2_PIN_MODEM_NRESET 12
#define LATCH2_PIN_MODEM_CODEC 13
#define LATCH2_PIN_HOOKFLASH1 14
#define LATCH2_PIN_HOOKFLASH2 15
static const struct gpio latch_gpios[] __initconst = {
{
.gpio = LATCH1_GPIO_BASE + 6,
......@@ -238,11 +259,6 @@ static const struct gpio latch_gpios[] __initconst = {
.flags = GPIOF_OUT_INIT_LOW,
.label = "scard_cmdvcc",
},
{
.gpio = AMS_DELTA_GPIO_PIN_MODEM_CODEC,
.flags = GPIOF_OUT_INIT_LOW,
.label = "modem_codec",
},
{
.gpio = AMS_DELTA_LATCH2_GPIO_BASE + 14,
.flags = GPIOF_OUT_INIT_LOW,
......@@ -323,6 +339,22 @@ static struct platform_device ams_delta_nand_device = {
.resource = ams_delta_nand_resources,
};
#define OMAP_GPIO_LABEL "gpio-0-15"
static struct gpiod_lookup_table ams_delta_nand_gpio_table = {
.table = {
GPIO_LOOKUP(OMAP_GPIO_LABEL, AMS_DELTA_GPIO_PIN_NAND_RB, "rdy",
0),
GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NCE, "nce", 0),
GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NRE, "nre", 0),
GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NWP, "nwp", 0),
GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_NWE, "nwe", 0),
GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_ALE, "ale", 0),
GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_NAND_CLE, "cle", 0),
{ },
},
};
static struct resource ams_delta_kp_resources[] = {
[0] = {
.start = INT_KEYBOARD,
......@@ -358,6 +390,14 @@ static struct platform_device ams_delta_lcd_device = {
.id = -1,
};
static struct gpiod_lookup_table ams_delta_lcd_gpio_table = {
.table = {
GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_LCD_VBLEN, "vblen", 0),
GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_LCD_NDISP, "ndisp", 0),
{ },
},
};
static const struct gpio_led gpio_leds[] __initconst = {
{
.name = "camera",
......@@ -449,11 +489,35 @@ static struct platform_device ams_delta_audio_device = {
.id = -1,
};
static struct gpiod_lookup_table ams_delta_audio_gpio_table = {
.table = {
GPIO_LOOKUP(OMAP_GPIO_LABEL, AMS_DELTA_GPIO_PIN_HOOK_SWITCH,
"hook_switch", 0),
GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_MODEM_CODEC,
"modem_codec", 0),
{ },
},
};
static struct platform_device cx20442_codec_device = {
.name = "cx20442-codec",
.id = -1,
};
static struct gpiod_lookup_table ams_delta_serio_gpio_table = {
.table = {
GPIO_LOOKUP(OMAP_GPIO_LABEL, AMS_DELTA_GPIO_PIN_KEYBRD_DATA,
"data", 0),
GPIO_LOOKUP(OMAP_GPIO_LABEL, AMS_DELTA_GPIO_PIN_KEYBRD_CLK,
"clock", 0),
GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_KEYBRD_PWR,
"power", 0),
GPIO_LOOKUP(LATCH2_LABEL, LATCH2_PIN_KEYBRD_DATAOUT,
"dataout", 0),
{ },
},
};
static struct platform_device *ams_delta_devices[] __initdata = {
&latch1_gpio_device,
&latch2_gpio_device,
......@@ -468,6 +532,16 @@ static struct platform_device *late_devices[] __initdata = {
&cx20442_codec_device,
};
static struct gpiod_lookup_table *ams_delta_gpio_tables[] __initdata = {
&ams_delta_audio_gpio_table,
&ams_delta_serio_gpio_table,
};
static struct gpiod_lookup_table *late_gpio_tables[] __initdata = {
&ams_delta_lcd_gpio_table,
&ams_delta_nand_gpio_table,
};
static void __init ams_delta_init(void)
{
/* mux pins for uarts */
......@@ -500,6 +574,20 @@ static void __init ams_delta_init(void)
gpio_led_register_device(-1, &leds_pdata);
platform_add_devices(ams_delta_devices, ARRAY_SIZE(ams_delta_devices));
/*
* As soon as devices have been registered, assign their dev_names
* to respective GPIO lookup tables before they are added.
*/
ams_delta_audio_gpio_table.dev_id =
dev_name(&ams_delta_audio_device.dev);
/*
* No device name is assigned to GPIO lookup table for serio device
* as long as serio driver is not converted to platform device driver.
*/
gpiod_add_lookup_tables(ams_delta_gpio_tables,
ARRAY_SIZE(ams_delta_gpio_tables));
ams_delta_init_fiq();
omap_writew(omap_readw(ARM_RSTCT1) | 0x0004, ARM_RSTCT1);
......@@ -570,6 +658,15 @@ static int __init late_init(void)
platform_add_devices(late_devices, ARRAY_SIZE(late_devices));
/*
* As soon as devices have been registered, assign their dev_names
* to respective GPIO lookup tables before they are added.
*/
ams_delta_lcd_gpio_table.dev_id = dev_name(&ams_delta_lcd_device.dev);
ams_delta_nand_gpio_table.dev_id = dev_name(&ams_delta_nand_device.dev);
gpiod_add_lookup_tables(late_gpio_tables, ARRAY_SIZE(late_gpio_tables));
err = platform_device_register(&modem_nreset_device);
if (err) {
pr_err("Couldn't register the modem regulator device\n");
......
......@@ -303,22 +303,22 @@ static const struct omap_lcd_config osk_lcd_config __initconst = {
#ifdef CONFIG_OMAP_OSK_MISTRAL
#include <linux/input.h>
#include <linux/platform_data/at24.h>
#include <linux/property.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <linux/platform_data/keypad-omap.h>
static struct at24_platform_data at24c04 = {
.byte_len = SZ_4K / 8,
.page_size = 16,
static const struct property_entry mistral_at24_properties[] = {
PROPERTY_ENTRY_U32("pagesize", 16),
{ }
};
static struct i2c_board_info __initdata mistral_i2c_board_info[] = {
{
/* NOTE: powered from LCD supply */
I2C_BOARD_INFO("24c04", 0x50),
.platform_data = &at24c04,
.properties = mistral_at24_properties,
},
/* TODO when driver support is ready:
* - optionally ov9640 camera sensor at 0x30
......
......@@ -78,7 +78,6 @@ endif
omap-4-5-pm-common = omap-mpuss-lowpower.o
obj-$(CONFIG_ARCH_OMAP4) += $(omap-4-5-pm-common)
obj-$(CONFIG_SOC_OMAP5) += $(omap-4-5-pm-common)
obj-$(CONFIG_OMAP_PM_NOOP) += omap-pm-noop.o
ifeq ($(CONFIG_PM),y)
obj-$(CONFIG_ARCH_OMAP2) += pm24xx.o
......
......@@ -31,8 +31,6 @@ static const struct of_device_id omap_dt_match_table[] __initconst = {
static void __init __maybe_unused omap_generic_init(void)
{
pdata_quirks_init(omap_dt_match_table);
omapdss_init_of();
omap_soc_device_init();
}
......
......@@ -23,6 +23,7 @@
#include <linux/limits.h>
#include <linux/err.h>
#include <linux/clk-provider.h>
#include <linux/cpu_pm.h>
#include <linux/io.h>
......@@ -31,6 +32,7 @@
#include "soc.h"
#include "clock.h"
#include "clockdomain.h"
#include "pm.h"
/* clkdm_list contains all registered struct clockdomains */
static LIST_HEAD(clkdm_list);
......@@ -39,6 +41,8 @@ static LIST_HEAD(clkdm_list);
static struct clkdm_autodep *autodeps;
static struct clkdm_ops *arch_clkdm;
void clkdm_save_context(void);
void clkdm_restore_context(void);
/* Private functions */
......@@ -449,6 +453,22 @@ int clkdm_register_autodeps(struct clkdm_autodep *ia)
return 0;
}
static int cpu_notifier(struct notifier_block *nb, unsigned long cmd, void *v)
{
switch (cmd) {
case CPU_CLUSTER_PM_ENTER:
if (enable_off_mode)
clkdm_save_context();
break;
case CPU_CLUSTER_PM_EXIT:
if (enable_off_mode)
clkdm_restore_context();
break;
}
return NOTIFY_OK;
}
/**
* clkdm_complete_init - set up the clockdomain layer
*
......@@ -460,6 +480,7 @@ int clkdm_register_autodeps(struct clkdm_autodep *ia)
int clkdm_complete_init(void)
{
struct clockdomain *clkdm;
static struct notifier_block nb;
if (list_empty(&clkdm_list))
return -EACCES;
......@@ -474,6 +495,12 @@ int clkdm_complete_init(void)
clkdm_clear_all_sleepdeps(clkdm);
}
/* Only AM43XX can lose clkdm context during rtc-ddr suspend */
if (soc_is_am43xx()) {
nb.notifier_call = cpu_notifier;
cpu_pm_register_notifier(&nb);
}
return 0;
}
......@@ -1307,3 +1334,49 @@ int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh)
return 0;
}
/**
* _clkdm_save_context - save the context for the control of this clkdm
*
* Due to a suspend or hibernation operation, the state of the registers
* controlling this clkdm will be lost, save their context.
*/
static int _clkdm_save_context(struct clockdomain *clkdm, void *ununsed)
{
if (!arch_clkdm || !arch_clkdm->clkdm_save_context)
return -EINVAL;
return arch_clkdm->clkdm_save_context(clkdm);
}
/**
* _clkdm_restore_context - restore context for control of this clkdm
*
* Restore the register values for this clockdomain.
*/
static int _clkdm_restore_context(struct clockdomain *clkdm, void *ununsed)
{
if (!arch_clkdm || !arch_clkdm->clkdm_restore_context)
return -EINVAL;
return arch_clkdm->clkdm_restore_context(clkdm);
}
/**
* clkdm_save_context - Saves the context for each registered clkdm
*
* Save the context for each registered clockdomain.
*/
void clkdm_save_context(void)
{
clkdm_for_each(_clkdm_save_context, NULL);
}
/**
* clkdm_restore_context - Restores the context for each registered clkdm
*
* Restore the context for each registered clockdomain.
*/
void clkdm_restore_context(void)
{
clkdm_for_each(_clkdm_restore_context, NULL);
}
......@@ -141,6 +141,7 @@ struct clockdomain {
int usecount;
int forcewake_count;
struct list_head node;
u32 context;
};
/**
......@@ -159,6 +160,8 @@ struct clockdomain {
* @clkdm_deny_idle: Disable hw supervised idle transitions for clock domain
* @clkdm_clk_enable: Put the clkdm in right state for a clock enable
* @clkdm_clk_disable: Put the clkdm in right state for a clock disable
* @clkdm_save_context: Save the current clkdm context
* @clkdm_restore_context: Restore the clkdm context
*/
struct clkdm_ops {
int (*clkdm_add_wkdep)(struct clockdomain *clkdm1, struct clockdomain *clkdm2);
......@@ -175,6 +178,8 @@ struct clkdm_ops {
void (*clkdm_deny_idle)(struct clockdomain *clkdm);
int (*clkdm_clk_enable)(struct clockdomain *clkdm);
int (*clkdm_clk_disable)(struct clockdomain *clkdm);
int (*clkdm_save_context)(struct clockdomain *clkdm);
int (*clkdm_restore_context)(struct clockdomain *clkdm);
};
int clkdm_register_platform_funcs(struct clkdm_ops *co);
......@@ -214,6 +219,9 @@ int clkdm_clk_disable(struct clockdomain *clkdm, struct clk *clk);
int clkdm_hwmod_enable(struct clockdomain *clkdm, struct omap_hwmod *oh);
int clkdm_hwmod_disable(struct clockdomain *clkdm, struct omap_hwmod *oh);
void clkdm_save_context(void);
void clkdm_restore_context(void);
extern void __init omap242x_clockdomains_init(void);
extern void __init omap243x_clockdomains_init(void);
extern void __init omap3xxx_clockdomains_init(void);
......
......@@ -72,6 +72,17 @@ static inline u32 am33xx_cm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx)
return v;
}
static inline u32 am33xx_cm_read_reg_bits(u16 inst, s16 idx, u32 mask)
{
u32 v;
v = am33xx_cm_read_reg(inst, idx);
v &= mask;
v >>= __ffs(mask);
return v;
}
/**
* _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield
* @inst: CM instance register offset (*_INST macro)
......@@ -338,6 +349,46 @@ static u32 am33xx_cm_xlate_clkctrl(u8 part, u16 inst, u16 offset)
return cm_base.pa + inst + offset;
}
/**
* am33xx_clkdm_save_context - Save the clockdomain transition context
* @clkdm: The clockdomain pointer whose context needs to be saved
*
* Save the clockdomain transition context.
*/
static int am33xx_clkdm_save_context(struct clockdomain *clkdm)
{
clkdm->context = am33xx_cm_read_reg_bits(clkdm->cm_inst,
clkdm->clkdm_offs,
AM33XX_CLKTRCTRL_MASK);
return 0;
}
/**
* am33xx_restore_save_context - Restore the clockdomain transition context
* @clkdm: The clockdomain pointer whose context needs to be restored
*
* Restore the clockdomain transition context.
*/
static int am33xx_clkdm_restore_context(struct clockdomain *clkdm)
{
switch (clkdm->context) {
case OMAP34XX_CLKSTCTRL_DISABLE_AUTO:
am33xx_clkdm_deny_idle(clkdm);
break;
case OMAP34XX_CLKSTCTRL_FORCE_SLEEP:
am33xx_clkdm_sleep(clkdm);
break;
case OMAP34XX_CLKSTCTRL_FORCE_WAKEUP:
am33xx_clkdm_wakeup(clkdm);
break;
case OMAP34XX_CLKSTCTRL_ENABLE_AUTO:
am33xx_clkdm_allow_idle(clkdm);
break;
}
return 0;
}
struct clkdm_ops am33xx_clkdm_operations = {
.clkdm_sleep = am33xx_clkdm_sleep,
.clkdm_wakeup = am33xx_clkdm_wakeup,
......@@ -345,6 +396,8 @@ struct clkdm_ops am33xx_clkdm_operations = {
.clkdm_deny_idle = am33xx_clkdm_deny_idle,
.clkdm_clk_enable = am33xx_clkdm_clk_enable,
.clkdm_clk_disable = am33xx_clkdm_clk_disable,
.clkdm_save_context = am33xx_clkdm_save_context,
.clkdm_restore_context = am33xx_clkdm_restore_context,
};
static const struct cm_ll_data am33xx_cm_ll_data = {
......
......@@ -481,6 +481,47 @@ static u32 omap4_cminst_xlate_clkctrl(u8 part, u16 inst, u16 offset)
return _cm_bases[part].pa + inst + offset;
}
/**
* omap4_clkdm_save_context - Save the clockdomain modulemode context
* @clkdm: The clockdomain pointer whose context needs to be saved
*
* Save the clockdomain modulemode context.
*/
static int omap4_clkdm_save_context(struct clockdomain *clkdm)
{
clkdm->context = omap4_cminst_read_inst_reg(clkdm->prcm_partition,
clkdm->cm_inst,
clkdm->clkdm_offs +
OMAP4_CM_CLKSTCTRL);
clkdm->context &= OMAP4430_MODULEMODE_MASK;
return 0;
}
/**
* omap4_clkdm_restore_context - Restore the clockdomain modulemode context
* @clkdm: The clockdomain pointer whose context needs to be restored
*
* Restore the clockdomain modulemode context.
*/
static int omap4_clkdm_restore_context(struct clockdomain *clkdm)
{
switch (clkdm->context) {
case OMAP34XX_CLKSTCTRL_DISABLE_AUTO:
omap4_clkdm_deny_idle(clkdm);
break;
case OMAP34XX_CLKSTCTRL_FORCE_SLEEP:
omap4_clkdm_sleep(clkdm);
break;
case OMAP34XX_CLKSTCTRL_FORCE_WAKEUP:
omap4_clkdm_wakeup(clkdm);
break;
case OMAP34XX_CLKSTCTRL_ENABLE_AUTO:
omap4_clkdm_allow_idle(clkdm);
break;
}
return 0;
}
struct clkdm_ops omap4_clkdm_operations = {
.clkdm_add_wkdep = omap4_clkdm_add_wkup_sleep_dep,
.clkdm_del_wkdep = omap4_clkdm_del_wkup_sleep_dep,
......@@ -496,6 +537,8 @@ struct clkdm_ops omap4_clkdm_operations = {
.clkdm_deny_idle = omap4_clkdm_deny_idle,
.clkdm_clk_enable = omap4_clkdm_clk_enable,
.clkdm_clk_disable = omap4_clkdm_clk_disable,
.clkdm_save_context = omap4_clkdm_save_context,
.clkdm_restore_context = omap4_clkdm_restore_context,
};
struct clkdm_ops am43xx_clkdm_operations = {
......
......@@ -44,6 +44,9 @@
#define OMAP_INTC_START NR_IRQS
extern int (*omap_pm_soc_init)(void);
int omap_pm_nop_init(void);
#if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP2)
int omap2_pm_init(void);
#else
......@@ -79,9 +82,12 @@ static inline int omap4_pm_init_early(void)
#if defined(CONFIG_PM) && (defined(CONFIG_SOC_AM33XX) || \
defined(CONFIG_SOC_AM43XX))
void amx3_common_pm_init(void);
int amx3_common_pm_init(void);
#else
static inline void amx3_common_pm_init(void) { }
static inline int amx3_common_pm_init(void)
{
return 0;
}
#endif
extern void omap2_init_common_infrastructure(void);
......@@ -122,14 +128,10 @@ void am43xx_init_early(void);
void am43xx_init_late(void);
void omap4430_init_early(void);
void omap5_init_early(void);
void omap3_init_late(void); /* Do not use this one */
void omap3_init_late(void);
void omap4430_init_late(void);
void omap2420_init_late(void);
void omap2430_init_late(void);
void omap3430_init_late(void);
void omap35xx_init_late(void);
void omap3630_init_late(void);
void am35xx_init_late(void);
void ti81xx_init_late(void);
void am33xx_init_late(void);
void omap5_init_late(void);
......@@ -350,7 +352,5 @@ extern int omap_dss_reset(struct omap_hwmod *);
/* SoC specific clock initializer */
int omap_clk_init(void);
int __init omapdss_init_of(void);
#endif /* __ASSEMBLER__ */
#endif /* __ARCH_ARM_MACH_OMAP2PLUS_COMMON_H */
......@@ -17,6 +17,7 @@
#include <linux/of_address.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
#include <linux/cpu_pm.h>
#include "soc.h"
#include "iomap.h"
......@@ -621,6 +622,110 @@ void __init omap3_ctrl_init(void)
}
#endif /* CONFIG_ARCH_OMAP3 && CONFIG_PM */
static unsigned long am43xx_control_reg_offsets[] = {
AM33XX_CONTROL_SYSCONFIG_OFFSET,
AM33XX_CONTROL_STATUS_OFFSET,
AM43XX_CONTROL_MPU_L2_CTRL_OFFSET,
AM33XX_CONTROL_CORE_SLDO_CTRL_OFFSET,
AM33XX_CONTROL_MPU_SLDO_CTRL_OFFSET,
AM33XX_CONTROL_CLK32KDIVRATIO_CTRL_OFFSET,
AM33XX_CONTROL_BANDGAP_CTRL_OFFSET,
AM33XX_CONTROL_BANDGAP_TRIM_OFFSET,
AM33XX_CONTROL_PLL_CLKINPULOW_CTRL_OFFSET,
AM33XX_CONTROL_MOSC_CTRL_OFFSET,
AM33XX_CONTROL_DEEPSLEEP_CTRL_OFFSET,
AM43XX_CONTROL_DISPLAY_PLL_SEL_OFFSET,
AM33XX_CONTROL_INIT_PRIORITY_0_OFFSET,
AM33XX_CONTROL_INIT_PRIORITY_1_OFFSET,
AM33XX_CONTROL_TPTC_CFG_OFFSET,
AM33XX_CONTROL_USB_CTRL0_OFFSET,
AM33XX_CONTROL_USB_CTRL1_OFFSET,
AM43XX_CONTROL_USB_CTRL2_OFFSET,
AM43XX_CONTROL_GMII_SEL_OFFSET,
AM43XX_CONTROL_MPUSS_CTRL_OFFSET,
AM43XX_CONTROL_TIMER_CASCADE_CTRL_OFFSET,
AM43XX_CONTROL_PWMSS_CTRL_OFFSET,
AM33XX_CONTROL_MREQPRIO_0_OFFSET,
AM33XX_CONTROL_MREQPRIO_1_OFFSET,
AM33XX_CONTROL_HW_EVENT_SEL_GRP1_OFFSET,
AM33XX_CONTROL_HW_EVENT_SEL_GRP2_OFFSET,
AM33XX_CONTROL_HW_EVENT_SEL_GRP3_OFFSET,
AM33XX_CONTROL_HW_EVENT_SEL_GRP4_OFFSET,
AM33XX_CONTROL_SMRT_CTRL_OFFSET,
AM33XX_CONTROL_MPUSS_HW_DEBUG_SEL_OFFSET,
AM43XX_CONTROL_CQDETECT_STS_OFFSET,
AM43XX_CONTROL_CQDETECT_STS2_OFFSET,
AM43XX_CONTROL_VTP_CTRL_OFFSET,
AM33XX_CONTROL_VREF_CTRL_OFFSET,
AM33XX_CONTROL_TPCC_EVT_MUX_0_3_OFFSET,
AM33XX_CONTROL_TPCC_EVT_MUX_4_7_OFFSET,
AM33XX_CONTROL_TPCC_EVT_MUX_8_11_OFFSET,
AM33XX_CONTROL_TPCC_EVT_MUX_12_15_OFFSET,
AM33XX_CONTROL_TPCC_EVT_MUX_16_19_OFFSET,
AM33XX_CONTROL_TPCC_EVT_MUX_20_23_OFFSET,
AM33XX_CONTROL_TPCC_EVT_MUX_24_27_OFFSET,
AM33XX_CONTROL_TPCC_EVT_MUX_28_31_OFFSET,
AM33XX_CONTROL_TPCC_EVT_MUX_32_35_OFFSET,
AM33XX_CONTROL_TPCC_EVT_MUX_36_39_OFFSET,
AM33XX_CONTROL_TPCC_EVT_MUX_40_43_OFFSET,
AM33XX_CONTROL_TPCC_EVT_MUX_44_47_OFFSET,
AM33XX_CONTROL_TPCC_EVT_MUX_48_51_OFFSET,
AM33XX_CONTROL_TPCC_EVT_MUX_52_55_OFFSET,
AM33XX_CONTROL_TPCC_EVT_MUX_56_59_OFFSET,
AM33XX_CONTROL_TPCC_EVT_MUX_60_63_OFFSET,
AM33XX_CONTROL_TIMER_EVT_CAPT_OFFSET,
AM33XX_CONTROL_ECAP_EVT_CAPT_OFFSET,
AM33XX_CONTROL_ADC_EVT_CAPT_OFFSET,
AM43XX_CONTROL_ADC1_EVT_CAPT_OFFSET,
AM33XX_CONTROL_RESET_ISO_OFFSET,
};
static u32 am33xx_control_vals[ARRAY_SIZE(am43xx_control_reg_offsets)];
/**
* am43xx_control_save_context - Save the wakeup domain registers
*
* Save the wkup domain registers
*/
void am43xx_control_save_context(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(am43xx_control_reg_offsets); i++)
am33xx_control_vals[i] =
omap_ctrl_readl(am43xx_control_reg_offsets[i]);
}
/**
* am43xx_control_restore_context - Restore the wakeup domain registers
*
* Restore the wkup domain registers
*/
void am43xx_control_restore_context(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(am43xx_control_reg_offsets); i++)
omap_ctrl_writel(am33xx_control_vals[i],
am43xx_control_reg_offsets[i]);
}
static int cpu_notifier(struct notifier_block *nb, unsigned long cmd, void *v)
{
switch (cmd) {
case CPU_CLUSTER_PM_ENTER:
if (enable_off_mode)
am43xx_control_save_context();
break;
case CPU_CLUSTER_PM_EXIT:
if (enable_off_mode)
am43xx_control_restore_context();
break;
}
return NOTIFY_OK;
}
struct control_init_data {
int index;
void __iomem *mem;
......@@ -699,6 +804,7 @@ int __init omap_control_init(void)
const struct omap_prcm_init_data *data;
int ret;
struct regmap *syscon;
static struct notifier_block nb;
for_each_matching_node_and_match(np, omap_scrm_dt_match_table, &match) {
data = match->data;
......@@ -731,6 +837,12 @@ int __init omap_control_init(void)
}
}
/* Only AM43XX can lose ctrl registers context during rtc-ddr suspend */
if (soc_is_am43xx()) {
nb.notifier_call = cpu_notifier;
cpu_pm_register_notifier(&nb);
}
return 0;
}
......
......@@ -409,6 +409,67 @@
#define AM33XX_DEV_FEATURE 0x604
#define AM33XX_SGX_MASK BIT(29)
/* Additional AM33XX/AM43XX CONTROL registers */
#define AM33XX_CONTROL_SYSCONFIG_OFFSET 0x0010
#define AM33XX_CONTROL_STATUS_OFFSET 0x0040
#define AM43XX_CONTROL_MPU_L2_CTRL_OFFSET 0x01e0
#define AM33XX_CONTROL_CORTEX_VBBLDO_CTRL_OFFSET 0x041c
#define AM33XX_CONTROL_CORE_SLDO_CTRL_OFFSET 0x0428
#define AM33XX_CONTROL_MPU_SLDO_CTRL_OFFSET 0x042c
#define AM33XX_CONTROL_CLK32KDIVRATIO_CTRL_OFFSET 0x0444
#define AM33XX_CONTROL_BANDGAP_CTRL_OFFSET 0x0448
#define AM33XX_CONTROL_BANDGAP_TRIM_OFFSET 0x044c
#define AM33XX_CONTROL_PLL_CLKINPULOW_CTRL_OFFSET 0x0458
#define AM33XX_CONTROL_MOSC_CTRL_OFFSET 0x0468
#define AM33XX_CONTROL_RCOSC_CTRL_OFFSET 0x046c
#define AM33XX_CONTROL_DEEPSLEEP_CTRL_OFFSET 0x0470
#define AM43XX_CONTROL_DISPLAY_PLL_SEL_OFFSET 0x0534
#define AM33XX_CONTROL_INIT_PRIORITY_0_OFFSET 0x0608
#define AM33XX_CONTROL_INIT_PRIORITY_1_OFFSET 0x060c
#define AM33XX_CONTROL_MMU_CFG_OFFSET 0x0610
#define AM33XX_CONTROL_TPTC_CFG_OFFSET 0x0614
#define AM33XX_CONTROL_USB_CTRL0_OFFSET 0x0620
#define AM33XX_CONTROL_USB_CTRL1_OFFSET 0x0628
#define AM33XX_CONTROL_USB_WKUP_CTRL_OFFSET 0x0648
#define AM43XX_CONTROL_USB_CTRL2_OFFSET 0x064c
#define AM43XX_CONTROL_GMII_SEL_OFFSET 0x0650
#define AM43XX_CONTROL_MPUSS_CTRL_OFFSET 0x0654
#define AM43XX_CONTROL_TIMER_CASCADE_CTRL_OFFSET 0x0658
#define AM43XX_CONTROL_PWMSS_CTRL_OFFSET 0x0664
#define AM33XX_CONTROL_MREQPRIO_0_OFFSET 0x0670
#define AM33XX_CONTROL_MREQPRIO_1_OFFSET 0x0674
#define AM33XX_CONTROL_HW_EVENT_SEL_GRP1_OFFSET 0x0690
#define AM33XX_CONTROL_HW_EVENT_SEL_GRP2_OFFSET 0x0694
#define AM33XX_CONTROL_HW_EVENT_SEL_GRP3_OFFSET 0x0698
#define AM33XX_CONTROL_HW_EVENT_SEL_GRP4_OFFSET 0x069c
#define AM33XX_CONTROL_SMRT_CTRL_OFFSET 0x06a0
#define AM33XX_CONTROL_MPUSS_HW_DEBUG_SEL_OFFSET 0x06a4
#define AM43XX_CONTROL_CQDETECT_STS_OFFSET 0x0e00
#define AM43XX_CONTROL_CQDETECT_STS2_OFFSET 0x0e08
#define AM43XX_CONTROL_VTP_CTRL_OFFSET 0x0e0c
#define AM33XX_CONTROL_VREF_CTRL_OFFSET 0x0e14
#define AM33XX_CONTROL_TPCC_EVT_MUX_0_3_OFFSET 0x0f90
#define AM33XX_CONTROL_TPCC_EVT_MUX_4_7_OFFSET 0x0f94
#define AM33XX_CONTROL_TPCC_EVT_MUX_8_11_OFFSET 0x0f98
#define AM33XX_CONTROL_TPCC_EVT_MUX_12_15_OFFSET 0x0f9c
#define AM33XX_CONTROL_TPCC_EVT_MUX_16_19_OFFSET 0x0fa0
#define AM33XX_CONTROL_TPCC_EVT_MUX_20_23_OFFSET 0x0fa4
#define AM33XX_CONTROL_TPCC_EVT_MUX_24_27_OFFSET 0x0fa8
#define AM33XX_CONTROL_TPCC_EVT_MUX_28_31_OFFSET 0x0fac
#define AM33XX_CONTROL_TPCC_EVT_MUX_32_35_OFFSET 0x0fb0
#define AM33XX_CONTROL_TPCC_EVT_MUX_36_39_OFFSET 0x0fb4
#define AM33XX_CONTROL_TPCC_EVT_MUX_40_43_OFFSET 0x0fb8
#define AM33XX_CONTROL_TPCC_EVT_MUX_44_47_OFFSET 0x0fbc
#define AM33XX_CONTROL_TPCC_EVT_MUX_48_51_OFFSET 0x0fc0
#define AM33XX_CONTROL_TPCC_EVT_MUX_52_55_OFFSET 0x0fc4
#define AM33XX_CONTROL_TPCC_EVT_MUX_56_59_OFFSET 0x0fc8
#define AM33XX_CONTROL_TPCC_EVT_MUX_60_63_OFFSET 0x0fcc
#define AM33XX_CONTROL_TIMER_EVT_CAPT_OFFSET 0x0fd0
#define AM33XX_CONTROL_ECAP_EVT_CAPT_OFFSET 0x0fd4
#define AM33XX_CONTROL_ADC_EVT_CAPT_OFFSET 0x0fd8
#define AM43XX_CONTROL_ADC1_EVT_CAPT_OFFSET 0x0fdc
#define AM33XX_CONTROL_RESET_ISO_OFFSET 0x1000
/* CONTROL OMAP STATUS register to identify OMAP3 features */
#define OMAP3_CONTROL_OMAP_STATUS 0x044c
......
......@@ -32,7 +32,6 @@
#include <linux/platform_data/omapdss.h>
#include "omap_hwmod.h"
#include "omap_device.h"
#include "omap-pm.h"
#include "common.h"
#include "soc.h"
......@@ -126,11 +125,6 @@ static void omap_dsi_disable_pads(int dsi_id, unsigned lane_mask)
omap4_dsi_mux_pads(dsi_id, 0);
}
static int omap_dss_set_min_bus_tput(struct device *dev, unsigned long tput)
{
return omap_pm_set_min_bus_tput(dev, OCP_INITIATOR_AGENT, tput);
}
static enum omapdss_version __init omap_display_get_version(void)
{
if (cpu_is_omap24xx())
......@@ -169,7 +163,6 @@ static int __init omapdss_init_fbdev(void)
static struct omap_dss_board_info board_data = {
.dsi_enable_pads = omap_dsi_enable_pads,
.dsi_disable_pads = omap_dsi_disable_pads,
.set_min_bus_tput = omap_dss_set_min_bus_tput,
};
struct device_node *node;
int r;
......@@ -392,7 +385,7 @@ static struct device_node * __init omapdss_find_dss_of_node(void)
return NULL;
}
int __init omapdss_init_of(void)
static int __init omapdss_init_of(void)
{
int r;
struct device_node *node;
......@@ -422,3 +415,4 @@ int __init omapdss_init_of(void)
return omapdss_init_fbdev();
}
omap_device_initcall(omapdss_init_of);
......@@ -18,7 +18,6 @@
#include "soc.h"
#include "omap_device.h"
#include "omap-pm.h"
#include "hsmmc.h"
#include "control.h"
......
......@@ -22,7 +22,6 @@
#include "soc.h"
#include "omap_hwmod.h"
#include "omap_device.h"
#include "omap-pm.h"
#include "prm.h"
#include "common.h"
......
......@@ -37,7 +37,6 @@
#include "clock.h"
#include "clock2xxx.h"
#include "clock3xxx.h"
#include "omap-pm.h"
#include "sdrc.h"
#include "control.h"
#include "serial.h"
......@@ -421,13 +420,6 @@ static void __init __maybe_unused omap_hwmod_init_postsetup(void)
postsetup_state = _HWMOD_STATE_ENABLED;
#endif
omap_hwmod_for_each(_set_hwmod_postsetup_state, &postsetup_state);
omap_pm_if_early_init();
}
static void __init __maybe_unused omap_common_late_init(void)
{
omap2_common_pm_late_init();
}
#ifdef CONFIG_SOC_OMAP2420
......@@ -450,9 +442,7 @@ void __init omap2420_init_early(void)
void __init omap2420_init_late(void)
{
omap_common_late_init();
omap2_pm_init();
omap2_clk_enable_autoidle_all();
omap_pm_soc_init = omap2_pm_init;
}
#endif
......@@ -476,9 +466,7 @@ void __init omap2430_init_early(void)
void __init omap2430_init_late(void)
{
omap_common_late_init();
omap2_pm_init();
omap2_clk_enable_autoidle_all();
omap_pm_soc_init = omap2_pm_init;
}
#endif
......@@ -529,43 +517,12 @@ void __init am35xx_init_early(void)
void __init omap3_init_late(void)
{
omap_common_late_init();
omap3_pm_init();
omap2_clk_enable_autoidle_all();
}
void __init omap3430_init_late(void)
{
omap_common_late_init();
omap3_pm_init();
omap2_clk_enable_autoidle_all();
}
void __init omap35xx_init_late(void)
{
omap_common_late_init();
omap3_pm_init();
omap2_clk_enable_autoidle_all();
}
void __init omap3630_init_late(void)
{
omap_common_late_init();
omap3_pm_init();
omap2_clk_enable_autoidle_all();
}
void __init am35xx_init_late(void)
{
omap_common_late_init();
omap3_pm_init();
omap2_clk_enable_autoidle_all();
omap_pm_soc_init = omap3_pm_init;
}
void __init ti81xx_init_late(void)
{
omap_common_late_init();
omap2_clk_enable_autoidle_all();
omap_pm_soc_init = omap_pm_nop_init;
}
#endif
......@@ -621,8 +578,7 @@ void __init am33xx_init_early(void)
void __init am33xx_init_late(void)
{
omap_common_late_init();
amx3_common_pm_init();
omap_pm_soc_init = amx3_common_pm_init;
}
#endif
......@@ -645,9 +601,7 @@ void __init am43xx_init_early(void)
void __init am43xx_init_late(void)
{
omap_common_late_init();
omap2_clk_enable_autoidle_all();
amx3_common_pm_init();
omap_pm_soc_init = amx3_common_pm_init;
}
#endif
......@@ -675,9 +629,7 @@ void __init omap4430_init_early(void)
void __init omap4430_init_late(void)
{
omap_common_late_init();
omap4_pm_init();
omap2_clk_enable_autoidle_all();
omap_pm_soc_init = omap4_pm_init;
}
#endif
......@@ -703,9 +655,7 @@ void __init omap5_init_early(void)
void __init omap5_init_late(void)
{
omap_common_late_init();
omap4_pm_init();
omap2_clk_enable_autoidle_all();
omap_pm_soc_init = omap4_pm_init;
}
#endif
......@@ -728,9 +678,7 @@ void __init dra7xx_init_early(void)
void __init dra7xx_init_late(void)
{
omap_common_late_init();
omap4_pm_init();
omap2_clk_enable_autoidle_all();
omap_pm_soc_init = omap4_pm_init;
}
#endif
......
// SPDX-License-Identifier: GPL-2.0
/*
* omap-pm-noop.c - OMAP power management interface - dummy version
*
* This code implements the OMAP power management interface to
* drivers, CPUIdle, CPUFreq, and DSP Bridge. It is strictly for
* debug/demonstration use, as it does nothing but printk() whenever a
* function is called (when DEBUG is defined, below)
*
* Copyright (C) 2008-2009 Texas Instruments, Inc.
* Copyright (C) 2008-2009 Nokia Corporation
* Paul Walmsley
*
* Interface developed by (in alphabetical order):
* Karthik Dasu, Tony Lindgren, Rajendra Nayak, Sakari Poussa, Veeramanikandan
* Raju, Anand Sawant, Igor Stoppa, Paul Walmsley, Richard Woodruff
*/
#undef DEBUG
#include <linux/init.h>
#include <linux/cpufreq.h>
#include <linux/device.h>
#include <linux/platform_device.h>
#include "omap_device.h"
#include "omap-pm.h"
static bool off_mode_enabled;
static int dummy_context_loss_counter;
/*
* Device-driver-originated constraints (via board-*.c files)
*/
int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t)
{
if (!dev || t < -1) {
WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
return -EINVAL;
}
if (t == -1)
pr_debug("OMAP PM: remove max MPU wakeup latency constraint: dev %s\n",
dev_name(dev));
else
pr_debug("OMAP PM: add max MPU wakeup latency constraint: dev %s, t = %ld usec\n",
dev_name(dev), t);
/*
* For current Linux, this needs to map the MPU to a
* powerdomain, then go through the list of current max lat
* constraints on the MPU and find the smallest. If
* the latency constraint has changed, the code should
* recompute the state to enter for the next powerdomain
* state.
*
* TI CDP code can call constraint_set here.
*/
return 0;
}
int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
{
if (!dev || (agent_id != OCP_INITIATOR_AGENT &&
agent_id != OCP_TARGET_AGENT)) {
WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
return -EINVAL;
}
if (r == 0)
pr_debug("OMAP PM: remove min bus tput constraint: dev %s for agent_id %d\n",
dev_name(dev), agent_id);
else
pr_debug("OMAP PM: add min bus tput constraint: dev %s for agent_id %d: rate %ld KiB\n",
dev_name(dev), agent_id, r);
/*
* This code should model the interconnect and compute the
* required clock frequency, convert that to a VDD2 OPP ID, then
* set the VDD2 OPP appropriately.
*
* TI CDP code can call constraint_set here on the VDD2 OPP.
*/
return 0;
}
/*
* DSP Bridge-specific constraints
*/
/**
* omap_pm_enable_off_mode - notify OMAP PM that off-mode is enabled
*
* Intended for use only by OMAP PM core code to notify this layer
* that off mode has been enabled.
*/
void omap_pm_enable_off_mode(void)
{
off_mode_enabled = true;
}
/**
* omap_pm_disable_off_mode - notify OMAP PM that off-mode is disabled
*
* Intended for use only by OMAP PM core code to notify this layer
* that off mode has been disabled.
*/
void omap_pm_disable_off_mode(void)
{
off_mode_enabled = false;
}
/*
* Device context loss tracking
*/
#ifdef CONFIG_ARCH_OMAP2PLUS
int omap_pm_get_dev_context_loss_count(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
int count;
if (WARN_ON(!dev))
return -ENODEV;
if (dev->pm_domain == &omap_device_pm_domain) {
count = omap_device_get_context_loss_count(pdev);
} else {
WARN_ONCE(off_mode_enabled, "omap_pm: using dummy context loss counter; device %s should be converted to omap_device",
dev_name(dev));
count = dummy_context_loss_counter;
if (off_mode_enabled) {
count++;
/*
* Context loss count has to be a non-negative value.
* Clear the sign bit to get a value range from 0 to
* INT_MAX.
*/
count &= INT_MAX;
dummy_context_loss_counter = count;
}
}
pr_debug("OMAP PM: context loss count for dev %s = %d\n",
dev_name(dev), count);
return count;
}
#else
int omap_pm_get_dev_context_loss_count(struct device *dev)
{
return dummy_context_loss_counter;
}
#endif
/* Should be called before clk framework init */
int __init omap_pm_if_early_init(void)
{
return 0;
}
/* Must be called after clock framework is initialized */
int __init omap_pm_if_init(void)
{
return 0;
}
/* SPDX-License-Identifier: GPL-2.0 */
/*
* omap-pm.h - OMAP power management interface
*
* Copyright (C) 2008-2010 Texas Instruments, Inc.
* Copyright (C) 2008-2010 Nokia Corporation
* Paul Walmsley
*
* Interface developed by (in alphabetical order): Karthik Dasu, Jouni
* Högander, Tony Lindgren, Rajendra Nayak, Sakari Poussa,
* Veeramanikandan Raju, Anand Sawant, Igor Stoppa, Paul Walmsley,
* Richard Woodruff
*/
#ifndef ASM_ARM_ARCH_OMAP_OMAP_PM_H
#define ASM_ARM_ARCH_OMAP_OMAP_PM_H
#include <linux/device.h>
#include <linux/cpufreq.h>
#include <linux/clk.h>
#include <linux/pm_opp.h>
/*
* agent_id values for use with omap_pm_set_min_bus_tput():
*
* OCP_INITIATOR_AGENT is only valid for devices that can act as
* initiators -- it represents the device's L3 interconnect
* connection. OCP_TARGET_AGENT represents the device's L4
* interconnect connection.
*/
#define OCP_TARGET_AGENT 1
#define OCP_INITIATOR_AGENT 2
/**
* omap_pm_if_early_init - OMAP PM init code called before clock fw init
* @mpu_opp_table: array ptr to struct omap_opp for MPU
* @dsp_opp_table: array ptr to struct omap_opp for DSP
* @l3_opp_table : array ptr to struct omap_opp for CORE
*
* Initialize anything that must be configured before the clock
* framework starts. The "_if_" is to avoid name collisions with the
* PM idle-loop code.
*/
int __init omap_pm_if_early_init(void);
/**
* omap_pm_if_init - OMAP PM init code called after clock fw init
*
* The main initialization code. OPP tables are passed in here. The
* "_if_" is to avoid name collisions with the PM idle-loop code.
*/
int __init omap_pm_if_init(void);
/*
* Device-driver-originated constraints (via board-*.c files, platform_data)
*/
/**
* omap_pm_set_max_mpu_wakeup_lat - set the maximum MPU wakeup latency
* @dev: struct device * requesting the constraint
* @t: maximum MPU wakeup latency in microseconds
*
* Request that the maximum interrupt latency for the MPU to be no
* greater than @t microseconds. "Interrupt latency" in this case is
* defined as the elapsed time from the occurrence of a hardware or
* timer interrupt to the time when the device driver's interrupt
* service routine has been entered by the MPU.
*
* It is intended that underlying PM code will use this information to
* determine what power state to put the MPU powerdomain into, and
* possibly the CORE powerdomain as well, since interrupt handling
* code currently runs from SDRAM. Advanced PM or board*.c code may
* also configure interrupt controller priorities, OCP bus priorities,
* CPU speed(s), etc.
*
* This function will not affect device wakeup latency, e.g., time
* elapsed from when a device driver enables a hardware device with
* clk_enable(), to when the device is ready for register access or
* other use. To control this device wakeup latency, use
* omap_pm_set_max_dev_wakeup_lat()
*
* Multiple calls to omap_pm_set_max_mpu_wakeup_lat() will replace the
* previous t value. To remove the latency target for the MPU, call
* with t = -1.
*
* XXX This constraint will be deprecated soon in favor of the more
* general omap_pm_set_max_dev_wakeup_lat()
*
* Returns -EINVAL for an invalid argument, -ERANGE if the constraint
* is not satisfiable, or 0 upon success.
*/
int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
/**
* omap_pm_set_min_bus_tput - set minimum bus throughput needed by device
* @dev: struct device * requesting the constraint
* @tbus_id: interconnect to operate on (OCP_{INITIATOR,TARGET}_AGENT)
* @r: minimum throughput (in KiB/s)
*
* Request that the minimum data throughput on the OCP interconnect
* attached to device @dev interconnect agent @tbus_id be no less
* than @r KiB/s.
*
* It is expected that the OMAP PM or bus code will use this
* information to set the interconnect clock to run at the lowest
* possible speed that satisfies all current system users. The PM or
* bus code will adjust the estimate based on its model of the bus, so
* device driver authors should attempt to specify an accurate
* quantity for their device use case, and let the PM or bus code
* overestimate the numbers as necessary to handle request/response
* latency, other competing users on the system, etc. On OMAP2/3, if
* a driver requests a minimum L4 interconnect speed constraint, the
* code will also need to add an minimum L3 interconnect speed
* constraint,
*
* Multiple calls to omap_pm_set_min_bus_tput() will replace the
* previous rate value for this device. To remove the interconnect
* throughput restriction for this device, call with r = 0.
*
* Returns -EINVAL for an invalid argument, -ERANGE if the constraint
* is not satisfiable, or 0 upon success.
*/
int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
/*
* CPUFreq-originated constraint
*
* In the future, this should be handled by custom OPP clocktype
* functions.
*/
/*
* Device context loss tracking
*/
/**
* omap_pm_get_dev_context_loss_count - return count of times dev has lost ctx
* @dev: struct device *
*
* This function returns the number of times that the device @dev has
* lost its internal context. This generally occurs on a powerdomain
* transition to OFF. Drivers use this as an optimization to avoid restoring
* context if the device hasn't lost it. To use, drivers should initially
* call this in their context save functions and store the result. Early in
* the driver's context restore function, the driver should call this function
* again, and compare the result to the stored counter. If they differ, the
* driver must restore device context. If the number of context losses
* exceeds the maximum positive integer, the function will wrap to 0 and
* continue counting. Returns the number of context losses for this device,
* or negative value upon error.
*/
int omap_pm_get_dev_context_loss_count(struct device *dev);
void omap_pm_enable_off_mode(void);
void omap_pm_disable_off_mode(void);
#endif
......@@ -143,7 +143,7 @@ static int omap_device_build_from_dt(struct platform_device *pdev)
struct resource res;
const char *oh_name;
int oh_cnt, i, ret = 0;
bool device_active = false;
bool device_active = false, skip_pm_domain = false;
oh_cnt = of_property_count_strings(node, "ti,hwmods");
if (oh_cnt <= 0) {
......@@ -151,8 +151,15 @@ static int omap_device_build_from_dt(struct platform_device *pdev)
return -ENODEV;
}
/* SDMA still needs special handling for omap_device_build() */
ret = of_property_read_string_index(node, "ti,hwmods", 0, &oh_name);
if (!ret && (!strncmp("dma_system", oh_name, 10) ||
!strncmp("dma", oh_name, 3)))
skip_pm_domain = true;
/* Use ti-sysc driver instead of omap_device? */
if (!omap_hwmod_parse_module_range(NULL, node, &res))
if (!skip_pm_domain &&
!omap_hwmod_parse_module_range(NULL, node, &res))
return -ENODEV;
hwmods = kzalloc(sizeof(struct omap_hwmod *) * oh_cnt, GFP_KERNEL);
......@@ -191,11 +198,12 @@ static int omap_device_build_from_dt(struct platform_device *pdev)
r->name = dev_name(&pdev->dev);
}
dev_pm_domain_set(&pdev->dev, &omap_device_pm_domain);
if (device_active) {
omap_device_enable(pdev);
pm_runtime_set_active(&pdev->dev);
if (!skip_pm_domain) {
dev_pm_domain_set(&pdev->dev, &omap_device_pm_domain);
if (device_active) {
omap_device_enable(pdev);
pm_runtime_set_active(&pdev->dev);
}
}
odbfd_exit1:
......
......@@ -481,7 +481,7 @@ static int _wait_softreset_complete(struct omap_hwmod *oh)
sysc = oh->class->sysc;
if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS)
if (sysc->sysc_flags & SYSS_HAS_RESET_STATUS && sysc->syss_offs > 0)
omap_test_timeout((omap_hwmod_read(oh, sysc->syss_offs)
& SYSS_RESETDONE_MASK),
MAX_MODULE_SOFTRESET_WAIT, c);
......@@ -3171,19 +3171,19 @@ static int omap_hwmod_init_regbits(struct device *dev,
*/
int omap_hwmod_init_reg_offs(struct device *dev,
const struct ti_sysc_module_data *data,
u32 *rev_offs, u32 *sysc_offs, u32 *syss_offs)
s32 *rev_offs, s32 *sysc_offs, s32 *syss_offs)
{
*rev_offs = 0;
*rev_offs = -ENODEV;
*sysc_offs = 0;
*syss_offs = 0;
if (data->offsets[SYSC_REVISION] > 0)
if (data->offsets[SYSC_REVISION] >= 0)
*rev_offs = data->offsets[SYSC_REVISION];
if (data->offsets[SYSC_SYSCONFIG] > 0)
if (data->offsets[SYSC_SYSCONFIG] >= 0)
*sysc_offs = data->offsets[SYSC_SYSCONFIG];
if (data->offsets[SYSC_SYSSTATUS] > 0)
if (data->offsets[SYSC_SYSSTATUS] >= 0)
*syss_offs = data->offsets[SYSC_SYSSTATUS];
return 0;
......@@ -3312,8 +3312,8 @@ static int omap_hwmod_check_module(struct device *dev,
struct omap_hwmod *oh,
const struct ti_sysc_module_data *data,
struct sysc_regbits *sysc_fields,
u32 rev_offs, u32 sysc_offs,
u32 syss_offs, u32 sysc_flags,
s32 rev_offs, s32 sysc_offs,
s32 syss_offs, u32 sysc_flags,
u32 idlemodes)
{
if (!oh->class->sysc)
......@@ -3365,7 +3365,7 @@ static int omap_hwmod_check_module(struct device *dev,
int omap_hwmod_allocate_module(struct device *dev, struct omap_hwmod *oh,
const struct ti_sysc_module_data *data,
struct sysc_regbits *sysc_fields,
u32 rev_offs, u32 sysc_offs, u32 syss_offs,
s32 rev_offs, s32 sysc_offs, s32 syss_offs,
u32 sysc_flags, u32 idlemodes)
{
struct omap_hwmod_class_sysconfig *sysc;
......@@ -3425,7 +3425,8 @@ int omap_hwmod_init_module(struct device *dev,
{
struct omap_hwmod *oh;
struct sysc_regbits *sysc_fields;
u32 rev_offs, sysc_offs, syss_offs, sysc_flags, idlemodes;
s32 rev_offs, sysc_offs, syss_offs;
u32 sysc_flags, idlemodes;
int error;
if (!dev || !data)
......
......@@ -317,9 +317,9 @@ struct omap_hwmod_ocp_if {
* then this field has to be populated with the correct offset structure.
*/
struct omap_hwmod_class_sysconfig {
u32 rev_offs;
u32 sysc_offs;
u32 syss_offs;
s32 rev_offs;
s32 sysc_offs;
s32 syss_offs;
u16 sysc_flags;
struct sysc_regbits *sysc_fields;
u8 srst_udelay;
......
......@@ -629,6 +629,7 @@ struct omap_hwmod am33xx_gpmc_hwmod = {
/* 'i2c' class */
static struct omap_hwmod_class_sysconfig am33xx_i2c_sysc = {
.rev_offs = 0,
.sysc_offs = 0x0010,
.syss_offs = 0x0090,
.sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
......
......@@ -885,6 +885,7 @@ static struct omap_hwmod omap3xxx_dma_system_hwmod = {
*/
static struct omap_hwmod_class_sysconfig omap3xxx_mcbsp_sysc = {
.rev_offs = -ENODEV,
.sysc_offs = 0x008c,
.sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP |
SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
......@@ -990,6 +991,7 @@ static struct omap_hwmod omap3xxx_mcbsp5_hwmod = {
/* 'mcbsp sidetone' class */
static struct omap_hwmod_class_sysconfig omap3xxx_mcbsp_sidetone_sysc = {
.rev_offs = -ENODEV,
.sysc_offs = 0x0010,
.sysc_flags = SYSC_HAS_AUTOIDLE,
.sysc_fields = &omap_hwmod_sysc_type1,
......@@ -1018,6 +1020,7 @@ static struct omap_hwmod omap3xxx_mcbsp3_sidetone_hwmod = {
/* SR common */
static struct omap_hwmod_class_sysconfig omap34xx_sr_sysc = {
.rev_offs = -ENODEV,
.sysc_offs = 0x24,
.sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_NO_CACHE),
.sysc_fields = &omap34xx_sr_sysc_fields,
......@@ -1030,6 +1033,7 @@ static struct omap_hwmod_class omap34xx_smartreflex_hwmod_class = {
};
static struct omap_hwmod_class_sysconfig omap36xx_sr_sysc = {
.rev_offs = -ENODEV,
.sysc_offs = 0x38,
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
.sysc_flags = (SYSC_HAS_SIDLEMODE | SYSC_HAS_ENAWAKEUP |
......
......@@ -378,6 +378,7 @@ static struct omap_hwmod am43xx_usb_otg_ss1_hwmod = {
};
static struct omap_hwmod_class_sysconfig am43xx_qspi_sysc = {
.rev_offs = 0,
.sysc_offs = 0x0010,
.sysc_flags = SYSC_HAS_SIDLEMODE,
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
......
......@@ -1360,6 +1360,7 @@ static struct omap_hwmod omap44xx_hsi_hwmod = {
*/
static struct omap_hwmod_class_sysconfig omap44xx_i2c_sysc = {
.rev_offs = 0,
.sysc_offs = 0x0010,
.syss_offs = 0x0090,
.sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
......@@ -1634,6 +1635,7 @@ static struct omap_hwmod omap44xx_mailbox_hwmod = {
/* The IP is not compliant to type1 / type2 scheme */
static struct omap_hwmod_class_sysconfig omap44xx_mcasp_sysc = {
.rev_offs = 0,
.sysc_offs = 0x0004,
.sysc_flags = SYSC_HAS_SIDLEMODE,
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
......@@ -1667,6 +1669,7 @@ static struct omap_hwmod omap44xx_mcasp_hwmod = {
*/
static struct omap_hwmod_class_sysconfig omap44xx_mcbsp_sysc = {
.rev_offs = -ENODEV,
.sysc_offs = 0x008c,
.sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP |
SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
......@@ -2353,6 +2356,7 @@ static struct omap_hwmod omap44xx_slimbus2_hwmod = {
/* The IP is not compliant to type1 / type2 scheme */
static struct omap_hwmod_class_sysconfig omap44xx_smartreflex_sysc = {
.rev_offs = -ENODEV,
.sysc_offs = 0x0038,
.sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE),
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
......
......@@ -804,6 +804,7 @@ static struct omap_hwmod omap54xx_gpio8_hwmod = {
*/
static struct omap_hwmod_class_sysconfig omap54xx_i2c_sysc = {
.rev_offs = 0,
.sysc_offs = 0x0010,
.syss_offs = 0x0090,
.sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
......@@ -974,6 +975,7 @@ static struct omap_hwmod omap54xx_mailbox_hwmod = {
*/
static struct omap_hwmod_class_sysconfig omap54xx_mcbsp_sysc = {
.rev_offs = -ENODEV,
.sysc_offs = 0x008c,
.sysc_flags = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_ENAWAKEUP |
SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
......@@ -1997,6 +1999,7 @@ static struct omap_hwmod omap54xx_ocp2scp3_hwmod = {
*/
static struct omap_hwmod_class_sysconfig omap54xx_sata_sysc = {
.rev_offs = 0x00fc,
.sysc_offs = 0x0000,
.sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE),
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
......
......@@ -1070,6 +1070,7 @@ static struct omap_hwmod dra7xx_hdq1w_hwmod = {
*/
static struct omap_hwmod_class_sysconfig dra7xx_i2c_sysc = {
.rev_offs = 0,
.sysc_offs = 0x0010,
.syss_offs = 0x0090,
.sysc_flags = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
......@@ -1440,6 +1441,7 @@ static struct omap_hwmod dra7xx_mcspi4_hwmod = {
*
*/
static struct omap_hwmod_class_sysconfig dra7xx_mcasp_sysc = {
.rev_offs = 0,
.sysc_offs = 0x0004,
.sysc_flags = SYSC_HAS_SIDLEMODE,
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
......@@ -1898,6 +1900,7 @@ static struct omap_hwmod dra7xx_pciess2_hwmod = {
*/
static struct omap_hwmod_class_sysconfig dra7xx_qspi_sysc = {
.rev_offs = 0,
.sysc_offs = 0x0010,
.sysc_flags = SYSC_HAS_SIDLEMODE,
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
......@@ -1930,6 +1933,7 @@ static struct omap_hwmod dra7xx_qspi_hwmod = {
*
*/
static struct omap_hwmod_class_sysconfig dra7xx_rtcss_sysc = {
.rev_offs = 0x0074,
.sysc_offs = 0x0078,
.sysc_flags = SYSC_HAS_SIDLEMODE,
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
......@@ -1965,6 +1969,7 @@ static struct omap_hwmod dra7xx_rtcss_hwmod = {
*/
static struct omap_hwmod_class_sysconfig dra7xx_sata_sysc = {
.rev_offs = 0x00fc,
.sysc_offs = 0x0000,
.sysc_flags = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE),
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
......@@ -2003,6 +2008,7 @@ static struct omap_hwmod dra7xx_sata_hwmod = {
/* The IP is not compliant to type1 / type2 scheme */
static struct omap_hwmod_class_sysconfig dra7xx_smartreflex_sysc = {
.rev_offs = -ENODEV,
.sysc_offs = 0x0038,
.sysc_flags = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE),
.idlemodes = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
......
......@@ -954,6 +954,7 @@ static struct omap_hwmod_ocp_if dm816x_l4_hs__emac1 = {
};
static struct omap_hwmod_class_sysconfig dm81xx_sata_sysc = {
.rev_offs = 0x00fc,
.sysc_offs = 0x1100,
.sysc_flags = SYSC_HAS_SIDLEMODE,
.idlemodes = SIDLE_FORCE,
......
......@@ -26,14 +26,12 @@
#include <linux/platform_data/iommu-omap.h>
#include <linux/platform_data/ti-sysc.h>
#include <linux/platform_data/wkup_m3.h>
#include <linux/platform_data/media/ir-rx51.h>
#include <linux/platform_data/asoc-ti-mcbsp.h>
#include "common.h"
#include "common-board-devices.h"
#include "control.h"
#include "omap_device.h"
#include "omap-pm.h"
#include "omap-secure.h"
#include "soc.h"
#include "hsmmc.h"
......@@ -514,18 +512,6 @@ void omap_auxdata_legacy_init(struct device *dev)
dev->platform_data = &twl_gpio_auxdata;
}
static struct ir_rx51_platform_data __maybe_unused rx51_ir_data = {
.set_max_mpu_wakeup_lat = omap_pm_set_max_mpu_wakeup_lat,
};
static struct platform_device __maybe_unused rx51_ir_device = {
.name = "ir_rx51",
.id = -1,
.dev = {
.platform_data = &rx51_ir_data,
},
};
#if IS_ENABLED(CONFIG_SND_OMAP_SOC_MCBSP)
static struct omap_mcbsp_platform_data mcbsp_pdata;
static void __init omap3_mcbsp_init(void)
......@@ -569,7 +555,6 @@ static struct of_dev_auxdata omap_auxdata_lookup[] = {
"480c9000.smartreflex", &omap_sr_pdata[OMAP_SR_MPU]),
OF_DEV_AUXDATA("ti,omap3-hsmmc", 0x4809c000, "4809c000.mmc", &mmc_pdata[0]),
OF_DEV_AUXDATA("ti,omap3-hsmmc", 0x480b4000, "480b4000.mmc", &mmc_pdata[1]),
OF_DEV_AUXDATA("nokia,n900-ir", 0, "n900-ir", &rx51_ir_data),
/* Only on am3517 */
OF_DEV_AUXDATA("ti,davinci_mdio", 0x5c030000, "davinci_mdio.0", NULL),
OF_DEV_AUXDATA("ti,am3517-emac", 0x5c000000, "davinci_emac.0",
......
......@@ -31,7 +31,6 @@
#include "clock.h"
#include "powerdomain.h"
#include "clockdomain.h"
#include "omap-pm.h"
#include "soc.h"
#include "cm2xxx_3xxx.h"
......@@ -240,10 +239,6 @@ static int option_set(void *data, u64 val)
*option = val;
if (option == &enable_off_mode) {
if (val)
omap_pm_enable_off_mode();
else
omap_pm_disable_off_mode();
if (cpu_is_omap34xx())
omap3_pm_off_mode_enable(val);
}
......
......@@ -16,11 +16,11 @@
#include <linux/pm_opp.h>
#include <linux/export.h>
#include <linux/suspend.h>
#include <linux/clk.h>
#include <linux/cpu.h>
#include <asm/system_misc.h>
#include "omap-pm.h"
#include "omap_device.h"
#include "common.h"
......@@ -230,16 +230,20 @@ static void __init omap4_init_voltages(void)
omap2_set_init_voltage("iva", "dpll_iva_m5x2_ck", "iva");
}
static int __init omap2_common_pm_init(void)
int __maybe_unused omap_pm_nop_init(void)
{
omap_pm_if_init();
return 0;
}
omap_postcore_initcall(omap2_common_pm_init);
int (*omap_pm_soc_init)(void);
int __init omap2_common_pm_late_init(void)
{
int error;
if (!omap_pm_soc_init)
return 0;
/* Init the voltage layer */
omap3_twl_init();
omap4_twl_init();
......@@ -252,5 +256,12 @@ int __init omap2_common_pm_late_init(void)
/* Smartreflex device init */
omap_devinit_smartreflex();
error = omap_pm_soc_init();
if (error)
pr_warn("%s: pm soc init failed: %i\n", __func__, error);
omap2_clk_enable_autoidle_all();
return 0;
}
omap_late_initcall(omap2_common_pm_late_init);
......@@ -173,7 +173,7 @@ static struct am33xx_pm_platform_data *am33xx_pm_get_pdata(void)
return NULL;
}
void __init amx3_common_pm_init(void)
int __init amx3_common_pm_init(void)
{
struct am33xx_pm_platform_data *pdata;
struct platform_device_info devinfo;
......@@ -186,4 +186,6 @@ void __init amx3_common_pm_init(void)
devinfo.size_data = sizeof(*pdata);
devinfo.id = -1;
platform_device_register_full(&devinfo);
return 0;
}
......@@ -131,6 +131,19 @@ static int __init pwrdms_setup(struct powerdomain *pwrdm, void *unused)
return 0;
}
/*
* Bootloader or kexec boot may have LOGICRETSTATE cleared
* for some domains. This is the case when kexec booting from
* Android kernels that support off mode for example.
* Make sure it's set at least for core and per, otherwise
* we currently will see lost GPIO interrupts for wlcore and
* smsc911x at least if per hits retention during idle.
*/
if (!strncmp(pwrdm->name, "core", 4) ||
!strncmp(pwrdm->name, "l4per", 5) ||
!strncmp(pwrdm->name, "wkup", 4))
pwrdm_set_logic_retst(pwrdm, PWRDM_POWER_RET);
pwrst = kmalloc(sizeof(struct power_state), GFP_ATOMIC);
if (!pwrst)
return -ENOMEM;
......
......@@ -14,6 +14,7 @@
*/
#undef DEBUG
#include <linux/cpu_pm.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/list.h>
......@@ -39,6 +40,9 @@
#define PWRDM_TRACE_STATES_FLAG (1<<31)
void pwrdms_save_context(void);
void pwrdms_restore_context(void);
enum {
PWRDM_STATE_NOW = 0,
PWRDM_STATE_PREV,
......@@ -333,6 +337,22 @@ int pwrdm_register_pwrdms(struct powerdomain **ps)
return 0;
}
static int cpu_notifier(struct notifier_block *nb, unsigned long cmd, void *v)
{
switch (cmd) {
case CPU_CLUSTER_PM_ENTER:
if (enable_off_mode)
pwrdms_save_context();
break;
case CPU_CLUSTER_PM_EXIT:
if (enable_off_mode)
pwrdms_restore_context();
break;
}
return NOTIFY_OK;
}
/**
* pwrdm_complete_init - set up the powerdomain layer
*
......@@ -347,6 +367,7 @@ int pwrdm_register_pwrdms(struct powerdomain **ps)
int pwrdm_complete_init(void)
{
struct powerdomain *temp_p;
static struct notifier_block nb;
if (list_empty(&pwrdm_list))
return -EACCES;
......@@ -354,6 +375,12 @@ int pwrdm_complete_init(void)
list_for_each_entry(temp_p, &pwrdm_list, node)
pwrdm_set_next_pwrst(temp_p, PWRDM_POWER_ON);
/* Only AM43XX can lose pwrdm context during rtc-ddr suspend */
if (soc_is_am43xx()) {
nb.notifier_call = cpu_notifier;
cpu_pm_register_notifier(&nb);
}
return 0;
}
......@@ -1199,3 +1226,63 @@ bool pwrdm_can_ever_lose_context(struct powerdomain *pwrdm)
return 0;
}
/**
* pwrdm_save_context - save powerdomain registers
*
* Register state is going to be lost due to a suspend or hibernate
* event. Save the powerdomain registers.
*/
static int pwrdm_save_context(struct powerdomain *pwrdm, void *unused)
{
if (arch_pwrdm && arch_pwrdm->pwrdm_save_context)
arch_pwrdm->pwrdm_save_context(pwrdm);
return 0;
}
/**
* pwrdm_save_context - restore powerdomain registers
*
* Restore powerdomain control registers after a suspend or resume
* event.
*/
static int pwrdm_restore_context(struct powerdomain *pwrdm, void *unused)
{
if (arch_pwrdm && arch_pwrdm->pwrdm_restore_context)
arch_pwrdm->pwrdm_restore_context(pwrdm);
return 0;
}
static int pwrdm_lost_power(struct powerdomain *pwrdm, void *unused)
{
int state;
/*
* Power has been lost across all powerdomains, increment the
* counter.
*/
state = pwrdm_read_pwrst(pwrdm);
if (state != PWRDM_POWER_OFF) {
pwrdm->state_counter[state]++;
pwrdm->state_counter[PWRDM_POWER_OFF]++;
}
pwrdm->state = state;
return 0;
}
void pwrdms_save_context(void)
{
pwrdm_for_each(pwrdm_save_context, NULL);
}
void pwrdms_restore_context(void)
{
pwrdm_for_each(pwrdm_restore_context, NULL);
}
void pwrdms_lost_power(void)
{
pwrdm_for_each(pwrdm_lost_power, NULL);
}
......@@ -144,6 +144,7 @@ struct powerdomain {
s64 timer;
s64 state_timer[PWRDM_MAX_PWRSTS];
#endif
u32 context;
};
/**
......@@ -198,6 +199,8 @@ struct pwrdm_ops {
int (*pwrdm_set_lowpwrstchange)(struct powerdomain *pwrdm);
int (*pwrdm_wait_transition)(struct powerdomain *pwrdm);
int (*pwrdm_has_voltdm)(void);
void (*pwrdm_save_context)(struct powerdomain *pwrdm);
void (*pwrdm_restore_context)(struct powerdomain *pwrdm);
};
int pwrdm_register_platform_funcs(struct pwrdm_ops *custom_funcs);
......@@ -273,4 +276,8 @@ extern struct powerdomain gfx_omap2_pwrdm;
extern void pwrdm_lock(struct powerdomain *pwrdm);
extern void pwrdm_unlock(struct powerdomain *pwrdm);
extern void pwrdms_save_context(void);
extern void pwrdms_restore_context(void);
extern void pwrdms_lost_power(void);
#endif
......@@ -342,6 +342,35 @@ static void am33xx_prm_global_warm_sw_reset(void)
AM33XX_PRM_RSTCTRL_OFFSET);
}
static void am33xx_pwrdm_save_context(struct powerdomain *pwrdm)
{
pwrdm->context = am33xx_prm_read_reg(pwrdm->prcm_offs,
pwrdm->pwrstctrl_offs);
/*
* Do not save LOWPOWERSTATECHANGE, writing a 1 indicates a request,
* reading back a 1 indicates a request in progress.
*/
pwrdm->context &= ~AM33XX_LOWPOWERSTATECHANGE_MASK;
}
static void am33xx_pwrdm_restore_context(struct powerdomain *pwrdm)
{
int st, ctrl;
st = am33xx_prm_read_reg(pwrdm->prcm_offs,
pwrdm->pwrstst_offs);
am33xx_prm_write_reg(pwrdm->context, pwrdm->prcm_offs,
pwrdm->pwrstctrl_offs);
/* Make sure we only wait for a transition if there is one */
st &= OMAP_POWERSTATEST_MASK;
ctrl = OMAP_POWERSTATEST_MASK & pwrdm->context;
if (st != ctrl)
am33xx_pwrdm_wait_transition(pwrdm);
}
struct pwrdm_ops am33xx_pwrdm_operations = {
.pwrdm_set_next_pwrst = am33xx_pwrdm_set_next_pwrst,
.pwrdm_read_next_pwrst = am33xx_pwrdm_read_next_pwrst,
......@@ -357,6 +386,8 @@ struct pwrdm_ops am33xx_pwrdm_operations = {
.pwrdm_set_mem_retst = am33xx_pwrdm_set_mem_retst,
.pwrdm_wait_transition = am33xx_pwrdm_wait_transition,
.pwrdm_has_voltdm = am33xx_check_vcvp,
.pwrdm_save_context = am33xx_pwrdm_save_context,
.pwrdm_restore_context = am33xx_pwrdm_restore_context,
};
static struct prm_ll_data am33xx_prm_ll_data = {
......
......@@ -12,6 +12,7 @@
* published by the Free Software Foundation.
*/
#include <linux/cpu_pm.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/errno.h>
......@@ -30,6 +31,7 @@
#include "prcm44xx.h"
#include "prminst44xx.h"
#include "powerdomain.h"
#include "pm.h"
/* Static data */
......@@ -57,6 +59,13 @@ static struct omap_prcm_irq_setup omap4_prcm_irq_setup = {
.reconfigure_io_chain = &omap44xx_prm_reconfigure_io_chain,
};
struct omap_prm_irq_context {
unsigned long irq_enable;
unsigned long pm_ctrl;
};
static struct omap_prm_irq_context omap_prm_context;
/*
* omap44xx_prm_reset_src_map - map from bits in the PRM_RSTST
* hardware register (which are specific to OMAP44xx SoCs) to reset
......@@ -667,6 +676,54 @@ static int omap4_check_vcvp(void)
return 0;
}
/**
* omap4_pwrdm_save_context - Saves the powerdomain state
* @pwrdm: pointer to individual powerdomain
*
* The function saves the powerdomain state control information.
* This is needed in rtc+ddr modes where we lose powerdomain context.
*/
static void omap4_pwrdm_save_context(struct powerdomain *pwrdm)
{
pwrdm->context = omap4_prminst_read_inst_reg(pwrdm->prcm_partition,
pwrdm->prcm_offs,
pwrdm->pwrstctrl_offs);
/*
* Do not save LOWPOWERSTATECHANGE, writing a 1 indicates a request,
* reading back a 1 indicates a request in progress.
*/
pwrdm->context &= ~OMAP4430_LOWPOWERSTATECHANGE_MASK;
}
/**
* omap4_pwrdm_restore_context - Restores the powerdomain state
* @pwrdm: pointer to individual powerdomain
*
* The function restores the powerdomain state control information.
* This is needed in rtc+ddr modes where we lose powerdomain context.
*/
static void omap4_pwrdm_restore_context(struct powerdomain *pwrdm)
{
int st, ctrl;
st = omap4_prminst_read_inst_reg(pwrdm->prcm_partition,
pwrdm->prcm_offs,
pwrdm->pwrstctrl_offs);
omap4_prminst_write_inst_reg(pwrdm->context,
pwrdm->prcm_partition,
pwrdm->prcm_offs,
pwrdm->pwrstctrl_offs);
/* Make sure we only wait for a transition if there is one */
st &= OMAP_POWERSTATEST_MASK;
ctrl = OMAP_POWERSTATEST_MASK & pwrdm->context;
if (st != ctrl)
omap4_pwrdm_wait_transition(pwrdm);
}
struct pwrdm_ops omap4_pwrdm_operations = {
.pwrdm_set_next_pwrst = omap4_pwrdm_set_next_pwrst,
.pwrdm_read_next_pwrst = omap4_pwrdm_read_next_pwrst,
......@@ -685,10 +742,50 @@ struct pwrdm_ops omap4_pwrdm_operations = {
.pwrdm_set_mem_retst = omap4_pwrdm_set_mem_retst,
.pwrdm_wait_transition = omap4_pwrdm_wait_transition,
.pwrdm_has_voltdm = omap4_check_vcvp,
.pwrdm_save_context = omap4_pwrdm_save_context,
.pwrdm_restore_context = omap4_pwrdm_restore_context,
};
static int omap44xx_prm_late_init(void);
void prm_save_context(void)
{
omap_prm_context.irq_enable =
omap4_prm_read_inst_reg(AM43XX_PRM_OCP_SOCKET_INST,
omap4_prcm_irq_setup.mask);
omap_prm_context.pm_ctrl =
omap4_prm_read_inst_reg(AM43XX_PRM_DEVICE_INST,
omap4_prcm_irq_setup.pm_ctrl);
}
void prm_restore_context(void)
{
omap4_prm_write_inst_reg(omap_prm_context.irq_enable,
OMAP4430_PRM_OCP_SOCKET_INST,
omap4_prcm_irq_setup.mask);
omap4_prm_write_inst_reg(omap_prm_context.pm_ctrl,
AM43XX_PRM_DEVICE_INST,
omap4_prcm_irq_setup.pm_ctrl);
}
static int cpu_notifier(struct notifier_block *nb, unsigned long cmd, void *v)
{
switch (cmd) {
case CPU_CLUSTER_PM_ENTER:
if (enable_off_mode)
prm_save_context();
break;
case CPU_CLUSTER_PM_EXIT:
if (enable_off_mode)
prm_restore_context();
break;
}
return NOTIFY_OK;
}
/*
* XXX document
*/
......@@ -709,6 +806,7 @@ static const struct omap_prcm_init_data *prm_init_data;
int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
{
static struct notifier_block nb;
omap_prm_base_init();
prm_init_data = data;
......@@ -730,6 +828,12 @@ int __init omap44xx_prm_init(const struct omap_prcm_init_data *data)
omap4_prcm_irq_setup.mask = AM43XX_PRM_IRQENABLE_MPU_OFFSET;
}
/* Only AM43XX can lose prm context during rtc-ddr suspend */
if (soc_is_am43xx()) {
nb.notifier_call = cpu_notifier;
cpu_pm_register_notifier(&nb);
}
return prm_register(&omap44xx_prm_ll_data);
}
......
......@@ -50,7 +50,6 @@
#include "omap_device.h"
#include <plat/counter-32k.h>
#include <clocksource/timer-ti-dm.h>
#include "omap-pm.h"
#include "soc.h"
#include "common.h"
......@@ -71,6 +70,9 @@ static struct clock_event_device clockevent_gpt;
/* Clockevent hwmod for am335x and am437x suspend */
static struct omap_hwmod *clockevent_gpt_hwmod;
/* Clockesource hwmod for am437x suspend */
static struct omap_hwmod *clocksource_gpt_hwmod;
#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
static unsigned long arch_timer_freq;
......@@ -168,6 +170,43 @@ static const struct of_device_id omap_timer_match[] __initconst = {
{ }
};
static int omap_timer_add_disabled_property(struct device_node *np)
{
struct property *prop;
prop = kzalloc(sizeof(*prop), GFP_KERNEL);
if (!prop)
return -ENOMEM;
prop->name = "status";
prop->value = "disabled";
prop->length = strlen(prop->value);
return of_add_property(np, prop);
}
static int omap_timer_update_dt(struct device_node *np)
{
int error = 0;
if (!of_device_is_compatible(np, "ti,omap-counter32k")) {
error = omap_timer_add_disabled_property(np);
if (error)
return error;
}
/* No parent interconnect target module configured? */
if (of_get_property(np, "ti,hwmods", NULL))
return error;
/* Tag parent interconnect target module disabled */
error = omap_timer_add_disabled_property(np->parent);
if (error)
return error;
return 0;
}
/**
* omap_get_timer_dt - get a timer using device-tree
* @match - device-tree match structure for matching a device type
......@@ -183,6 +222,7 @@ static struct device_node * __init omap_get_timer_dt(const struct of_device_id *
const char *property)
{
struct device_node *np;
int error;
for_each_matching_node(np, match) {
if (!of_device_is_available(np))
......@@ -197,17 +237,9 @@ static struct device_node * __init omap_get_timer_dt(const struct of_device_id *
of_get_property(np, "ti,timer-secure", NULL)))
continue;
if (!of_device_is_compatible(np, "ti,omap-counter32k")) {
struct property *prop;
error = omap_timer_update_dt(np);
WARN(error, "%s: Could not update dt: %i\n", __func__, error);
prop = kzalloc(sizeof(*prop), GFP_KERNEL);
if (!prop)
return NULL;
prop->name = "status";
prop->value = "disabled";
prop->length = strlen(prop->value);
of_add_property(np, prop);
}
return np;
}
......@@ -266,8 +298,12 @@ static int __init omap_dm_timer_init_one(struct omap_dm_timer *timer,
return -ENODEV;
of_property_read_string_index(np, "ti,hwmods", 0, &oh_name);
if (!oh_name)
return -ENODEV;
if (!oh_name) {
of_property_read_string_index(np->parent, "ti,hwmods", 0,
&oh_name);
if (!oh_name)
return -ENODEV;
}
timer->irq = irq_of_parse_and_map(np, 0);
if (!timer->irq)
......@@ -419,9 +455,12 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void)
if (!np)
return -ENODEV;
of_property_read_string_index(np, "ti,hwmods", 0, &oh_name);
if (!oh_name)
return -ENODEV;
of_property_read_string_index(np->parent, "ti,hwmods", 0, &oh_name);
if (!oh_name) {
of_property_read_string_index(np, "ti,hwmods", 0, &oh_name);
if (!oh_name)
return -ENODEV;
}
/*
* First check hwmod data is available for sync32k counter
......@@ -442,6 +481,26 @@ static int __init __maybe_unused omap2_sync32k_clocksource_init(void)
return ret;
}
static unsigned int omap2_gptimer_clksrc_load;
static void omap2_gptimer_clksrc_suspend(struct clocksource *unused)
{
omap2_gptimer_clksrc_load =
__omap_dm_timer_read_counter(&clksrc, OMAP_TIMER_NONPOSTED);
omap_hwmod_idle(clocksource_gpt_hwmod);
}
static void omap2_gptimer_clksrc_resume(struct clocksource *unused)
{
omap_hwmod_enable(clocksource_gpt_hwmod);
__omap_dm_timer_load_start(&clksrc,
OMAP_TIMER_CTRL_ST | OMAP_TIMER_CTRL_AR,
omap2_gptimer_clksrc_load,
OMAP_TIMER_NONPOSTED);
}
static void __init omap2_gptimer_clocksource_init(int gptimer_id,
const char *fck_source,
const char *property)
......@@ -454,6 +513,15 @@ static void __init omap2_gptimer_clocksource_init(int gptimer_id,
res = omap_dm_timer_init_one(&clksrc, fck_source, property,
&clocksource_gpt.name,
OMAP_TIMER_NONPOSTED);
if (soc_is_am43xx()) {
clocksource_gpt.suspend = omap2_gptimer_clksrc_suspend;
clocksource_gpt.resume = omap2_gptimer_clksrc_resume;
clocksource_gpt_hwmod =
omap_hwmod_lookup(clocksource_gpt.name);
}
BUG_ON(res);
__omap_dm_timer_load_start(&clksrc,
......
......@@ -446,6 +446,10 @@ static int __init pxa3xx_init(void)
pxa3xx_init_pm();
enable_irq_wake(IRQ_WAKEUP0);
if (cpu_is_pxa320())
enable_irq_wake(IRQ_WAKEUP1);
register_syscore_ops(&pxa_irq_syscore_ops);
register_syscore_ops(&pxa3xx_mfp_syscore_ops);
......
......@@ -27,11 +27,11 @@
#include <linux/platform_data/i2c-pxa.h>
#include <linux/platform_data/pcf857x.h>
#include <linux/platform_data/at24.h>
#include <linux/smc91x.h>
#include <linux/gpio/machine.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <linux/property.h>
#include <asm/types.h>
#include <asm/setup.h>
......@@ -795,9 +795,9 @@ static struct pcf857x_platform_data platform_data_pcf857x = {
.context = NULL,
};
static struct at24_platform_data pca9500_eeprom_pdata = {
.byte_len = 256,
.page_size = 4,
static const struct property_entry pca9500_eeprom_properties[] = {
PROPERTY_ENTRY_U32("pagesize", 4),
{ }
};
/**
......@@ -935,7 +935,7 @@ static struct i2c_board_info __initdata stargate2_i2c_board_info[] = {
}, {
.type = "24c02",
.addr = 0x57,
.platform_data = &pca9500_eeprom_pdata,
.properties = pca9500_eeprom_properties,
}, {
.type = "max1238",
.addr = 0x35,
......
// SPDX-License-Identifier: GPL-1.0
// SPDX-License-Identifier: GPL-1.0+
//
// Copyright (c) Arnaud Patard <arnaud.patard@rtp-net.org>
//
......
......@@ -20,7 +20,7 @@
#include <linux/serial_core.h>
#include <linux/serial_s3c.h>
#include <linux/dm9000.h>
#include <linux/platform_data/at24.h>
#include <linux/property.h>
#include <linux/platform_device.h>
#include <linux/gpio_keys.h>
#include <linux/i2c.h>
......@@ -481,15 +481,15 @@ static struct platform_device mini2440_audio = {
/*
* I2C devices
*/
static struct at24_platform_data at24c08 = {
.byte_len = SZ_8K / 8,
.page_size = 16,
static const struct property_entry mini2440_at24_properties[] = {
PROPERTY_ENTRY_U32("pagesize", 16),
{ }
};
static struct i2c_board_info mini2440_i2c_devs[] __initdata = {
{
I2C_BOARD_INFO("24c08", 0x50),
.platform_data = &at24c08,
.properties = mini2440_at24_properties,
},
};
......
......@@ -74,6 +74,10 @@ config ARCH_R8A7745
bool "RZ/G1E (R8A77450)"
select ARCH_RCAR_GEN2
config ARCH_R8A77470
bool "RZ/G1C (R8A77470)"
select ARCH_RCAR_GEN2
config ARCH_R8A7778
bool "R-Car M1A (R8A77781)"
select ARCH_RCAR_GEN1
......@@ -109,6 +113,15 @@ config ARCH_R8A7794
bool "R-Car E2 (R8A77940)"
select ARCH_RCAR_GEN2
config ARCH_R9A06G032
bool "RZ/N1D (R9A06G032)"
select ARCH_RZN1
config ARCH_RZN1
bool "RZ/N1 (R9A06G0xx) Family"
select ARM_AMBA
select CPU_V7
config ARCH_SH73A0
bool "SH-Mobile AG5 (R8A73A00)"
select ARCH_RMOBILE
......
......@@ -2,7 +2,6 @@
#ifndef __ARCH_MACH_COMMON_H
#define __ARCH_MACH_COMMON_H
extern void shmobile_init_cntvoff(void);
extern void shmobile_init_delay(void);
extern void shmobile_boot_vector(void);
extern unsigned long shmobile_boot_fn;
......
......@@ -11,29 +11,9 @@
#include <linux/linkage.h>
#include <asm/assembler.h>
ENTRY(shmobile_init_cntvoff)
/*
* CNTVOFF has to be initialized either from non-secure Hypervisor
* mode or secure Monitor mode with SCR.NS==1. If TrustZone is enabled
* then it should be handled by the secure code
*/
cps #MON_MODE
mrc p15, 0, r1, c1, c1, 0 /* Get Secure Config */
orr r0, r1, #1
mcr p15, 0, r0, c1, c1, 0 /* Set Non Secure bit */
instr_sync
mov r0, #0
mcrr p15, 4, r0, r0, c14 /* CNTVOFF = 0 */
instr_sync
mcr p15, 0, r1, c1, c1, 0 /* Set Secure bit */
instr_sync
cps #SVC_MODE
ret lr
ENDPROC(shmobile_init_cntvoff)
#ifdef CONFIG_SMP
ENTRY(shmobile_boot_apmu)
bl shmobile_init_cntvoff
bl secure_cntvoff_init
b secondary_startup
ENDPROC(shmobile_boot_apmu)
#endif
......@@ -26,6 +26,7 @@
#include <linux/of_fdt.h>
#include <linux/of_platform.h>
#include <asm/mach/arch.h>
#include <asm/secure_cntvoff.h>
#include "common.h"
#include "rcar-gen2.h"
......@@ -70,9 +71,10 @@ void __init rcar_gen2_timer_init(void)
void __iomem *base;
u32 freq;
shmobile_init_cntvoff();
secure_cntvoff_init();
if (of_machine_is_compatible("renesas,r8a7745") ||
of_machine_is_compatible("renesas,r8a77470") ||
of_machine_is_compatible("renesas,r8a7792") ||
of_machine_is_compatible("renesas,r8a7794")) {
freq = 260000000 / 8; /* ZS / 8 */
......@@ -205,6 +207,7 @@ MACHINE_END
static const char * const rz_g1_boards_compat_dt[] __initconst = {
"renesas,r8a7743",
"renesas,r8a7745",
"renesas,r8a77470",
NULL,
};
......
......@@ -51,7 +51,7 @@ config MACH_SUN9I
config ARCH_SUNXI_MC_SMP
bool
depends on SMP
default MACH_SUN9I
default MACH_SUN9I || MACH_SUN8I
select ARM_CCI400_PORT_CTRL
select ARM_CPU_SUSPEND
......
CFLAGS_mc_smp.o += -march=armv7-a
obj-$(CONFIG_ARCH_SUNXI) += sunxi.o
obj-$(CONFIG_ARCH_SUNXI_MC_SMP) += mc_smp.o
obj-$(CONFIG_ARCH_SUNXI_MC_SMP) += mc_smp.o headsmp.o
obj-$(CONFIG_SMP) += platsmp.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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