blob: d963595840c77b72c89a8a3ee5587cfb0e35796e [file]
// Copyright 2024 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 "src/graphics/display/drivers/amlogic-display/display-device-driver.h"
#include <fidl/fuchsia.driver.framework/cpp/wire.h>
#include <fidl/fuchsia.hardware.platform.device/cpp/wire.h>
#include <lib/driver/component/cpp/driver_export2.h>
#include <lib/driver/component/cpp/node_add_args.h>
#include <lib/driver/mmio/cpp/mmio-buffer.h>
#include <lib/driver/outgoing/cpp/outgoing_directory.h>
#include <lib/inspect/component/cpp/component.h>
#include <lib/inspect/cpp/inspector.h>
#include <lib/zx/bti.h>
#include <lib/zx/result.h>
#include <zircon/assert.h>
#include <cinttypes>
#include <cstdint>
#include <memory>
#include <fbl/alloc_checker.h>
#include "fidl/fuchsia.driver.framework/cpp/natural_types.h"
#include "src/graphics/display/drivers/amlogic-display/display-engine.h"
#include "src/graphics/display/drivers/amlogic-display/structured_config.h"
#include "src/graphics/display/lib/api-protocols/cpp/display-engine-events-fidl.h"
#include "src/graphics/display/lib/api-protocols/cpp/display-engine-fidl-adapter.h"
namespace amlogic_display {
DisplayDeviceDriver::DisplayDeviceDriver() : fdf::DriverBase2("amlogic-display") {}
zx::result<> DisplayDeviceDriver::Start(fdf::DriverContext context) {
auto config = context.take_config<structured_config::Config>();
std::shared_ptr<fdf::Namespace> incoming_ptr(context.take_incoming());
fbl::AllocChecker alloc_checker;
engine_events_ = fbl::make_unique_checked<display::DisplayEngineEventsFidl>(&alloc_checker);
if (!alloc_checker.check()) {
fdf::error("Failed to allocate memory for DisplayEngineEventsFidl");
return zx::error(ZX_ERR_NO_MEMORY);
}
zx::result<std::unique_ptr<DisplayEngine>> create_display_engine_result =
DisplayEngine::Create(incoming_ptr, engine_events_.get(), config);
if (create_display_engine_result.is_error()) {
fdf::error("Failed to create DisplayEngine: {}", create_display_engine_result);
return create_display_engine_result.take_error();
}
display_engine_ = std::move(create_display_engine_result).value();
engine_fidl_adapter_ = fbl::make_unique_checked<display::DisplayEngineFidlAdapter>(
&alloc_checker, display_engine_.get(), engine_events_.get());
if (!alloc_checker.check()) {
fdf::error("Failed to allocate memory for DisplayEngineFidlAdapter");
return zx::error(ZX_ERR_NO_MEMORY);
}
inspect::Node config_node = display_engine_->inspector().GetRoot().CreateChild("config");
config.RecordInspect(&config_node);
fuchsia_hardware_display_engine::Service::InstanceHandler service_handler(
{.engine = engine_fidl_adapter_->CreateHandler(*(driver_dispatcher()->get()))});
zx::result<> add_service_result =
outgoing()->AddService<fuchsia_hardware_display_engine::Service>(std::move(service_handler));
if (add_service_result.is_error()) {
fdf::error("Failed to add service: {}", add_service_result);
return add_service_result.take_error();
}
const std::vector<fuchsia_driver_framework::Offer> node_offers = {
fdf::MakeOffer2<fuchsia_hardware_display_engine::Service>(),
};
zx::result<fidl::ClientEnd<fuchsia_driver_framework::NodeController>> controller_client_result =
AddChild(name(), std::span<const fuchsia_driver_framework::NodeProperty>(), node_offers);
if (controller_client_result.is_error()) {
fdf::error("Failed to add child node: {}", controller_client_result);
return controller_client_result.take_error();
}
controller_ = fidl::WireSyncClient(std::move(controller_client_result).value());
return zx::ok();
}
} // namespace amlogic_display
FUCHSIA_DRIVER_EXPORT2(amlogic_display::DisplayDeviceDriver);