From: John Jacques <john.jacq...@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.jacq...@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.jacq...@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.jacq...@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.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 */ 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.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 + +/* + 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 -- _______________________________________________ linux-yocto mailing list linux-yocto@yoctoproject.org https://lists.yoctoproject.org/listinfo/linux-yocto