// Copyright 2017 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.

#ifndef REGISTERS_H
#define REGISTERS_H

#include "magma_util/macros.h"
#include "magma_util/register_bitfields.h"
#include "magma_util/register_io.h"

namespace registers {

class GpuId : public magma::RegisterBase {
public:
    DEF_FIELD(3, 0, version_status);
    DEF_FIELD(11, 4, minor_revision);
    DEF_FIELD(15, 12, major_revision);
    DEF_FIELD(31, 16, product_id);

    static auto Get() { return magma::RegisterAddr<GpuId>(0); }
};

class L2Features : public magma::RegisterBase {
public:
    DEF_FIELD(7, 0, log2_line_size);
    DEF_FIELD(15, 8, associativity);
    DEF_FIELD(23, 16, log2_cache_size);
    DEF_FIELD(31, 24, external_bus_width);

    static auto Get() { return magma::RegisterAddr<L2Features>(0x4); }
};

class TilerFeatures : public magma::RegisterBase {
public:
    DEF_FIELD(5, 0, log2_bin_size_bytes);
    DEF_FIELD(11, 8, max_active_levels);

    static auto Get() { return magma::RegisterAddr<TilerFeatures>(0xc); }
};

class MemoryFeatures : public magma::RegisterBase {
public:
    DEF_FIELD(1, 0, groups_l2_coherent);
    DEF_FIELD(11, 8, num_l2_slices_minus1);

    static auto Get() { return magma::RegisterAddr<MemoryFeatures>(0x10); }
};

class MmuFeatures : public magma::RegisterBase {
public:
    DEF_FIELD(7, 0, va_bits);
    DEF_FIELD(15, 8, pa_bits);

    static auto Get() { return magma::RegisterAddr<MmuFeatures>(0x14); }
};

class ThreadFeatures : public magma::RegisterBase {
public:
    DEF_FIELD(15, 0, max_registers);
    DEF_FIELD(23, 16, max_task_queue);
    DEF_FIELD(29, 24, max_thread_group_split);
    DEF_FIELD(31, 30, impl_tech);

    static auto Get() { return magma::RegisterAddr<ThreadFeatures>(0xac); }
};

class CoherencyFeatures : public magma::RegisterBase {
public:
    // ACE-lite lets the GPU snoop on changes made by the CPU
    DEF_BIT(0, ace_lite);

    // ACE lets the GPU and CPU snoop on each other.
    DEF_BIT(1, ace);

    DEF_BIT(31, none);

    static auto GetPresent() { return magma::RegisterAddr<CoherencyFeatures>(0x300); }
    static auto GetEnable() { return magma::RegisterAddr<CoherencyFeatures>(0x304); }
};

class GpuStatus : public magma::RegisterBase {
public:
    DEF_BIT(0, gpu_active);
    DEF_BIT(1, power_active);
    DEF_BIT(2, performance_counters_active);

    static auto Get() { return magma::RegisterAddr<GpuStatus>(0x34); }
};

// May return incorrect value on rollover.
class CycleCount : public magma::RegisterPairBase {
public:
    static auto Get() { return magma::RegisterAddr<CycleCount>(0x90); }
};

// May return incorrect value on rollover.
class Timestamp : public magma::RegisterPairBase {
public:
    static auto Get() { return magma::RegisterAddr<Timestamp>(0x98); }
};

class GpuCommand {
public:
    static constexpr uint32_t kOffset = 0x30;

    enum {
        kCmdNop = 0,
        kCmdSoftReset = 0x1,
        kCmdHardReset = 0x2,
        kCmdClearPerformanceCounters = 0x3,
        kCmdSamplePerformanceCounters = 0x4,
        kCmdCycleCountStart = 0x5,
        kCmdCycleCountStop = 0x6,
        kCmdCleanCaches = 0x7,
        kCmdCleanAndInvalidateCaches = 0x8,
        kCmdSetProtectedMode = 0x9,
    };
};

class GpuIrqFlags : public magma::RegisterBase {
public:
    DEF_BIT(0, gpu_fault);
    DEF_BIT(7, multiple_gpu_faults);
    DEF_BIT(8, reset_completed);
    DEF_BIT(9, power_changed_single);
    DEF_BIT(10, power_changed_all);
    DEF_BIT(16, performance_counter_sample_completed);
    DEF_BIT(17, clean_caches_completed);

