1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-19 17:55:07 +00:00
serenity/Kernel/Devices/GPU/3dfx/VoodooDisplayConnector.h
Edwin Rijkee 8388fe51b5 Kernel: Add a framebuffer driver for 3Dfx Voodoo 3
A bit old but a relatively uncomplicated device capable of outputting
1920x1080 video with 32-bit color. Tested with a Voodoo 3 3000 16MB
PCI card. Resolution switching from DisplaySettings also works.

If the requested mode contains timing information, it is used directly.
Otherwise, display timing values are selected from the EDID. First the
detailed timings are checked, and then standard and established
timings for which there is a matching DMT mode. The driver does not
(yet) read the actual EDID, so the generic EDID in DisplayConnector now
includes a set of common display modes to make this work.

The driver should also be compatible with the Voodoo Banshee, 4 and 5
but I don't have these cards to test this with. The PCI IDs of these
cards are included as a commented line in case someone wants to give it
a try.
2023-10-16 01:25:45 +02:00

59 lines
2.8 KiB
C++

/*
* Copyright (c) 2023, Edwin Rijkee <edwin@virtualparadise.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <Kernel/Devices/DeviceManagement.h>
#include <Kernel/Devices/GPU/3dfx/Definitions.h>
#include <Kernel/Devices/GPU/Console/GenericFramebufferConsole.h>
#include <Kernel/Devices/GPU/DisplayConnector.h>
#include <Kernel/Library/IOWindow.h>
#include <Kernel/Memory/TypedMapping.h>
namespace Kernel::VoodooGraphics {
class VoodooDisplayConnector final
: public DisplayConnector {
friend class VoodooGraphicsAdapter;
friend class Kernel::DeviceManagement;
public:
static NonnullLockRefPtr<VoodooDisplayConnector> must_create(PhysicalAddress framebuffer_address, size_t framebuffer_resource_size, Memory::TypedMapping<RegisterMap volatile>, NonnullOwnPtr<IOWindow> io_window);
private:
ErrorOr<void> fetch_and_initialize_edid();
ErrorOr<void> create_attached_framebuffer_console();
VoodooDisplayConnector(PhysicalAddress framebuffer_address, size_t framebuffer_resource_size, Memory::TypedMapping<RegisterMap volatile>, NonnullOwnPtr<IOWindow> io_window);
virtual bool mutable_mode_setting_capable() const override final { return false; }
virtual bool double_framebuffering_capable() const override { return false; }
virtual ErrorOr<void> set_mode_setting(ModeSetting const&) override;
virtual ErrorOr<void> set_y_offset(size_t y) override;
virtual ErrorOr<void> set_safe_mode_setting() override final;
virtual ErrorOr<void> unblank() override;
virtual bool partial_flush_support() const override final { return false; }
virtual bool flush_support() const override final { return false; }
virtual bool refresh_rate_support() const override final { return false; }
virtual ErrorOr<void> flush_first_surface() override final;
virtual void enable_console() override final;
virtual void disable_console() override final;
ErrorOr<IterationDecision> for_each_dmt_timing_in_edid(Function<IterationDecision(EDID::DMT::MonitorTiming const&)>) const;
ErrorOr<ModeSetting> find_suitable_mode(ModeSetting const& requested_mode) const;
u8 read_vga(VGAPort port);
u8 read_vga_indexed(VGAPort index_port, VGAPort data_port, u8 index);
void write_vga(VGAPort port, u8 value);
void write_vga_indexed(VGAPort index_port, VGAPort data_port, u8 index, u8 value);
ErrorOr<void> wait_for_fifo_space(u32 minimum_entries);
static PLLSettings calculate_pll(i32 desired_frequency_in_khz);
ErrorOr<ModeRegisters> prepare_mode_switch(ModeSetting const& mode_setting);
ErrorOr<void> perform_mode_switch(ModeRegisters const& regs);
LockRefPtr<Graphics::GenericFramebufferConsole> m_framebuffer_console;
Memory::TypedMapping<RegisterMap volatile> m_registers;
NonnullOwnPtr<IOWindow> m_io_window;
};
}