-- -- Copyright (C) 2015-2016 secunet Security Networks AG -- Copyright (C) 2017 Nico Huber -- -- This program is free software; you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation; either version 2 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- with HW; use type HW.Pos64; use type HW.Word32; package HW.GFX is -- such that the count of pixels in any framebuffer may fit subtype Pixel_Type is Int32 range 0 .. 8192 * 8192; subtype Pos_Pixel_Type is Pixel_Type range 1 .. Pixel_Type'Last; -- assume at most 8 bytes per pixel subtype Size_Type is Int32 range 0 .. Pixel_Type'Last * 8; -- Allow same range for width and height (for rotated framebuffers) subtype Width_Type is Pos32 range 1 .. 8192; subtype Height_Type is Pos32 range 1 .. 8192; subtype Position_Type is Int32 range 0 .. 4095; Auto_BPC : constant := 5; subtype BPC_Type is Int64 range Auto_BPC .. 16; type Tiling_Type is (Linear, X_Tiled, Y_Tiled); subtype XY_Tiling is Tiling_Type range X_Tiled .. Y_Tiled; type Rotation_Type is (No_Rotation, Rotated_90, Rotated_180, Rotated_270); type Framebuffer_Type is record Width : Width_Type; Height : Height_Type; Start_X : Position_Type; Start_Y : Position_Type; BPC : BPC_Type; Stride : Width_Type; V_Stride : Height_Type; Tiling : Tiling_Type; Rotation : Rotation_Type; Offset : Word32; end record; Default_FB : constant Framebuffer_Type := Framebuffer_Type' (Width => 1, Height => 1, Start_X => 0, Start_Y => 0, BPC => 8, Stride => 1, V_Stride => 1, Tiling => Linear, Rotation => No_Rotation, Offset => 0); subtype Frequency_Type is Pos64 range 1_000_000 .. 2_500_000_000; type DP_Lane_Count is (DP_Lane_Count_1, DP_Lane_Count_2, DP_Lane_Count_4); subtype DP_Lane_Count_Type is Pos64 range 1 .. 4; type DP_Lane_Count_Integers is array (DP_Lane_Count) of DP_Lane_Count_Type; Lane_Count_As_Integer : constant DP_Lane_Count_Integers := DP_Lane_Count_Integers' (DP_Lane_Count_1 => 1, DP_Lane_Count_2 => 2, DP_Lane_Count_4 => 4); type DP_Bandwidth is (DP_Bandwidth_1_62, DP_Bandwidth_2_7, DP_Bandwidth_5_4); for DP_Bandwidth use (DP_Bandwidth_1_62 => 6, DP_Bandwidth_2_7 => 10, DP_Bandwidth_5_4 => 20); for DP_Bandwidth'Size use 8; subtype DP_Symbol_Rate_Type is Pos64 range 1 .. 810_000_000; type DP_Symbol_Rate_Array is array (DP_Bandwidth) of DP_Symbol_Rate_Type; DP_Symbol_Rate : constant DP_Symbol_Rate_Array := DP_Symbol_Rate_Array' (DP_Bandwidth_1_62 => 162_000_000, DP_Bandwidth_2_7 => 270_000_000, DP_Bandwidth_5_4 => 540_000_000); type DP_Caps is record Rev : Word8; Max_Link_Rate : DP_Bandwidth; Max_Lane_Count : DP_Lane_Count; TPS3_Supported : Boolean; Enhanced_Framing : Boolean; No_Aux_Handshake : Boolean; Aux_RD_Interval : Word8; end record; type DP_Link is record Receiver_Caps : DP_Caps; Lane_Count : DP_Lane_Count; Bandwidth : DP_Bandwidth; Enhanced_Framing : Boolean; Opportunistic_Training : Boolean; end record; Default_DP : constant DP_Link := DP_Link' (Receiver_Caps => DP_Caps' (Rev => 16#00#, Max_Link_Rate => DP_Bandwidth'First, Max_Lane_Count => DP_Lane_Count'First, TPS3_Supported => False, Enhanced_Framing => False, No_Aux_Handshake => False, Aux_RD_Interval => 16#00#), Lane_Count => DP_Lane_Count'First, Bandwidth => DP_Bandwidth'First, Enhanced_Framing => False, Opportunistic_Training => False); type Display_Type is (None, LVDS, DP, HDMI, VGA); subtype Internal_Type is Display_Type range None .. DP; type Mode_Type is record Dotclock : Frequency_Type; H_Visible : Width_Type; H_Sync_Begin : Width_Type; H_Sync_End : Width_Type; H_Total : Width_Type; V_Visible : Height_Type; V_Sync_Begin : Height_Type; V_Sync_End : Height_Type; V_Total : Height_Type; H_Sync_Active_High : Boolean; V_Sync_Active_High : Boolean; BPC : BPC_Type; end record; ---------------------------------------------------------------------------- -- Constants ---------------------------------------------------------------------------- -- modeline constants -- Dotclock is calculated using: Refresh_Rate * H_Total * V_Total M2560x1600_60 : constant Mode_Type := Mode_Type' (60*(2720*1646), 2560, 2608, 2640, 2720, 1600, 1603, 1609, 1646, True, True, Auto_BPC); M2560x1440_60 : constant Mode_Type := Mode_Type' (60*(2720*1481), 2560, 2608, 2640, 2720, 1440, 1443, 1448, 1481, True, False, Auto_BPC); M1920x1200_60 : constant Mode_Type := Mode_Type' (60*(2080*1235), 1920, 1968, 2000, 2080, 1200, 1203, 1209, 1235, False, False, Auto_BPC); M1920x1080_60 : constant Mode_Type := Mode_Type' (60*(2185*1135), 1920, 2008, 2052, 2185, 1080, 1084, 1089, 1135, False, False, Auto_BPC); M1680x1050_60 : constant Mode_Type := Mode_Type' (60*(2256*1087), 1680, 1784, 1968, 2256, 1050, 1051, 1054, 1087, False, True, Auto_BPC); M1600x1200_60 : constant Mode_Type := Mode_Type' (60*(2160*1250), 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, True, True, Auto_BPC); M1600x900_60 : constant Mode_Type := Mode_Type' (60*(2010*912), 1600, 1664, 1706, 2010, 900, 903, 906, 912, False, False, Auto_BPC); M1440x900_60 : constant Mode_Type := Mode_Type' (60*(1834*920), 1440, 1488, 1520, 1834, 900, 903, 909, 920, False, False, Auto_BPC); M1366x768_60 : constant Mode_Type := Mode_Type' (60*(1446*788), 1366, 1414, 1446, 1466, 768, 769, 773, 788, False, False, Auto_BPC); M1280x1024_60 : constant Mode_Type := Mode_Type' (60*(1712*1063), 1280, 1368, 1496, 1712, 1024, 1027, 1034, 1063, False, True, Auto_BPC); M1024x768_60 : constant Mode_Type := Mode_Type' (60*(1344*806), 1024, 1048, 1184, 1344, 768, 771, 777, 806, False, False, Auto_BPC); Invalid_Mode : constant Mode_Type := Mode_Type' (Frequency_Type'First, 1, 1, 1, 1, 1, 1, 1, 1, False, False, Auto_BPC); private function Rotation_90 (FB : Framebuffer_Type) return Boolean is (FB.Rotation = Rotated_90 or FB.Rotation = Rotated_270); function Rotated_Width (FB : Framebuffer_Type) return Width_Type is (if Rotation_90 (FB) then FB.Height else FB.Width); function Rotated_Height (FB : Framebuffer_Type) return Height_Type is (if Rotation_90 (FB) then FB.Width else FB.Height); function Pixel_To_Bytes (Pixel : Pixel_Type; FB : Framebuffer_Type) return Size_Type is (Pixel * Pos32 (FB.BPC) / (8 / 4)); function FB_Size (FB : Framebuffer_Type) return Pos32 is (Pixel_To_Bytes (FB.Stride * FB.V_Stride, FB)); function Requires_Scaling (FB : Framebuffer_Type; Mode : Mode_Type) return Boolean is (Rotated_Width (FB) /= Mode.H_Visible or Rotated_Height (FB) /= Mode.V_Visible); type Scaling_Aspect is (Uniform, Letterbox, Pillarbox); function Scaling_Type (Width : Width_Type; Height : Height_Type; Scaled_Width : Width_Type; Scaled_Height : Height_Type) return Scaling_Aspect is (if Scaled_Width * Height < Scaled_Height * Width then Letterbox elsif Scaled_Width * Height > Scaled_Height * Width then Pillarbox else Uniform); function Scaling_Type (FB : Framebuffer_Type; Mode : Mode_Type) return Scaling_Aspect is (Scaling_Type (Rotated_Width (FB), Rotated_Height (FB), Mode.H_Visible, Mode.V_Visible)); end HW.GFX;