aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-4.14/823-pm-support-layerscape.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-4.14/823-pm-support-layerscape.patch')
-rw-r--r--target/linux/layerscape/patches-4.14/823-pm-support-layerscape.patch718
1 files changed, 718 insertions, 0 deletions
diff --git a/target/linux/layerscape/patches-4.14/823-pm-support-layerscape.patch b/target/linux/layerscape/patches-4.14/823-pm-support-layerscape.patch
new file mode 100644
index 0000000000..e5c3b7db08
--- /dev/null
+++ b/target/linux/layerscape/patches-4.14/823-pm-support-layerscape.patch
@@ -0,0 +1,718 @@
+From aded309f403c4202b9c6f61ea6a635e0c736eb77 Mon Sep 17 00:00:00 2001
+From: Biwen Li <biwen.li@nxp.com>
+Date: Tue, 30 Oct 2018 18:27:07 +0800
+Subject: [PATCH 40/40] pm: support layerscape
+This is an integrated patch of pm for layerscape
+
+Signed-off-by: Chenhui Zhao <chenhui.zhao@freescale.com>
+Signed-off-by: Hongbo Zhang <hongbo.zhang@freescale.com>
+Signed-off-by: Li Yang <leoyang.li@nxp.com>
+Signed-off-by: Ran Wang <ran.wang_1@nxp.com>
+Signed-off-by: Tang Yuantian <andy.tang@nxp.com>
+Signed-off-by: Zhao Chenhui <chenhui.zhao@nxp.com>
+Signed-off-by: Biwen Li <biwen.li@nxp.com>
+---
+ .../devicetree/bindings/powerpc/fsl/pmc.txt | 59 ++--
+ drivers/firmware/psci.c | 16 +-
+ drivers/soc/fsl/rcpm.c | 158 ++++++++++
+ drivers/soc/fsl/sleep_fsm.c | 279 ++++++++++++++++++
+ drivers/soc/fsl/sleep_fsm.h | 130 ++++++++
+ 5 files changed, 615 insertions(+), 27 deletions(-)
+ create mode 100644 drivers/soc/fsl/rcpm.c
+ create mode 100644 drivers/soc/fsl/sleep_fsm.c
+ create mode 100644 drivers/soc/fsl/sleep_fsm.h
+
+--- a/Documentation/devicetree/bindings/powerpc/fsl/pmc.txt
++++ b/Documentation/devicetree/bindings/powerpc/fsl/pmc.txt
+@@ -9,15 +9,20 @@ Properties:
+
+ "fsl,mpc8548-pmc" should be listed for any chip whose PMC is
+ compatible. "fsl,mpc8536-pmc" should also be listed for any chip
+- whose PMC is compatible, and implies deep-sleep capability.
++ whose PMC is compatible, and implies deep-sleep capability and
++ wake on user defined packet(wakeup on ARP).
++
++ "fsl,p1022-pmc" should be listed for any chip whose PMC is
++ compatible, and implies lossless Ethernet capability during sleep.
+
+ "fsl,mpc8641d-pmc" should be listed for any chip whose PMC is
+ compatible; all statements below that apply to "fsl,mpc8548-pmc" also
+ apply to "fsl,mpc8641d-pmc".
+
+ Compatibility does not include bit assignments in SCCR/PMCDR/DEVDISR; these
+- bit assignments are indicated via the sleep specifier in each device's
+- sleep property.
++ bit assignments are indicated via the clock nodes. Device which has a
++ controllable clock source should have a "fsl,pmc-handle" property pointing
++ to the clock node.
+
+ - reg: For devices compatible with "fsl,mpc8349-pmc", the first resource
+ is the PMC block, and the second resource is the Clock Configuration
+@@ -33,31 +38,35 @@ Properties:
+ this is a phandle to an "fsl,gtm" node on which timer 4 can be used as
+ a wakeup source from deep sleep.
+
+-Sleep specifiers:
+-
+- fsl,mpc8349-pmc: Sleep specifiers consist of one cell. For each bit
+- that is set in the cell, the corresponding bit in SCCR will be saved
+- and cleared on suspend, and restored on resume. This sleep controller
+- supports disabling and resuming devices at any time.
+-
+- fsl,mpc8536-pmc: Sleep specifiers consist of three cells, the third of
+- which will be ORed into PMCDR upon suspend, and cleared from PMCDR
+- upon resume. The first two cells are as described for fsl,mpc8578-pmc.
+- This sleep controller only supports disabling devices during system
+- sleep, or permanently.
+-
+- fsl,mpc8548-pmc: Sleep specifiers consist of one or two cells, the
+- first of which will be ORed into DEVDISR (and the second into
+- DEVDISR2, if present -- this cell should be zero or absent if the
+- hardware does not have DEVDISR2) upon a request for permanent device
+- disabling. This sleep controller does not support configuring devices
+- to disable during system sleep (unless supported by another compatible
+- match), or dynamically.
++Clock nodes:
++The clock nodes are to describe the masks in PM controller registers for each
++soc clock.
++- fsl,pmcdr-mask: For "fsl,mpc8548-pmc"-compatible devices, the mask will be
++ ORed into PMCDR before suspend if the device using this clock is the wake-up
++ source and need to be running during low power mode; clear the mask if
++ otherwise.
++
++- fsl,sccr-mask: For "fsl,mpc8349-pmc"-compatible devices, the corresponding
++ bit specified by the mask in SCCR will be saved and cleared on suspend, and
++ restored on resume.
++
++- fsl,devdisr-mask: Contain one or two cells, depending on the availability of
++ DEVDISR2 register. For compatible devices, the mask will be ORed into DEVDISR
++ or DEVDISR2 when the clock should be permenently disabled.
+
+ Example:
+
+- power@b00 {
+- compatible = "fsl,mpc8313-pmc", "fsl,mpc8349-pmc";
+- reg = <0xb00 0x100 0xa00 0x100>;
+- interrupts = <80 8>;
++ power@e0070 {
++ compatible = "fsl,mpc8536-pmc", "fsl,mpc8548-pmc";
++ reg = <0xe0070 0x20>;
++
++ etsec1_clk: soc-clk@24 {
++ fsl,pmcdr-mask = <0x00000080>;
++ };
++ etsec2_clk: soc-clk@25 {
++ fsl,pmcdr-mask = <0x00000040>;
++ };
++ etsec3_clk: soc-clk@26 {
++ fsl,pmcdr-mask = <0x00000020>;
++ };
+ };
+--- a/drivers/firmware/psci.c
++++ b/drivers/firmware/psci.c
+@@ -437,8 +437,18 @@ CPUIDLE_METHOD_OF_DECLARE(psci, "psci",
+
+ static int psci_system_suspend(unsigned long unused)
+ {
+- return invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND),
+- __pa_symbol(cpu_resume), 0, 0);
++ u32 state;
++ u32 ver = psci_get_version();
++
++ if (PSCI_VERSION_MAJOR(ver) >= 1) {
++ return invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND),
++ virt_to_phys(cpu_resume), 0, 0);
++ } else {
++ state = ( 2 << PSCI_0_2_POWER_STATE_AFFL_SHIFT) |
++ (1 << PSCI_0_2_POWER_STATE_TYPE_SHIFT);
++
++ return psci_cpu_suspend(state, virt_to_phys(cpu_resume));
++ }
+ }
+
+ static int psci_system_suspend_enter(suspend_state_t state)
+@@ -562,6 +572,8 @@ static void __init psci_0_2_set_function
+ arm_pm_restart = psci_sys_reset;
+
+ pm_power_off = psci_sys_poweroff;
++
++ suspend_set_ops(&psci_suspend_ops);
+ }
+
+ /*
+--- /dev/null
++++ b/drivers/soc/fsl/rcpm.c
+@@ -0,0 +1,158 @@
++/*
++ * Run Control and Power Management (RCPM) driver
++ *
++ * Copyright 2016 NXP
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ */
++#define pr_fmt(fmt) "RCPM: %s: " fmt, __func__
++
++#include <linux/kernel.h>
++#include <linux/io.h>
++#include <linux/of_platform.h>
++#include <linux/of_address.h>
++#include <linux/suspend.h>
++
++/* RCPM register offset */
++#define RCPM_IPPDEXPCR0 0x140
++
++#define RCPM_WAKEUP_CELL_SIZE 2
++
++struct rcpm_config {
++ int ipp_num;
++ int ippdexpcr_offset;
++ u32 ippdexpcr[2];
++ void *rcpm_reg_base;
++};
++
++static struct rcpm_config *rcpm;
++
++static inline void rcpm_reg_write(u32 offset, u32 value)
++{
++ iowrite32be(value, rcpm->rcpm_reg_base + offset);
++}
++
++static inline u32 rcpm_reg_read(u32 offset)
++{
++ return ioread32be(rcpm->rcpm_reg_base + offset);
++}
++
++static void rcpm_wakeup_fixup(struct device *dev, void *data)
++{
++ struct device_node *node = dev ? dev->of_node : NULL;
++ u32 value[RCPM_WAKEUP_CELL_SIZE];
++ int ret, i;
++
++ if (!dev || !node || !device_may_wakeup(dev))
++ return;
++
++ /*
++ * Get the values in the "rcpm-wakeup" property.
++ * Three values are:
++ * The first is a pointer to the RCPM node.
++ * The second is the value of the ippdexpcr0 register.
++ * The third is the value of the ippdexpcr1 register.
++ */
++ ret = of_property_read_u32_array(node, "fsl,rcpm-wakeup",
++ value, RCPM_WAKEUP_CELL_SIZE);
++ if (ret)
++ return;
++
++ pr_debug("wakeup source: the device %s\n", node->full_name);
++
++ for (i = 0; i < rcpm->ipp_num; i++)
++ rcpm->ippdexpcr[i] |= value[i + 1];
++}
++
++static int rcpm_suspend_prepare(void)
++{
++ int i;
++ u32 val;
++
++ BUG_ON(!rcpm);
++
++ for (i = 0; i < rcpm->ipp_num; i++)
++ rcpm->ippdexpcr[i] = 0;
++
++ dpm_for_each_dev(NULL, rcpm_wakeup_fixup);
++
++ for (i = 0; i < rcpm->ipp_num; i++) {
++ if (rcpm->ippdexpcr[i]) {
++ val = rcpm_reg_read(rcpm->ippdexpcr_offset + 4 * i);
++ rcpm_reg_write(rcpm->ippdexpcr_offset + 4 * i,
++ val | rcpm->ippdexpcr[i]);
++ pr_debug("ippdexpcr%d = 0x%x\n", i, rcpm->ippdexpcr[i]);
++ }
++ }
++
++ return 0;
++}
++
++static int rcpm_suspend_notifier_call(struct notifier_block *bl,
++ unsigned long state,
++ void *unused)
++{
++ switch (state) {
++ case PM_SUSPEND_PREPARE:
++ rcpm_suspend_prepare();
++ break;
++ }
++
++ return NOTIFY_DONE;
++}
++
++static struct rcpm_config rcpm_default_config = {
++ .ipp_num = 1,
++ .ippdexpcr_offset = RCPM_IPPDEXPCR0,
++};
++
++static const struct of_device_id rcpm_matches[] = {
++ {
++ .compatible = "fsl,qoriq-rcpm-2.1",
++ .data = &rcpm_default_config,
++ },
++ {}
++};
++
++static struct notifier_block rcpm_suspend_notifier = {
++ .notifier_call = rcpm_suspend_notifier_call,
++};
++
++static int __init layerscape_rcpm_init(void)
++{
++ const struct of_device_id *match;
++ struct device_node *np;
++
++ np = of_find_matching_node_and_match(NULL, rcpm_matches, &match);
++ if (!np) {
++ pr_err("Can't find the RCPM node.\n");
++ return -EINVAL;
++ }
++
++ if (match->data)
++ rcpm = (struct rcpm_config *)match->data;
++ else
++ return -EINVAL;
++
++ rcpm->rcpm_reg_base = of_iomap(np, 0);
++ of_node_put(np);
++ if (!rcpm->rcpm_reg_base)
++ return -ENOMEM;
++
++ register_pm_notifier(&rcpm_suspend_notifier);
++
++ pr_info("The RCPM driver initialized.\n");
++
++ return 0;
++}
++
++subsys_initcall(layerscape_rcpm_init);
+--- /dev/null
++++ b/drivers/soc/fsl/sleep_fsm.c
+@@ -0,0 +1,279 @@
++/*
++ * deep sleep FSM (finite-state machine) configuration
++ *
++ * Copyright 2018 NXP
++ *
++ * Author: Hongbo Zhang <hongbo.zhang@freescale.com>
++ * Chenhui Zhao <chenhui.zhao@freescale.com>
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are met:
++ * * Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * * Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * * Neither the name of the above-listed copyright holders nor the
++ * names of any contributors may be used to endorse or promote products
++ * derived from this software without specific prior written permission.
++ *
++ * ALTERNATIVELY, this software may be distributed under the terms of the
++ * GNU General Public License ("GPL") as published by the Free Software
++ * Foundation, either version 2 of that License or (at your option) any
++ * later version.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++ * POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#include <linux/kernel.h>
++#include <linux/io.h>
++#include <linux/types.h>
++
++#include "sleep_fsm.h"
++/*
++ * These values are from chip's reference manual. For example,
++ * the values for T1040 can be found in "8.4.3.8 Programming
++ * supporting deep sleep mode" of Chapter 8 "Run Control and
++ * Power Management (RCPM)".
++ * The default value can be applied to T104x, LS1021.
++ */
++struct fsm_reg_vals epu_default_val[] = {
++ /* EPGCR (Event Processor Global Control Register) */
++ {EPGCR, 0},
++ /* EPECR (Event Processor Event Control Registers) */
++ {EPECR0 + EPECR_STRIDE * 0, 0},
++ {EPECR0 + EPECR_STRIDE * 1, 0},
++ {EPECR0 + EPECR_STRIDE * 2, 0xF0004004},
++ {EPECR0 + EPECR_STRIDE * 3, 0x80000084},
++ {EPECR0 + EPECR_STRIDE * 4, 0x20000084},
++ {EPECR0 + EPECR_STRIDE * 5, 0x08000004},
++ {EPECR0 + EPECR_STRIDE * 6, 0x80000084},
++ {EPECR0 + EPECR_STRIDE * 7, 0x80000084},
++ {EPECR0 + EPECR_STRIDE * 8, 0x60000084},
++ {EPECR0 + EPECR_STRIDE * 9, 0x08000084},
++ {EPECR0 + EPECR_STRIDE * 10, 0x42000084},
++ {EPECR0 + EPECR_STRIDE * 11, 0x90000084},
++ {EPECR0 + EPECR_STRIDE * 12, 0x80000084},
++ {EPECR0 + EPECR_STRIDE * 13, 0x08000084},
++ {EPECR0 + EPECR_STRIDE * 14, 0x02000084},
++ {EPECR0 + EPECR_STRIDE * 15, 0x00000004},
++ /*
++ * EPEVTCR (Event Processor EVT Pin Control Registers)
++ * SCU8 triger EVT2, and SCU11 triger EVT9
++ */
++ {EPEVTCR0 + EPEVTCR_STRIDE * 0, 0},
++ {EPEVTCR0 + EPEVTCR_STRIDE * 1, 0},
++ {EPEVTCR0 + EPEVTCR_STRIDE * 2, 0x80000001},
++ {EPEVTCR0 + EPEVTCR_STRIDE * 3, 0},
++ {EPEVTCR0 + EPEVTCR_STRIDE * 4, 0},
++ {EPEVTCR0 + EPEVTCR_STRIDE * 5, 0},
++ {EPEVTCR0 + EPEVTCR_STRIDE * 6, 0},
++ {EPEVTCR0 + EPEVTCR_STRIDE * 7, 0},
++ {EPEVTCR0 + EPEVTCR_STRIDE * 8, 0},
++ {EPEVTCR0 + EPEVTCR_STRIDE * 9, 0xB0000001},
++ /* EPCMPR (Event Processor Counter Compare Registers) */
++ {EPCMPR0 + EPCMPR_STRIDE * 0, 0},
++ {EPCMPR0 + EPCMPR_STRIDE * 1, 0},
++ {EPCMPR0 + EPCMPR_STRIDE * 2, 0x000000FF},
++ {EPCMPR0 + EPCMPR_STRIDE * 3, 0},
++ {EPCMPR0 + EPCMPR_STRIDE * 4, 0x000000FF},
++ {EPCMPR0 + EPCMPR_STRIDE * 5, 0x00000020},
++ {EPCMPR0 + EPCMPR_STRIDE * 6, 0},
++ {EPCMPR0 + EPCMPR_STRIDE * 7, 0},
++ {EPCMPR0 + EPCMPR_STRIDE * 8, 0x000000FF},
++ {EPCMPR0 + EPCMPR_STRIDE * 9, 0x000000FF},
++ {EPCMPR0 + EPCMPR_STRIDE * 10, 0x000000FF},
++ {EPCMPR0 + EPCMPR_STRIDE * 11, 0x000000FF},
++ {EPCMPR0 + EPCMPR_STRIDE * 12, 0x000000FF},
++ {EPCMPR0 + EPCMPR_STRIDE * 13, 0},
++ {EPCMPR0 + EPCMPR_STRIDE * 14, 0x000000FF},
++ {EPCMPR0 + EPCMPR_STRIDE * 15, 0x000000FF},
++ /* EPCCR (Event Processor Counter Control Registers) */
++ {EPCCR0 + EPCCR_STRIDE * 0, 0},
++ {EPCCR0 + EPCCR_STRIDE * 1, 0},
++ {EPCCR0 + EPCCR_STRIDE * 2, 0x92840000},
++ {EPCCR0 + EPCCR_STRIDE * 3, 0},
++ {EPCCR0 + EPCCR_STRIDE * 4, 0x92840000},
++ {EPCCR0 + EPCCR_STRIDE * 5, 0x92840000},
++ {EPCCR0 + EPCCR_STRIDE * 6, 0},
++ {EPCCR0 + EPCCR_STRIDE * 7, 0},
++ {EPCCR0 + EPCCR_STRIDE * 8, 0x92840000},
++ {EPCCR0 + EPCCR_STRIDE * 9, 0x92840000},
++ {EPCCR0 + EPCCR_STRIDE * 10, 0x92840000},
++ {EPCCR0 + EPCCR_STRIDE * 11, 0x92840000},
++ {EPCCR0 + EPCCR_STRIDE * 12, 0x92840000},
++ {EPCCR0 + EPCCR_STRIDE * 13, 0},
++ {EPCCR0 + EPCCR_STRIDE * 14, 0x92840000},
++ {EPCCR0 + EPCCR_STRIDE * 15, 0x92840000},
++ /* EPSMCR (Event Processor SCU Mux Control Registers) */
++ {EPSMCR0 + EPSMCR_STRIDE * 0, 0},
++ {EPSMCR0 + EPSMCR_STRIDE * 1, 0},
++ {EPSMCR0 + EPSMCR_STRIDE * 2, 0x6C700000},
++ {EPSMCR0 + EPSMCR_STRIDE * 3, 0x2F000000},
++ {EPSMCR0 + EPSMCR_STRIDE * 4, 0x002F0000},
++ {EPSMCR0 + EPSMCR_STRIDE * 5, 0x00002E00},
++ {EPSMCR0 + EPSMCR_STRIDE * 6, 0x7C000000},
++ {EPSMCR0 + EPSMCR_STRIDE * 7, 0x30000000},
++ {EPSMCR0 + EPSMCR_STRIDE * 8, 0x64300000},
++ {EPSMCR0 + EPSMCR_STRIDE * 9, 0x00003000},
++ {EPSMCR0 + EPSMCR_STRIDE * 10, 0x65000030},
++ {EPSMCR0 + EPSMCR_STRIDE * 11, 0x31740000},
++ {EPSMCR0 + EPSMCR_STRIDE * 12, 0x7F000000},
++ {EPSMCR0 + EPSMCR_STRIDE * 13, 0x00003100},
++ {EPSMCR0 + EPSMCR_STRIDE * 14, 0x00000031},
++ {EPSMCR0 + EPSMCR_STRIDE * 15, 0x76000000},
++ /* EPACR (Event Processor Action Control Registers) */
++ {EPACR0 + EPACR_STRIDE * 0, 0},
++ {EPACR0 + EPACR_STRIDE * 1, 0},
++ {EPACR0 + EPACR_STRIDE * 2, 0},
++ {EPACR0 + EPACR_STRIDE * 3, 0x00000080},
++ {EPACR0 + EPACR_STRIDE * 4, 0},
++ {EPACR0 + EPACR_STRIDE * 5, 0x00000040},
++ {EPACR0 + EPACR_STRIDE * 6, 0},
++ {EPACR0 + EPACR_STRIDE * 7, 0},
++ {EPACR0 + EPACR_STRIDE * 8, 0},
++ {EPACR0 + EPACR_STRIDE * 9, 0x0000001C},
++ {EPACR0 + EPACR_STRIDE * 10, 0x00000020},
++ {EPACR0 + EPACR_STRIDE * 11, 0},
++ {EPACR0 + EPACR_STRIDE * 12, 0x00000003},
++ {EPACR0 + EPACR_STRIDE * 13, 0x06000000},
++ {EPACR0 + EPACR_STRIDE * 14, 0x04000000},
++ {EPACR0 + EPACR_STRIDE * 15, 0x02000000},
++ /* EPIMCR (Event Processor Input Mux Control Registers) */
++ {EPIMCR0 + EPIMCR_STRIDE * 0, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 1, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 2, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 3, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 4, 0x44000000},
++ {EPIMCR0 + EPIMCR_STRIDE * 5, 0x40000000},
++ {EPIMCR0 + EPIMCR_STRIDE * 6, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 7, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 8, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 9, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 10, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 11, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 12, 0x44000000},
++ {EPIMCR0 + EPIMCR_STRIDE * 13, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 14, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 15, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 16, 0x6A000000},
++ {EPIMCR0 + EPIMCR_STRIDE * 17, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 18, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 19, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 20, 0x48000000},
++ {EPIMCR0 + EPIMCR_STRIDE * 21, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 22, 0x6C000000},
++ {EPIMCR0 + EPIMCR_STRIDE * 23, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 24, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 25, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 26, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 27, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 28, 0x76000000},
++ {EPIMCR0 + EPIMCR_STRIDE * 29, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 30, 0},
++ {EPIMCR0 + EPIMCR_STRIDE * 31, 0x76000000},
++ /* EPXTRIGCR (Event Processor Crosstrigger Control Register) */
++ {EPXTRIGCR, 0x0000FFDF},
++ /* end */
++ {FSM_END_FLAG, 0},
++};
++
++struct fsm_reg_vals npc_default_val[] = {
++ /* NPC triggered Memory-Mapped Access Registers */
++ {NCR, 0x80000000},
++ {MCCR1, 0},
++ {MCSR1, 0},
++ {MMAR1LO, 0},
++ {MMAR1HI, 0},
++ {MMDR1, 0},
++ {MCSR2, 0},
++ {MMAR2LO, 0},
++ {MMAR2HI, 0},
++ {MMDR2, 0},
++ {MCSR3, 0x80000000},
++ {MMAR3LO, 0x000E2130},
++ {MMAR3HI, 0x00030000},
++ {MMDR3, 0x00020000},
++ /* end */
++ {FSM_END_FLAG, 0},
++};
++
++/**
++ * fsl_fsm_setup - Configure EPU's FSM registers
++ * @base: the base address of registers
++ * @val: Pointer to address-value pairs for FSM registers
++ */
++void fsl_fsm_setup(void __iomem *base, struct fsm_reg_vals *val)
++{
++ struct fsm_reg_vals *data = val;
++
++ WARN_ON(!base || !data);
++ while (data->offset != FSM_END_FLAG) {
++ iowrite32be(data->value, base + data->offset);
++ data++;
++ }
++}
++
++void fsl_epu_setup_default(void __iomem *epu_base)
++{
++ fsl_fsm_setup(epu_base, epu_default_val);
++}
++
++void fsl_npc_setup_default(void __iomem *npc_base)
++{
++ fsl_fsm_setup(npc_base, npc_default_val);
++}
++
++void fsl_epu_clean_default(void __iomem *epu_base)
++{
++ u32 offset;
++
++ /* follow the exact sequence to clear the registers */
++ /* Clear EPACRn */
++ for (offset = EPACR0; offset <= EPACR15; offset += EPACR_STRIDE)
++ iowrite32be(0, epu_base + offset);
++
++ /* Clear EPEVTCRn */
++ for (offset = EPEVTCR0; offset <= EPEVTCR9; offset += EPEVTCR_STRIDE)
++ iowrite32be(0, epu_base + offset);
++
++ /* Clear EPGCR */
++ iowrite32be(0, epu_base + EPGCR);
++
++ /* Clear EPSMCRn */
++ for (offset = EPSMCR0; offset <= EPSMCR15; offset += EPSMCR_STRIDE)
++ iowrite32be(0, epu_base + offset);
++
++ /* Clear EPCCRn */
++ for (offset = EPCCR0; offset <= EPCCR31; offset += EPCCR_STRIDE)
++ iowrite32be(0, epu_base + offset);
++
++ /* Clear EPCMPRn */
++ for (offset = EPCMPR0; offset <= EPCMPR31; offset += EPCMPR_STRIDE)
++ iowrite32be(0, epu_base + offset);
++
++ /* Clear EPCTRn */
++ for (offset = EPCTR0; offset <= EPCTR31; offset += EPCTR_STRIDE)
++ iowrite32be(0, epu_base + offset);
++
++ /* Clear EPIMCRn */
++ for (offset = EPIMCR0; offset <= EPIMCR31; offset += EPIMCR_STRIDE)
++ iowrite32be(0, epu_base + offset);
++
++ /* Clear EPXTRIGCRn */
++ iowrite32be(0, epu_base + EPXTRIGCR);
++
++ /* Clear EPECRn */
++ for (offset = EPECR0; offset <= EPECR15; offset += EPECR_STRIDE)
++ iowrite32be(0, epu_base + offset);
++}
+--- /dev/null
++++ b/drivers/soc/fsl/sleep_fsm.h
+@@ -0,0 +1,130 @@
++/*
++ * deep sleep FSM (finite-state machine) configuration
++ *
++ * Copyright 2018 NXP
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions are met:
++ * * Redistributions of source code must retain the above copyright
++ * notice, this list of conditions and the following disclaimer.
++ * * Redistributions in binary form must reproduce the above copyright
++ * notice, this list of conditions and the following disclaimer in the
++ * documentation and/or other materials provided with the distribution.
++ * * Neither the name of the above-listed copyright holders nor the
++ * names of any contributors may be used to endorse or promote products
++ * derived from this software without specific prior written permission.
++ *
++ *
++ * ALTERNATIVELY, this software may be distributed under the terms of the
++ * GNU General Public License ("GPL") as published by the Free Software
++ * Foundation, either version 2 of that License or (at your option) any
++ * later version.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++ * POSSIBILITY OF SUCH DAMAGE.
++ */
++
++#ifndef _FSL_SLEEP_FSM_H
++#define _FSL_SLEEP_FSM_H
++
++#define FSL_STRIDE_4B 4
++#define FSL_STRIDE_8B 8
++
++/* End flag */
++#define FSM_END_FLAG 0xFFFFFFFFUL
++
++/* Block offsets */
++#define RCPM_BLOCK_OFFSET 0x00022000
++#define EPU_BLOCK_OFFSET 0x00000000
++#define NPC_BLOCK_OFFSET 0x00001000
++
++/* EPGCR (Event Processor Global Control Register) */
++#define EPGCR 0x000
++
++/* EPEVTCR0-9 (Event Processor EVT Pin Control Registers) */
++#define EPEVTCR0 0x050
++#define EPEVTCR9 0x074
++#define EPEVTCR_STRIDE FSL_STRIDE_4B
++
++/* EPXTRIGCR (Event Processor Crosstrigger Control Register) */
++#define EPXTRIGCR 0x090
++
++/* EPIMCR0-31 (Event Processor Input Mux Control Registers) */
++#define EPIMCR0 0x100
++#define EPIMCR31 0x17C
++#define EPIMCR_STRIDE FSL_STRIDE_4B
++
++/* EPSMCR0-15 (Event Processor SCU Mux Control Registers) */
++#define EPSMCR0 0x200
++#define EPSMCR15 0x278
++#define EPSMCR_STRIDE FSL_STRIDE_8B
++
++/* EPECR0-15 (Event Processor Event Control Registers) */
++#define EPECR0 0x300
++#define EPECR15 0x33C
++#define EPECR_STRIDE FSL_STRIDE_4B
++
++/* EPACR0-15 (Event Processor Action Control Registers) */
++#define EPACR0 0x400
++#define EPACR15 0x43C
++#define EPACR_STRIDE FSL_STRIDE_4B
++
++/* EPCCRi0-15 (Event Processor Counter Control Registers) */
++#define EPCCR0 0x800
++#define EPCCR15 0x83C
++#define EPCCR31 0x87C
++#define EPCCR_STRIDE FSL_STRIDE_4B
++
++/* EPCMPR0-15 (Event Processor Counter Compare Registers) */
++#define EPCMPR0 0x900
++#define EPCMPR15 0x93C
++#define EPCMPR31 0x97C
++#define EPCMPR_STRIDE FSL_STRIDE_4B
++
++/* EPCTR0-31 (Event Processor Counter Register) */
++#define EPCTR0 0xA00
++#define EPCTR31 0xA7C
++#define EPCTR_STRIDE FSL_STRIDE_4B
++
++/* NPC triggered Memory-Mapped Access Registers */
++#define NCR 0x000
++#define MCCR1 0x0CC
++#define MCSR1 0x0D0
++#define MMAR1LO 0x0D4
++#define MMAR1HI 0x0D8
++#define MMDR1 0x0DC
++#define MCSR2 0x0E0
++#define MMAR2LO 0x0E4
++#define MMAR2HI 0x0E8
++#define MMDR2 0x0EC
++#define MCSR3 0x0F0
++#define MMAR3LO 0x0F4
++#define MMAR3HI 0x0F8
++#define MMDR3 0x0FC
++
++/* RCPM Core State Action Control Register 0 */
++#define CSTTACR0 0xB00
++
++/* RCPM Core Group 1 Configuration Register 0 */
++#define CG1CR0 0x31C
++
++struct fsm_reg_vals {
++ u32 offset;
++ u32 value;
++};
++
++void fsl_fsm_setup(void __iomem *base, struct fsm_reg_vals *val);
++void fsl_epu_setup_default(void __iomem *epu_base);
++void fsl_npc_setup_default(void __iomem *npc_base);
++void fsl_epu_clean_default(void __iomem *epu_base);
++
++#endif /* _FSL_SLEEP_FSM_H */