blob: 4a0985a37990adf858f6c32cfeaa8f04b718c0a6 [file] [log] [blame] [edit]
// 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.
#include "osd.h"
#include <ddk/debug.h>
#include <ddktl/device.h>
namespace astro_display {
constexpr uint32_t VpuViuOsd1BlkCfgTblAddrShift = 16;
constexpr uint32_t VpuViuOsd1BlkCfgLittleEndian = (1 << 15);
constexpr uint32_t VpuViuOsd1BlkCfgOsdBlkMode32Bit = 5;
constexpr uint32_t VpuViuOsd1BlkCfgOsdBlkModeShift = 8;
constexpr uint32_t VpuViuOsd1BlkCfgColorMatrixArgb = 1;
constexpr uint32_t VpuViuOsd1BlkCfgColorMatrixShift = 2;
constexpr uint32_t VpuViuOsd1CtrlStat2ReplacedAlphaEn = (1 << 14);
constexpr uint32_t VpuViuOsd1CtrlStat2ReplacedAlphaShift = 6u;
zx_status_t Osd::Init(zx_device_t* parent) {
zx_status_t status = device_get_protocol(parent, ZX_PROTOCOL_PLATFORM_DEV, &pdev_);
if (status != ZX_OK) {
return status;
}
// Map vpu mmio used by the OSD object
status = pdev_map_mmio_buffer(&pdev_, MMIO_VPU, ZX_CACHE_POLICY_UNCACHED_DEVICE,
&mmio_vpu_);
if (status != ZX_OK) {
DISP_ERROR("osd: Could not map VPU mmio\n");
return status;
}
vpu_regs_ = fbl::make_unique<hwreg::RegisterIo>(io_buffer_virt(&mmio_vpu_));
// OSD object is ready to be used.
return ZX_OK;
}
void Osd::Disable(void) {
uint32_t regVal = vpu_regs_->Read<uint32_t>(VPU_VIU_OSD1_CTRL_STAT);
regVal &= ~(1 << 0);
vpu_regs_->Write(VPU_VIU_OSD1_CTRL_STAT, regVal);
}
void Osd::Enable(void) {
uint32_t regVal = vpu_regs_->Read<uint32_t>(VPU_VIU_OSD1_CTRL_STAT);
regVal |= (1 << 0);
vpu_regs_->Write(VPU_VIU_OSD1_CTRL_STAT, regVal);
}
zx_status_t Osd::Configure(void) {
// TODO(payamm): OSD for g12a is slightly different from gxl. Currently, uBoot enables
// scaling and 16bit mode (565) and configures various layers based on that assumption.
// Since we don't have a full end-to-end driver at this moment, we cannot simply turn off
// scaling.
// For now, we will only configure the OSD layer to use the new Canvas index,
// and use 32-bit color.
uint32_t ctrl_stat2 = vpu_regs_->Read<uint32_t>(VPU_VIU_OSD1_CTRL_STAT2);
ctrl_stat2 |= VpuViuOsd1CtrlStat2ReplacedAlphaEn |
(0xff << VpuViuOsd1CtrlStat2ReplacedAlphaShift);
// Set to use BGRX instead of BGRA.
vpu_regs_->Write(VPU_VIU_OSD1_CTRL_STAT2, ctrl_stat2);
return ZX_OK;
}
void Osd::Flip(uint8_t idx) {
uint32_t cfg_w0 = (idx << VpuViuOsd1BlkCfgTblAddrShift) |
VpuViuOsd1BlkCfgLittleEndian |
(VpuViuOsd1BlkCfgOsdBlkMode32Bit << VpuViuOsd1BlkCfgOsdBlkModeShift) |
(VpuViuOsd1BlkCfgColorMatrixArgb << VpuViuOsd1BlkCfgColorMatrixShift);
vpu_regs_->Write(VPU_VIU_OSD1_BLK0_CFG_W0, cfg_w0);
Enable();
}
} // namespace astro_display