From: John Jacques <john.jacq...@intel.com>

There are OEM functions in the secure monitor to control DSP
cluster power and coherency.  This commit adds the ability
to control DSP cluster power and coherency from Linux.

Signed-off-by: John Jacques <john.jacq...@intel.com>
---
 drivers/misc/Kconfig       |   6 ++
 drivers/misc/Makefile      |   1 +
 drivers/misc/axxia-dspc.c  | 190 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/axxia-dspc.h |  21 +++++
 4 files changed, 218 insertions(+)
 create mode 100644 drivers/misc/axxia-dspc.c
 create mode 100644 include/linux/axxia-dspc.h

diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 0313169..45fe9a3 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -574,6 +574,12 @@ config LSI_SMMON
        help
          Monitor the system memory controllers for errors.
 
+config AXXIA_DSPC
+       bool "Axxia DSP Control"
+       depends on ARCH_AXXIA
+       help
+        Control the state of the DSPs.
+
 config AXXIA_PEI
        bool "Axxia PEI Controller Setup"
        depends on ARCH_AXXIA
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index b2615c5..ee6dbc6 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_GENWQE)          += genwqe/
 obj-$(CONFIG_LSI_NCR)           += lsi-ncr.o
 obj-$(CONFIG_LSI_MTC)          += lsi-mtc.o
 obj-$(CONFIG_LSI_SMMON)         += lsi-smmon.o
+obj-$(CONFIG_AXXIA_DSPC)        += axxia-dspc.o
 obj-$(CONFIG_AXXIA_PEI)         += axxia-pei.o
 obj-$(CONFIG_ECHO)             += echo/
 obj-$(CONFIG_VEXPRESS_SYSCFG)  += vexpress-syscfg.o
diff --git a/drivers/misc/axxia-dspc.c b/drivers/misc/axxia-dspc.c
new file mode 100644
index 0000000..ff32f23
--- /dev/null
+++ b/drivers/misc/axxia-dspc.c
@@ -0,0 +1,190 @@
+/*
+ *  Copyright (C) 2016 Intel Corporation
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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.
+ */
+
+/*
+  
==============================================================================
+  
==============================================================================
+  Private
+  
==============================================================================
+  
==============================================================================
+*/
+
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/proc_fs.h>
+#include <linux/slab.h>
+#include <linux/linkage.h>
+#include <linux/axxia-dspc.h>
+#include <linux/uaccess.h>
+
+struct oem_parameters {
+       volatile unsigned long reg0;
+       volatile unsigned long reg1;
+       volatile unsigned long reg2;
+       volatile unsigned long reg3;
+};
+
+static void
+invoke_oem_fn(struct oem_parameters *p)
+{
+       asm volatile("mov x0, %x0\n"
+                    "mov x1, %x1\n"
+                    "mov x2, %x2\n"
+                    "mov x3, %x3" : : "r" (p->reg0), "r" (p->reg1),
+                    "r" (p->reg2), "r" (p->reg3));
+       asm volatile("smc #0");
+       asm volatile("mov %x0, x0\n"
+                    "mov %x1, x1\n"
+                    "mov %x2, x2\n"
+                    "mov %x3, x3" : "=r" (p->reg0), "=r" (p->reg1),
+                    "=r" (p->reg2), "=r" (p->reg3));
+
+       return 0;
+}
+
+/*
+  
==============================================================================
+  
==============================================================================
+  Public
+  
==============================================================================
+  
==============================================================================
+*/
+
+/*
+  
------------------------------------------------------------------------------
+  axxia_dspc_get_state
+*/
+
+unsigned long
+axxia_dspc_get_state(void)
+{
+       struct oem_parameters parameters;
+
+       parameters.reg0 = 0xc3000000;
+       parameters.reg1 = 0;
+       parameters.reg2 = 0;
+       parameters.reg3 = 0;
+       invoke_oem_fn(&parameters);
+
+       if (0 != parameters.reg0)
+               pr_warn("Getting the DSP State Failed!\n");
+
+       return parameters.reg1;
+}
+EXPORT_SYMBOL(axxia_dspc_get_state);
+
+/*
+  
------------------------------------------------------------------------------
+  axxia_dspc_set_state
+*/
+
+void
+axxia_dspc_set_state(unsigned long state)
+{
+       struct oem_parameters parameters;
+
+       parameters.reg0 = 0xc3000001;
+       parameters.reg1 = state;
+       parameters.reg2 = 0;
+       parameters.reg3 = 0;
+       invoke_oem_fn(&parameters);
+
+       if (0 != parameters.reg0)
+               pr_warn("Setting the DSP State Failed!\n");
+
+       return 0;
+}
+EXPORT_SYMBOL(axxia_dspc_set_state);
+
+static ssize_t
+axxia_dspc_read(struct file *filp, char *buffer, size_t length, loff_t *offset)
+{
+       static int finished;
+       char return_buffer[80];
+
+       if (0 != finished) {
+               finished = 0;
+
+               return 0;
+       }
+
+       finished = 1;
+       sprintf(return_buffer, "0x%lx\n", axxia_dspc_get_state());
+
+       if (copy_to_user(buffer, return_buffer, strlen(return_buffer)))
+               return -EFAULT;
+
+       return strlen(return_buffer);
+}
+
+static ssize_t
+axxia_dspc_write(struct file *file, const char __user *buffer,
+                size_t count, loff_t *ppos)
+{
+       char *input;
+       unsigned long mask;
+
+       input = kmalloc(count, __GFP_WAIT);
+       memset(input, 0, count);
+
+       if (NULL == input)
+               return -ENOSPC;
+
+       if (copy_from_user(input, buffer, count))
+               return -EFAULT;
+
+       mask = kstrtoul(input, NULL, 0);
+       axxia_dspc_set_state((unsigned int)mask);
+
+       return count;
+}
+
+static const struct file_operations axxia_dspc_proc_ops = {
+       .read       = axxia_dspc_read,
+       .write      = axxia_dspc_write,
+       .llseek     = noop_llseek,
+};
+
+/*
+  
------------------------------------------------------------------------------
+  axxia_dspc_init
+*/
+
+static int
+axxia_dspc_init(void)
+{
+       /* Only applicable to the 6700. */
+       if (!of_find_compatible_node(NULL, NULL, "lsi,axc6732"))
+               return -1;
+
+       if (0 != proc_create("driver/axxia_dspc", S_IWUSR, NULL,
+                            &axxia_dspc_proc_ops)) {
+               pr_err("Could not create /proc/driver/axxia_pcie_reset!\n");
+
+               return -1;
+       }
+
+       pr_info("Axxia DSP Control Initialized\n");
+
+       return 0;
+}
+
+device_initcall(axxia_dspc_init);
+
+MODULE_AUTHOR("John Jacques <john.jacq...@intel.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Axxia DSP Control");
diff --git a/include/linux/axxia-dspc.h b/include/linux/axxia-dspc.h
new file mode 100644
index 0000000..ca68d88
--- /dev/null
+++ b/include/linux/axxia-dspc.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 Intel <john.jacq...@intel.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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.
+ */
+
+#ifndef __DRIVERS_MISC_AXXIA_DSPC_H
+#define __DRIVERS_MISC_AXXIA_DSPC_H
+
+unsigned long axxia_dspc_get_state(void);
+void axxia_dspc_set_state(unsigned long);
+
+#endif /* __DRIVERS_MISC_AXXIA_DSPC_H */
-- 
2.7.4

-- 
_______________________________________________
linux-yocto mailing list
linux-yocto@yoctoproject.org
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to