    static auto GetRawStat() { return magma::RegisterAddr<GpuIrqFlags>(0x20); }
    static auto GetIrqClear() { return magma::RegisterAddr<GpuIrqFlags>(0x24); }
    static auto GetIrqMask() { return magma::RegisterAddr<GpuIrqFlags>(0x28); }
    static auto GetStatus() { return magma::RegisterAddr<GpuIrqFlags>(0x2c); }
};

class MmuIrqFlags : public magma::RegisterBase {
public:
    DEF_FIELD(15, 0, pf_flags);
    DEF_FIELD(31, 16, bf_flags);

    static auto GetRawStat() { return magma::RegisterAddr<MmuIrqFlags>(0x2000); }
    static auto GetIrqClear() { return magma::RegisterAddr<MmuIrqFlags>(0x2004); }
    static auto GetIrqMask() { return magma::RegisterAddr<MmuIrqFlags>(0x2008); }
    static auto GetStatus() { return magma::RegisterAddr<MmuIrqFlags>(0x200c); }
};

class JobIrqFlags : public magma::RegisterBase {
public:
    DEF_FIELD(15, 0, finished_slots);
    DEF_FIELD(31, 16, failed_slots);

    static auto GetRawStat() { return magma::RegisterAddr<JobIrqFlags>(0x1000); }
    static auto GetIrqClear() { return magma::RegisterAddr<JobIrqFlags>(0x1004); }
    static auto GetIrqMask() { return magma::RegisterAddr<JobIrqFlags>(0x1008); }
    static auto GetStatus() { return magma::RegisterAddr<JobIrqFlags>(0x100c); }
};

class ShaderConfig : public magma::RegisterBase {
public:
    DEF_BIT(17, tls_hashing_enable);

    static auto Get() { return magma::RegisterAddr<ShaderConfig>(0xf04); }
};

// Not legal to write to while the performance counters are enabled.
class PerformanceCounterBase : public magma::RegisterPairBase {
public:
    static auto Get() { return magma::RegisterAddr<PerformanceCounterBase>(0x60); }
};

class PerformanceCounterConfig : public magma::RegisterBase {
public:
    enum Mode {
        kModeDisabled = 0,
        kModeManual = 1,
    };
    DEF_FIELD(3, 0, mode);
    DEF_FIELD(7, 4, address_space);

    static auto Get() { return magma::RegisterAddr<PerformanceCounterConfig>(0x68); }
};

// Not legal to write to while the performance counters are enabled.
class PerformanceCounterJmEnable : public magma::RegisterBase {
public:
    static auto Get() { return magma::RegisterAddr<PerformanceCounterJmEnable>(0x6c); }
};

// Not legal to write to while the performance counters are enabled.
class PerformanceCounterShaderEnable : public magma::RegisterBase {
public:
    static auto Get() { return magma::RegisterAddr<PerformanceCounterShaderEnable>(0x70); }
};

// Not legal to write to while the performance counters are enabled.
class PerformanceCounterTilerEnable : public magma::RegisterBase {
public:
    static auto Get() { return magma::RegisterAddr<PerformanceCounterTilerEnable>(0x74); }
};

// Not legal to write to while the performance counters are enabled.
class PerformanceCounterMmuL2Enable : public magma::RegisterBase {
public:
    static auto Get() { return magma::RegisterAddr<PerformanceCounterMmuL2Enable>(0x7c); }
};

class CoreReadyState {
public:
    enum class CoreType {
        kShader = 0x100,
        kL2 = 0x120,
        kTiler = 0x110,
        kCoreStack = 0xe00,
    };

    enum class StatusType {
        // Read-only: the set of cores that are physically present in the
        // device.
        kPresent = 0,

        // Read-only: the set of cores that are powered on and ready to do
        // work.
        kReady = 0x40,

        // Read-only: the set of cores that are changing power states.
        kPowerTransitioning = 0x100,

        // Read-only: the set of cores that are currently executing work.
        kPowerActive = 0x100,
    };

    enum class ActionType {
        // Write-only: power on the specified set of cores.
        kActionPowerOn = 0x80,

        // Write-only: power off the specified set of cores.
        kActionPowerOff = 0xc0,
    };

