blob: f7172445464fed1d428d8ab21b499f393e9bb5c8 [file] [log] [blame]
// 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 <assert.h>
#include <ddk/protocol/display-controller.h>
#include <ddk/protocol/intel-gpu-core.h>
#include <hwreg/bitfields.h>
#include <zircon/pixelformat.h>
namespace registers {
// Number of pipes that the hardware provides.
static constexpr uint32_t kPipeCount = 3;
enum Pipe { PIPE_A, PIPE_B, PIPE_C };
static const Pipe kPipes[kPipeCount] = {
PIPE_A, PIPE_B, PIPE_C,
};
static constexpr uint32_t kPrimaryPlaneCount = 3;
// PIPE_SRCSZ
class PipeSourceSize : public hwreg::RegisterBase<PipeSourceSize, uint32_t> {
public:
static constexpr uint32_t kBaseAddr = 0x6001c;
DEF_FIELD(28, 16, horizontal_source_size);
DEF_FIELD(11, 0, vertical_source_size);
};
// PLANE_SURF
class PlaneSurface : public hwreg::RegisterBase<PlaneSurface, uint32_t> {
public:
static constexpr uint32_t kBaseAddr = 0x7019c;
// This field omits the lower 12 bits of the address, so the address
// must be 4k-aligned.
static constexpr uint32_t kPageShift = 12;
DEF_FIELD(31, 12, surface_base_addr);
static constexpr uint32_t kRShiftCount = 12;
static constexpr uint32_t kLinearAlignment = 256 * 1024;
static constexpr uint32_t kXTilingAlignment = 256 * 1024;
static constexpr uint32_t kYTilingAlignment = 1024 * 1024;
DEF_BIT(3, ring_flip_source);
};
// PLANE_SURFLIVE
class PlaneSurfaceLive : public hwreg::RegisterBase<PlaneSurfaceLive, uint32_t> {
public:
static constexpr uint32_t kBaseAddr = 0x701ac;
// This field omits the lower 12 bits of the address, so the address
// must be 4k-aligned.
static constexpr uint32_t kPageShift = 12;
DEF_FIELD(31, 12, surface_base_addr);
};
// PLANE_STRIDE
class PlaneSurfaceStride : public hwreg::RegisterBase<PlaneSurfaceStride, uint32_t> {
public:
static constexpr uint32_t kBaseAddr = 0x70188;
DEF_FIELD(9, 0, stride);
};
// PLANE_SIZE
class PlaneSurfaceSize : public hwreg::RegisterBase<PlaneSurfaceSize, uint32_t> {
public:
static constexpr uint32_t kBaseAddr = 0x70190;
DEF_FIELD(27, 16, height_minus_1);
DEF_FIELD(12, 0, width_minus_1);
};
// PLANE_CTL
class PlaneControl : public hwreg::RegisterBase<PlaneControl, uint32_t> {
public:
static constexpr uint32_t kBaseAddr = 0x70180;
DEF_BIT(31, plane_enable);
DEF_BIT(30, pipe_gamma_enable);
DEF_BIT(29, remove_yuv_offset);
DEF_BIT(28, yuv_range_correction_disable);
DEF_FIELD(27, 24, source_pixel_format);
static constexpr uint32_t kFormatRgb8888 = 4;
DEF_BIT(23, pipe_csc_enable);
DEF_FIELD(22, 21, key_enable);
DEF_BIT(20, rgb_color_order);
DEF_BIT(19, plane_yuv_to_rgb_csc_dis);
DEF_BIT(18, plane_yuv_to_rgb_csc_format);
DEF_FIELD(17, 16, yuv_422_byte_order);
DEF_BIT(15, render_decompression);
DEF_BIT(14, trickle_feed_enable);
DEF_BIT(13, plane_gamma_disable);
DEF_FIELD(12, 10, tiled_surface);
static constexpr uint32_t kLinear = 0;
static constexpr uint32_t kTilingX = 1;
static constexpr uint32_t kTilingYLegacy = 4;
static constexpr uint32_t kTilingYF = 5;
DEF_BIT(9, async_address_update_enable);
DEF_FIELD(7, 6, stereo_surface_vblank_mask);
DEF_FIELD(5, 4, alpha_mode);
DEF_BIT(3, allow_double_buffer_update_disable);
DEF_FIELD(1, 0, plane_rotation);
static constexpr uint32_t kIdentity = 0;
static constexpr uint32_t k90deg = 1;
static constexpr uint32_t k180deg = 2;
static constexpr uint32_t k270deg = 3;
};
// PLANE_BUF_CFG
class PlaneBufCfg : public hwreg::RegisterBase<PlaneBufCfg, uint32_t> {
public:
static constexpr uint32_t kBaseAddr = 0x7017c;
static constexpr uint32_t kBufferCount = 892;
DEF_FIELD(25, 16, buffer_end);
DEF_FIELD(9, 0, buffer_start);
};
// PLANE_WM
class PlaneWm : public hwreg::RegisterBase<PlaneWm, uint32_t> {
public:
static constexpr uint32_t kBaseAddr = 0x70140;
DEF_BIT(31, enable);
DEF_FIELD(18, 14, lines);
DEF_FIELD(9, 0, blocks);
};
// PS_CTRL
class PipeScalerCtrl : public hwreg::RegisterBase<PipeScalerCtrl, uint32_t> {
public:
static constexpr uint32_t kBaseAddr = 0x68180;
DEF_BIT(31, enable);
};
// PS_WIN_SIZE
class PipeScalerWinSize : public hwreg::RegisterBase<PipeScalerWinSize, uint32_t> {
public:
static constexpr uint32_t kBaseAddr = 0x68174;
DEF_FIELD(28, 16, x_size);
DEF_FIELD(11, 0, y_size);
};
// DE_PIPE_INTERRUPT
class PipeDeInterrupt : public hwreg::RegisterBase<PipeDeInterrupt, uint32_t> {
public:
DEF_BIT(1, vsync);
};
// PLANE_OFFSET
class PlaneOffset : public hwreg::RegisterBase<PlaneOffset, uint32_t> {
public:
static constexpr uint32_t kBaseAddr = 0x701a4;
DEF_FIELD(28, 16, start_y);
DEF_FIELD(12, 0, start_x);
};
// PLANE_POS
class PlanePosition : public hwreg::RegisterBase<PlanePosition, uint32_t> {
public:
static constexpr uint32_t kBaseAddr = 0x7018c;
DEF_FIELD(28, 16, y_pos);
DEF_FIELD(12, 0, x_pos);
};
// An instance of PipeRegs represents the registers for a particular pipe.
class PipeRegs {
public:
static constexpr uint32_t kStatusReg = 0x44400;
static constexpr uint32_t kMaskReg = 0x44404;
static constexpr uint32_t kIdentityReg = 0x44408;
static constexpr uint32_t kEnableReg = 0x4440c;
PipeRegs(Pipe pipe) : pipe_(pipe) { }
hwreg::RegisterAddr<registers::PipeSourceSize> PipeSourceSize() {
return GetReg<registers::PipeSourceSize>();
}
hwreg::RegisterAddr<registers::PlaneSurface> PlaneSurface(int32_t plane_num) {
return GetPlaneReg<registers::PlaneSurface>(plane_num);
}
hwreg::RegisterAddr<registers::PlaneSurfaceLive> PlaneSurfaceLive(int32_t plane_num) {
return GetPlaneReg<registers::PlaneSurfaceLive>(plane_num);
}
hwreg::RegisterAddr<registers::PlaneSurfaceStride> PlaneSurfaceStride(int32_t plane_num) {
return GetPlaneReg<registers::PlaneSurfaceStride>(plane_num);
}
hwreg::RegisterAddr<registers::PlaneSurfaceSize> PlaneSurfaceSize(int32_t plane_num) {
return GetPlaneReg<registers::PlaneSurfaceSize>(plane_num);
}
hwreg::RegisterAddr<registers::PlaneControl> PlaneControl(int32_t plane_num) {
return GetPlaneReg<registers::PlaneControl>(plane_num);
}
hwreg::RegisterAddr<registers::PlaneOffset> PlaneOffset(int32_t plane_num) {
return GetPlaneReg<registers::PlaneOffset>(plane_num);
}
hwreg::RegisterAddr<registers::PlanePosition> PlanePosition(int32_t plane_num) {
return GetPlaneReg<registers::PlanePosition>(plane_num);
}
// 0 == cursor, 1-3 are regular planes
hwreg::RegisterAddr<registers::PlaneBufCfg> PlaneBufCfg(int plane) {
return hwreg::RegisterAddr<registers::PlaneBufCfg>(
PlaneBufCfg::kBaseAddr + 0x1000 * pipe_ + 0x100 * plane);
}
hwreg::RegisterAddr<registers::PlaneWm>PlaneWatermark(int plane, int wm_num) {
return hwreg::RegisterAddr<PlaneWm>(
PlaneWm::kBaseAddr + 0x1000 * pipe_ + 0x100 * plane + 4 * wm_num);
}
hwreg::RegisterAddr<registers::PipeScalerCtrl> PipeScalerCtrl(int num) {
return hwreg::RegisterAddr<registers::PipeScalerCtrl>(
PipeScalerCtrl::kBaseAddr + 0x800 * pipe_ + num * 0x100);
}
hwreg::RegisterAddr<registers::PipeScalerWinSize> PipeScalerWinSize(int num) {
return hwreg::RegisterAddr<registers::PipeScalerWinSize>(
PipeScalerWinSize::kBaseAddr + 0x800 * pipe_ + num * 0x100);
}
hwreg::RegisterAddr<registers::PipeDeInterrupt> PipeDeInterrupt(uint32_t type) {
return hwreg::RegisterAddr<registers::PipeDeInterrupt>(type + 0x10 * pipe_);
}
private:
template <class RegType> hwreg::RegisterAddr<RegType> GetReg() {
return hwreg::RegisterAddr<RegType>(RegType::kBaseAddr + 0x1000 * pipe_);
}
template <class RegType> hwreg::RegisterAddr<RegType> GetPlaneReg(int32_t plane) {
return hwreg::RegisterAddr<RegType>(RegType::kBaseAddr + 0x1000 * pipe_ + 0x100 * plane);
}
Pipe pipe_;
};
} // namespace registers