// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/graphics/display/drivers/intel-i915/power-controller.h"

#include <lib/ddk/debug.h>
#include <lib/mmio/mmio-buffer.h>
#include <lib/zx/clock.h>
#include <lib/zx/result.h>
#include <lib/zx/time.h>
#include <zircon/assert.h>
#include <zircon/errors.h>

#include <cstdint>

#include <hwreg/bitfields.h>

#include "src/graphics/display/drivers/intel-i915/poll-until.h"
#include "src/graphics/display/drivers/intel-i915/registers-gt-mailbox.h"
#include "src/graphics/display/drivers/intel-i915/scoped-value-change.h"

namespace i915 {

namespace {

// The amount of microseconds to wait for PCU to complete a previous command.
//
// This should be at least as large as all known command timeouts below.
//
// Overridden in tests via
// PowerController::OverridePreviousCommandTimeoutUsForTesting().
int g_previous_command_timeout_us = 200;

// Timeout for the PCU firmware to reply to a voltage change request.
// Overridden in tests via
// PowerController::OverrideVoltageLevelRequestReplyTimeoutUsForTesting().
int g_voltage_level_request_reply_timeout_us = 150;

// Timeout for the PCU firmware to execute a voltage change request.
// Overridden in tests via
// PowerController::OverrideVoltageLevelRequestTotalTimeoutUsForTesting().
int g_voltage_level_request_total_timeout_us = 3'000;  // 3ms

// Timeout for the PCU firmware to reply to a TCCOLD blocking change request.
// Overridden in tests via
// PowerController::OverrideTypeCColdBlockingChangeReplyTimeoutUsForTesting().
int g_typec_cold_blocking_change_reply_timeout_us = 200;

// Timeout for the PCU firmware to execute a TCCOLD blocking change request.
// Overridden in tests via
// PowerController::OverrideTypeCColdBlockingChangeTotalTimeoutUsForTesting().
int g_typec_cold_blocking_change_total_timeout_us = 600;

// Timeout for the PCU firmware to reply to a SAGV enablement change request.
// Overridden in tests via
// PowerController::OverrideSystemAgentEnablementChangeReplyTimeoutUsForTesting().
int g_system_agent_enablement_change_reply_timeout_us = 150;

// Timeout for the PCU firmware to execute a SAGV enablement change request.
// Overridden in tests via
// PowerController::OverrideSystemAgentEnablementChangeTotalTimeoutUsForTesting().
int g_system_agent_enablement_change_total_timeout_us = 1'000;  // 1ms

// Timeout for the PCU firmware to reply to a memory subsystem info request.
// Overridden in tests via
// PowerController::OverrideGetMemorySubsystemInfoReplyTimeoutUsForTesting().
int g_get_memory_subsystem_info_reply_timeout_us = 150;

// Timeout for the PCU firmware to reply to a memory latency info request.
// Overridden in tests via
// PowerController::OverrideGetMemoryLatencyReplyTimeoutUsForTesting().
int g_get_memory_latency_reply_timeout_us = 100;

}  // namespace

PowerController::PowerController(fdf::MmioBuffer* mmio_buffer) : mmio_buffer_(mmio_buffer) {
  ZX_DEBUG_ASSERT(mmio_buffer);
}

zx::result<uint64_t> PowerController::Transact(PowerControllerCommand command) {
  auto mailbox_interface = registers::PowerMailboxInterface::Get().FromValue(0);

  if (!PollUntil([&] { return !mailbox_interface.ReadFrom(mmio_buffer_).has_active_transaction(); },
                 zx::usec(1), g_previous_command_timeout_us)) {
    zxlogf(WARNING, "Timed out while waiting for PCU to finish pre-existing work");
    return zx::error_result(ZX_ERR_IO_MISSED_DEADLINE);
  }

  auto mailbox_data0 = registers::PowerMailboxData0::Get().FromValue(0);
  mailbox_data0.set_reg_value(static_cast<uint32_t>(command.data)).WriteTo(mmio_buffer_);
  auto mailbox_data1 = registers::PowerMailboxData1::Get().FromValue(0);
  mailbox_data1.set_reg_value(static_cast<uint32_t>(command.data >> 32)).WriteTo(mmio_buffer_);
  mailbox_interface.set_command_code(command.command)
      .set_param1(command.param1)
      .set_param2(command.param2)
      .set_has_active_transaction(true)
      .WriteTo(mmio_buffer_);

  if (command.timeout_us == 0) {
    return zx::ok(0);
  }

  if (!PollUntil([&] { return !mailbox_interface.ReadFrom(mmio_buffer_).has_active_transaction(); },
                 zx::usec(1), command.timeout_us)) {
    return zx::error_result(ZX_ERR_IO_MISSED_DEADLINE);
  }

  const uint32_t data_low = mailbox_data0.ReadFrom(mmio_buffer_).reg_value();
  const uint32_t data_high = mailbox_data1.ReadFrom(mmio_buffer_).reg_value();
  const uint64_t data = (uint64_t{data_high} << 32) | data_low;
  return zx::ok(data);
}

zx::result<> PowerController::RequestDisplayVoltageLevel(int voltage_level,
                                                         RetryBehavior retry_behavior) {
  // This operation is documented in the Clocking sections in Intel's display
  // engine PRMs.
  //
  // Tiger Lake: IHD-OS-TGL-Vol 12-1.22-Rev2.0 section "Display Voltage
  //             Frequency Switching" > "Sequence Before Frequency Change" and
  //             "Sequence After Frequency Change", page 195
  // Kaby Lake: IHD-OS-KBL-Vol 12-1.17 "Sequences for Changing CD Clock
  //            Frequency", pages 138-139
  // Skylake: IHD-OS-SKL-Vol 12-05.16 "Skylake Sequences for Changing CD Clock
  //          Frequency", pages 135-136

  // ZX_DEBUG_ASSERT() is appropriate for most cases where individual parameters
  // are set incorrectly, but only correct MMIO addresses are accessed. However,
  // confusing the PCU firmware can have pretty catastrophic consequences for
  // the system, so we're very strict here.
  ZX_ASSERT(voltage_level >= 0);
  ZX_ASSERT(voltage_level <= 3);

  const zx::time deadline =
      (retry_behavior == RetryBehavior::kRetryUntilStateChanges)
          ? zx::deadline_after(zx::usec(g_voltage_level_request_total_timeout_us))
          : zx::time::infinite_past();

  do {
    zx::result<uint64_t> mailbox_result = Transact({
        .command = 0x07,
        .data = static_cast<uint64_t>(voltage_level),
        .timeout_us = g_voltage_level_request_reply_timeout_us,
    });
    if (mailbox_result.is_error()) {
      return mailbox_result.take_error();
    }
    const bool success = (mailbox_result.value() & 1) == 1;
    if (success) {
      return zx::ok();
    }
  } while (zx::clock::get_monotonic() < deadline);

  return zx::error_result(ZX_ERR_IO_REFUSED);
}

zx::result<> PowerController::SetDisplayTypeCColdBlockingTigerLake(bool blocked,
                                                                   RetryBehavior retry_behavior) {
  // This operation is documented in IHD-OS-TGL-Vol 12-1.22-Rev2.0, sections
  // "GT Driver Mailbox to Block TCCOLD" and "GT Driver Mailbox to Unblock
  // TCCOLD" sections in Intel's display engine PRMs.
  //
  // IHD-OS-LKF-Vol 12-4.21 also documents the TCCOLD concept, but Lakefield's
  // PCU firmware uses a different API for managing TCCOLD.

  const zx::time deadline =
      (retry_behavior == RetryBehavior::kRetryUntilStateChanges)
          ? zx::deadline_after(zx::usec(g_typec_cold_blocking_change_total_timeout_us))
          : zx::time::infinite_past();

  const uint64_t command_data = blocked ? 0 : 1;
  do {
    zx::result<uint64_t> mailbox_result = Transact({
        .command = 0x26,
        .data = command_data,
        .timeout_us = g_typec_cold_blocking_change_reply_timeout_us,
    });
    if (mailbox_result.is_error()) {
      return mailbox_result.take_error();
    }
    const bool type_c_controller_in_cold_state = (mailbox_result.value() & 1) == 1;
    if (type_c_controller_in_cold_state != blocked) {
      return zx::ok();
    }
  } while (zx::clock::get_monotonic() < deadline);

  return zx::error_result(ZX_ERR_IO_REFUSED);
}

zx::result<> PowerController::SetSystemAgentGeyservilleEnabled(bool enabled,
                                                               RetryBehavior retry_behavior) {
  // Tiger Lake: IHD-OS-TGL-Vol 12-1.22-Rev2.0 section
  //             "MAILBOX_GTDRIVER_CMD_DE_LTR_SETTING", pages 214-215
  // DG1: IHD-OS-DG1-Vol 12-2.21 section ""MAILBOX_GTDRIVER_CMD_DE_LTR_SETTING",
  //      pages 171-172
  // Kaby Lake: IHD-OS-KBL-Vol 12-1.17 "System Agent Geyserville (SAGV)", page
  //            206
  // Skylake: IHD-OS-SKL-Vol 12-05.16 "System Agent Geyserville (SAGV)", pages
  //          197-198

  const zx::time deadline =
      (retry_behavior == RetryBehavior::kRetryUntilStateChanges)
          ? zx::deadline_after(zx::usec(g_system_agent_enablement_change_total_timeout_us))
          : zx::time::infinite_past();

  // The data is documented as the EL_THLD (Threshold) LTR (most likely "Latency
  // Tolerance Reporting") override on Tiger Lake and DG1.
  const uint64_t command_data = enabled ? 3 : 0;
  do {
    zx::result<uint64_t> mailbox_result = Transact({
        .command = 0x21,
        .data = command_data,
        .timeout_us = g_system_agent_enablement_change_reply_timeout_us,
    });
    if (mailbox_result.is_error()) {
      return mailbox_result.take_error();
    }
    const bool success = (mailbox_result.value() & 1) == 1;
    if (success) {
      return zx::ok();
    }
  } while (zx::clock::get_monotonic() < deadline);

  return zx::error_result(ZX_ERR_IO_REFUSED);
}

zx::result<uint32_t> PowerController::GetSystemAgentBlockTimeUsTigerLake() {
  // Documented in the "Display Watermark Programming" > "SAGV Block Time"
  // section in the PRMs.
  //
  // Tiger Lake: IHD-OS-TGL-Vol 12-1.22-Rev2.0 pages 436-437
  // DG1: IHD-OS-DG1-Vol 12-2.21 page 362

  zx::result<uint64_t> mailbox_result = Transact({
      .command = 0x23,
      .param1 = 0,
      .param2 = 0,
      .data = 0,
      .timeout_us = g_get_memory_latency_reply_timeout_us,
  });
  if (mailbox_result.is_error()) {
    return mailbox_result.take_error();
  }

  // This PCU command returns an error code in the Command/Error Code field
  // of the Mailbox Interface register.
  auto mailbox_interface = registers::PowerMailboxInterface::Get().ReadFrom(mmio_buffer_);
  if (mailbox_interface.command_code() != 0) {
    return zx::error_result(ZX_ERR_IO_REFUSED);
  }

  return zx::ok(static_cast<uint32_t>(mailbox_result.value()));
}

zx::result<uint32_t> PowerController::GetSystemAgentBlockTimeUsKabyLake() {
  // Documented in the "Display Watermark Programming" > "SAGV Block Time"
  // section in the PRMs.
  //
  // Kaby Lake: IHD-OS-KBL-Vol 12-1.17 page 209
  // Skylake: IHD-OS-SKL-Vol 12-05.16 page 200

  return zx::ok(30);
}

zx::result<std::array<uint8_t, 8>> PowerController::GetRawMemoryLatencyDataUs() {
  // Documented in the "Display Watermark Programming" > "Memory Values" section
  // in the PRMs.
  //
  // Tiger Lake: IHD-OS-TGL-Vol 12-1.22-Rev2.0 pages 435-436
  // DG1: IHD-OS-DG1-Vol 12-2.21 pages 361-362
  // Kaby Lake: IHD-OS-KBL-Vol 12-1.17 pages 208-209
  // Skylake: IHD-OS-SKL-Vol 12-05.16 pages 199-200

  uint32_t latency_data[2];

  for (int values_index = 0; values_index < 2; ++values_index) {
    zx::result<uint64_t> mailbox_result = Transact({
        .command = 0x06,
        .param1 = 0,
        .param2 = 0,
        .data = static_cast<uint64_t>(values_index),
        .timeout_us = g_get_memory_latency_reply_timeout_us,
    });
    if (mailbox_result.is_error()) {
      return mailbox_result.take_error();
    }

    // This PCU command returns an error code in the Command/Error Code field
    // of the Mailbox Interface register.
    auto mailbox_interface = registers::PowerMailboxInterface::Get().ReadFrom(mmio_buffer_);
    if (mailbox_interface.command_code() != 0) {
      return zx::error_result(ZX_ERR_IO_REFUSED);
    }
    latency_data[values_index] = static_cast<uint32_t>(mailbox_result.value());
  }

  std::array<uint8_t, 8> latency_levels;
  static_assert(sizeof(latency_data) == sizeof(latency_levels));
  std::memcpy(latency_levels.data(), latency_data, sizeof(latency_data));
  return zx::ok(latency_levels);
}

namespace {

// MAILBOX_GTRDIVER_CMD_MEM_SS_INFO_SUBCOMMAND_READ_GLOBAL_INFO result.
//
// Tiger Lake: IHD-OS-TGL-Vol 12-1.22-Rev2.0 pages 212-213
// DG1: IHD-OS-TGL-Vol 12-1.22-Rev2.0 pages 169-170
class MemorySubsystemGlobalConfig
    : public hwreg::RegisterBase<MemorySubsystemGlobalConfig, uint64_t> {
 public:
  DEF_FIELD(11, 8, enabled_qgv_point_count);
  DEF_FIELD(7, 4, populated_channel_count);
  DEF_ENUM_FIELD(MemorySubsystemInfo::RamType, 3, 0, ddr_type_select);

  static auto GetFromValue(uint64_t mailbox_data) {
    return hwreg::RegisterAddr<MemorySubsystemGlobalConfig>(0).FromValue(mailbox_data);
  }
};

// MAILBOX_GTRDIVER_CMD_MEM_SS_INFO_SUBCOMMAND_READ_QGV_POINT_INFO result.
//
//
// Tiger Lake: IHD-OS-TGL-Vol 12-1.22-Rev2.0 pages 212-213
// DG1: IHD-OS-TGL-Vol 12-1.22-Rev2.0 pages 169-170
class MemorySubsystemPointInfo : public hwreg::RegisterBase<MemorySubsystemPointInfo, uint64_t> {
 public:
  // DRAM timings. See `MemorySubsystemInfo` for explanations.
  DEF_FIELD(48, 40, tras_dclks);
  DEF_FIELD(39, 32, trdpre_dclks);
  DEF_FIELD(31, 24, trcd_dclks);
  DEF_FIELD(23, 16, trp_dclks);