    // Returns a bitmask of the cores in a specified state.
    static uint64_t ReadBitmask(magma::RegisterIo* register_io, CoreType core_type,
                                StatusType action_type)
    {
        DASSERT(core_type != CoreType::kCoreStack);

        uint32_t offset = static_cast<uint32_t>(core_type) + static_cast<uint32_t>(action_type);
        return register_io->Read32(offset) |
               (static_cast<uint64_t>(register_io->Read32(offset + 4)) << 32);
    }

    static void WriteState(magma::RegisterIo* register_io, enum CoreType core_type,
                           enum ActionType action_type, uint64_t value)
    {
        uint32_t offset = static_cast<uint32_t>(core_type) + static_cast<uint32_t>(action_type);
        uint32_t value_low = value & 0xffffffff;
        uint32_t value_high = (value >> 32) & 0xffffffff;
        if (value_low)
            register_io->Write32(offset, value_low);
        if (value_high)
            register_io->Write32(offset + 4, value_high);
    }
};

class GpuFaultStatus : public magma::RegisterBase {
public:
    static auto Get() { return magma::RegisterAddr<GpuFaultStatus>(0x3c); }
};

class GpuFaultAddress : public magma::RegisterPairBase {
public:
    static auto Get() { return magma::RegisterAddr<GpuFaultAddress>(0x40); }
};

class AsTranslationTable : public magma::RegisterPairBase {
public:
    static constexpr uint32_t kBaseAddr = 0x0;
};

class AsMemoryAttributes : public magma::RegisterPairBase {
public:
    static constexpr uint32_t kBaseAddr = 0x8;
};

class AsLockAddress : public magma::RegisterPairBase {
public:
    static constexpr uint32_t kBaseAddr = 0x10;
};

class AsCommand : public magma::RegisterBase {
public:
    static constexpr uint32_t kBaseAddr = 0x18;

    enum {
        kCmdNop = 0x0,
        kCmdUpdate = 0x1,
        kCmdLock = 0x2,
        kCmdUnlock = 0x3,
        kCmdFlush = 0x4,
        kCmdFlushPageTable = 0x4,
        kCmdFlushMem = 0x5
    };
};

class AsFaultStatus : public magma::RegisterBase {
public:
    static constexpr uint32_t kBaseAddr = 0x1c;
};

class AsFaultAddress : public magma::RegisterPairBase {
public:
    static constexpr uint32_t kBaseAddr = 0x20;
};

class AsStatus : public magma::RegisterBase {
public:
    static constexpr uint32_t kBaseAddr = 0x28;
};

class AsTransConfig : public magma::RegisterPairBase {
public:
    static constexpr uint32_t kBaseAddr = 0x30;
};

class AsFaultExtra : public magma::RegisterPairBase {
public:
    static constexpr uint32_t kBaseAddr = 0x30;
};

class AsRegisters {
public:
    static constexpr uint32_t kBaseAddr = 0x2400;
    static constexpr uint32_t kAsStride = 0x40;

    // Maximum registers.
    static constexpr uint32_t kAddressSpacesCount = 16;

    AsRegisters(uint32_t address_space) : address_space_(address_space)
    {
        DASSERT(address_space < kAddressSpacesCount);
    }

    uint32_t address_space() const { return address_space_; }

    auto TranslationTable() { return GetReg<registers::AsTranslationTable>(); }
    auto MemoryAttributes() { return GetReg<registers::AsMemoryAttributes>(); }
    auto LockAddress() { return GetReg<registers::AsLockAddress>(); }
    auto Command() { return GetReg<registers::AsCommand>(); }
    auto FaultStatus() { return GetReg<registers::AsFaultStatus>(); }
    auto FaultAddress() { return GetReg<registers::AsFaultAddress>(); }
    auto Status() { return GetReg<registers::AsStatus>(); }
    auto TransConfig() { return GetReg<registers::AsTransConfig>(); }
    auto FaultExtra() { return GetReg<registers::AsFaultExtra>(); }

private:
    template <class RegType> magma::RegisterAddr<RegType> GetReg()
    {
        return magma::RegisterAddr<RegType>(RegType::kBaseAddr + kBaseAddr +
                                            kAsStride * address_space_);
    }

    uint32_t address_space_;
};

class JobSlotConfig : public magma::RegisterBase {
public:
    static constexpr uint32_t kBaseAddr = 0x18;
    static constexpr uint32_t kBaseAddrNext = 0x58;

