// 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. #pragma once #include #include #include "registers-ddi.h" namespace registers { static constexpr uint32_t kDpllCount = 4; enum Dpll { DPLL_INVALID = -1, DPLL_0 = 0, DPLL_1, DPLL_2, DPLL_3, }; static const Dpll kDplls[kDpllCount] = { DPLL_0, DPLL_1, DPLL_2, DPLL_3, }; // DPLL_CTRL1 class DpllControl1 : public hwreg::RegisterBase { public: hwreg::BitfieldRef dpll_hdmi_mode(Dpll dpll) { int bit = dpll * 6 + 5; return hwreg::BitfieldRef(reg_value_ptr(), bit, bit); } hwreg::BitfieldRef dpll_ssc_enable(Dpll dpll) { int bit = dpll * 6 + 4; return hwreg::BitfieldRef(reg_value_ptr(), bit, bit); } hwreg::BitfieldRef dpll_link_rate(Dpll dpll) { int bit = dpll * 6 + 1; return hwreg::BitfieldRef(reg_value_ptr(), bit + 2, bit); } static constexpr int kLinkRate2700Mhz = 0; // DisplayPort 5.4 GHz static constexpr int kLinkRate1350Mhz = 1; // DisplayPort 2.7 GHz static constexpr int kLinkRate810Mhz = 2; // DisplayPort 1.62 GHz static constexpr int kLinkRate1620Mhz = 3; // DisplayPort 3.24 GHz static constexpr int kLinkRate1080Mhz = 4; // DisplayPort 2.16 GHz static constexpr int kLinkRate2160Mhz = 5; // DisplayPort 4.32 GHz hwreg::BitfieldRef dpll_override(Dpll dpll) { int bit = dpll * 6; return hwreg::BitfieldRef(reg_value_ptr(), bit, bit); } static auto Get() { return hwreg::RegisterAddr(0x6c058); } }; // DPLL_CTRL2 class DpllControl2 : public hwreg::RegisterBase { public: hwreg::BitfieldRef ddi_clock_off(Ddi ddi) { int bit = 15 + ddi; return hwreg::BitfieldRef(reg_value_ptr(), bit, bit); } hwreg::BitfieldRef ddi_clock_select(Ddi ddi) { int bit = ddi * 3 + 1; return hwreg::BitfieldRef(reg_value_ptr(), bit + 1, bit); } hwreg::BitfieldRef ddi_select_override(Ddi ddi) { int bit = ddi * 3; return hwreg::BitfieldRef(reg_value_ptr(), bit, bit); } static auto Get() { return hwreg::RegisterAddr(0x6c05c); } }; // DPLL_CFGCR1 class DpllConfig1 : public hwreg::RegisterBase { public: DEF_BIT(31, frequency_enable); DEF_FIELD(23, 9, dco_fraction); DEF_FIELD(8, 0, dco_integer); static auto Get(Dpll dpll) { ZX_ASSERT(dpll == DPLL_1 || dpll == DPLL_2 || dpll == DPLL_3); return hwreg::RegisterAddr(0x6c040 + ((dpll - 1) * 8)); } }; // DPLL_CFGCR2 class DpllConfig2 : public hwreg::RegisterBase { public: DEF_FIELD(15, 8, qdiv_ratio); DEF_BIT(7, qdiv_mode); DEF_FIELD(6, 5, kdiv_ratio); static constexpr uint8_t kKdiv5 = 0; static constexpr uint8_t kKdiv2 = 1; static constexpr uint8_t kKdiv3 = 2; static constexpr uint8_t kKdiv1 = 3; DEF_FIELD(4, 2, pdiv_ratio); static constexpr uint8_t kPdiv1 = 0; static constexpr uint8_t kPdiv2 = 1; static constexpr uint8_t kPdiv3 = 2; static constexpr uint8_t kPdiv7 = 4; DEF_FIELD(1, 0, central_freq); static constexpr uint8_t k9600Mhz = 0; static constexpr uint8_t k9000Mhz = 1; static constexpr uint8_t k8400Mhz = 3; static auto Get(int dpll) { ZX_ASSERT(dpll == DPLL_1 || dpll == DPLL_2 || dpll == DPLL_3); return hwreg::RegisterAddr(0x6c044 + ((dpll - 1) * 8)); } }; // Virtual register which unifies the dpll enable bits (which are spread // across 4 registers) class DpllEnable : public hwreg::RegisterBase { public: DEF_BIT(31, enable_dpll); static auto Get(Dpll dpll) { if (dpll == 0) { return hwreg::RegisterAddr(0x46010); // LCPLL1_CTL } else if (dpll == 1) { return hwreg::RegisterAddr(0x46014); // LCPLL2_CTL } else if (dpll == 2) { return hwreg::RegisterAddr(0x46040); // WRPLL_CTL1 } else { // dpll == 3 return hwreg::RegisterAddr(0x46060); // WRPLL_CTL2 } } }; // DPLL_STATUS class DpllStatus : public hwreg::RegisterBase { public: hwreg::BitfieldRef dpll_lock(Dpll dpll) { int bit = dpll * 8; return hwreg::BitfieldRef(reg_value_ptr(), bit, bit); } static auto Get() { return hwreg::RegisterAddr(0x6c060); } }; // LCPLL1_CTL class Lcpll1Control : public hwreg::RegisterBase { public: DEF_BIT(30, pll_lock); static auto Get() { return hwreg::RegisterAddr(0x46010); } }; } // namespace registers