14 Mar, 2020

1 commit


02 Jan, 2020

8 commits

  • When the hierarchical CPU topology layout is used in DT and the PSCI OSI
    mode is supported by the PSCI FW, let's initialize a corresponding PM
    domain topology by using genpd. This enables a CPU and a group of CPUs,
    when attached to the topology, to be power-managed accordingly.

    To trigger the attempt to initialize the genpd data structures let's use a
    subsys_initcall, which should be early enough to allow CPUs, but also other
    devices to be attached.

    The initialization consists of parsing the PSCI OF node for the topology
    and the "domain idle states" DT bindings. In case the idle states are
    compatible with "domain-idle-state", the initialized genpd becomes
    responsible of selecting an idle state for the PM domain, via assigning it
    a genpd governor.

    Note that, a successful initialization of the genpd data structures, is
    followed by a call to psci_set_osi_mode(), as to try to enable the OSI mode
    in the PSCI FW. In case this fails, we fall back into a degraded mode
    rather than bailing out and returning error codes.

    Co-developed-by: Lina Iyer
    Signed-off-by: Lina Iyer
    Signed-off-by: Ulf Hansson
    Reviewed-by: Sudeep Holla
    Acked-by: Rafael J. Wysocki

    Ulf Hansson
     
  • When the hierarchical CPU topology is used and when a CPU is put offline,
    that CPU prevents its PM domain from being powered off, which is because
    genpd observes the corresponding attached device as being active from a
    runtime PM point of view. Furthermore, any potential master PM domains are
    also prevented from being powered off.

    To address this limitation, let's add add a new CPU hotplug state
    (CPUHP_AP_CPU_PM_STARTING) and register up/down callbacks for it, which
    allows us to deal with runtime PM accordingly.

    Signed-off-by: Ulf Hansson
    Reviewed-by: Sudeep Holla
    Acked-by: Rafael J. Wysocki

    Ulf Hansson
     
  • In case we have succeeded to attach a CPU to its PM domain, let's deploy
    runtime PM support for the corresponding attached device, to allow the CPU
    to be powered-managed accordingly.

    The triggering point for when runtime PM reference counting should be done,
    has been selected to the deepest idle state for the CPU. However, from the
    hierarchical point view, there may be good reasons to do runtime PM
    reference counting even on shallower idle states, but at this point this
    isn't supported, mainly due to limitations set by the generic PM domain.

    Signed-off-by: Ulf Hansson
    Reviewed-by: Sudeep Holla
    Acked-by: Rafael J. Wysocki

    Ulf Hansson
     
  • The per CPU variable psci_power_state, contains an array of fixed values,
    which reflects the corresponding arm,psci-suspend-param parsed from DT, for
    each of the available CPU idle states.

    This isn't sufficient when using the hierarchical CPU topology in DT, in
    combination with having PSCI OS initiated (OSI) mode enabled. More
    precisely, in OSI mode, Linux is responsible of telling the PSCI FW what
    idle state the cluster (a group of CPUs) should enter, while in PSCI
    Platform Coordinated (PC) mode, each CPU independently votes for an idle
    state of the cluster.

    For this reason, introduce a per CPU variable called domain_state and
    implement two helper functions to read/write its value. Then let the
    domain_state take precedence over the regular selected state, when entering
    and idle state.

    To avoid executing the above OSI specific code in the ->enter() callback,
    while operating in the default PSCI Platform Coordinated mode, let's also
    add a new enter-function and use it for OSI.

    Co-developed-by: Lina Iyer
    Signed-off-by: Lina Iyer
    Signed-off-by: Ulf Hansson
    Reviewed-by: Sudeep Holla
    Acked-by: Rafael J. Wysocki

    Ulf Hansson
     
  • In order to enable a CPU to be power managed through its PM domain, let's
    try to attach it by calling psci_dt_attach_cpu() during the cpuidle
    initialization.

    psci_dt_attach_cpu() returns a pointer to the attached struct device, which
    later should be used for runtime PM, hence we need to store it somewhere.
    Rather than adding yet another per CPU variable, let's create a per CPU
    struct to collect the relevant per CPU variables.

    Signed-off-by: Ulf Hansson
    Reviewed-by: Sudeep Holla
    Acked-by: Rafael J. Wysocki

    Ulf Hansson
     
  • Currently CPU's idle states are represented using the flattened model.
    Let's add support for the hierarchical layout, via converting to use
    of_get_cpu_state_node().

    Signed-off-by: Ulf Hansson
    Reviewed-by: Sudeep Holla
    Acked-by: Rafael J. Wysocki

    Ulf Hansson
     
  • Iterating through the idle state nodes in DT, to find out the number of
    states that needs to be allocated is unnecessary, as it has already been
    done from dt_init_idle_driver(). Therefore, drop the iteration and use the
    number we already have at hand.

    Signed-off-by: Ulf Hansson
    Reviewed-by: Sudeep Holla
    Acked-by: Rafael J. Wysocki

    Ulf Hansson
     
  • Instead of allocating 'n-1' states in psci_power_state to manage 'n'
    idle states which include "ARM WFI" state, it would be simpler to have
    1:1 mapping between psci_power_state and cpuidle driver states.

    ARM WFI state(i.e. idx == 0) is handled specially in the generic macro
    CPU_PM_CPU_IDLE_ENTER_PARAM and hence state[-1] is not possible. However
    for sake of code readability, it is better to have 1:1 mapping and not
    use [idx - 1] to access psci_power_state corresponding to driver cpuidle
    state for idx.

    psci_power_state[0] is default initialised to 0 and is never accessed
    while entering WFI state.

    Reported-by: Ulf Hansson
    Signed-off-by: Sudeep Holla
    Reviewed-by: Ulf Hansson
    Acked-by: Rafael J. Wysocki

    Sudeep Holla
     

