| // Copyright 2018 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_GRAPHICS_DISPLAY_DRIVERS_AMLOGIC_DISPLAY_RDMA_REGS_H_ |
| #define SRC_GRAPHICS_DISPLAY_DRIVERS_AMLOGIC_DISPLAY_RDMA_REGS_H_ |
| |
| #include <lib/mmio/mmio-buffer.h> |
| |
| #include <cstdint> |
| |
| #include <hwreg/bitfields.h> |
| |
| // The register definitions here are from AMLogic S912 Datasheet revision 0.1. |
| // The information was cross-checked against AMLogic's VLSI GXL RDMA |
| // Specification, Version 1.0, dated September 26, 2018. |
| |
| // The RDMA (Register Direct Memory Access) is briefly described in the S912 |
| // Datasheet section 27.3 "Video Output" > "RDMA". |
| // |
| // The A311D datasheet Section 10.2.1 "Video Output" > "Overview" mentions that |
| // the VPU includes an RDMA submodule, but does not list the registers. Our |
| // experiments and passing tests indicate that the RDMA functionality we use is |
| // unchanged. |
| |
| // Register addresses from the S912 datasheet section 27.3 "RDMA", Table |
| // IV.29.3 "Register List of RDMA". The table specifies absolute addresses, but |
| // the addresses are relative to the VPU's MMIO block. S912 datasheet section |
| // 16 "Memory Map" indicates that the S912's VPU's MMIO block starts at |
| // 0xd0100000. |
| #define VPU_RDMA_AHB_START_ADDR_MAN 0x4400 |
| #define VPU_RDMA_AHB_END_ADDR_MAN 0x4404 |
| #define VPU_RDMA_AHB_START_ADDR_1 0x4408 |
| #define VPU_RDMA_AHB_END_ADDR_1 0x440c |
| #define VPU_RDMA_AHB_START_ADDR_2 0x4410 |
| #define VPU_RDMA_AHB_END_ADDR_2 0x4414 |
| #define VPU_RDMA_AHB_START_ADDR_3 0x4418 |
| #define VPU_RDMA_AHB_END_ADDR_3 0x441c |
| #define VPU_RDMA_AHB_START_ADDR_4 0x4420 |
| #define VPU_RDMA_AHB_END_ADDR_4 0x4424 |
| #define VPU_RDMA_AHB_START_ADDR_5 0x4428 |
| #define VPU_RDMA_AHB_END_ADDR_5 0x442c |
| #define VPU_RDMA_AHB_START_ADDR_6 0x4430 |
| #define VPU_RDMA_AHB_END_ADDR_6 0x4434 |
| #define VPU_RDMA_AHB_START_ADDR_7 0x4438 |
| #define VPU_RDMA_AHB_END_ADDR_7 0x443c |
| #define VPU_RDMA_ACCESS_AUTO 0x4440 |
| #define VPU_RDMA_ACCESS_AUTO2 0x4444 |
| #define VPU_RDMA_ACCESS_AUTO3 0x4448 |
| #define VPU_RDMA_ACCESS_MAN 0x444c |
| #define VPU_RDMA_CTRL 0x4450 |
| #define VPU_RDMA_STATUS 0x4454 |
| #define VPU_RDMA_STATUS2 0x4458 |
| #define VPU_RDMA_STATUS3 0x445c |
| |
| #define VPU_RDMA_AHB_START_ADDR(x) (VPU_RDMA_AHB_START_ADDR_MAN + ((x) << 3)) |
| #define VPU_RDMA_AHB_END_ADDR(x) (VPU_RDMA_AHB_END_ADDR_MAN + ((x) << 3)) |
| |
| // VPU_RDMA_ACCESS_AUTO Bit Definition |
| #define RDMA_ACCESS_AUTO_INT_EN(channel) (1 << ((channel) << 3)) |
| #define RDMA_ACCESS_AUTO_WRITE(channel) (1 << ((channel) + 4)) |
| |
| // VPU_RDMA_CTRL Bit Definition |
| #define RDMA_CTRL_INT_DONE(channel) (1 << (channel)) |
| |
| // VPU_RDMA_STATUS Bit Definition |
| #define RDMA_STATUS_DONE(channel) (1 << (channel)) |
| |
| class RdmaStatusReg : public hwreg::RegisterBase<RdmaStatusReg, uint32_t> { |
| public: |
| // Both of these fields use bit 0 for manual RDMA. Auto RDMA is 1-indexed. |
| DEF_FIELD(31, 24, done); |
| DEF_FIELD(7, 0, req_latch); |
| static auto Get() { return hwreg::RegisterAddr<RdmaStatusReg>(VPU_RDMA_STATUS); } |
| |
| bool RequestLatched(uint8_t chan) const { return req_latch() & (1 << chan); } |
| |
| bool ChannelDone(uint8_t chan) const { return done() & (1 << chan); } |
| |
| static bool ChannelDone(uint8_t chan, fdf::MmioBuffer* mmio) { |
| return Get().ReadFrom(mmio).ChannelDone(chan); |
| } |
| |
| // compute a value for .done() to match given the current state of |
| // VPU_RDMA_ACCESS_AUTO, AUTO2, and AUTO3. |
| static uint32_t DoneFromAccessAuto(const uint32_t aa, const uint32_t aa2, const uint32_t aa3) { |
| const uint32_t chn7 = ((aa3 >> 24) & 0x1) << 7; |
| const uint32_t chn2 = ((aa >> 24) & 0x1) << 2; |
| const uint32_t chn1 = ((aa >> 16) & 0x1) << 1; |
| const uint32_t chn0 = ((aa >> 8) & 0x1) << 0; |
| return chn7 | chn2 | chn1 | chn0; |
| } |
| }; |
| |
| class RdmaCtrlReg : public hwreg::RegisterBase<RdmaCtrlReg, uint32_t> { |
| public: |
| // As with RDMA_STATUS, this field uses bit 0 for manual RDMA. |
| DEF_FIELD(31, 24, clear_done); |
| DEF_BIT(7, write_urgent); |
| DEF_BIT(6, read_urgent); |
| static auto Get() { return hwreg::RegisterAddr<RdmaCtrlReg>(VPU_RDMA_CTRL); } |
| |
| static void ClearInterrupt(uint8_t chan, fdf::MmioBuffer* mmio) { |
| Get().ReadFrom(mmio).set_clear_done(1 << chan).WriteTo(mmio); |
| } |
| }; |
| |
| class RdmaAccessAutoReg : public hwreg::RegisterBase<RdmaAccessAutoReg, uint32_t> { |
| public: |
| DEF_FIELD(31, 24, chn3_intr); |
| DEF_FIELD(23, 16, chn2_intr); |
| DEF_FIELD(15, 8, chn1_intr); |
| DEF_BIT(7, chn3_auto_write); |
| DEF_BIT(6, chn2_auto_write); |
| DEF_BIT(5, chn1_auto_write); |
| static auto Get() { return hwreg::RegisterAddr<RdmaAccessAutoReg>(VPU_RDMA_ACCESS_AUTO); } |
| }; |
| |
| class RdmaAccessAuto2Reg : public hwreg::RegisterBase<RdmaAccessAuto2Reg, uint32_t> { |
| public: |
| DEF_BIT(7, chn7_auto_write); |
| static auto Get() { return hwreg::RegisterAddr<RdmaAccessAuto2Reg>(VPU_RDMA_ACCESS_AUTO2); } |
| }; |
| |
| class RdmaAccessAuto3Reg : public hwreg::RegisterBase<RdmaAccessAuto3Reg, uint32_t> { |
| public: |
| DEF_FIELD(31, 24, chn7_intr); |
| static auto Get() { return hwreg::RegisterAddr<RdmaAccessAuto3Reg>(VPU_RDMA_ACCESS_AUTO3); } |
| }; |
| |
| #endif // SRC_GRAPHICS_DISPLAY_DRIVERS_AMLOGIC_DISPLAY_RDMA_REGS_H_ |