Re: [RFC 3/3] CPPC: Add ACPI accessors to CPC registers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



+ 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 cpufreq" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux Kernel Devel]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Forum]     [Linux SCSI]

  Powered by Linux