// 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 "registers-pipe.h" namespace registers { static constexpr uint32_t kTransCount = 4; enum Trans { TRANS_A, TRANS_B, TRANS_C, TRANS_EDP }; static const Trans kTrans[kTransCount] = { TRANS_A, TRANS_B, TRANS_C, TRANS_EDP, }; // TRANS_HTOTAL, TRANS_HBLANK, // TRANS_VTOTAL, TRANS_VBLANK class TransHVTotal : public hwreg::RegisterBase { public: DEF_FIELD(28, 16, count_total); // same as blank_start DEF_FIELD(12, 0, count_active); // same as blank_end }; // TRANS_HSYNC, TRANS_VSYNC class TransHVSync : public hwreg::RegisterBase { public: DEF_FIELD(28, 16, sync_end); DEF_FIELD(12, 0, sync_start); }; // TRANS_DDI_FUNC_CTL class TransDdiFuncControl : public hwreg::RegisterBase { public: DEF_BIT(31, trans_ddi_function_enable); DEF_FIELD(30, 28, ddi_select); DEF_FIELD(26, 24, trans_ddi_mode_select); static constexpr uint32_t kModeHdmi = 0; static constexpr uint32_t kModeDvi = 1; static constexpr uint32_t kModeDisplayPortSst = 2; static constexpr uint32_t kModeDisplayPortMst = 3; DEF_FIELD(22, 20, bits_per_color); static constexpr uint32_t k8bbc = 0; static constexpr uint32_t k10bbc = 1; static constexpr uint32_t k6bbc = 2; static constexpr uint32_t k12bbc = 3; DEF_FIELD(19, 18, port_sync_mode_master_select); DEF_FIELD(17, 16, sync_polarity); DEF_BIT(15, port_sync_mode_enable); DEF_FIELD(14, 12, edp_input_select); static constexpr uint32_t kPipeA = 0; static constexpr uint32_t kPipeB = 5; static constexpr uint32_t kPipeC = 6; DEF_BIT(8, dp_vc_payload_allocate); DEF_FIELD(3, 1, dp_port_width_selection); }; // TRANS_CONF class TransConf : public hwreg::RegisterBase { public: DEF_BIT(31, transcoder_enable); DEF_BIT(30, transcoder_state); DEF_FIELD(22, 21, interlaced_mode); }; // TRANS_CLK_SEL class TransClockSelect : public hwreg::RegisterBase { public: DEF_FIELD(31, 29, trans_clock_select); }; // DATAM class TransDataM : public hwreg::RegisterBase { public: DEF_FIELD(30, 25, tu_or_vcpayload_size); DEF_FIELD(23, 0, data_m_value); }; // DATAN class TransDataN : public hwreg::RegisterBase { public: DEF_FIELD(23, 0, data_n_value); }; // LINKM1 class TransLinkM : public hwreg::RegisterBase { public: DEF_FIELD(23, 0, link_m_value); }; // LINKN1 class TransLinkN : public hwreg::RegisterBase { public: DEF_FIELD(23, 0, link_n_value); }; // TRANS_MSA_MISC class TransMsaMisc : public hwreg::RegisterBase { public: // Byte 1 is MISC1 from DP spec DEF_FIELD(10, 9, stereo_video); DEF_BIT(8, interlaced_vertical_total_even); // Byte 0 is MISC0 from DP spec DEF_FIELD(7, 5, bits_per_color); static constexpr uint32_t k6Bbc = 0; static constexpr uint32_t k8Bbc = 1; static constexpr uint32_t k10Bbc = 2; static constexpr uint32_t k12Bbc = 3; static constexpr uint32_t k16Bbc = 4; DEF_BIT(4, colorimetry); DEF_BIT(3, dynamic_range); DEF_FIELD(2, 1, color_format); static constexpr uint32_t kRgb = 0; static constexpr uint32_t kYcbCr422 = 1; static constexpr uint32_t kYcbCr444 = 2; DEF_BIT(0, sync_clock); }; class TranscoderRegs { public: TranscoderRegs(Trans trans) : trans_(trans) { offset_ = trans == TRANS_EDP ? 0xf000 : (trans * 0x1000); } hwreg::RegisterAddr HTotal() { return GetReg(0x60000); } hwreg::RegisterAddr HBlank() { return GetReg(0x60004); } hwreg::RegisterAddr HSync() { return GetReg(0x60008); } hwreg::RegisterAddr VTotal() { return GetReg(0x6000c); } hwreg::RegisterAddr VBlank() { return GetReg(0x60010); } hwreg::RegisterAddr VSync() { return GetReg(0x60014); } hwreg::RegisterAddr DdiFuncControl() { return GetReg(0x60400); } hwreg::RegisterAddr Conf() { return GetReg(0x70008); } hwreg::RegisterAddr ClockSelect() { ZX_ASSERT(trans_ != TRANS_EDP); // This uses a different offset from the other transcoder registers. return hwreg::RegisterAddr(0x46140 + trans_ * 4); } hwreg::RegisterAddr DataM() { return GetReg(0x60030); } hwreg::RegisterAddr DataN() { return GetReg(0x60034); } hwreg::RegisterAddr LinkM() { return GetReg(0x60040); } hwreg::RegisterAddr LinkN() { return GetReg(0x60044); } hwreg::RegisterAddr MsaMisc() { return GetReg(0x60410); } private: template hwreg::RegisterAddr GetReg(uint32_t base_addr) { return hwreg::RegisterAddr(base_addr + offset_); } Trans trans_; uint32_t offset_; }; } // namespace registers