[linux-yocto] [PATCH 24/26] drivers/misc: Update Axxia OEM Call Handling
Daniel Dragomir
daniel.dragomir at windriver.com
Wed Nov 16 08:57:00 PST 2016
From: John Jacques <john.jacques at intel.com>
Add the ability to control the ACTLR_EL3 and ACTLR_EL2 registers
on Axxia using OEM calls to the secure monitor. As this driver
now does more than just control DSP clusters, the name has been
changed.
Signed-off-by: John Jacques <john.jacques at intel.com>
---
drivers/misc/Kconfig | 6 +-
drivers/misc/Makefile | 2 +-
drivers/misc/axxia-dspc.c | 190 ----------------------
drivers/misc/axxia-oem.c | 392 +++++++++++++++++++++++++++++++++++++++++++++
include/linux/axxia-dspc.h | 21 ---
include/linux/axxia-oem.h | 34 ++++
6 files changed, 430 insertions(+), 215 deletions(-)
delete mode 100644 drivers/misc/axxia-dspc.c
create mode 100644 drivers/misc/axxia-oem.c
delete mode 100644 include/linux/axxia-dspc.h
create mode 100644 include/linux/axxia-oem.h
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 45fe9a3..e07d08d 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -574,11 +574,11 @@ config LSI_SMMON
help
Monitor the system memory controllers for errors.
-config AXXIA_DSPC
- bool "Axxia DSP Control"
+config AXXIA_OEM
+ bool "Axxia OEM Calls"
depends on ARCH_AXXIA
help
- Control the state of the DSPs.
+ OEM calls to the secure monitor for Axxia.
config AXXIA_PEI
bool "Axxia PEI Controller Setup"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index ee6dbc6..fedabfc 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -57,7 +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_OEM) += axxia-oem.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
deleted file mode 100644
index ff32f23..0000000
--- a/drivers/misc/axxia-dspc.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * 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(¶meters);
-
- 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(¶meters);
-
- 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.jacques at intel.com>");
-MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Axxia DSP Control");
diff --git a/drivers/misc/axxia-oem.c b/drivers/misc/axxia-oem.c
new file mode 100644
index 0000000..4db5c6c
--- /dev/null
+++ b/drivers/misc/axxia-oem.c
@@ -0,0 +1,392 @@
+/*
+ * 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-oem.h>
+#include <linux/uaccess.h>
+
+/*
+ OEM Calls
+*/
+
+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;
+}
+
+/*
+ DSP Cluster Control
+*/
+
+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,
+};
+
+/*
+ ACTLR_EL3 Control
+*/
+
+static ssize_t
+axxia_actlr_el3_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_actlr_el3_get());
+
+ if (copy_to_user(buffer, return_buffer, strlen(return_buffer)))
+ return -EFAULT;
+
+ return strlen(return_buffer);
+}
+
+static ssize_t
+axxia_actlr_el3_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ char *input;
+
+ input = kmalloc(count, __GFP_WAIT);
+ memset(input, 0, count);
+
+ if (NULL == input)
+ return -ENOSPC;
+
+ if (copy_from_user(input, buffer, count))
+ return -EFAULT;
+
+ axxia_actlr_el3_set(kstrtoul(input, NULL, 0));
+
+ return count;
+}
+
+static const struct file_operations axxia_actlr_el3_proc_ops = {
+ .read = axxia_actlr_el3_read,
+ .write = axxia_actlr_el3_write,
+ .llseek = noop_llseek,
+};
+
+/*
+ ACTLR_EL2 Control
+*/
+
+static ssize_t
+axxia_actlr_el2_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_actlr_el2_get());
+
+ if (copy_to_user(buffer, return_buffer, strlen(return_buffer)))
+ return -EFAULT;
+
+ return strlen(return_buffer);
+}
+
+static ssize_t
+axxia_actlr_el2_write(struct file *file, const char __user *buffer,
+ size_t count, loff_t *ppos)
+{
+ char *input;
+
+ input = kmalloc(count, __GFP_WAIT);
+ memset(input, 0, count);
+
+ if (NULL == input)
+ return -ENOSPC;
+
+ if (copy_from_user(input, buffer, count))
+ return -EFAULT;
+
+ axxia_actlr_el2_set(kstrtoul(input, NULL, 0));
+
+ return count;
+}
+
+static const struct file_operations axxia_actlr_el2_proc_ops = {
+ .read = axxia_actlr_el2_read,
+ .write = axxia_actlr_el2_write,
+ .llseek = noop_llseek,
+};
+
+/*
+ ==============================================================================
+ ==============================================================================
+ 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(¶meters);
+
+ 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(¶meters);
+
+ if (0 != parameters.reg0)
+ pr_warn("Setting the DSP State Failed!\n");
+
+ return 0;
+}
+EXPORT_SYMBOL(axxia_dspc_set_state);
+
+/*
+ ------------------------------------------------------------------------------
+ axxia_actlr_el3_get
+*/
+
+unsigned long
+axxia_actlr_el3_get(void)
+{
+ struct oem_parameters parameters;
+
+ parameters.reg0 = 0xc3000002;
+ invoke_oem_fn(¶meters);
+
+ if (0 != parameters.reg0)
+ pr_warn("Getting ACTLR_EL3 Failed!\n");
+
+ return parameters.reg1;
+}
+EXPORT_SYMBOL(axxia_actlr_el3_get);
+
+/*
+ ------------------------------------------------------------------------------
+ axxia_actlr_el3_set
+*/
+
+void
+axxia_actlr_el3_set(unsigned long input)
+{
+ struct oem_parameters parameters;
+
+ parameters.reg0 = 0xc3000003;
+ parameters.reg1 = input;
+ invoke_oem_fn(¶meters);
+
+ if (0 != parameters.reg0)
+ pr_warn("Setting ACTLR_EL3 Failed!\n");
+
+ return 0;
+}
+EXPORT_SYMBOL(axxia_actlr_el3_set);
+
+/*
+ ------------------------------------------------------------------------------
+ axxia_actlr_el2_get
+*/
+
+unsigned long
+axxia_actlr_el2_get(void)
+{
+ struct oem_parameters parameters;
+
+ parameters.reg0 = 0xc3000004;
+ invoke_oem_fn(¶meters);
+
+ if (0 != parameters.reg0)
+ pr_warn("Getting ACTLR_EL2 Failed!\n");
+
+ return parameters.reg1;
+}
+EXPORT_SYMBOL(axxia_actlr_el2_get);
+
+/*
+ ------------------------------------------------------------------------------
+ axxia_actlr_el2_set
+*/
+
+void
+axxia_actlr_el2_set(unsigned long input)
+{
+ struct oem_parameters parameters;
+
+ parameters.reg0 = 0xc3000005;
+ parameters.reg1 = input;
+ invoke_oem_fn(¶meters);
+
+ if (0 != parameters.reg0)
+ pr_warn("Setting ACTLR_EL2 Failed!\n");
+
+ return 0;
+}
+EXPORT_SYMBOL(axxia_actlr_el2_set);
+
+/*
+ ------------------------------------------------------------------------------
+ axxia_dspc_init
+*/
+
+static int
+axxia_oem_init(void)
+{
+ if (of_find_compatible_node(NULL, NULL, "lsi,axc6732")) {
+ /* Only applicable to the 6700. */
+ if (0 != proc_create("driver/axxia_dspc", S_IWUSR, NULL,
+ &axxia_dspc_proc_ops))
+ pr_err("Could not create /proc/driver/axxia_dspc!\n");
+ else
+ pr_info("Axxia DSP Control Initialized\n");
+ }
+
+ if (0 != proc_create("driver/axxia_actlr_el3", S_IWUSR, NULL,
+ &axxia_actlr_el3_proc_ops))
+ pr_err("Could not create /proc/driver/axxia_actlr_el3!\n");
+ else
+ pr_info("Axxia ACTLR_EL3 Control Initialized\n");
+
+ if (0 != proc_create("driver/axxia_actlr_el2", S_IWUSR, NULL,
+ &axxia_actlr_el2_proc_ops))
+ pr_err("Could not create /proc/driver/axxia_actlr_el2!\n");
+ else
+ pr_info("Axxia ACTLR_EL3 Control Initialized\n");
+
+ return 0;
+}
+
+device_initcall(axxia_oem_init);
+
+MODULE_AUTHOR("John Jacques <john.jacques at intel.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Axxia OEM Control");
diff --git a/include/linux/axxia-dspc.h b/include/linux/axxia-dspc.h
deleted file mode 100644
index ca68d88..0000000
--- a/include/linux/axxia-dspc.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2016 Intel <john.jacques at 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 */
diff --git a/include/linux/axxia-oem.h b/include/linux/axxia-oem.h
new file mode 100644
index 0000000..b3721a8
--- /dev/null
+++ b/include/linux/axxia-oem.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 Intel <john.jacques at 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
+
+/*
+ DSP Cluster Control -- Only on 6700
+*/
+
+unsigned long axxia_dspc_get_state(void);
+void axxia_dspc_set_state(unsigned long);
+
+/*
+ ACTLR_EL3/ACTLR_EL2 Access -- For Performance Testing
+*/
+
+unsigned long axxia_actlr_el3_get(void);
+void axxia_actlr_el3_set(unsigned long);
+unsigned long axxia_actlr_el2_get(void);
+void axxia_actlr_el2_set(unsigned long);
+
+#endif /* __DRIVERS_MISC_AXXIA_DSPC_H */
--
2.7.4
More information about the linux-yocto
mailing list