blob: b88929339c2fb1eb30ba3d33cba308c2b5c86906 [file] [log] [blame]
// Copyright 2019 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 "disp-rdma.h"
#include "registers-disp-rdma.h"
#include <fbl/alloc_checker.h>
namespace mt8167s_display {
namespace {
constexpr int kIdleTimeout = 20000;
} // namespace
zx_status_t DispRdma::Init(zx_device_t* parent) {
if (initialized_) {
return ZX_OK;
}
zx_status_t status = device_get_protocol(parent, ZX_PROTOCOL_PDEV, &pdev_);
if (status != ZX_OK) {
return status;
}
// Map Disp RDMA MMIO
mmio_buffer_t mmio;
status = pdev_map_mmio_buffer(&pdev_, MMIO_DISP_RDMA, ZX_CACHE_POLICY_UNCACHED_DEVICE,
&mmio);
if (status != ZX_OK) {
DISP_ERROR("Could not map DISP RDMA mmio\n");
return status;
}
fbl::AllocChecker ac;
disp_rdma_mmio_ = fbl::make_unique_checked<ddk::MmioBuffer>(&ac, mmio);
if (!ac.check()) {
DISP_ERROR("Could not map DISP RDMA MMIO\n");
return ZX_ERR_NO_MEMORY;
}
// Get BTI from parent
status = pdev_get_bti(&pdev_, 0, bti_.reset_and_get_address());
if (status != ZX_OK) {
DISP_ERROR("Could not get BTI handle\n");
return status;
}
// DISP RDMA is ready to be used
initialized_ = true;
return ZX_OK;
}
void DispRdma::Reset() {
ZX_DEBUG_ASSERT(initialized_);
int timeout = kIdleTimeout;
Stop();
// Set Soft Reset Bit
disp_rdma_mmio_->Write32(disp_rdma_mmio_->Read32(DISP_RDMA_GLOBAL_CON) | GLOBAL_CON_SOFT_RESET,
DISP_RDMA_GLOBAL_CON);
while (((disp_rdma_mmio_->Read32(DISP_RDMA_GLOBAL_CON) & GLOBAL_CON_RESET_STATE_MASK) ==
GLOBAL_CON_RESTE_STATE_IDLE) && timeout--) {
zx_nanosleep(zx_deadline_after(ZX_USEC(10)));
}
ZX_ASSERT(timeout > 0);
// Clear Soft Reset Bit
disp_rdma_mmio_->Write32(disp_rdma_mmio_->Read32(DISP_RDMA_GLOBAL_CON) & ~GLOBAL_CON_SOFT_RESET,
DISP_RDMA_GLOBAL_CON);
timeout = kIdleTimeout;
while (((disp_rdma_mmio_->Read32(DISP_RDMA_GLOBAL_CON) & GLOBAL_CON_RESET_STATE_MASK) !=
GLOBAL_CON_RESTE_STATE_IDLE) && timeout--) {
zx_nanosleep(zx_deadline_after(ZX_USEC(10)));
}
ZX_ASSERT(timeout > 0);
}
void DispRdma::Start() {
ZX_DEBUG_ASSERT(initialized_);
disp_rdma_mmio_->Write32(disp_rdma_mmio_->Read32(DISP_RDMA_GLOBAL_CON) | GLOBAL_CON_ENGINE_EN,
DISP_RDMA_GLOBAL_CON);
}
void DispRdma::Stop() {
ZX_DEBUG_ASSERT(initialized_);
disp_rdma_mmio_->Write32(0, DISP_RDMA_GLOBAL_CON);
disp_rdma_mmio_->Write32(0, DISP_RDMA_INT_ENABLE);
disp_rdma_mmio_->Write32(0, DISP_RDMA_INT_STATUS);
}
zx_status_t DispRdma::Config() {
ZX_DEBUG_ASSERT(initialized_);
// This also disables matrix conversion since we are operating in direct link mode
disp_rdma_mmio_->Write32(SIZE_CON0_WIDTH(width_), DISP_RDMA_SIZE_CON0);
disp_rdma_mmio_->Write32(SIZE_CON1_HEIGHT(height_), DISP_RDMA_SIZE_CON1);
// Clear a bunch of registers that are only relevant in Memory mode and not direct mode
disp_rdma_mmio_->Write32(0, DISP_RDMA_MEM_CON);
disp_rdma_mmio_->Write32(0, DISP_RDMA_MEM_SRC_PITCH);
disp_rdma_mmio_->Write32(0, DISP_RDMA_MEM_START_ADDR);
disp_rdma_mmio_->Write32(0, DISP_RDMA_INT_ENABLE); // not using interrupts
disp_rdma_mmio_->ClearBits32(FIFO_CON_CLEAR_MASK, DISP_RDMA_FIFO_CON);
disp_rdma_mmio_->Write32(FIFO_CON_FIFO_THRESHOLD_DEFAULT |
FIFO_CON_UNDERFLOW_EN | disp_rdma_mmio_->Read32(DISP_RDMA_FIFO_CON),
DISP_RDMA_FIFO_CON);
// magic number needed to setup ultra registers
disp_rdma_mmio_->Write32(0x1a01356b, DISP_RDMA_MEM_GMC_SETTING_0);
return ZX_OK;
}
void DispRdma::Dump() {
ZX_DEBUG_ASSERT(initialized_);
zxlogf(INFO, "Dumping DISP RDMA Registers\n");
zxlogf(INFO, "######################\n\n");
zxlogf(INFO, "DISP_RDMA_INT_ENABLE = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_INT_ENABLE));
zxlogf(INFO, "DISP_RDMA_INT_STATUS = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_INT_STATUS));
zxlogf(INFO, "DISP_RDMA_GLOBAL_CON = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_GLOBAL_CON));
zxlogf(INFO, "DISP_RDMA_SIZE_CON0 = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_SIZE_CON0));
zxlogf(INFO, "DISP_RDMA_SIZE_CON1 = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_SIZE_CON1));
zxlogf(INFO, "DISP_RDMA_TARGET_LINE = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_TARGET_LINE));
zxlogf(INFO, "DISP_RDMA_MEM_CON = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_MEM_CON));
zxlogf(INFO, "DISP_RDMA_MEM_SRC_PITCH = 0x%x\n",
disp_rdma_mmio_->Read32(DISP_RDMA_MEM_SRC_PITCH));
zxlogf(INFO, "DISP_RDMA_MEM_GMC_SETTING_0 = 0x%x\n",
disp_rdma_mmio_->Read32(DISP_RDMA_MEM_GMC_SETTING_0));
zxlogf(INFO, "DISP_RDMA_MEM_SLOW_CON = 0x%x\n",
disp_rdma_mmio_->Read32(DISP_RDMA_MEM_SLOW_CON));
zxlogf(INFO, "DISP_RDMA_MEM_GMC_SETTING_1 = 0x%x\n",
disp_rdma_mmio_->Read32(DISP_RDMA_MEM_GMC_SETTING_1));
zxlogf(INFO, "DISP_RDMA_FIFO_CON = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_FIFO_CON));
zxlogf(INFO, "DISP_RDMA_FIFO_LOG = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_FIFO_LOG));
zxlogf(INFO, "DISP_RDMA_C00 = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_C00));
zxlogf(INFO, "DISP_RDMA_C01 = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_C01));
zxlogf(INFO, "DISP_RDMA_C02 = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_C02));
zxlogf(INFO, "DISP_RDMA_C10 = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_C10));
zxlogf(INFO, "DISP_RDMA_C11 = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_C11));
zxlogf(INFO, "DISP_RDMA_C12 = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_C12));
zxlogf(INFO, "DISP_RDMA_C20 = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_C20));
zxlogf(INFO, "DISP_RDMA_C21 = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_C21));
zxlogf(INFO, "DISP_RDMA_C22 = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_C22));
zxlogf(INFO, "DISP_RDMA_PRE_ADD_0 = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_PRE_ADD_0));
zxlogf(INFO, "DISP_RDMA_PRE_ADD_1 = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_PRE_ADD_1));
zxlogf(INFO, "DISP_RDMA_PRE_ADD_2 = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_PRE_ADD_2));
zxlogf(INFO, "DISP_RDMA_POST_ADD_0 = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_POST_ADD_0));
zxlogf(INFO, "DISP_RDMA_POST_ADD_1 = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_POST_ADD_1));
zxlogf(INFO, "DISP_RDMA_POST_ADD_2 = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_POST_ADD_2));
zxlogf(INFO, "DISP_RDMA_DUMMY = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_DUMMY));
zxlogf(INFO, "DISP_RDMA_DEBUG_OUT_SEL = 0x%x\n",
disp_rdma_mmio_->Read32(DISP_RDMA_DEBUG_OUT_SEL));
zxlogf(INFO, "DISP_RDMA_BG_CON_0 = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_BG_CON_0));
zxlogf(INFO, "DISP_RDMA_BG_CON_1 = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_BG_CON_1));
zxlogf(INFO, "DISP_RDMA_THRESHOLD_FOR_SODI = 0x%x\n",
disp_rdma_mmio_->Read32(DISP_RDMA_THRESHOLD_FOR_SODI));
zxlogf(INFO, "DISP_RDMA_IN_P_CNT = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_IN_P_CNT));
zxlogf(INFO, "DISP_RDMA_IN_LINE_CNT = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_IN_LINE_CNT));
zxlogf(INFO, "DISP_RDMA_OUT_P_CNT = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_OUT_P_CNT));
zxlogf(INFO, "DISP_RDMA_OUT_LINE_CNT = 0x%x\n", disp_rdma_mmio_->Read32(DISP_RDMA_OUT_LINE_CNT));
zxlogf(INFO, "DISP_RDMA_MEM_START_ADDR = 0x%x\n",
disp_rdma_mmio_->Read32(DISP_RDMA_MEM_START_ADDR));
zxlogf(INFO, "######################\n\n");
}
} // namespace mt8167s_display