aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-4.9/803-cpufreq-support-layerscape.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/layerscape/patches-4.9/803-cpufreq-support-layerscape.patch')
-rw-r--r--target/linux/layerscape/patches-4.9/803-cpufreq-support-layerscape.patch173
1 files changed, 168 insertions, 5 deletions
diff --git a/target/linux/layerscape/patches-4.9/803-cpufreq-support-layerscape.patch b/target/linux/layerscape/patches-4.9/803-cpufreq-support-layerscape.patch
index 2bc0f24f72..2da45b6cf0 100644
--- a/target/linux/layerscape/patches-4.9/803-cpufreq-support-layerscape.patch
+++ b/target/linux/layerscape/patches-4.9/803-cpufreq-support-layerscape.patch
@@ -1,9 +1,9 @@
-From a9ebdf9fa18fd317a4e97f46e8c5263898094864 Mon Sep 17 00:00:00 2001
+From b018e44a68dc2f4df819ae194e39e07313841dad Mon Sep 17 00:00:00 2001
From: Yangbo Lu <yangbo.lu@nxp.com>
-Date: Mon, 25 Sep 2017 12:20:10 +0800
-Subject: [PATCH] cpufreq: support layerscape
+Date: Wed, 17 Jan 2018 15:27:58 +0800
+Subject: [PATCH 15/30] cpufreq: support layerscape
-This is a integrated patch for layerscape pm support.
+This is an integrated patch for layerscape pm support.
Signed-off-by: Tang Yuantian <Yuantian.Tang@nxp.com>
Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
@@ -11,7 +11,9 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
drivers/cpufreq/Kconfig | 2 +-
drivers/cpufreq/qoriq-cpufreq.c | 176 +++++++++++++++-------------------------
drivers/firmware/psci.c | 12 ++-
- 3 files changed, 77 insertions(+), 113 deletions(-)
+ drivers/soc/fsl/rcpm.c | 158 ++++++++++++++++++++++++++++++++++++
+ 4 files changed, 235 insertions(+), 113 deletions(-)
+ create mode 100644 drivers/soc/fsl/rcpm.c
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -359,3 +361,164 @@ Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
}
/*
+--- /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);