    DEF_FIELD(7, 0, address_space);
    DEF_BIT(8, start_flush_clean);
    DEF_BIT(9, start_flush_invalidate);
    DEF_BIT(10, start_mmu);
    DEF_BIT(11, job_chain_flag);
    DEF_BIT(12, end_flush_clean);
    DEF_BIT(13, end_flush_invalidate);
    DEF_BIT(14, enable_flush_reduction);
    DEF_BIT(15, disable_descriptor_write_back);
    DEF_FIELD(23, 16, thread_priority);
};

class JobSlotHead : public magma::RegisterPairBase {
public:
    static constexpr uint32_t kBaseAddr = 0x00;
    static constexpr uint32_t kBaseAddrNext = 0x40;
};

class JobSlotAffinity : public magma::RegisterPairBase {
public:
    static constexpr uint32_t kBaseAddr = 0x10;
    static constexpr uint32_t kBaseAddrNext = 0x50;
};

class JobSlotXAffinity : public magma::RegisterBase {
public:
    static constexpr uint32_t kBaseAddr = 0x1c;
    static constexpr uint32_t kBaseAddrNext = 0x5c;
};

class JobSlotCommand : public magma::RegisterBase {
public:
    static constexpr uint32_t kCommandNop = 0x0;
    static constexpr uint32_t kCommandStart = 0x1;
    static constexpr uint32_t kCommandSoftStop = 0x2;
    static constexpr uint32_t kCommandHardStop = 0x3;
    static constexpr uint32_t kCommandSoftStop_0 = 0x4;
    static constexpr uint32_t kCommandHardStop_0 = 0x5;
    static constexpr uint32_t kCommandStopStop_1 = 0x6;
    static constexpr uint32_t kCommandHardStop_1 = 0x7;

    static constexpr uint32_t kBaseAddr = 0x20;
    static constexpr uint32_t kBaseAddrNext = 0x60;
};

class JobSlotStatus : public magma::RegisterBase {
public:
    static constexpr uint32_t kBaseAddr = 0x24;
};

class JobSlotTail : public magma::RegisterPairBase {
public:
    static constexpr uint32_t kBaseAddr = 0x08;
};

class JobSlotFlushId : public magma::RegisterBase {
public:
    static constexpr uint32_t kBaseAddrNext = 0x70;
};

class JobSlotRegisters {
public:
    static constexpr uint32_t kBaseAddr = 0x1000 + 0x800;
    static constexpr uint32_t kJobSlotStride = 0x80;

    // Maximum registers - actual hardware provides fewer.
    static constexpr uint32_t kJobSlotsCount = 16;

    JobSlotRegisters(uint32_t job_slot) : job_slot_(job_slot)
    {
        DASSERT(job_slot < kJobSlotsCount);
    }

    // These registers are for the currently executing job.
    auto Head() { return GetReg<registers::JobSlotHead>(); }
    auto Tail() { return GetReg<registers::JobSlotTail>(); }
    auto Status() { return GetReg<registers::JobSlotStatus>(); }
    auto Config() { return GetReg<registers::JobSlotConfig>(); }
    auto Affinity() { return GetReg<registers::JobSlotAffinity>(); }
    auto XAffinity() { return GetReg<registers::JobSlotXAffinity>(); }
    auto Command() { return GetReg<registers::JobSlotCommand>(); }

    // These registers are for the next job to execute. It can start executing
    // once the start command is sent.
    auto HeadNext() { return GetRegNext<registers::JobSlotHead>(); }
    auto ConfigNext() { return GetRegNext<registers::JobSlotConfig>(); }
    auto AffinityNext() { return GetRegNext<registers::JobSlotAffinity>(); }
    auto XAffinityNext() { return GetRegNext<registers::JobSlotXAffinity>(); }
    auto CommandNext() { return GetRegNext<registers::JobSlotCommand>(); }

private:
    template <class RegType> magma::RegisterAddr<RegType> GetRegNext()
    {
        return magma::RegisterAddr<RegType>(RegType::kBaseAddrNext + kBaseAddr +
                                            kJobSlotStride * job_slot_);
    }

    template <class RegType> magma::RegisterAddr<RegType> GetReg()
    {
        return magma::RegisterAddr<RegType>(RegType::kBaseAddr + kBaseAddr +
                                            kJobSlotStride * job_slot_);
    }

    uint32_t job_slot_;
};

} // namespace registers

#endif // REGISTERS_H
