blob: fb5c7e567253e5c644fac459f974119bcd8fe00e [file] [log] [blame]
Nico Huber83693c82016-10-08 22:17:55 +02001--
Nico Huber247adf32017-06-12 14:39:11 +02002-- Copyright (C) 2015-2017 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;
18with HW.Port_IO;
19
20package HW.GFX.GMA
21with
22 Abstract_State =>
23 (State,
24 Init_State,
25 Config_State,
26 (Device_State with External)),
27 Initializes =>
28 (Init_State,
29 Config_State)
30is
31
32 type CPU_Type is
Arthur Heymans73ea0322018-03-28 17:17:07 +020033 (G45,
34 Ironlake,
Nico Huber83693c82016-10-08 22:17:55 +020035 Sandybridge,
36 Ivybridge,
37 Haswell,
38 Broadwell,
Nico Huber21da5742017-01-20 14:00:53 +010039 Broxton,
Nico Huber83693c82016-10-08 22:17:55 +020040 Skylake);
41
42 type CPU_Variant is (Normal, ULT);
43
44 type Port_Type is
45 (Disabled,
46 Internal,
47 DP1,
48 DP2,
49 DP3,
Nico Huber0d454cd2016-11-21 13:33:43 +010050 HDMI1, -- or DVI
51 HDMI2, -- or DVI
52 HDMI3, -- or DVI
Nico Huber83693c82016-10-08 22:17:55 +020053 Analog);
Nico Huber83693c82016-10-08 22:17:55 +020054
Nico Huber99f10f32016-11-20 00:34:05 +010055 type Pipe_Config is record
Nico Huber83693c82016-10-08 22:17:55 +020056 Port : Port_Type;
57 Framebuffer : Framebuffer_Type;
58 Mode : Mode_Type;
59 end record;
Nico Huber99f10f32016-11-20 00:34:05 +010060 type Pipe_Index is (Primary, Secondary, Tertiary);
61 type Pipe_Configs is array (Pipe_Index) of Pipe_Config;
Nico Huber83693c82016-10-08 22:17:55 +020062
Nico Huber3675db52016-11-04 16:27:29 +010063 -- Special framebuffer offset to indicate legacy VGA plane.
64 -- Only valid on primary pipe.
65 VGA_PLANE_FRAMEBUFFER_OFFSET : constant := 16#ffff_ffff#;
66
Nico Huberbebca132017-06-12 23:04:46 +020067 pragma Warnings (GNATprove, Off, "unused variable ""Write_Delay""",
68 Reason => "Write_Delay is used for debugging only");
Nico Huber83693c82016-10-08 22:17:55 +020069 procedure Initialize
Nico Huber2b6f6992017-07-09 18:11:34 +020070 (Write_Delay : in Word64 := 0;
Nico Huber793a8d42016-11-21 18:57:03 +010071 Clean_State : in Boolean := False;
Nico Huber83693c82016-10-08 22:17:55 +020072 Success : out Boolean)
73 with
74 Global =>
75 (In_Out => (Config_State, Device_State, Port_IO.State),
76 Output => (State, Init_State),
77 Input => (Time.State)),
78 Post => Success = Is_Initialized;
79 function Is_Initialized return Boolean
80 with
81 Global => (Input => Init_State);
Nico Huberbebca132017-06-12 23:04:46 +020082 pragma Warnings (GNATprove, On, "unused variable ""Write_Delay""");
Nico Huber83693c82016-10-08 22:17:55 +020083
Nico Huber42fb2d02017-09-01 17:01:51 +020084 pragma Warnings (GNATprove, Off, "subprogram ""Power_Up_VGA"" has no effect",
85 Reason => "Effect depends on the platform compiled for");
86 procedure Power_Up_VGA
87 with
88 Pre => Is_Initialized;
89
Nico Huber99f10f32016-11-20 00:34:05 +010090 procedure Update_Outputs (Configs : Pipe_Configs);
Nico Huber83693c82016-10-08 22:17:55 +020091
92 pragma Warnings (GNATprove, Off, "subprogram ""Dump_Configs"" has no effect",
93 Reason => "It's only used for debugging");
Nico Huber99f10f32016-11-20 00:34:05 +010094 procedure Dump_Configs (Configs : Pipe_Configs);
Nico Huber83693c82016-10-08 22:17:55 +020095
Nico Huber194e57e2017-07-15 21:15:46 +020096 GTT_Page_Size : constant := 4096;
Nico Huber83693c82016-10-08 22:17:55 +020097 type GTT_Address_Type is mod 2 ** 39;
Nico Huber194e57e2017-07-15 21:15:46 +020098 subtype GTT_Range is Natural range 0 .. 16#8_0000# - 1;
Nico Huber9b479412017-08-27 11:55:56 +020099 GTT_Rotation_Offset : constant GTT_Range := GTT_Range'Last / 2 + 1;
100
Nico Huber83693c82016-10-08 22:17:55 +0200101 procedure Write_GTT
102 (GTT_Page : GTT_Range;
103 Device_Address : GTT_Address_Type;
104 Valid : Boolean);
105
Nico Huber34be6542017-12-13 09:26:24 +0100106 -- For the default framebuffer setup (see below) with 90 degree rotations,
107 -- we expect the offset which is used for the final scanout to be above
108 -- `GTT_Rotation_Offset`. So we can use `Offset - GTT_Rotation_Offset` for
109 -- the physical memory location and aperture mapping.
110 function Phys_Offset (FB : Framebuffer_Type) return Word32 is
111 (if Rotation_90 (FB)
112 then FB.Offset - Word32 (GTT_Rotation_Offset) * GTT_Page_Size
113 else FB.Offset);
114
Nico Huber5374c3a2017-07-15 21:48:06 +0200115 procedure Setup_Default_FB
116 (FB : in Framebuffer_Type;
117 Clear : in Boolean := True;
118 Success : out Boolean)
Nico Huber194e57e2017-07-15 21:15:46 +0200119 with
Nico Huber5374c3a2017-07-15 21:48:06 +0200120 Pre => Is_Initialized and HW.Config.Dynamic_MMIO;
Nico Huber83693c82016-10-08 22:17:55 +0200121
Nico Huberc3f66f62017-07-16 21:39:54 +0200122 procedure Map_Linear_FB (Linear_FB : out Word64; FB : in Framebuffer_Type)
123 with
124 Pre => Is_Initialized and HW.Config.Dynamic_MMIO;
125
Nico Huber83693c82016-10-08 22:17:55 +0200126private
127
Nico Huber8c45bcf2016-11-20 17:30:57 +0100128 ----------------------------------------------------------------------------
129 -- State tracking for the currently configured pipes
130
131 Cur_Configs : Pipe_Configs with Part_Of => State;
132
133 ----------------------------------------------------------------------------
134 -- Internal representation of a single pipe's configuration
135
136 subtype Active_Port_Type is Port_Type
137 range Port_Type'Succ (Disabled) .. Port_Type'Last;
138
Arthur Heymans5d08a932018-03-28 17:00:18 +0200139 type GPU_Port is (DIGI_A, DIGI_B, DIGI_C, DIGI_D, DIGI_E, LVDS, VGA);
Nico Huber83693c82016-10-08 22:17:55 +0200140
141 subtype Digital_Port is GPU_Port range DIGI_A .. DIGI_E;
Arthur Heymans5d08a932018-03-28 17:00:18 +0200142 subtype GMCH_DP_Port is GPU_Port range DIGI_B .. DIGI_D;
143 subtype GMCH_HDMI_Port is GPU_Port range DIGI_B .. DIGI_C;
Nico Huber83693c82016-10-08 22:17:55 +0200144
145 type PCH_Port is
146 (PCH_DAC, PCH_LVDS,
147 PCH_HDMI_B, PCH_HDMI_C, PCH_HDMI_D,
148 PCH_DP_B, PCH_DP_C, PCH_DP_D);
149
150 subtype PCH_HDMI_Port is PCH_Port range PCH_HDMI_B .. PCH_HDMI_D;
151 subtype PCH_DP_Port is PCH_Port range PCH_DP_B .. PCH_DP_D;
152
Nico Huber83693c82016-10-08 22:17:55 +0200153 type Port_Config is
154 record
155 Port : GPU_Port;
156 PCH_Port : GMA.PCH_Port;
157 Display : Display_Type;
158 Mode : Mode_Type;
159 Is_FDI : Boolean;
160 FDI : DP_Link;
161 DP : DP_Link;
162 end record;
163
164 type FDI_Training_Type is (Simple_Training, Full_Training, Auto_Training);
165
166 ----------------------------------------------------------------------------
167
168 type DP_Port is (DP_A, DP_B, DP_C, DP_D);
169
Nico Huber247adf32017-06-12 14:39:11 +0200170 ----------------------------------------------------------------------------
171
172 subtype DDI_HDMI_Buf_Trans_Range is Integer range 0 .. 11;
173
Nico Huber0164b022017-08-24 15:12:51 +0200174 ----------------------------------------------------------------------------
175
176 Tile_Width : constant array (Tiling_Type) of Pos32 :=
177 (Linear => 16, X_Tiled => 128, Y_Tiled => 32);
Nico Huber9b479412017-08-27 11:55:56 +0200178 Tile_Rows : constant array (Tiling_Type) of Pos32 :=
179 (Linear => 1, X_Tiled => 8, Y_Tiled => 32);
Nico Huber0164b022017-08-24 15:12:51 +0200180
Nico Huber5ef4d602017-12-13 13:56:47 +0100181 function FB_Pitch (Px : Pos_Pixel_Type; FB : Framebuffer_Type) return Natural
182 is (Natural (Div_Round_Up
183 (Pixel_To_Bytes (Px, FB), Tile_Width (FB.Tiling) * 4)));
Nico Huber0164b022017-08-24 15:12:51 +0200184
185 function Valid_Stride (FB : Framebuffer_Type) return Boolean is
Nico Huber5ef4d602017-12-13 13:56:47 +0100186 (FB.Width + FB.Start_X <= FB.Stride and
Nico Huber9b479412017-08-27 11:55:56 +0200187 Pixel_To_Bytes (FB.Stride, FB) mod (Tile_Width (FB.Tiling) * 4) = 0 and
Nico Huber5ef4d602017-12-13 13:56:47 +0100188 FB.Height + FB.Start_Y <= FB.V_Stride and
Nico Huber9b479412017-08-27 11:55:56 +0200189 FB.V_Stride mod Tile_Rows (FB.Tiling) = 0);
Nico Huber0164b022017-08-24 15:12:51 +0200190
Nico Huber83693c82016-10-08 22:17:55 +0200191end HW.GFX.GMA;