blob: 2bce92126c18b8c00f2f300e903e329a37582300 [file] [log] [blame]
// Copyright 2020 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 <fidl/fuchsia.hardware.platform.bus/cpp/driver/fidl.h>
#include <fidl/fuchsia.hardware.platform.bus/cpp/fidl.h>
#include <lib/ddk/binding.h>
#include <lib/ddk/debug.h>
#include <lib/ddk/device.h>
#include <lib/ddk/platform-defs.h>
#include <lib/driver/component/cpp/composite_node_spec.h>
#include <lib/driver/component/cpp/node_add_args.h>
#include <bind/fuchsia/amlogic/platform/cpp/bind.h>
#include <bind/fuchsia/clock/cpp/bind.h>
#include <bind/fuchsia/cpp/bind.h>
#include <bind/fuchsia/hardware/amlogiccanvas/cpp/bind.h>
#include <bind/fuchsia/hardware/clock/cpp/bind.h>
#include <bind/fuchsia/hardware/sysmem/cpp/bind.h>
#include <soc/aml-meson/g12b-clk.h>
#include <soc/aml-t931/t931-hw.h>
#include "sherlock.h"
namespace fdf {
using namespace fuchsia_driver_framework;
} // namespace fdf
namespace sherlock {
namespace fpbus = fuchsia_hardware_platform_bus;
static const std::vector<fpbus::Mmio> sherlock_video_enc_mmios{
{{
.base = T931_CBUS_BASE,
.length = T931_CBUS_LENGTH,
}},
{{
.base = T931_DOS_BASE,
.length = T931_DOS_LENGTH,
}},
{{
.base = T931_AOBUS_BASE,
.length = T931_AOBUS_LENGTH,
}},
{{
.base = T931_HIU_BASE,
.length = T931_HIU_LENGTH,
}},
};
static const std::vector<fpbus::Bti> sherlock_video_enc_btis{
{{
.iommu_index = 0,
.bti_id = BTI_VIDEO_ENC,
}},
};
static const std::vector<fpbus::Irq> sherlock_video_enc_irqs{
{{
.irq = T931_DOS_MBOX_2_IRQ,
.mode = ZX_INTERRUPT_MODE_EDGE_HIGH,
}},
};
const std::vector<fdf::BindRule> kSysmemRules = std::vector{fdf::MakeAcceptBindRule(
bind_fuchsia_hardware_sysmem::SERVICE, bind_fuchsia_hardware_sysmem::SERVICE_ZIRCONTRANSPORT)};
const std::vector<fdf::NodeProperty> kSysmemProperties = std::vector{
fdf::MakeProperty(bind_fuchsia_hardware_sysmem::SERVICE,
bind_fuchsia_hardware_sysmem::SERVICE_ZIRCONTRANSPORT),
};
const std::vector<fdf::BindRule> kCanvasRules = std::vector{
fdf::MakeAcceptBindRule(bind_fuchsia_hardware_amlogiccanvas::SERVICE,
bind_fuchsia_hardware_amlogiccanvas::SERVICE_ZIRCONTRANSPORT)};
const std::vector<fdf::NodeProperty> kCanvasProperties = std::vector{
fdf::MakeProperty(bind_fuchsia_hardware_amlogiccanvas::SERVICE,
bind_fuchsia_hardware_amlogiccanvas::SERVICE_ZIRCONTRANSPORT),
};
const std::vector<fdf::BindRule> kClkDosHCodecRules = std::vector{
fdf::MakeAcceptBindRule(bind_fuchsia_hardware_clock::SERVICE,
bind_fuchsia_hardware_clock::SERVICE_ZIRCONTRANSPORT),
fdf::MakeAcceptBindRule(bind_fuchsia::CLOCK_ID, g12b_clk::G12B_CLK_DOS_GCLK_HCODEC),
};
const std::vector<fdf::NodeProperty> kClkDosHCodecProperties = std::vector{
fdf::MakeProperty(bind_fuchsia_hardware_clock::SERVICE,
bind_fuchsia_hardware_clock::SERVICE_ZIRCONTRANSPORT),
fdf::MakeProperty(bind_fuchsia_clock::FUNCTION, bind_fuchsia_clock::FUNCTION_DOS_GCLK_HCODEC),
};
const std::vector<fdf::BindRule> kClkDosRules = std::vector{
fdf::MakeAcceptBindRule(bind_fuchsia_hardware_clock::SERVICE,
bind_fuchsia_hardware_clock::SERVICE_ZIRCONTRANSPORT),
fdf::MakeAcceptBindRule(bind_fuchsia::CLOCK_ID, g12b_clk::G12B_CLK_DOS),
};
const std::vector<fdf::NodeProperty> kClkDosProperties = std::vector{
fdf::MakeProperty(bind_fuchsia_hardware_clock::SERVICE,
bind_fuchsia_hardware_clock::SERVICE_ZIRCONTRANSPORT),
fdf::MakeProperty(bind_fuchsia_clock::FUNCTION, bind_fuchsia_clock::FUNCTION_DOS),
};
static const fpbus::Node video_enc_dev = []() {
fpbus::Node dev = {};
dev.name() = "aml-video-enc";
dev.vid() = bind_fuchsia_amlogic_platform::BIND_PLATFORM_DEV_VID_AMLOGIC;
dev.pid() = bind_fuchsia_amlogic_platform::BIND_PLATFORM_DEV_PID_T931;
dev.did() = bind_fuchsia_amlogic_platform::BIND_PLATFORM_DEV_DID_VIDEO_ENC;
dev.mmio() = sherlock_video_enc_mmios;
dev.bti() = sherlock_video_enc_btis;
dev.irq() = sherlock_video_enc_irqs;
return dev;
}();
// TODO(b/42072838): Remove this duplicate pbus node once we finished migrating
// to composite node specs.
static const fpbus::Node video_enc_dev_old = []() {
fpbus::Node dev = {};
dev.name() = "aml-video-enc-old";
dev.vid() = bind_fuchsia_amlogic_platform::BIND_PLATFORM_DEV_VID_AMLOGIC;
dev.pid() = bind_fuchsia_amlogic_platform::BIND_PLATFORM_DEV_PID_T931;
dev.did() = bind_fuchsia_amlogic_platform::BIND_PLATFORM_DEV_DID_VIDEO_ENC;
dev.instance_id() = 1;
dev.mmio() = sherlock_video_enc_mmios;
dev.bti() = sherlock_video_enc_btis;
dev.irq() = sherlock_video_enc_irqs;
return dev;
}();
zx_status_t Sherlock::VideoEncInit() {
zxlogf(INFO, "video-enc init");
fidl::Arena<> fidl_arena;
std::vector<fdf::ParentSpec> kVideoEncParents = {
fdf::ParentSpec{{kSysmemRules, kSysmemProperties}},
fdf::ParentSpec{{kCanvasRules, kCanvasProperties}},
fdf::ParentSpec{{kClkDosHCodecRules, kClkDosHCodecProperties}},
fdf::ParentSpec{{kClkDosRules, kClkDosProperties}}};
fdf::Arena arena('VIDE');
auto composite_result = pbus_.buffer(arena)->AddCompositeNodeSpec(
fidl::ToWire(fidl_arena, video_enc_dev),
fidl::ToWire(fidl_arena, fuchsia_driver_framework::CompositeNodeSpec{
{.name = "aml-video-enc", .parents = kVideoEncParents}}));
if (!composite_result.ok()) {
zxlogf(ERROR, "AddCompositeNodeSpec VideoEnc(video_enc_dev) request failed: %s",
composite_result.FormatDescription().data());
return composite_result.status();
}
if (composite_result->is_error()) {
zxlogf(ERROR, "AddCompositeNodeSpec VideoEnc(video_enc_dev) failed: %s",
zx_status_get_string(composite_result->error_value()));
return composite_result->error_value();
}
return ZX_OK;
}
} // namespace sherlock