10 Aug, 2019

2 commits

  • Current PSCI code handles idle state entry through the
    psci_cpu_suspend_enter() API, that takes an idle state index as a
    parameter and convert the index into a previously initialized
    power_state parameter before calling the PSCI.CPU_SUSPEND() with it.

    This is unwieldly, since it forces the PSCI firmware layer to keep track
    of power_state parameter for every idle state so that the
    index->power_state conversion can be made in the PSCI firmware layer
    instead of the CPUidle driver implementations.

    Move the power_state handling out of drivers/firmware/psci
    into the respective ACPI/DT PSCI CPUidle backends and convert
    the psci_cpu_suspend_enter() API to get the power_state
    parameter as input, which makes it closer to its firmware
    interface PSCI.CPU_SUSPEND() API.

    A notable side effect is that the PSCI ACPI/DT CPUidle backends
    now can directly handle (and if needed update) power_state
    parameters before handing them over to the PSCI firmware
    interface to trigger PSCI.CPU_SUSPEND() calls.

    Signed-off-by: Lorenzo Pieralisi
    Acked-by: Daniel Lezcano
    Reviewed-by: Ulf Hansson
    Reviewed-by: Sudeep Holla
    Cc: Will Deacon
    Cc: Ulf Hansson
    Cc: Sudeep Holla
    Cc: Daniel Lezcano
    Cc: Catalin Marinas
    Cc: Mark Rutland
    Cc: "Rafael J. Wysocki"
    Signed-off-by: Will Deacon

    Lorenzo Pieralisi
     
  • PSCI firmware is the standard power management control for
    all ARM64 based platforms and it is also deployed on some
    ARM 32 bit platforms to date.

    Idle state entry in PSCI is currently achieved by calling
    arm_cpuidle_init() and arm_cpuidle_suspend() in a generic
    idle driver, which in turn relies on ARM/ARM64 CPUidle back-end
    to relay the call into PSCI firmware if PSCI is the boot method.

    Given that PSCI is the standard idle entry method on ARM64 systems
    (which means that no other CPUidle driver are expected on ARM64
    platforms - so PSCI is already a generic idle driver), in order to
    simplify idle entry and code maintenance, it makes sense to have a PSCI
    specific idle driver so that idle code that it is currently living in
    drivers/firmware directory can be hoisted out of it and moved
    where it belongs, into a full-fledged PSCI driver, leaving PSCI code
    in drivers/firmware as a pure firmware interface, as it should be.

    Implement a PSCI CPUidle driver. By default it is a silent Kconfig entry
    which is left unselected, since it selection would clash with the
    generic ARM CPUidle driver that provides a PSCI based idle driver
    through the arm/arm64 arches back-ends CPU operations.

    Signed-off-by: Lorenzo Pieralisi
    Acked-by: Daniel Lezcano
    Reviewed-by: Ulf Hansson
    Reviewed-by: Sudeep Holla
    Cc: Ulf Hansson
    Cc: Sudeep Holla
    Cc: Daniel Lezcano
    Cc: Mark Rutland
    Cc: "Rafael J. Wysocki"
    Signed-off-by: Will Deacon

    Lorenzo Pieralisi