  // DRAM clock in multiples of 16.6666 MHz.
  DEF_FIELD(15, 0, dclk_multiplier);

  static auto GetFromValue(uint64_t mailbox_data) {
    return hwreg::RegisterAddr<MemorySubsystemPointInfo>(0).FromValue(mailbox_data);
  }
};

}  // namespace

// static
MemorySubsystemInfo::GlobalInfo MemorySubsystemInfo::GlobalInfo::CreateFromMailboxDataTigerLake(
    uint64_t mailbox_data) {
  auto global_config = MemorySubsystemGlobalConfig::GetFromValue(mailbox_data);
  return MemorySubsystemInfo::GlobalInfo{
      .ram_type = global_config.ddr_type_select(),
      .memory_channel_count = static_cast<int8_t>(global_config.populated_channel_count()),
      .agent_point_count = static_cast<int8_t>(global_config.enabled_qgv_point_count()),
  };
}

MemorySubsystemInfo::AgentPoint MemorySubsystemInfo::AgentPoint::CreateFromMailboxDataTigerLake(
    uint64_t mailbox_data) {
  auto point_info = MemorySubsystemPointInfo::GetFromValue(mailbox_data);
  return MemorySubsystemInfo::AgentPoint{
      // The cast is lossless because the underlying field is 16 bits. The
      // multiplication does not overflow because the maximum result is
      // 1,092,206,310 which fits in 31 bits.
      .dram_clock_khz =
          static_cast<int32_t>(static_cast<int32_t>(point_info.dclk_multiplier()) * 16'666),

      // The casts are lossless because the underlying fields are 9 bits.
      .row_precharge_to_open_cycles = static_cast<int16_t>(point_info.trp_dclks()),
      .row_access_to_column_access_delay_cycles = static_cast<int16_t>(point_info.trcd_dclks()),
      .read_to_precharge_cycles = static_cast<int16_t>(point_info.trdpre_dclks()),
      .row_activate_to_precharge_cycles = static_cast<int16_t>(point_info.tras_dclks()),
  };
}

zx::result<MemorySubsystemInfo> PowerController::GetMemorySubsystemInfoTigerLake() {
  // Documented in the "Mailbox Commands" > "MAILBOX_GTRDIVER_CMD_MEM_SS_INFO"
  // section of the PRMs.
  //
  // Tiger Lake: IHD-OS-TGL-Vol 12-1.22-Rev2.0 pages 212-213
  // DG1: IHD-OS-TGL-Vol 12-1.22-Rev2.0 pages 169-170

  MemorySubsystemInfo result;

  {
    // MAILBOX_GTRDIVER_CMD_MEM_SS_INFO_SUBCOMMAND_READ_GLOBAL_INFO in the PRM.
    zx::result<uint64_t> global_info = Transact({
        .command = 0x0d,
        .param1 = 0,
        .param2 = 0,
        .data = 0,
        .timeout_us = g_get_memory_subsystem_info_reply_timeout_us,
    });
    if (global_info.is_error()) {
      return global_info.take_error();
    }
    zxlogf(TRACE, "MAILBOX_GTRDIVER_CMD_MEM_SS_INFO_SUBCOMMAND_READ_GLOBAL_INFO - %lx",
           global_info.value());
    result.global_info =
        MemorySubsystemInfo::GlobalInfo::CreateFromMailboxDataTigerLake(global_info.value());
  }

  const int point_count = result.global_info.agent_point_count;
  for (int point_index = 0; point_index < point_count; ++point_index) {
    // MAILBOX_GTRDIVER_CMD_MEM_SS_INFO_SUBCOMMAND_READ_QGV_POINT_INFO in the
    // PRM.
    zx::result<uint64_t> point_info = Transact({
        .command = 0x0d,
        .param1 = 1,
        .param2 = static_cast<uint8_t>(point_index),
        .data = 0,
        .timeout_us = g_get_memory_subsystem_info_reply_timeout_us,
    });
    if (point_info.is_error()) {
      return point_info.take_error();
    }

    // This PCU command returns an error code in the Command/Error Code field
    // of the Mailbox Interface register.
    auto mailbox_interface = registers::PowerMailboxInterface::Get().ReadFrom(mmio_buffer_);
    if (mailbox_interface.command_code() != 0) {
      return zx::error_result(ZX_ERR_IO_REFUSED);
    }

    zxlogf(TRACE, "MAILBOX_GTRDIVER_CMD_MEM_SS_INFO_SUBCOMMAND_READ_QGV_POINT_INFO - %lx",
           point_info.value());
    result.points[point_index] =
        MemorySubsystemInfo::AgentPoint::CreateFromMailboxDataTigerLake(point_info.value());
  }

  return zx::ok(result);
}

// static
ScopedValueChange<int> PowerController::OverridePreviousCommandTimeoutUsForTesting(int timeout_us) {
  return ScopedValueChange(g_previous_command_timeout_us, timeout_us);
}

// static
ScopedValueChange<int> PowerController::OverrideVoltageLevelRequestReplyTimeoutUsForTesting(
    int timeout_us) {
  return ScopedValueChange(g_voltage_level_request_reply_timeout_us, timeout_us);
}

// static
ScopedValueChange<int> PowerController::OverrideVoltageLevelRequestTotalTimeoutUsForTesting(
    int timeout_us) {
  return ScopedValueChange(g_voltage_level_request_total_timeout_us, timeout_us);
}

// static
ScopedValueChange<int> PowerController::OverrideTypeCColdBlockingChangeReplyTimeoutUsForTesting(
    int timeout_us) {
  return ScopedValueChange(g_typec_cold_blocking_change_reply_timeout_us, timeout_us);
}

// static
ScopedValueChange<int> PowerController::OverrideTypeCColdBlockingChangeTotalTimeoutUsForTesting(
    int timeout_us) {
  return ScopedValueChange(g_typec_cold_blocking_change_total_timeout_us, timeout_us);
}

// static
ScopedValueChange<int> PowerController::OverrideSystemAgentEnablementChangeReplyTimeoutUsForTesting(
    int timeout_us) {
  return ScopedValueChange(g_system_agent_enablement_change_reply_timeout_us, timeout_us);
}

// static
ScopedValueChange<int> PowerController::OverrideSystemAgentEnablementChangeTotalTimeoutUsForTesting(
    int timeout_us) {
  return ScopedValueChange(g_system_agent_enablement_change_total_timeout_us, timeout_us);
}

// static
ScopedValueChange<int> PowerController::OverrideGetMemorySubsystemInfoReplyTimeoutUsForTesting(
    int timeout_us) {
  return ScopedValueChange(g_get_memory_subsystem_info_reply_timeout_us, timeout_us);
}

// static
ScopedValueChange<int> PowerController::OverrideGetMemoryLatencyReplyTimeoutUsForTesting(
    int timeout_us) {
  return ScopedValueChange(g_get_memory_latency_reply_timeout_us, timeout_us);
}

}  // namespace i915
