19827Sakash.bagdia@arm.com/*
210249Sstephan.diestelhorst@arm.com * Copyright (c) 2012-2014 ARM Limited
39827Sakash.bagdia@arm.com * All rights reserved
49827Sakash.bagdia@arm.com *
59827Sakash.bagdia@arm.com * The license below extends only to copyright in the software and shall
69827Sakash.bagdia@arm.com * not be construed as granting a license to any other intellectual
79827Sakash.bagdia@arm.com * property including but not limited to intellectual property relating
89827Sakash.bagdia@arm.com * to a hardware implementation of the functionality of the software
99827Sakash.bagdia@arm.com * licensed hereunder.  You may use the software subject to the license
109827Sakash.bagdia@arm.com * terms below provided that you ensure that this notice is replicated
119827Sakash.bagdia@arm.com * unmodified and in its entirety in all distributions of the software,
129827Sakash.bagdia@arm.com * modified or unmodified, in source code or in binary form.
139827Sakash.bagdia@arm.com *
149827Sakash.bagdia@arm.com * Redistribution and use in source and binary forms, with or without
159827Sakash.bagdia@arm.com * modification, are permitted provided that the following conditions are
169827Sakash.bagdia@arm.com * met: redistributions of source code must retain the above copyright
179827Sakash.bagdia@arm.com * notice, this list of conditions and the following disclaimer;
189827Sakash.bagdia@arm.com * redistributions in binary form must reproduce the above copyright
199827Sakash.bagdia@arm.com * notice, this list of conditions and the following disclaimer in the
209827Sakash.bagdia@arm.com * documentation and/or other materials provided with the distribution;
219827Sakash.bagdia@arm.com * neither the name of the copyright holders nor the names of its
229827Sakash.bagdia@arm.com * contributors may be used to endorse or promote products derived from
239827Sakash.bagdia@arm.com * this software without specific prior written permission.
249827Sakash.bagdia@arm.com *
259827Sakash.bagdia@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
269827Sakash.bagdia@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
279827Sakash.bagdia@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
289827Sakash.bagdia@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
299827Sakash.bagdia@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
309827Sakash.bagdia@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
319827Sakash.bagdia@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
329827Sakash.bagdia@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
339827Sakash.bagdia@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
349827Sakash.bagdia@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
359827Sakash.bagdia@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
369827Sakash.bagdia@arm.com *
379827Sakash.bagdia@arm.com * Authors: Vasileios Spiliopoulos
389827Sakash.bagdia@arm.com *          Akash Bagdia
399827Sakash.bagdia@arm.com */
409827Sakash.bagdia@arm.com
4111793Sbrandon.potter@amd.com#include "sim/voltage_domain.hh"
4211793Sbrandon.potter@amd.com
4310249Sstephan.diestelhorst@arm.com#include <algorithm>
4410249Sstephan.diestelhorst@arm.com
4510249Sstephan.diestelhorst@arm.com#include "base/statistics.hh"
4611800Sbrandon.potter@amd.com#include "base/trace.hh"
479827Sakash.bagdia@arm.com#include "debug/VoltageDomain.hh"
489827Sakash.bagdia@arm.com#include "params/VoltageDomain.hh"
499827Sakash.bagdia@arm.com#include "sim/sim_object.hh"
509827Sakash.bagdia@arm.com
519827Sakash.bagdia@arm.comVoltageDomain::VoltageDomain(const Params *p)
5210249Sstephan.diestelhorst@arm.com    : SimObject(p), voltageOpPoints(p->voltage), _perfLevel(0)
539827Sakash.bagdia@arm.com{
5410249Sstephan.diestelhorst@arm.com    fatal_if(voltageOpPoints.empty(), "DVFS: Empty set of voltages for "\
5510249Sstephan.diestelhorst@arm.com             "voltage domain %s\n", name());
5610249Sstephan.diestelhorst@arm.com
5710249Sstephan.diestelhorst@arm.com    // Voltages must be sorted in descending order.
5810249Sstephan.diestelhorst@arm.com    fatal_if(!std::is_sorted(voltageOpPoints.begin(), voltageOpPoints.end(),
5910395Sstephan.diestelhorst@arm.com             std::greater<Voltages::value_type>()), "DVFS: Voltage operation "\
6010395Sstephan.diestelhorst@arm.com             "points not in descending order for voltage domain %s\n",
6110395Sstephan.diestelhorst@arm.com             name());
629827Sakash.bagdia@arm.com}
639827Sakash.bagdia@arm.com
649827Sakash.bagdia@arm.comvoid
6510249Sstephan.diestelhorst@arm.comVoltageDomain::perfLevel(PerfLevel perf_level)
669827Sakash.bagdia@arm.com{
6710249Sstephan.diestelhorst@arm.com    chatty_assert(perf_level < voltageOpPoints.size(),
6810249Sstephan.diestelhorst@arm.com                  "DVFS: Requested voltage ID %d is outside the known "\
6910249Sstephan.diestelhorst@arm.com                  "range for domain %s.\n", perf_level, name());
7010249Sstephan.diestelhorst@arm.com
7110395Sstephan.diestelhorst@arm.com    if (perf_level == _perfLevel) {
7210395Sstephan.diestelhorst@arm.com        // Silently ignore identical overwrites
7310395Sstephan.diestelhorst@arm.com        return;
7410395Sstephan.diestelhorst@arm.com    }
7510395Sstephan.diestelhorst@arm.com
7610249Sstephan.diestelhorst@arm.com    _perfLevel = perf_level;
7710249Sstephan.diestelhorst@arm.com
7810249Sstephan.diestelhorst@arm.com    DPRINTF(VoltageDomain, "Setting voltage to %.3fV idx: %d for domain %s\n",
7910249Sstephan.diestelhorst@arm.com            voltage(), perf_level, name());
8010249Sstephan.diestelhorst@arm.com}
8110249Sstephan.diestelhorst@arm.com
8210249Sstephan.diestelhorst@arm.combool
8310249Sstephan.diestelhorst@arm.comVoltageDomain::sanitiseVoltages()
8410249Sstephan.diestelhorst@arm.com{
8510249Sstephan.diestelhorst@arm.com    if (numVoltages() == 1)
8610249Sstephan.diestelhorst@arm.com        return false;
8710249Sstephan.diestelhorst@arm.com
8810249Sstephan.diestelhorst@arm.com    // Find the highest requested performance level and update the voltage
8910249Sstephan.diestelhorst@arm.com    // domain with it
9010249Sstephan.diestelhorst@arm.com    PerfLevel perf_max = (PerfLevel)-1;
9110249Sstephan.diestelhorst@arm.com    for (auto dit = srcClockChildren.begin(); dit != srcClockChildren.end(); ++dit) {
9210249Sstephan.diestelhorst@arm.com        SrcClockDomain* d = *dit;
9310249Sstephan.diestelhorst@arm.com        chatty_assert(d->voltageDomain() == this, "DVFS: Clock domain %s "\
9410249Sstephan.diestelhorst@arm.com                      "(id: %d) should not be registered with voltage domain "\
9510249Sstephan.diestelhorst@arm.com                      "%s\n", d->name(), d->domainID(), name());
9610249Sstephan.diestelhorst@arm.com
9710249Sstephan.diestelhorst@arm.com        PerfLevel perf = d->perfLevel();
9810249Sstephan.diestelhorst@arm.com
9910249Sstephan.diestelhorst@arm.com        DPRINTF(VoltageDomain, "DVFS: Clock domain %s (id: %d) requests perf "\
10010249Sstephan.diestelhorst@arm.com                "level %d\n", d->name(), d->domainID(), perf);
10110249Sstephan.diestelhorst@arm.com
10210249Sstephan.diestelhorst@arm.com        // NOTE: Descending sort of performance levels: 0 - fast, 5 - slow
10310249Sstephan.diestelhorst@arm.com        if (perf < perf_max) {
10410249Sstephan.diestelhorst@arm.com            DPRINTF(VoltageDomain, "DVFS: Updating max perf level %d -> %d\n",
10510249Sstephan.diestelhorst@arm.com                    perf_max, perf);
10610249Sstephan.diestelhorst@arm.com            perf_max = perf;
10710249Sstephan.diestelhorst@arm.com        }
1089827Sakash.bagdia@arm.com    }
10910249Sstephan.diestelhorst@arm.com    DPRINTF(VoltageDomain, "DVFS: Setting perf level of voltage domain %s "\
11010249Sstephan.diestelhorst@arm.com            "from %d to %d.\n", name(), perfLevel(), perf_max);
1119827Sakash.bagdia@arm.com
11210249Sstephan.diestelhorst@arm.com    // Set the performance level
11310249Sstephan.diestelhorst@arm.com    if (perf_max != perfLevel()) {
11410249Sstephan.diestelhorst@arm.com        perfLevel(perf_max);
11510249Sstephan.diestelhorst@arm.com        return true;
11610249Sstephan.diestelhorst@arm.com    } else {
11710249Sstephan.diestelhorst@arm.com        return false;
11810249Sstephan.diestelhorst@arm.com    }
11910249Sstephan.diestelhorst@arm.com}
12010249Sstephan.diestelhorst@arm.com
12110249Sstephan.diestelhorst@arm.comvoid
12210249Sstephan.diestelhorst@arm.comVoltageDomain::startup() {
12310249Sstephan.diestelhorst@arm.com    bool changed = sanitiseVoltages();
12410249Sstephan.diestelhorst@arm.com    if (changed) {
12510249Sstephan.diestelhorst@arm.com        warn("DVFS: Perf level for voltage domain %s adapted to "\
12610249Sstephan.diestelhorst@arm.com             "requested perf levels from source clock domains.\n", name());
12710249Sstephan.diestelhorst@arm.com    }
1289827Sakash.bagdia@arm.com}
1299827Sakash.bagdia@arm.com
13010022SAndreas.Hansson@ARM.comvoid
13110022SAndreas.Hansson@ARM.comVoltageDomain::regStats()
13210022SAndreas.Hansson@ARM.com{
13311523Sdavid.guillen@arm.com    SimObject::regStats();
13411523Sdavid.guillen@arm.com
13510022SAndreas.Hansson@ARM.com    currentVoltage
13610249Sstephan.diestelhorst@arm.com        .method(this, &VoltageDomain::voltage)
13710022SAndreas.Hansson@ARM.com        .name(params()->name + ".voltage")
13810022SAndreas.Hansson@ARM.com        .desc("Voltage in Volts")
13910022SAndreas.Hansson@ARM.com        ;
14010022SAndreas.Hansson@ARM.com}
14110022SAndreas.Hansson@ARM.com
1429827Sakash.bagdia@arm.comVoltageDomain *
1439827Sakash.bagdia@arm.comVoltageDomainParams::create()
1449827Sakash.bagdia@arm.com{
1459827Sakash.bagdia@arm.com    return new VoltageDomain(this);
1469827Sakash.bagdia@arm.com}
14710249Sstephan.diestelhorst@arm.com
14810249Sstephan.diestelhorst@arm.comvoid
14910905Sandreas.sandberg@arm.comVoltageDomain::serialize(CheckpointOut &cp) const
15010905Sandreas.sandberg@arm.com{
15110249Sstephan.diestelhorst@arm.com    SERIALIZE_SCALAR(_perfLevel);
15210249Sstephan.diestelhorst@arm.com}
15310249Sstephan.diestelhorst@arm.com
15410249Sstephan.diestelhorst@arm.comvoid
15510905Sandreas.sandberg@arm.comVoltageDomain::unserialize(CheckpointIn &cp)
15610905Sandreas.sandberg@arm.com{
15710249Sstephan.diestelhorst@arm.com    UNSERIALIZE_SCALAR(_perfLevel);
15810249Sstephan.diestelhorst@arm.com    perfLevel(_perfLevel);
15910249Sstephan.diestelhorst@arm.com}
160