[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(&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.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(&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);
+
+/*
+  ------------------------------------------------------------------------------
+  axxia_actlr_el3_get
+*/
+
+unsigned long
+axxia_actlr_el3_get(void)
+{
+	struct oem_parameters parameters;
+
+	parameters.reg0 = 0xc3000002;
+	invoke_oem_fn(&parameters);
+
+	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(&parameters);
+
+	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(&parameters);
+
+	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(&parameters);
+
+	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