mirror of
https://github.com/SerenityOS/serenity.git
synced 2025-01-22 09:21:57 -05:00
Kernel/GPU: Add a simple-framebuffer devicetree driver
simple-framebuffer nodes describe pre-initialized framebuffers that we can use without any special setup code.
This commit is contained in:
parent
60bb8edd7b
commit
6127f03108
2 changed files with 74 additions and 0 deletions
|
@ -95,6 +95,7 @@ set(KERNEL_SOURCES
|
|||
Devices/GPU/Console/ContiguousFramebufferConsole.cpp
|
||||
Devices/GPU/DisplayConnector.cpp
|
||||
Devices/GPU/Generic/DisplayConnector.cpp
|
||||
Devices/GPU/Generic/SimpleFramebuffer.cpp
|
||||
Devices/GPU/Management.cpp
|
||||
Devices/GPU/Intel/Auxiliary/GMBusConnector.cpp
|
||||
Devices/GPU/Intel/Plane/DisplayPlane.cpp
|
||||
|
|
73
Kernel/Devices/GPU/Generic/SimpleFramebuffer.cpp
Normal file
73
Kernel/Devices/GPU/Generic/SimpleFramebuffer.cpp
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Sönke Holz <sholz8530@gmail.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <AK/GenericShorthands.h>
|
||||
#include <Kernel/Boot/BootInfo.h>
|
||||
#include <Kernel/Devices/GPU/Console/BootFramebufferConsole.h>
|
||||
#include <Kernel/Firmware/DeviceTree/DeviceTree.h>
|
||||
#include <Kernel/Firmware/DeviceTree/Driver.h>
|
||||
#include <Kernel/Firmware/DeviceTree/Management.h>
|
||||
|
||||
namespace Kernel {
|
||||
extern Atomic<Graphics::Console*> g_boot_console;
|
||||
}
|
||||
|
||||
namespace Kernel::Graphics {
|
||||
|
||||
static constinit Array const compatibles_array = {
|
||||
"simple-framebuffer"sv,
|
||||
};
|
||||
|
||||
DEVICETREE_DRIVER(SimpleFramebufferDriver, compatibles_array);
|
||||
|
||||
// https://www.kernel.org/doc/Documentation/devicetree/bindings/display/simple-framebuffer.yaml
|
||||
ErrorOr<void> SimpleFramebufferDriver::probe(DeviceTree::Device const& device, StringView) const
|
||||
{
|
||||
// Prefer to use the bootloader-provided framebuffer, if available.
|
||||
if (!g_boot_info.boot_framebuffer.paddr.is_null() && g_boot_info.boot_framebuffer.type == BootFramebufferType::BGRx8888)
|
||||
return {};
|
||||
|
||||
auto maybe_width = device.node().get_property("width"sv);
|
||||
if (!maybe_width.has_value())
|
||||
return EINVAL;
|
||||
|
||||
auto maybe_height = device.node().get_property("height"sv);
|
||||
if (!maybe_height.has_value())
|
||||
return EINVAL;
|
||||
|
||||
auto maybe_stride = device.node().get_property("stride"sv);
|
||||
if (!maybe_stride.has_value())
|
||||
return EINVAL;
|
||||
|
||||
auto maybe_format = device.node().get_property("format"sv);
|
||||
if (!maybe_format.has_value())
|
||||
return EINVAL;
|
||||
|
||||
if (!first_is_one_of(maybe_format.value().as_string(), "a8r8g8b8"sv, "x8r8g8b8"sv))
|
||||
return ENOTSUP;
|
||||
|
||||
auto framebuffer_resource = TRY(device.get_resource(0));
|
||||
|
||||
g_boot_info.boot_framebuffer = {
|
||||
.paddr = framebuffer_resource.paddr,
|
||||
.pitch = maybe_stride.release_value().as<u32>(),
|
||||
.width = maybe_width.release_value().as<u32>(),
|
||||
.height = maybe_height.release_value().as<u32>(),
|
||||
.bpp = 32,
|
||||
.type = BootFramebufferType::BGRx8888,
|
||||
};
|
||||
|
||||
// Devicetree drivers are probed after the initial boot console is set up, so we need to re-initialize the g_boot_console to use the this framebuffer.
|
||||
// g_boot_console should currently be a BootDummyConsole, as we ignore the simple-framebuffer node if the bootloader provided a framebuffer.
|
||||
auto boot_console = TRY(try_make_lock_ref_counted<Graphics::BootFramebufferConsole>(g_boot_info.boot_framebuffer.paddr, g_boot_info.boot_framebuffer.width, g_boot_info.boot_framebuffer.height, g_boot_info.boot_framebuffer.pitch));
|
||||
auto* old_boot_console = g_boot_console.exchange(&boot_console.leak_ref());
|
||||
if (old_boot_console != nullptr)
|
||||
old_boot_console->unref();
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue