blob: 3ee3d183f43d61fd0c75caa025634a0c5556e9fd [file] [log] [blame]
Nico Huber83693c82016-10-08 22:17:55 +02001--
Nico Huber3d06de82018-05-29 01:35:04 +02002-- Copyright (C) 2015-2018 secunet Security Networks AG
Nico Huber194e57e2017-07-15 21:15:46 +02003-- Copyright (C) 2017 Nico Huber <nico.h@gmx.de>
Nico Huber83693c82016-10-08 22:17:55 +02004--
5-- This program is free software; you can redistribute it and/or modify
6-- it under the terms of the GNU General Public License as published by
Nico Huber125a29e2016-10-18 00:23:54 +02007-- the Free Software Foundation; either version 2 of the License, or
8-- (at your option) any later version.
Nico Huber83693c82016-10-08 22:17:55 +02009--
10-- This program is distributed in the hope that it will be useful,
11-- but WITHOUT ANY WARRANTY; without even the implied warranty of
12-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13-- GNU General Public License for more details.
14--
15
Nico Huber194e57e2017-07-15 21:15:46 +020016with HW.Config;
Nico Huber83693c82016-10-08 22:17:55 +020017with HW.Time;
Nico Huberc5c66ec2019-09-28 23:59:45 +020018with HW.PCI;
Nico Huber83693c82016-10-08 22:17:55 +020019with HW.Port_IO;
Nico Hubercf88f3d2018-06-05 13:27:34 +020020with HW.GFX.Framebuffer_Filler;
Nico Huber83693c82016-10-08 22:17:55 +020021
Elyes Haouas066e52e2022-09-26 12:48:47 +020022use type HW.Word32;
23
Nico Huber83693c82016-10-08 22:17:55 +020024package HW.GFX.GMA
25with
26 Abstract_State =>
27 (State,
28 Init_State,
Nico Huber83693c82016-10-08 22:17:55 +020029 (Device_State with External)),
Nico Huber27088aa2018-06-10 13:28:05 +020030 Initializes => Init_State
Nico Huber83693c82016-10-08 22:17:55 +020031is
32
Nico Hubera02b2c62018-01-09 15:58:34 +010033 GTT_Page_Size : constant := 4096;
34 type GTT_Address_Type is mod 2 ** 39;
35 subtype GTT_Range is Natural range 0 .. 16#8_0000# - 1;
36 GTT_Rotation_Offset : constant GTT_Range := GTT_Range'Last / 2 + 1;
37
Nico Huberc505ae72024-07-21 20:03:38 +020038 type Generation is
39 (I945,
40 G45,
41 Ironlake,
42 Haswell,
43 Broxton,
44 Skylake,
45 Tigerlake,
46 AlderlakeP);
Nico Huber6621a142018-06-07 23:56:54 +020047
Nico Huber83693c82016-10-08 22:17:55 +020048 type CPU_Type is
Arthur Heymans960e2392026-03-03 19:45:24 +010049 (I945G,
50 I945GM,
Arthur Heymans3f37cce2026-03-03 18:52:12 +010051 GM965,
Arthur Heymans6dc78432026-06-18 09:34:50 +020052 Pineview,
53 Pineview_M,
Arthur Heymans960e2392026-03-03 19:45:24 +010054 G45,
Nico Huber7f3e2802019-09-28 20:40:55 +020055 GM45,
Arthur Heymans73ea0322018-03-28 17:17:07 +020056 Ironlake,
Nico Huber83693c82016-10-08 22:17:55 +020057 Sandybridge,
58 Ivybridge,
59 Haswell,
60 Broadwell,
Nico Huber21da5742017-01-20 14:00:53 +010061 Broxton,
Nico Huber88badbe2018-09-27 16:36:47 +020062 Skylake,
Tim Wawrzynczak605660b2022-06-08 12:48:19 -060063 Kabylake,
Tim Wawrzynczake9631d82022-09-09 12:26:32 -060064 Tigerlake,
Nico Huberc505ae72024-07-21 20:03:38 +020065 AlderlakeP);
Nico Huber83693c82016-10-08 22:17:55 +020066
Nico Huber25fdb152019-02-17 15:54:39 +010067 type CPU_Variant is (Normal, ULT, ULX);
Nico Huber83693c82016-10-08 22:17:55 +020068
Nico Hubere79babd2020-12-20 01:33:26 +010069 type PCH_Type is
70 (No_PCH,
71 Ibex_Peak,
72 Cougar_Point, -- Panther Point compatible
73 Lynx_Point, -- Wildcat Point compatible
Nico Huberdde06302020-12-20 02:18:30 +010074 Sunrise_Point, -- Union Point compatible
Tim Wawrzynczak605660b2022-06-08 12:48:19 -060075 Cannon_Point,
Tim Wawrzynczake9631d82022-09-09 12:26:32 -060076 Tiger_Point,
77 Alder_Point);
Nico Hubere79babd2020-12-20 01:33:26 +010078
Nico Huber83693c82016-10-08 22:17:55 +020079 type Port_Type is
80 (Disabled,
Nico Huber8beafd72020-01-07 14:59:44 +010081 LVDS,
82 eDP,
Nico Huber83693c82016-10-08 22:17:55 +020083 DP1,
84 DP2,
85 DP3,
Nico Huberad096092024-07-02 18:45:44 +020086 DP_TC1, -- DP_TC ports use Type-C lanes to
87 DP_TC2, -- implement physical DP or DP++ ports.
88 DP_TC3,
89 DP_TC4,
90 HDMI1, -- HDMI ports share lanes with their DP siblings.
91 HDMI2, -- They can also be implemented as DVI.
92 HDMI3,
93 HDMI_TC1, -- HDMI_TC use Type-C lanes to implement
94 HDMI_TC2, -- physical HDMI, DVI or the HDMI part of DP++.
95 HDMI_TC3,
96 HDMI_TC4,
Tim Wawrzynczak605660b2022-06-08 12:48:19 -060097 Analog,
Nico Huberad096092024-07-02 18:45:44 +020098 USBC1, -- Type-C lanes used to implement
99 USBC2, -- physical USB-C ports with DP Alt Mode.
100 USBC3,
101 USBC4);
Nico Huber040d9b62019-02-18 00:52:00 +0100102 subtype Active_Port_Type is Port_Type
103 range Port_Type'Succ (Disabled) .. Port_Type'Last;
Nico Huber8beafd72020-01-07 14:59:44 +0100104 subtype Internal_Port_Type is Port_Type range LVDS .. eDP;
Nico Huberad096092024-07-02 18:45:44 +0200105 subtype Physical_DP_Ports is Port_Type range DP1 .. DP_TC4;
106 subtype Physical_HDMI_Ports is Port_Type range HDMI1 .. HDMI_TC4;
107 subtype Physical_USBC_Ports is Port_Type range USBC1 .. USBC4;
Nico Huber83693c82016-10-08 22:17:55 +0200108
Nico Huber20fd3fc2026-06-23 11:26:16 +0000109 type Alignment is
110 (Top_Left, Top, Top_Right,
111 Left, Center, Right,
112 Bottom_Left, Bottom, Bottom_Right);
113 type Scaling is
114 (None, -- Copy framebuffer contents 1:1
115 Fit, -- Scale up to fit the available space, maintaining aspect ratio
116 Stretch); -- Scale up to fill the entire space, ignoring aspect ratio
117
Nico Hubera02b2c62018-01-09 15:58:34 +0100118 type Cursor_Mode is (No_Cursor, ARGB_Cursor);
119 type Cursor_Size is (Cursor_64x64, Cursor_128x128, Cursor_256x256);
120 Cursor_Width : constant array (Cursor_Size) of Width_Type := (64, 128, 256);
121
122 subtype Cursor_Pos is Int32 range Int32'First / 2 .. Int32'Last / 2;
123
124 type Cursor_Type is record
125 Mode : Cursor_Mode;
126 Size : Cursor_Size;
127 Center_X : Cursor_Pos;
128 Center_Y : Cursor_Pos;
129 GTT_Offset : GTT_Range;
130 end record;
131 Default_Cursor : constant Cursor_Type :=
132 (Mode => No_Cursor,
133 Size => Cursor_Size'First,
134 Center_X => 0,
135 Center_Y => 0,
136 GTT_Offset => 0);
137
Nico Huber99f10f32016-11-20 00:34:05 +0100138 type Pipe_Config is record
Nico Huber83693c82016-10-08 22:17:55 +0200139 Port : Port_Type;
140 Framebuffer : Framebuffer_Type;
Nico Huber20fd3fc2026-06-23 11:26:16 +0000141 Alignment : GMA.Alignment;
142 Scaling : GMA.Scaling;
Nico Hubera02b2c62018-01-09 15:58:34 +0100143 Cursor : Cursor_Type;
Nico Huber83693c82016-10-08 22:17:55 +0200144 Mode : Mode_Type;
145 end record;
Nico Huber99f10f32016-11-20 00:34:05 +0100146 type Pipe_Index is (Primary, Secondary, Tertiary);
147 type Pipe_Configs is array (Pipe_Index) of Pipe_Config;
Nico Huber83693c82016-10-08 22:17:55 +0200148
Nico Huber3675db52016-11-04 16:27:29 +0100149 -- Special framebuffer offset to indicate legacy VGA plane.
150 -- Only valid on primary pipe.
151 VGA_PLANE_FRAMEBUFFER_OFFSET : constant := 16#ffff_ffff#;
152
Nico Huberbebca132017-06-12 23:04:46 +0200153 pragma Warnings (GNATprove, Off, "unused variable ""Write_Delay""",
154 Reason => "Write_Delay is used for debugging only");
Nico Huber83693c82016-10-08 22:17:55 +0200155 procedure Initialize
Nico Huber2b6f6992017-07-09 18:11:34 +0200156 (Write_Delay : in Word64 := 0;
Nico Huber793a8d42016-11-21 18:57:03 +0100157 Clean_State : in Boolean := False;
Nico Huber83693c82016-10-08 22:17:55 +0200158 Success : out Boolean)
159 with
160 Global =>
Nico Huber27088aa2018-06-10 13:28:05 +0200161 (In_Out => (Device_State, Port_IO.State),
Nico Hubere317e9c2019-09-29 03:03:18 +0200162 Output => (State, Init_State),
Nico Huber83693c82016-10-08 22:17:55 +0200163 Input => (Time.State)),
164 Post => Success = Is_Initialized;
165 function Is_Initialized return Boolean
166 with
167 Global => (Input => Init_State);
Nico Huberbebca132017-06-12 23:04:46 +0200168 pragma Warnings (GNATprove, On, "unused variable ""Write_Delay""");
Nico Huber83693c82016-10-08 22:17:55 +0200169
Nico Huber42fb2d02017-09-01 17:01:51 +0200170 procedure Power_Up_VGA
171 with
Nico Hubercf88f3d2018-06-05 13:27:34 +0200172 Global =>
Tim Wawrzynczak5473d292023-02-06 16:46:33 -0700173 (Input => (Time.State),
174 In_Out => (Device_State, State),
Nico Hubercf88f3d2018-06-05 13:27:34 +0200175 Proof_In => (Init_State)),
Nico Huber42fb2d02017-09-01 17:01:51 +0200176 Pre => Is_Initialized;
177
Nico Hubercf88f3d2018-06-05 13:27:34 +0200178 ----------------------------------------------------------------------------
Nico Huber83693c82016-10-08 22:17:55 +0200179
Nico Hubercf88f3d2018-06-05 13:27:34 +0200180 procedure Update_Outputs (Configs : Pipe_Configs)
181 with
182 Global =>
Nico Hubere317e9c2019-09-29 03:03:18 +0200183 (Input => (Time.State),
Nico Hubercf88f3d2018-06-05 13:27:34 +0200184 In_Out => (State, Device_State, Port_IO.State),
185 Proof_In => (Init_State)),
186 Pre => Is_Initialized;
187
188 procedure Update_Cursor (Pipe : Pipe_Index; Cursor : Cursor_Type)
189 with
190 Global =>
Nico Hubere317e9c2019-09-29 03:03:18 +0200191 (In_Out => (State, Device_State),
Nico Hubercf88f3d2018-06-05 13:27:34 +0200192 Proof_In => (Init_State)),
Nico Hubere317e9c2019-09-29 03:03:18 +0200193 Pre => Is_Initialized;
Nico Hubercf88f3d2018-06-05 13:27:34 +0200194
Nico Huber15ffc4f2018-01-11 14:44:43 +0100195 procedure Place_Cursor
196 (Pipe : Pipe_Index;
197 X : Cursor_Pos;
Nico Hubercf88f3d2018-06-05 13:27:34 +0200198 Y : Cursor_Pos)
199 with
200 Global =>
Nico Hubere317e9c2019-09-29 03:03:18 +0200201 (In_Out => (State, Device_State),
Nico Hubercf88f3d2018-06-05 13:27:34 +0200202 Proof_In => (Init_State)),
Nico Hubere317e9c2019-09-29 03:03:18 +0200203 Pre => Is_Initialized;
Nico Hubercf88f3d2018-06-05 13:27:34 +0200204
Nico Huber15ffc4f2018-01-11 14:44:43 +0100205 procedure Move_Cursor
206 (Pipe : Pipe_Index;
207 X : Cursor_Pos;
Nico Hubercf88f3d2018-06-05 13:27:34 +0200208 Y : Cursor_Pos)
209 with
210 Global =>
Nico Hubere317e9c2019-09-29 03:03:18 +0200211 (In_Out => (State, Device_State),
Nico Hubercf88f3d2018-06-05 13:27:34 +0200212 Proof_In => (Init_State)),
Nico Hubere317e9c2019-09-29 03:03:18 +0200213 Pre => Is_Initialized;
Nico Huber15ffc4f2018-01-11 14:44:43 +0100214
Nico Hubercf88f3d2018-06-05 13:27:34 +0200215 ----------------------------------------------------------------------------
Nico Huber83693c82016-10-08 22:17:55 +0200216
Nico Huberbc0588e2020-07-21 12:17:19 +0200217 procedure Backlight_On (Port : Active_Port_Type)
218 with
219 Global => (In_Out => Device_State);
220
221 procedure Backlight_Off (Port : Active_Port_Type)
222 with
223 Global => (In_Out => Device_State);
224
225 procedure Set_Brightness (Port : Active_Port_Type; Level : Word32)
226 with
227 Global => (In_Out => Device_State);
228
229 procedure Get_Max_Brightness (Port : Active_Port_Type; Level : out Word32)
230 with
231 Global => (In_Out => Device_State);
232
233 ----------------------------------------------------------------------------
234
Nico Huber83693c82016-10-08 22:17:55 +0200235 procedure Write_GTT
236 (GTT_Page : GTT_Range;
237 Device_Address : GTT_Address_Type;
Nico Hubercf88f3d2018-06-05 13:27:34 +0200238 Valid : Boolean)
239 with
Nico Huberadfe11f2018-06-10 14:59:04 +0200240 Global =>
Nico Hubere317e9c2019-09-29 03:03:18 +0200241 (Input => State,
Nico Huberadfe11f2018-06-10 14:59:04 +0200242 In_Out => Device_State, Proof_In => Init_State),
Nico Hubercf88f3d2018-06-05 13:27:34 +0200243 Pre => Is_Initialized;
Nico Huber83693c82016-10-08 22:17:55 +0200244
Nico Huberceda17d2018-06-09 22:00:29 +0200245 procedure Read_GTT
246 (Device_Address : out GTT_Address_Type;
247 Valid : out Boolean;
248 GTT_Page : in GTT_Range)
249 with
Nico Huberadfe11f2018-06-10 14:59:04 +0200250 Global =>
Nico Hubere317e9c2019-09-29 03:03:18 +0200251 (Input => State,
Nico Huberadfe11f2018-06-10 14:59:04 +0200252 In_Out => Device_State, Proof_In => Init_State),
Nico Huberceda17d2018-06-09 22:00:29 +0200253 Pre => Is_Initialized;
254
Arthur Heymans960e2392026-03-03 19:45:24 +0100255 procedure GTT_Entry_Count (Count : out Natural)
256 with
257 Global =>
258 (Input => State,
259 In_Out => Device_State, Proof_In => Init_State),
260 Pre => Is_Initialized and HW.Config.Dynamic_MMIO;
261
Nico Huber5374c3a2017-07-15 21:48:06 +0200262 procedure Setup_Default_FB
263 (FB : in Framebuffer_Type;
264 Clear : in Boolean := True;
265 Success : out Boolean)
Nico Huber194e57e2017-07-15 21:15:46 +0200266 with
Nico Hubercf88f3d2018-06-05 13:27:34 +0200267 Global =>
Nico Hubere317e9c2019-09-29 03:03:18 +0200268 (In_Out =>
Nico Hubercf88f3d2018-06-05 13:27:34 +0200269 (State, Device_State,
270 Framebuffer_Filler.State, Framebuffer_Filler.Base_Address),
271 Proof_In => (Init_State)),
Nico Huber5374c3a2017-07-15 21:48:06 +0200272 Pre => Is_Initialized and HW.Config.Dynamic_MMIO;
Nico Huber83693c82016-10-08 22:17:55 +0200273
Nico Huberc3f66f62017-07-16 21:39:54 +0200274 procedure Map_Linear_FB (Linear_FB : out Word64; FB : in Framebuffer_Type)
275 with
Nico Hubercf88f3d2018-06-05 13:27:34 +0200276 Global =>
Nico Hubere317e9c2019-09-29 03:03:18 +0200277 (In_Out => (State, Device_State),
Nico Hubercf88f3d2018-06-05 13:27:34 +0200278 Proof_In => (Init_State)),
Nico Hubere317e9c2019-09-29 03:03:18 +0200279 Pre => Is_Initialized and HW.Config.Dynamic_MMIO;
Nico Huberc3f66f62017-07-16 21:39:54 +0200280
Nico Hubercf88f3d2018-06-05 13:27:34 +0200281 ----------------------------------------------------------------------------
282
283 pragma Warnings (GNATprove, Off, "subprogram ""Dump_Configs"" has no effect",
284 Reason => "It's only used for debugging");
285 procedure Dump_Configs (Configs : Pipe_Configs);
286
Nico Huber83693c82016-10-08 22:17:55 +0200287private
288
Nico Huberc5c66ec2019-09-28 23:59:45 +0200289 use type HW.PCI.Index;
290 procedure PCI_Read16 (Value : out Word16; Offset : HW.PCI.Index)
291 with
Nico Huber4ba49112020-06-10 16:31:36 +0200292 Pre => Offset mod 2 = 0;
Nico Huberc5c66ec2019-09-28 23:59:45 +0200293
294 ----------------------------------------------------------------------------
295
Nico Huber3299ad52018-06-02 16:53:39 +0200296 -- For the default framebuffer setup (see below) with 90 degree rotations,
297 -- we expect the offset which is used for the final scanout to be above
298 -- `GTT_Rotation_Offset`. So we can use `Offset - GTT_Rotation_Offset` for
299 -- the physical memory location and aperture mapping.
300 function Phys_Offset (FB : Framebuffer_Type) return Word32 is
301 (if Rotation_90 (FB)
302 then FB.Offset - Word32 (GTT_Rotation_Offset) * GTT_Page_Size
303 else FB.Offset);
304
Nico Huber8c45bcf2016-11-20 17:30:57 +0100305 ----------------------------------------------------------------------------
306 -- State tracking for the currently configured pipes
307
308 Cur_Configs : Pipe_Configs with Part_Of => State;
309
Nico Huber3d06de82018-05-29 01:35:04 +0200310 function Requires_Scaling (Pipe_Cfg : Pipe_Config) return Boolean is
311 (Requires_Scaling (Pipe_Cfg.Framebuffer, Pipe_Cfg.Mode));
312
Nico Huberb217ece2018-06-02 16:56:35 +0200313 function Scaling_Type (Pipe_Cfg : Pipe_Config) return Scaling_Aspect is
314 (Scaling_Type (Pipe_Cfg.Framebuffer, Pipe_Cfg.Mode));
315
Nico Huber8c45bcf2016-11-20 17:30:57 +0100316 ----------------------------------------------------------------------------
317 -- Internal representation of a single pipe's configuration
318
Tim Wawrzynczak605660b2022-06-08 12:48:19 -0600319 type GPU_Port is
320 (DIGI_A, DIGI_B, DIGI_C, DIGI_D, DIGI_E,
321 DDI_TC1, DDI_TC2, DDI_TC3, DDI_TC4, DDI_TC5, DDI_TC6,
322 LVDS, VGA);
Nico Huber83693c82016-10-08 22:17:55 +0200323
324 subtype Digital_Port is GPU_Port range DIGI_A .. DIGI_E;
Arthur Heymans5d08a932018-03-28 17:00:18 +0200325 subtype GMCH_DP_Port is GPU_Port range DIGI_B .. DIGI_D;
326 subtype GMCH_HDMI_Port is GPU_Port range DIGI_B .. DIGI_C;
Nico Huber09472732026-04-20 22:33:33 +0200327 subtype DDI_Port is GPU_Port range DIGI_A .. DDI_TC6;
Tim Wawrzynczak605660b2022-06-08 12:48:19 -0600328 subtype Combo_Port is GPU_Port range DIGI_A .. DIGI_C;
329 subtype USBC_Port is GPU_Port range DDI_TC1 .. DDI_TC6;
Tim Wawrzynczak5473d292023-02-06 16:46:33 -0700330 subtype TGL_Digital_Port is GPU_Port range DIGI_A .. DDI_TC6
331 with
332 Static_Predicate => (TGL_Digital_Port /= DIGI_D and TGL_Digital_Port /= DIGI_E);
Nico Huber09472732026-04-20 22:33:33 +0200333 subtype XELPD_Digital_Port is GPU_Port range DIGI_A .. DDI_TC4;
Tim Wawrzynczak605660b2022-06-08 12:48:19 -0600334
335 function Is_Digital_Port (Port : GPU_Port) return Boolean is
336 (Port in Digital_Port or Port in TGL_Digital_Port);
Nico Huber83693c82016-10-08 22:17:55 +0200337
338 type PCH_Port is
339 (PCH_DAC, PCH_LVDS,
Tim Wawrzynczak605660b2022-06-08 12:48:19 -0600340 PCH_HDMI_A, PCH_HDMI_B, PCH_HDMI_C, PCH_HDMI_D,
341 PCH_DP_B, PCH_DP_C, PCH_DP_D,
342 PCH_TC1, PCH_TC2, PCH_TC3, PCH_TC4, PCH_TC5, PCH_TC6);
Nico Huber83693c82016-10-08 22:17:55 +0200343
Tim Wawrzynczak605660b2022-06-08 12:48:19 -0600344 subtype PCH_HDMI_Port is PCH_Port range PCH_HDMI_A .. PCH_HDMI_D;
Nico Huber83693c82016-10-08 22:17:55 +0200345 subtype PCH_DP_Port is PCH_Port range PCH_DP_B .. PCH_DP_D;
Tim Wawrzynczak605660b2022-06-08 12:48:19 -0600346 subtype PCH_TC_Port is PCH_Port range PCH_TC1 .. PCH_TC6;
Nico Huber83693c82016-10-08 22:17:55 +0200347
Nico Huber5dbaf4b2020-01-08 17:24:58 +0100348 type Panel_Control is (No_Panel, Panel_1, Panel_2);
349 subtype Valid_Panels is Panel_Control range Panel_1 .. Panel_2;
Nico Huber2bbd6e72020-01-07 18:22:59 +0100350
Nico Huber83693c82016-10-08 22:17:55 +0200351 type Port_Config is
352 record
353 Port : GPU_Port;
354 PCH_Port : GMA.PCH_Port;
355 Display : Display_Type;
Nico Huber2bbd6e72020-01-07 18:22:59 +0100356 Panel : Panel_Control;
Nico Huber83693c82016-10-08 22:17:55 +0200357 Mode : Mode_Type;
358 Is_FDI : Boolean;
Nico Huber7b36b692024-03-07 15:20:29 +0000359 Is_eDP : Boolean;
Nico Huber83693c82016-10-08 22:17:55 +0200360 FDI : DP_Link;
361 DP : DP_Link;
362 end record;
363
364 type FDI_Training_Type is (Simple_Training, Full_Training, Auto_Training);
365
366 ----------------------------------------------------------------------------
367
Tim Wawrzynczak24748f32022-09-09 10:54:05 -0600368 type DP_Port is (DP_A, DP_B, DP_C, DP_D, DP_E, DP_F, DP_G, DP_H, DP_I);
Nico Huber83693c82016-10-08 22:17:55 +0200369
Nico Huber247adf32017-06-12 14:39:11 +0200370 ----------------------------------------------------------------------------
371
372 subtype DDI_HDMI_Buf_Trans_Range is Integer range 0 .. 11;
373
Nico Huber0164b022017-08-24 15:12:51 +0200374 ----------------------------------------------------------------------------
375
Nico Huberc5c767a2018-06-03 01:09:04 +0200376 Tile_Width : constant array (Tiling_Type) of Width_Type :=
Nico Huber0164b022017-08-24 15:12:51 +0200377 (Linear => 16, X_Tiled => 128, Y_Tiled => 32);
Nico Huberc5c767a2018-06-03 01:09:04 +0200378 Tile_Rows : constant array (Tiling_Type) of Height_Type :=
Nico Huber9b479412017-08-27 11:55:56 +0200379 (Linear => 1, X_Tiled => 8, Y_Tiled => 32);
Nico Huber0164b022017-08-24 15:12:51 +0200380
Nico Huber5ef4d602017-12-13 13:56:47 +0100381 function FB_Pitch (Px : Pos_Pixel_Type; FB : Framebuffer_Type) return Natural
382 is (Natural (Div_Round_Up
383 (Pixel_To_Bytes (Px, FB), Tile_Width (FB.Tiling) * 4)));
Nico Huber0164b022017-08-24 15:12:51 +0200384
385 function Valid_Stride (FB : Framebuffer_Type) return Boolean is
Nico Huber5ef4d602017-12-13 13:56:47 +0100386 (FB.Width + FB.Start_X <= FB.Stride and
Nico Huber9b479412017-08-27 11:55:56 +0200387 Pixel_To_Bytes (FB.Stride, FB) mod (Tile_Width (FB.Tiling) * 4) = 0 and
Nico Huber5ef4d602017-12-13 13:56:47 +0100388 FB.Height + FB.Start_Y <= FB.V_Stride and
Nico Huber9b479412017-08-27 11:55:56 +0200389 FB.V_Stride mod Tile_Rows (FB.Tiling) = 0);
Nico Huber0164b022017-08-24 15:12:51 +0200390
Nico Huber1dae2202020-10-05 13:31:25 +0200391 ----------------------------------------------------------------------------
392
393 type Cursor_Coord is record
394 X : Cursor_Pos;
395 Y : Cursor_Pos;
396 end record;
397
Nico Huber83693c82016-10-08 22:17:55 +0200398end HW.GFX.GMA;