blob: ce464df76cb144ef59e8fd906db85b9512acd64c [file] [log] [blame]
// Copyright 2024 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 SRC_DEVICES_CLOCK_DRIVERS_VIM3_CLK_MESON_GATE_H_
#define SRC_DEVICES_CLOCK_DRIVERS_VIM3_CLK_MESON_GATE_H_
#include <lib/mmio/mmio.h>
#include <zircon/assert.h>
#include <cstdint>
#include <optional>
namespace vim3_clock {
enum class RegisterBank { Hiu, Dos };
using meson_gate_descriptor_t = struct meson_gate_descriptor {
const uint32_t id;
const uint32_t offset;
const uint32_t mask;
const RegisterBank bank;
};
class MesonGate {
public:
MesonGate(uint32_t id, uint32_t offset, uint32_t mask, fdf::MmioView mmio)
: id_(id), offset_(offset), mask_(mask), mmio_(mmio) {}
void Enable();
void Disable();
private:
void EnableHw();
void DisableHw();
// Number of times Enable has been called on this clock.
// Clock is enabled iff `vote_count_` is greater than 0.
int vote_count_ = 0;
const uint32_t id_;
const uint32_t offset_;
const uint32_t mask_;
fdf::MmioView mmio_;
};
constexpr uint32_t kG12bHhiSysCpuClkCntl1 = (0x57 << 2);
constexpr uint32_t kG12bHhiSysCpubClkCntl1 = (0x80 << 2);
constexpr uint32_t kG12bHhiSysCpubClkCntl = (0x82 << 2);
constexpr uint32_t kG12bHhiTsClkCntl = (0x64 << 2);
constexpr uint32_t kG12bHhiXtalDivnCntl = (0x2f << 2);
constexpr uint32_t kG12bDosGclkEn0 = (0x3f01 << 2);
constexpr uint32_t kG12bHhiGclkMpeg0 = (0x50 << 2);
constexpr uint32_t kG12bHhiGclkMpeg1 = (0x51 << 2);
constexpr uint32_t kG12bHhiGclkMpeg2 = (0x52 << 2);
constexpr uint32_t kHhiSysCpuClkCntl0 = (0x67 << 2);
// clang-format off
static constexpr meson_gate_descriptor_t kGateDescriptors[] = {
// Sys CPU Clock Gates
{.id = 0, .offset = kG12bHhiSysCpuClkCntl1, .mask=(1 << 24), .bank=RegisterBank::Hiu},
{.id = 1, .offset = kG12bHhiSysCpuClkCntl1, .mask=(1 << 1), .bank=RegisterBank::Hiu},
{.id = 2, .offset = kG12bHhiXtalDivnCntl, .mask=(1 << 11), .bank=RegisterBank::Hiu},
// Sys CPUB Clock Gates
{.id = 3, .offset = kG12bHhiSysCpubClkCntl1, .mask=(1 << 24), .bank=RegisterBank::Hiu},
{.id = 4, .offset = kG12bHhiSysCpubClkCntl1, .mask=(1 << 1), .bank=RegisterBank::Hiu},
// Graphics
{.id = 5, .offset = kG12bDosGclkEn0, .mask= 0x3ff, .bank=RegisterBank::Dos},
{.id = 6, .offset = kG12bDosGclkEn0, .mask=(0x7fff << 12), .bank=RegisterBank::Dos},
// MPeg 0 DOS
{.id = 7, .offset = kG12bHhiGclkMpeg0, .mask=(1 << 1), .bank=RegisterBank::Hiu},
// USB Gates
{.id = 8, .offset = kG12bHhiGclkMpeg1, .mask=(1 << 26), .bank=RegisterBank::Hiu},
{.id = 9, .offset = kG12bHhiGclkMpeg2, .mask=(1 << 8), .bank=RegisterBank::Hiu},
{.id = 10, .offset = kG12bHhiXtalDivnCntl, .mask=(1 << 12), .bank=RegisterBank::Hiu},
{.id = 11, .offset = kG12bHhiGclkMpeg1, .mask=(1 << 0), .bank=RegisterBank::Hiu},
{.id = 12, .offset = kG12bHhiGclkMpeg0, .mask=(1 << 26), .bank=RegisterBank::Hiu},
// Temp Sensors
{.id = 13, .offset = kG12bHhiTsClkCntl, .mask=(1 << 8), .bank=RegisterBank::Hiu},
};
// clang-format on
} // namespace vim3_clock
#endif // SRC_DEVICES_CLOCK_DRIVERS_VIM3_CLK_MESON_GATE_H_