/**
 * Copyright (C) 2017 IBM Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <phosphor-logging/log.hpp>
#include "cfam_access.hpp"
#include "p9_cfam.hpp"
#include "registration.hpp"
#include "targeting.hpp"

namespace openpower
{
namespace p9
{

using namespace phosphor::logging;
using namespace openpower::cfam::access;
using namespace openpower::cfam::p9;
using namespace openpower::targeting;


/**
 * @brief Performs the 'VCS Workaround' on all P9s in the system.
 * @return void
 */
void vcsWorkaround()
{
    Targeting targets;
    const auto& master = *(targets.begin());

    // First determine if we need to run this workaround (not needed on chips
    // which are not DD1.0)
    // Mixing DD1.0 parts with other levels is not allowed so just look
    // at the first chip
    auto chipID = readReg(master, P9_FSI2PIB_CHIPID);
    if (chipID != P9_DD10_CHIPID)
    {
        log<level::INFO>("P9 procedure vcsWorkaround not needed",
                         entry("CHIPID=0x%08X", chipID));
        return;
    }

    log<level::INFO>("Running P9 procedure vcsWorkaround",
                     entry("NUM_PROCS=%d", targets.size()));

    //Set asynchronous clock mode
    writeReg(master, P9_LL_MODE_REG, 0x00000001);

    for (const auto& t : targets)
    {
        //Unfence PLL controls
        writeRegWithMask(t, P9_ROOT_CTRL0,
                         0x00000000, 0x00010000);

        //Assert Perv chiplet endpoint reset
        writeRegWithMask(t, P9_PERV_CTRL0,
                         0x40000000, 0x40000000);

        //Enable Nest PLL
        writeRegWithMask(t, P9_PERV_CTRL0,
                         0x00000001, 0x00000001);
    }
}

REGISTER_PROCEDURE("vcsWorkaround", vcsWorkaround);

}
}
