This patchset adds support for the PCC (Platform Communication Channel)
interface as described in the current ACPI 5.0 spec. See Section 14 of the
ACPI spec - http://acpi.info/DOWNLOADS/ACPI_5_Errata%20A.pdf for more details
on how PCC works.
In brief PCC is a generic means for PCC clients, to talk to the firmware. The
PCC register space is typically memory mapped IO and uses a doorbell mechanism
to communicate synchronously from the OS to the firmware. The PCC driver is
completely agnostic to the protocol implemented by the PCC clients. It only
implements the enumeration of PCC channels and the low level transport mechanism
and leaves the rest to the PCC clients.
The PCC is meant to be useable in the future by clients such as CPPC
(Collaborative Processor Performance Control), RAS (Reliability,
Availability and Serviceability) and MPST (Memory Power State Tables) and possibly others.
Changes since V2:
- Rebased on top of git://git.linaro.org/landing-teams/working/fujitsu/integration.git
branch mailbox-for-3.17
- Added PCC API to mailbox framework as per Arnd's suggestion to allow usage without ACPI.
Changes since V1:
-Integration with Mailbox framework - https://lkml.org/lkml/2014/5/15/49
Ashwin Chaugule (3):
Mailbox: Add support for PCC mailbox and channels
Add support for Platform Communication Channel
PCC-test: Test driver to trigger PCC commands
drivers/mailbox/Kconfig | 12 ++
drivers/mailbox/Makefile | 2 +
drivers/mailbox/mailbox.c | 118 +++++++++++++++++--
drivers/mailbox/pcc-test.c | 208 +++++++++++++++++++++++++++++++++
drivers/mailbox/pcc.c | 228 +++++++++++++++++++++++++++++++++++++
include/linux/mailbox_client.h | 6 +
include/linux/mailbox_controller.h | 1 +
7 files changed, 568 insertions(+), 7 deletions(-)
create mode 100644 drivers/mailbox/pcc-test.c
create mode 100644 drivers/mailbox/pcc.c
--
1.9.1
ACPI 5.1 has been released and now be freely available for
download [1]. It fixed some major gaps to run ACPI on ARM,
this patch just follow the ACPI 5.1 spec and prepare the
code to run ACPI on ARM64.
ACPI 5.1 has some major changes for the following tables and
method which are essential for ARM platforms:
1) MADT table updates.
New fields were introduced to cover MPIDR and virtualization in
GICC, and introduce GICR and GIC MSI frame structure to cover
GICv3 and GICv2m (this patch set only cover GICv2).
2) FADT updates for PSCI
New fields were introduced to cover PSCI and ACPI can use psci
to boot SMP and other PSCI related functions.
3) GTDT
GTDT was updated to support arch timer, memory-mapped tiemr,
SBSA watchdog timer, in this patch, only arch timer tested on
Juno board, so only arch timer init is available.
4) _DSD
_DSD (Device Specific Data) will provide some key values which
presented by FDT before, it makes possible that some devices can
be emumerated in ACPI way, please refer to the document provided
in this patch set for detail.
This patch set is the ARM64 ACPI core patches covered MADT, FADT
and GTDT, _DSD is not covered in this patch set. We first introduce
acpi.c and its related head file which are needed by ACPI core, and
then get RSDP to extract all the ACPI boot-time tables.
When all the boot-time tables (FADT, MADT, GTDT) are ready, then
parse them to init the sytem when booted. Specifically,
a) we use FADT to init PSCI and use PSCI to boot SMP;
b) Use MADT for GIC init and SMP init;
c) GTDT for arch timer init.
This patch set is based on Rafael's linux-pm tree/linux-next branch,
and I already compiled it OK with:
a) each patch applied on ARM64 with CONFIG_ACPI=y;
b) CONFIG_ACPI=n on ARM64;
c) CONFIG_ACPI=y on x86.
Updates since v1:
- Set ACPI default off on ARM64 suggested by Olof;
- Rebase the patch set on top of linux-next branch/linux-pm tree which
includes the ACPICA for full ACPI 5.1 support.
- Update the document as suggested;
- Adress lots of comments from Mark, Sudeep, Randy, Naresh, Olof, Geoff
and more...
[1]
http://www.uefi.org/sites/default/files/resources/ACPI_5_1release.pdf
Al Stone (3):
ARM64 / ACPI: Get RSDP and ACPI boot-time tables
ARM64 / ACPI: Select ACPI_REDUCED_HARDWARE_ONLY if ACPI is enabled on
ARM64
ARM64 / ACPI: Introduce early_param for "acpi" and set ACPI default
off
Ashwin Chaugule (1):
ACPI / table: Add new function to get table entries
Graeme Gregory (4):
ARM64 / ACPI: Introduce lowlevel suspend function
ARM64 / ACPI: If we chose to boot from acpi then disable FDT
ARM64 / ACPI: Enable ARM64 in Kconfig
Documentation: ACPI for ARM64
Hanjun Guo (9):
ARM64: Move the init of cpu_logical_map(0) before
unflatten_device_tree()
ARM64 / ACPI: Make PCI optional for ACPI on ARM64
ARM64 / ACPI: Parse FADT table to get PSCI flags for PSCI init
ARM64 / ACPI: Parse MADT to map logical cpu to MPIDR and get
cpu_possible/present_map
ACPI / table: Print GIC information when MADT is parsed
ARM64 / ACPI: Get the enable method for SMP initialization in ACPI
way
ACPI / processor: Make it possible to get CPU hardware ID via GICC
ARM64 / ACPI: Introduce ACPI_IRQ_MODEL_GIC and register device's gsi
ARM64 / ACPI: Parse GTDT to initialize arch timer
Tomasz Nowicki (1):
ARM64 / ACPI: Add GICv2 specific ACPI boot support
Documentation/arm64/arm-acpi.txt | 215 +++++++++++++++++++
Documentation/kernel-parameters.txt | 5 +-
arch/arm64/Kconfig | 3 +
arch/arm64/include/asm/acenv.h | 18 ++
arch/arm64/include/asm/acpi.h | 113 ++++++++++
arch/arm64/include/asm/cpu.h | 11 +
arch/arm64/include/asm/pci.h | 11 +
arch/arm64/include/asm/smp.h | 3 +-
arch/arm64/kernel/Makefile | 1 +
arch/arm64/kernel/acpi.c | 380 ++++++++++++++++++++++++++++++++++
arch/arm64/kernel/cpu_ops.c | 62 +++++-
arch/arm64/kernel/irq.c | 5 +
arch/arm64/kernel/psci.c | 89 ++++++--
arch/arm64/kernel/setup.c | 13 +-
arch/arm64/kernel/smp.c | 37 +++-
arch/arm64/kernel/time.c | 7 +
drivers/acpi/Kconfig | 6 +-
drivers/acpi/Makefile | 2 +-
drivers/acpi/bus.c | 3 +
drivers/acpi/internal.h | 5 +
drivers/acpi/processor_core.c | 37 ++++
drivers/acpi/tables.c | 109 ++++++++--
drivers/clocksource/arm_arch_timer.c | 117 +++++++++--
drivers/irqchip/irq-gic.c | 114 ++++++++++
include/linux/acpi.h | 5 +
include/linux/clocksource.h | 6 +
include/linux/irqchip/arm-gic-acpi.h | 36 ++++
include/linux/pci.h | 37 +++-
28 files changed, 1359 insertions(+), 91 deletions(-)
create mode 100644 Documentation/arm64/arm-acpi.txt
create mode 100644 arch/arm64/include/asm/acenv.h
create mode 100644 arch/arm64/include/asm/acpi.h
create mode 100644 arch/arm64/include/asm/cpu.h
create mode 100644 arch/arm64/include/asm/pci.h
create mode 100644 arch/arm64/kernel/acpi.c
create mode 100644 include/linux/irqchip/arm-gic-acpi.h
--
1.7.9.5
Hello,
Apologies in advance for a lengthy cover letter. Hopefully it has all the
required information so you dont need to read the ACPI spec. ;)
This patchset introduces the ideas behind CPPC (Collaborative Processor
Performance Control) and implements support for controlling CPU performance
using the existing PID (Proportional-Integral-Derivative) controller (from
intel_pstate.c) and some CPPC semantics.
The patchwork is not a final proposal of the CPPC implementation. I've had
to hack some sections due to lack of hardware, details of which are in the
Testing section.
There are several bits of information which are needed in order to make CPPC
work great on Linux based platforms and I'm hoping to start a wider discussion on
how to address the missing bits. The following sections briefly introduce CPPC
and later highlight the information which is missing.
More importantly, I'm also looking for ideas on how to support CPPC in the short
term, given that we will soon be seeing products based on ARM64 and X86 which
support CPPC.[1] Although we may not have all the information, we could make it
work with existing governors in a way this patchset demonstrates. Hopefully,
this approach is acceptable for mainline inclusion in the short term.
Finer details about the CPPC spec are available in the latest ACPI 5.1
specification.[2]
If these issues are being discussed on some other thread or elsewhere, or if
someone is already working on it, please let me know. Also, please correct me if
I have misunderstood anything.
What is CPPC:
=============
CPPC is the new interface for CPU performance control between the OS and the
platform defined in ACPI 5.0+. The interface is built on an abstract
representation of CPU performance rather than raw frequency. Basic operation
consists of:
* Platform enumerates supported performance range to OS
* OS requests desired performance level over some time window along
with min and max instantaneous limits
* Platform is free to optimize power/performance within bounds provided by OS
* Platform provides telemetry back to OS on delivered performance
Communication with the OS is abstracted via another ACPI construct called
Platform Communication Channel (PCC) which is essentially a generic shared
memory channel with doorbell interrupts going back and forth. This abstraction
allows the “platform” for CPPC to be a variety of different entities – driver,
firmware, BMC, etc.
CPPC describes the following registers:
* HighestPerformance: (read from platform)
Indicates the highest level of performance the processor is theoretically
capable of achieving, given ideal operating conditions.
* Nominal Performance: (read from platform)
Indicates the highest sustained performance level of the processor. This is the
highest operating performance level the CPU is expected to deliver continuously.
* LowestNonlinearPerformance: (read from platform)
Indicates the lowest performance level of the processor with non- linear power
savings.
* LowestPerformance: (read from platform)
Indicates the lowest performance level of the processor.
* GuaranteedPerformanceRegister: (read from platform)
Optional. If supported, contains register to read the current guaranteed
performance from. This is current max sustained performance of the CPU taking
into account all budgeting constraints. This can change at runtime and is
notified to the OS via ACPI notification mechanisms.
* DesiredPerformanceRegister: (write to platform)
Register to write desired performance level from the OS.
* MinimumPerformanceRegister: (write to platform)
Optional. This is the min allowable performance as requested by the OS.
* MaximumPerformanceRegister: (write to platform)
Optional. This is the max allowable performance as requested by the OS.
* PerformanceReductionToleranceRegister (write to platform)
Optional. This is the deviation below the desired perf value as requested by the
OS. If the Time window register(below) is supported, then this value is the min
performance on average over the time window that the OS desires.
* TimeWindowRegister: (write to platform)
Optional. The OS requests desired performance over this time window.
* CounterWraparoundTime: (read from platform)
Optional. Min time before the performance counters wrap around.
* ReferencePerformanceCounterRegister: (read from platform)
A counter that increments proportionally to the reference performance of the
processor.
* DeliveredPerformanceCounterRegister: (read from platform)
Delivered perf = reference perf * delta(delivered perf ctr)/delta(ref perf ctr)
* PerformanceLimitedRegister: (read from platform)
This is set by the platform in the event that it has to limit available
performance due to thermal or budgeting constraints.
* CPPCEnableRegister: (read/write from platform)
Enable/disable CPPC
* AutonomousSelectionEnable:
Platform decides CPU performance level w/o OS assist.
* AutonomousActivityWindowRegister:
This influences the increase or decrease in cpu performance of the platforms
autonomous selection policy.
* EnergyPerformancePreferenceRegister:
Provides a energy or perf bias hint to the platform when in autonomous mode.
* Reference Performance: (read from platform)
Indicates the rate at which the reference counter increments.
Whats missing in CPPC:
=====================
Currently CPPC makes no mention of power. However, this could be added in future
versions of the spec.
e.g. although CPPC works off of a continuous range of CPU perf levels, we could
discretize the scale such that we only extract points where the power level changes
substantially between CPU perf levels and export this information to the
scheduler.
Whats missing in the kernel:
============================
We may have some of this information in the scheduler, but I couldn't see a good way
to extract it for CPPC yet.
(1) An intelligent way to provide a min/max bound and a desired value for CPU
performance.
(2) A timing window for the platform to deliver requested performance within
bounds. This could be a kind of sampling interval between consecutive reads of
delivered cpu performance.
(3) Centralized decision making by any CPU in a freq domain for all its
siblings.
The last point needs some elaboration:
I see that the CPUfreq layer allows defining "related CPUs" and that we can have
the same policy for CPUs in the same freq domain and one governor per policy.
However, from what I could tell, there are at least 2 baked in assumptions in
this layer which break things at least for platforms like ARM (Please correct me
if I'm wrong!)
(a) All CPUs run at the exact same max, min and cur freq.
(b) Any CPU always gets exactly the freq it asked for.
So, although the CPUFreq layer is capable of making somewhat centralized cpufreq
decisions for CPUs under the same policy, it seems to be deciding things under
the wrong/inapplicable assumptions. Moreover only one CPU is in charge of
policy handling at a time and the policy handling is shifted to another CPU in the
domain, only if the former CPU is hotplugged out.
Not having a proper centralized decision maker adversely affects power saving
possibilities in platforms that can't distinguish when a CPU requests a specific
freq and then goes to sleep. This potentially has the effect of keeping other
CPUs in the domain running at a much higher frequency than required, while the
initial requester is deep asleep.
So, for point (3), I'm not sure which path we should take among the following:
(I) Fix cpufreq layer and add CPPC support as a cpufreq_driver. (a) Change
every call to get freq to make it read h/w registers and then snap value back to
freq table. This way, cpufreq can keep its idea of freq current. However, this
may end up waking CPUs to read counters, unless they are mem mapped. (b) Allow
any CPU in the "related_cpus" mask to make policy decisions on behalf of
siblings. So the policy maker switching is not tied to hotplug.
(II) Not touch CPUfreq and use the PID algorithm instead, but change the busyness
calculation to accumulate busyness values from all CPUs in common domain.
Requires implementation of domain awareness.
(III) Address these issues in the upcoming CPUfreq/CPUidle integration layer(?)
(IV) Handle it in the platform or lose out. I understand this has some potential
for adding latency to cpu freq requests so it may not be possible for all
platforms.
(V) ..?
For points (1) and (2), the long term solution IMHO is to work it out along with the
scheduler CPUFreq/CPUidle integration. But its not clear to me what would be
the best short term approach. I'd greatly appreciate any suggestions/comments.
If anyone is already working on these issues, please CC me as well.
Test setup:
==========
For the sake of experiments, I used the Thinkpad x240 laptop, which advertises
CPPC tables in its ACPI firmware. The PCC and CPPC drivers included in this
patchset are able to parse the tables and get all the required addresses.
However, it seems that this laptop doesn't implement PCC doorbell and the
firmware side of CPPC. The PCC doorbell calls would just wait forever. Not sure
whats going on there. So, I had to hack it and emulate what the platform
would've done to some extent.
I extracted the PID algo from intel_pstate.c and modified it with CPPC function
wrappers. It shouldn't be hard to replace PID with anything else we think is
suitable. In the long term, I hope we can make CPPC calls directly from the
scheduler.
There are two versions of the low level CPPC accessors. The one included in the
patchset is how I'd imagine it would work with platforms that completely
implement CPPC in firmware.
The other version is here [5]. This should help with DT or platforms with broken
firmware, enablement purposes etc.
I ran a simple kernel compilation with intel_pstate.c and the CPPC modified
version as the governors and saw no real difference in compile times. So no new
overheads added.
I verified that CPU freq requests were taken by reading out the PERF_STATUS register.
[1] - See the HWP section 14.4 http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-3…
[2] - http://www.uefi.org/sites/default/files/resources/ACPI_5_1release.pdf
[3] - https://plus.google.com/+TheodoreTso/posts/2vEekAsG2QT
[4] - https://plus.google.com/+ArjanvandeVen/posts/dLn9T4ehywL
[5] - http://git.linaro.org/people/ashwin.chaugule/leg-kernel.git/blob/236d901d31…
Ashwin Chaugule (3):
ACPI: Add support for Platform Communication Channel
CPPC: Add support for Collaborative Processor Performance Control
CPPC: Add ACPI accessors to CPC registers
drivers/acpi/Kconfig | 10 +
drivers/acpi/Makefile | 1 +
drivers/acpi/pcc.c | 301 +++++++++++++++
drivers/cpufreq/Kconfig | 19 +
drivers/cpufreq/Makefile | 2 +
drivers/cpufreq/cppc.c | 874 ++++++++++++++++++++++++++++++++++++++++++++
drivers/cpufreq/cppc.h | 181 +++++++++
drivers/cpufreq/cppc_acpi.c | 80 ++++
8 files changed, 1468 insertions(+)
create mode 100644 drivers/acpi/pcc.c
create mode 100644 drivers/cpufreq/cppc.c
create mode 100644 drivers/cpufreq/cppc.h
create mode 100644 drivers/cpufreq/cppc_acpi.c
--
1.9.1
The flag definitions of TimerFlags and VirtualTimerFlags in
struct acpi_gtdt_timer_entry is missing, fix it.
Signed-off-by: Hanjun Guo <hanjun.guo(a)linaro.org>
---
Those two patches are for ACPICA, I will send them to Bob and Lv.
---
source/include/actbl3.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/source/include/actbl3.h b/source/include/actbl3.h
index b30e80f..1e59241 100644
--- a/source/include/actbl3.h
+++ b/source/include/actbl3.h
@@ -432,6 +432,10 @@ typedef struct acpi_gtdt_timer_entry
} ACPI_GTDT_TIMER_ENTRY;
+/* Flag Definitions: TimerFlags and VirtualTimerFlags above */
+
+#define ACPI_GTDT_GT_INTERRUPT_TRIGGER_MODE (1)
+#define ACPI_GTDT_GT_INTERRUPT_POLARITY (1<<1)
/* Flag Definitions: CommonFlags above */
--
1.7.9.5