+ Rafael [corrected email addr] On 14 August 2014 15:57, Ashwin Chaugule <ashwin.chaugule@xxxxxxxxxx> wrote: > If the firmware supports CPPC natively in the firmware > then we can use the ACPI defined semantics to access > the CPPC specific registers. > > Signed-off-by: Ashwin Chaugule <ashwin.chaugule@xxxxxxxxxx> > --- > drivers/cpufreq/Kconfig | 9 +++++ > drivers/cpufreq/Makefile | 1 + > drivers/cpufreq/cppc.h | 4 +-- > drivers/cpufreq/cppc_acpi.c | 80 +++++++++++++++++++++++++++++++++++++++++++++ > 4 files changed, 92 insertions(+), 2 deletions(-) > create mode 100644 drivers/cpufreq/cppc_acpi.c > > diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig > index d8e8335..c5f3c0b 100644 > --- a/drivers/cpufreq/Kconfig > +++ b/drivers/cpufreq/Kconfig > @@ -206,6 +206,15 @@ config CPPC_CPUFREQ > (e.g. BMC) interpret and optimize it for power and performance in a > platform specific manner. > > +config CPPC_ACPI > + bool "CPPC with ACPI accessors" > + depends on ACPI && ACPI_PCC > + default n > + help > + This driver implements the low level accessors to the registers as described > + in the ACPI 5.1 spec. Select this driver if you know your platform supports CPPC > + and PCC in the firmware. > + > menu "x86 CPU frequency scaling drivers" > depends on X86 > source "drivers/cpufreq/Kconfig.x86" > diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile > index b392c8c..d49a999 100644 > --- a/drivers/cpufreq/Makefile > +++ b/drivers/cpufreq/Makefile > @@ -15,6 +15,7 @@ obj-$(CONFIG_CPU_FREQ_GOV_COMMON) += cpufreq_governor.o > > obj-$(CONFIG_GENERIC_CPUFREQ_CPU0) += cpufreq-cpu0.o > obj-$(CONFIG_CPPC_CPUFREQ) += cppc.o > +obj-$(CONFIG_CPPC_ACPI) += cppc_acpi.o > > ################################################################################## > # x86 drivers. > diff --git a/drivers/cpufreq/cppc.h b/drivers/cpufreq/cppc.h > index 3adbd3d..a119c3b 100644 > --- a/drivers/cpufreq/cppc.h > +++ b/drivers/cpufreq/cppc.h > @@ -175,7 +175,7 @@ struct cpc_funcs { > }; > > extern struct cpc_funcs *cppc_func_ops; > -extern u64 cpc_read64(struct cpc_register_resource *reg); > -extern int cpc_write64(u64 val, struct cpc_register_resource *reg); > +extern u64 cpc_read64(struct cpc_register_resource *reg, void __iomem *base_addr); > +extern int cpc_write64(u64 val, struct cpc_register_resource *reg, void __iomem *base_addr); > > #endif /* _CPPC_H */ > diff --git a/drivers/cpufreq/cppc_acpi.c b/drivers/cpufreq/cppc_acpi.c > new file mode 100644 > index 0000000..1835fe7 > --- /dev/null > +++ b/drivers/cpufreq/cppc_acpi.c > @@ -0,0 +1,80 @@ > +/* > + * Copyright (C) 2014 Linaro Ltd. > + * Author: Ashwin Chaugule <ashwin.chaugule@xxxxxxxxxx> > + * > + * 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. > + * > + */ > + > +#include <linux/acpi.h> > + > +#include "cppc.h" > + > +static u32 acpi_get_highest_perf(struct cpudata *cpu) > +{ > + struct cpc_register_resource *high_perf = &cpu->cpc_desc->cpc_regs[HIGHEST_PERF]; > + > + return cpc_read64(high_perf, cpu->pcc_comm_address); > +} > + > +static u64 acpi_get_ref_perf_ctr(struct cpudata *cpu) > +{ > + struct cpc_register_resource *ref_perf = &cpu->cpc_desc->cpc_regs[REFERENCE_CTR]; > + return cpc_read64(ref_perf, cpu->pcc_comm_address); > +} > + > +static u32 acpi_get_lowest_perf(struct cpudata *cpu) > +{ > + struct cpc_register_resource *low_perf = &cpu->cpc_desc->cpc_regs[LOWEST_PERF]; > + return cpc_read64(low_perf, cpu->pcc_comm_address); > +} > + > +static void acpi_set_desired_perf(struct cpudata *cpu, u32 val) > +{ > + struct cpc_register_resource *desired_perf = &cpu->cpc_desc->cpc_regs[DESIRED_PERF]; > + cpc_write64(val, desired_perf, cpu->pcc_comm_address); > +} > + > +static u64 acpi_get_delivered_ctr(struct cpudata *cpu) > +{ > + struct cpc_register_resource *delivered_ctr = &cpu->cpc_desc->cpc_regs[DELIVERED_CTR]; > + return cpc_read64(delivered_ctr, cpu->pcc_comm_address); > +} > + > +struct cpc_funcs acpi_cppc_func_ops = { > + .pid_policy = { > + .sample_rate_ms = 10, > + .deadband = 0, > + .setpoint = 97, > + .p_gain_pct = 20, > + .d_gain_pct = 0, > + .i_gain_pct = 0, > + }, > + .get_highest_perf = acpi_get_highest_perf, > + .get_ref_perf_ctr = acpi_get_ref_perf_ctr, > + .get_lowest_perf = acpi_get_lowest_perf, > + .set_desired_perf = acpi_set_desired_perf, > + .get_delivered_ctr = acpi_get_delivered_ctr, > +}; > + > +static int __init acpi_cppc_init(void) > +{ > + if (acpi_disabled) > + return 0; > + > + cppc_func_ops = &acpi_cppc_func_ops; > + > + pr_info("Registered ACPI CPPC function ops\n"); > + > + return 0; > +} > +early_initcall(acpi_cppc_init); > + > -- > 1.9.1 > -- To unsubscribe from this list: send the line "unsubscribe linux-acpi" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html