blob: 82f5222eafbb30fbc37d875a3090e9dfdfc55289 [file] [log] [blame]
Nico Huber83693c82016-10-08 22:17:55 +02001--
Nico Huberfdb0df12018-02-07 14:30:34 +01002-- Copyright (C) 2015-2018 secunet Security Networks AG
Nico Huber83693c82016-10-08 22:17:55 +02003--
4-- This program is free software; you can redistribute it and/or modify
5-- it under the terms of the GNU General Public License as published by
Nico Huber125a29e2016-10-18 00:23:54 +02006-- the Free Software Foundation; either version 2 of the License, or
7-- (at your option) any later version.
Nico Huber83693c82016-10-08 22:17:55 +02008--
9-- This program is distributed in the hope that it will be useful,
10-- but WITHOUT ANY WARRANTY; without even the implied warranty of
11-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12-- GNU General Public License for more details.
13--
14
15with HW.Debug;
16with GNAT.Source_Info;
17
Nico Huber7ad2d652016-12-07 15:19:32 +010018with HW.GFX.GMA.Transcoder;
Nico Huber83693c82016-10-08 22:17:55 +020019
20package body HW.GFX.GMA.Pipe_Setup is
21
Nico Huberfbb42202016-11-07 15:08:26 +010022 ILK_DISPLAY_CHICKEN1_VGA_MASK : constant := 7 * 2 ** 29;
23 ILK_DISPLAY_CHICKEN1_VGA_ENABLE : constant := 5 * 2 ** 29;
24 ILK_DISPLAY_CHICKEN2_VGA_MASK : constant := 1 * 2 ** 25;
25 ILK_DISPLAY_CHICKEN2_VGA_ENABLE : constant := 0 * 2 ** 25;
26
Nico Huber7ad2d652016-12-07 15:19:32 +010027 DSPCNTR_ENABLE : constant := 1 * 2 ** 31;
28 DSPCNTR_GAMMA_CORRECTION : constant := 1 * 2 ** 30;
Nico Huber7ad2d652016-12-07 15:19:32 +010029 DSPCNTR_FORMAT_MASK : constant := 15 * 2 ** 26;
Nico Huberab69e362018-05-29 21:20:30 +020030 DSPCNTR_DISABLE_TRICKLE_FEED : constant := 1 * 2 ** 14;
31 DSPCNTR_TILED_SURFACE_LINEAR : constant := 0 * 2 ** 10;
32 DSPCNTR_TILED_SURFACE_X_TILED : constant := 1 * 2 ** 10;
33
34 DSPCNTR_TILED_SURFACE : constant array (Tiling_Type) of Word32 :=
35 (Linear => DSPCNTR_TILED_SURFACE_LINEAR,
36 X_Tiled => DSPCNTR_TILED_SURFACE_X_TILED,
37 Y_Tiled => 0); -- unsupported
Nico Huber83693c82016-10-08 22:17:55 +020038
39 DSPCNTR_MASK : constant Word32 :=
40 DSPCNTR_ENABLE or
41 DSPCNTR_GAMMA_CORRECTION or
42 DSPCNTR_FORMAT_MASK or
Nico Huberab69e362018-05-29 21:20:30 +020043 DSPCNTR_DISABLE_TRICKLE_FEED or
44 DSPCNTR_TILED_SURFACE_X_TILED;
Nico Huber83693c82016-10-08 22:17:55 +020045
46 PLANE_CTL_PLANE_ENABLE : constant := 1 * 2 ** 31;
47 PLANE_CTL_SRC_PIX_FMT_RGB_32B_8888 : constant := 4 * 2 ** 24;
48 PLANE_CTL_PLANE_GAMMA_DISABLE : constant := 1 * 2 ** 13;
Nico Huber0164b022017-08-24 15:12:51 +020049 PLANE_CTL_TILED_SURFACE_MASK : constant := 7 * 2 ** 10;
50 PLANE_CTL_TILED_SURFACE_LINEAR : constant := 0 * 2 ** 10;
51 PLANE_CTL_TILED_SURFACE_X_TILED : constant := 1 * 2 ** 10;
52 PLANE_CTL_TILED_SURFACE_Y_TILED : constant := 4 * 2 ** 10;
53 PLANE_CTL_TILED_SURFACE_YF_TILED : constant := 5 * 2 ** 10;
54
55 PLANE_CTL_TILED_SURFACE : constant array (Tiling_Type) of Word32 :=
56 (Linear => PLANE_CTL_TILED_SURFACE_LINEAR,
57 X_Tiled => PLANE_CTL_TILED_SURFACE_X_TILED,
58 Y_Tiled => PLANE_CTL_TILED_SURFACE_Y_TILED);
Nico Huber83693c82016-10-08 22:17:55 +020059
Nico Huber9b479412017-08-27 11:55:56 +020060 PLANE_CTL_PLANE_ROTATION_MASK : constant := 3 * 2 ** 0;
61 PLANE_CTL_PLANE_ROTATION : constant array (Rotation_Type) of Word32 :=
62 (No_Rotation => 0 * 2 ** 0,
63 Rotated_90 => 1 * 2 ** 0,
64 Rotated_180 => 2 * 2 ** 0,
65 Rotated_270 => 3 * 2 ** 0);
66
Nico Huber83693c82016-10-08 22:17:55 +020067 PLANE_WM_ENABLE : constant := 1 * 2 ** 31;
68 PLANE_WM_LINES_SHIFT : constant := 14;
69 PLANE_WM_LINES_MASK : constant := 16#001f# * 2 ** 14;
70 PLANE_WM_BLOCKS_MASK : constant := 16#03ff# * 2 ** 0;
71
Nico Huber33912aa2016-12-06 20:36:23 +010072 VGA_SR_INDEX : constant := 16#03c4#;
73 VGA_SR_DATA : constant := 16#03c5#;
74 VGA_SR01 : constant := 16#01#;
75 VGA_SR01_SCREEN_OFF : constant := 1 * 2 ** 5;
Nico Huber3675db52016-11-04 16:27:29 +010076
77 VGA_CONTROL_VGA_DISPLAY_DISABLE : constant := 1 * 2 ** 31;
78 VGA_CONTROL_BLINK_DUTY_CYCLE_MASK : constant := 16#0003# * 2 ** 6;
79 VGA_CONTROL_BLINK_DUTY_CYCLE_50 : constant := 2 * 2 ** 6;
80 VGA_CONTROL_VSYNC_BLINK_RATE_MASK : constant := 16#003f# * 2 ** 0;
81
Nico Huber4dc4c612018-01-10 15:55:09 +010082 CUR_CTL_PIPE_SELECT : constant array (Pipe_Index) of Word32 :=
83 (Primary => 0 * 2 ** 28,
84 Secondary => 1 * 2 ** 28,
85 Tertiary => 2 * 2 ** 28);
86 CUR_CTL_MODE : constant array (Cursor_Mode, Cursor_Size) of Word32 :=
87 (No_Cursor => (others => 16#00#),
88 ARGB_Cursor =>
89 (Cursor_64x64 => 16#27#,
90 Cursor_128x128 => 16#22#,
91 Cursor_256x256 => 16#23#));
92
93 function CUR_POS_Y (Y : Int32) return Word32 is
94 ((if Y >= 0 then 0 else 1 * 2 ** 31) or Shift_Left (Word32 (abs Y), 16))
95 with
96 Pre => Y > Int32'First;
97 function CUR_POS_X (X : Int32) return Word32 is
98 ((if X >= 0 then 0 else 1 * 2 ** 15) or Word32 (abs X))
99 with
100 Pre => X > Int32'First;
101
Nico Huber3675db52016-11-04 16:27:29 +0100102 subtype VGA_Cycle_Count is Pos32 range 2 .. 128;
103 function VGA_CONTROL_VSYNC_BLINK_RATE
104 (Cycles : VGA_Cycle_Count)
105 return Word32
106 is
107 begin
108 return Word32 (Cycles) / 2 - 1;
109 end VGA_CONTROL_VSYNC_BLINK_RATE;
110
Nico Huber7ad2d652016-12-07 15:19:32 +0100111 PF_CTRL_ENABLE : constant := 1 * 2 ** 31;
112 PF_CTRL_PIPE_SELECT_MASK : constant := 3 * 2 ** 29;
113 PF_CTRL_FILTER_MED : constant := 1 * 2 ** 23;
Nico Huber83693c82016-10-08 22:17:55 +0200114
Nico Huber7ad2d652016-12-07 15:19:32 +0100115 PS_CTRL_ENABLE_SCALER : constant := 1 * 2 ** 31;
116 PS_CTRL_SCALER_MODE_7X5_EXTENDED : constant := 1 * 2 ** 28;
117 PS_CTRL_FILTER_SELECT_MEDIUM_2 : constant := 1 * 2 ** 23;
Nico Huber83693c82016-10-08 22:17:55 +0200118
Arthur Heymansd5198442018-03-28 17:05:12 +0200119 GMCH_PFIT_CONTROL_SELECT_MASK : constant := 3 * 2 ** 29;
120 GMCH_PFIT_CONTROL_SELECT_PIPE_A : constant := 0 * 2 ** 29;
121 GMCH_PFIT_CONTROL_SELECT_PIPE_B : constant := 1 * 2 ** 29;
Nico Huber958c5642018-06-02 16:59:31 +0200122 GMCH_PFIT_CONTROL_SCALING_MASK : constant := 3 * 2 ** 26;
123 GMCH_PFIT_CONTROL_SCALING : constant array (Scaling_Aspect) of Word32 :=
124 (Uniform => 0 * 2 ** 26,
125 Pillarbox => 2 * 2 ** 26,
126 Letterbox => 3 * 2 ** 26);
Arthur Heymansd5198442018-03-28 17:05:12 +0200127
Arthur Heymansdfcdd772018-03-28 16:42:50 +0200128 VGACNTRL_REG : constant Registers.Registers_Index :=
129 (if Config.Has_GMCH_VGACNTRL then
130 Registers.GMCH_VGACNTRL
131 else Registers.CPU_VGACNTRL);
132
Nico Huber83693c82016-10-08 22:17:55 +0200133 ---------------------------------------------------------------------------
134
Nico Huber83693c82016-10-08 22:17:55 +0200135 function PLANE_WM_LINES (Lines : Natural) return Word32 is
136 begin
137 return Shift_Left (Word32 (Lines), PLANE_WM_LINES_SHIFT)
138 and PLANE_WM_LINES_MASK;
139 end PLANE_WM_LINES;
140
141 function PLANE_WM_BLOCKS (Blocks : Natural) return Word32 is
142 begin
143 return Word32 (Blocks) and PLANE_WM_BLOCKS_MASK;
144 end PLANE_WM_BLOCKS;
145
146 ---------------------------------------------------------------------------
147
Nico Huberc5c767a2018-06-03 01:09:04 +0200148 function Encode (LSW, MSW : Pos32) return Word32 is
Nico Huber83693c82016-10-08 22:17:55 +0200149 begin
Nico Huber7ad2d652016-12-07 15:19:32 +0100150 return Shift_Left (Word32 (MSW) - 1, 16) or (Word32 (LSW) - 1);
Nico Huber83693c82016-10-08 22:17:55 +0200151 end Encode;
152
153 ----------------------------------------------------------------------------
154
Nico Huber83693c82016-10-08 22:17:55 +0200155 procedure Clear_Watermarks (Controller : Controller_Type) is
156 begin
Nico Huber4dc4c612018-01-10 15:55:09 +0100157 Registers.Write (Controller.CUR_BUF_CFG, 16#0000_0000#);
158 for Level in WM_Levels loop
159 Registers.Write (Controller.CUR_WM (Level), 16#0000_0000#);
Nico Huber83693c82016-10-08 22:17:55 +0200160 end loop;
Nico Huber4dc4c612018-01-10 15:55:09 +0100161 Registers.Write (Controller.PLANE_BUF_CFG, 16#0000_0000#);
162 for Level in WM_Levels loop
163 Registers.Write (Controller.PLANE_WM (Level), 16#0000_0000#);
164 end loop;
165 Registers.Write (Controller.WM_LINETIME, 16#0000_0000#);
Nico Huber83693c82016-10-08 22:17:55 +0200166 end Clear_Watermarks;
167
168 procedure Setup_Watermarks (Controller : Controller_Type)
169 is
Nico Huberf3e23662016-12-05 21:33:03 +0100170 type Per_Plane_Buffer_Range is array (Pipe_Index) of Word32;
Nico Huber4dc4c612018-01-10 15:55:09 +0100171 Cur_Buffer_Range : constant Per_Plane_Buffer_Range :=
172 (Primary => Shift_Left ( 7, 16) or 0,
173 Secondary => Shift_Left (167, 16) or 160,
174 Tertiary => Shift_Left (327, 16) or 320);
175 Plane_Buffer_Range : constant Per_Plane_Buffer_Range :=
176 (Primary => Shift_Left (159, 16) or 8,
177 Secondary => Shift_Left (319, 16) or 168,
178 Tertiary => Shift_Left (479, 16) or 328);
Nico Huber83693c82016-10-08 22:17:55 +0200179 begin
180 Registers.Write
181 (Register => Controller.PLANE_BUF_CFG,
Nico Huber4dc4c612018-01-10 15:55:09 +0100182 Value => Plane_Buffer_Range (Controller.Pipe));
Nico Huber83693c82016-10-08 22:17:55 +0200183 Registers.Write
184 (Register => Controller.PLANE_WM (0),
185 Value => PLANE_WM_ENABLE or
186 PLANE_WM_LINES (2) or
Nico Huber4dc4c612018-01-10 15:55:09 +0100187 PLANE_WM_BLOCKS (152));
188 Registers.Write
189 (Register => Controller.CUR_BUF_CFG,
190 Value => Cur_Buffer_Range (Controller.Pipe));
191 Registers.Write
192 (Register => Controller.CUR_WM (0),
193 Value => PLANE_WM_ENABLE or
194 PLANE_WM_LINES (2) or
195 PLANE_WM_BLOCKS (8));
Nico Huber83693c82016-10-08 22:17:55 +0200196 end Setup_Watermarks;
197
198 ----------------------------------------------------------------------------
199
Nico Huber3675db52016-11-04 16:27:29 +0100200 procedure Setup_Hires_Plane
Nico Huber6a4dfc82016-11-04 15:50:58 +0100201 (Controller : Controller_Type;
Nico Huber0164b022017-08-24 15:12:51 +0200202 FB : HW.GFX.Framebuffer_Type)
Nico Huber83693c82016-10-08 22:17:55 +0200203 with
204 Global => (In_Out => Registers.Register_State),
205 Depends =>
206 (Registers.Register_State
207 =>+
208 (Registers.Register_State,
209 Controller,
Nico Huber9b479412017-08-27 11:55:56 +0200210 FB)),
Nico Huber5ef4d602017-12-13 13:56:47 +0100211 Pre => FB.Height + FB.Start_Y <= FB.V_Stride
Nico Huber83693c82016-10-08 22:17:55 +0200212 is
213 -- FIXME: setup correct format, based on framebuffer RGB format
214 Format : constant Word32 := 6 * 2 ** 26;
215 PRI : Word32 := DSPCNTR_ENABLE or Format;
Nico Huber83693c82016-10-08 22:17:55 +0200216 begin
217 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
218
Nico Huber83693c82016-10-08 22:17:55 +0200219 if Config.Has_Plane_Control then
Nico Huber9b479412017-08-27 11:55:56 +0200220 declare
Nico Huber34be6542017-12-13 09:26:24 +0100221 Stride, Offset : Word32;
Nico Huberc5c767a2018-06-03 01:09:04 +0200222 Width : constant Width_Type := Rotated_Width (FB);
223 Height : constant Width_Type := Rotated_Height (FB);
Nico Huber9b479412017-08-27 11:55:56 +0200224 begin
225 if Rotation_90 (FB) then
Nico Huber5ef4d602017-12-13 13:56:47 +0100226 Stride := Word32 (FB_Pitch (FB.V_Stride, FB));
227 Offset := Shift_Left (Word32 (FB.Start_X), 16) or
228 Word32 (FB.V_Stride - FB.Height - FB.Start_Y);
Nico Huber9b479412017-08-27 11:55:56 +0200229 else
Nico Huber5ef4d602017-12-13 13:56:47 +0100230 Stride := Word32 (FB_Pitch (FB.Stride, FB));
231 Offset := Shift_Left (Word32 (FB.Start_Y), 16) or
232 Word32 (FB.Start_X);
Nico Huber9b479412017-08-27 11:55:56 +0200233 end if;
234 Registers.Write
235 (Register => Controller.PLANE_CTL,
236 Value => PLANE_CTL_PLANE_ENABLE or
237 PLANE_CTL_SRC_PIX_FMT_RGB_32B_8888 or
238 PLANE_CTL_PLANE_GAMMA_DISABLE or
239 PLANE_CTL_TILED_SURFACE (FB.Tiling) or
240 PLANE_CTL_PLANE_ROTATION (FB.Rotation));
241 Registers.Write (Controller.PLANE_OFFSET, Offset);
242 Registers.Write (Controller.PLANE_SIZE, Encode (Width, Height));
243 Registers.Write (Controller.PLANE_STRIDE, Stride);
244 Registers.Write (Controller.PLANE_POS, 16#0000_0000#);
Nico Huber34be6542017-12-13 09:26:24 +0100245 Registers.Write (Controller.PLANE_SURF, FB.Offset and 16#ffff_f000#);
Nico Huber9b479412017-08-27 11:55:56 +0200246 end;
Nico Huber83693c82016-10-08 22:17:55 +0200247 else
248 if Config.Disable_Trickle_Feed then
249 PRI := PRI or DSPCNTR_DISABLE_TRICKLE_FEED;
250 end if;
251 -- for now, just disable gamma LUT (can't do anything
252 -- useful without colorimetry information from display)
253 Registers.Unset_And_Set_Mask
254 (Register => Controller.DSPCNTR,
255 Mask_Unset => DSPCNTR_MASK,
Nico Huberab69e362018-05-29 21:20:30 +0200256 Mask_Set => PRI or DSPCNTR_TILED_SURFACE (FB.Tiling));
Nico Huber83693c82016-10-08 22:17:55 +0200257
Nico Huber0164b022017-08-24 15:12:51 +0200258 Registers.Write
259 (Controller.DSPSTRIDE, Word32 (Pixel_To_Bytes (FB.Stride, FB)));
Nico Huberab69e362018-05-29 21:20:30 +0200260 if Config.Has_DSP_Linoff and then FB.Tiling = Linear then
Nico Huberd49b56b2018-06-18 17:19:15 +0200261 pragma Assert_And_Cut (True);
262 declare
263 Linear_Offset : constant Pixel_Type :=
264 FB.Start_Y * FB.Stride + FB.Start_X;
265 begin
266 Registers.Write
267 (Register => Controller.DSPLINOFF,
268 Value => Word32 (Pixel_To_Bytes (Linear_Offset, FB)));
269 Registers.Write (Controller.DSPTILEOFF, 0);
270 end;
Nico Huber5ef4d602017-12-13 13:56:47 +0100271 else
Nico Huberab69e362018-05-29 21:20:30 +0200272 if Config.Has_DSP_Linoff then
273 Registers.Write (Controller.DSPLINOFF, 0);
274 end if;
Nico Huber5ef4d602017-12-13 13:56:47 +0100275 Registers.Write
276 (Register => Controller.DSPTILEOFF,
277 Value => Shift_Left (Word32 (FB.Start_Y), 16) or
278 Word32 (FB.Start_X));
Nico Huber83693c82016-10-08 22:17:55 +0200279 end if;
Nico Huber8fd92a12018-01-02 14:02:59 +0100280 Registers.Write (Controller.DSPSURF, FB.Offset and 16#ffff_f000#);
Nico Huber83693c82016-10-08 22:17:55 +0200281 end if;
Nico Huber3675db52016-11-04 16:27:29 +0100282 end Setup_Hires_Plane;
283
284 procedure Setup_Display
Nico Huber113a14b2016-12-06 21:59:15 +0100285 (Controller : Controller_Type;
286 Framebuffer : Framebuffer_Type;
287 Dither_BPC : BPC_Type;
288 Dither : Boolean)
Nico Huber3675db52016-11-04 16:27:29 +0100289 with
Nico Huber9b479412017-08-27 11:55:56 +0200290 Pre =>
291 Framebuffer.Offset = VGA_PLANE_FRAMEBUFFER_OFFSET or
Nico Huber5ef4d602017-12-13 13:56:47 +0100292 Framebuffer.Height + Framebuffer.Start_Y <= Framebuffer.V_Stride
Nico Huber3675db52016-11-04 16:27:29 +0100293 is
294 use type Word8;
295
296 Reg8 : Word8;
297 begin
298 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
299
300 if Config.Has_Plane_Control then
301 Setup_Watermarks (Controller);
302 end if;
303
304 if Framebuffer.Offset = VGA_PLANE_FRAMEBUFFER_OFFSET then
Nico Huberfbb42202016-11-07 15:08:26 +0100305 if Config.VGA_Plane_Workaround then
306 Registers.Unset_And_Set_Mask
307 (Register => Registers.ILK_DISPLAY_CHICKEN1,
308 Mask_Unset => ILK_DISPLAY_CHICKEN1_VGA_MASK,
309 Mask_Set => ILK_DISPLAY_CHICKEN1_VGA_ENABLE);
310 Registers.Unset_And_Set_Mask
311 (Register => Registers.ILK_DISPLAY_CHICKEN2,
312 Mask_Unset => ILK_DISPLAY_CHICKEN2_VGA_MASK,
313 Mask_Set => ILK_DISPLAY_CHICKEN2_VGA_ENABLE);
314 end if;
315
Nico Huber3675db52016-11-04 16:27:29 +0100316 Registers.Unset_And_Set_Mask
Arthur Heymansdfcdd772018-03-28 16:42:50 +0200317 (Register => VGACNTRL_REG,
Nico Huber3675db52016-11-04 16:27:29 +0100318 Mask_Unset => VGA_CONTROL_VGA_DISPLAY_DISABLE or
319 VGA_CONTROL_BLINK_DUTY_CYCLE_MASK or
320 VGA_CONTROL_VSYNC_BLINK_RATE_MASK,
321 Mask_Set => VGA_CONTROL_BLINK_DUTY_CYCLE_50 or
322 VGA_CONTROL_VSYNC_BLINK_RATE (30));
323
324 Port_IO.OutB (VGA_SR_INDEX, VGA_SR01);
325 Port_IO.InB (Reg8, VGA_SR_DATA);
326 Port_IO.OutB (VGA_SR_DATA, Reg8 and not (VGA_SR01_SCREEN_OFF));
327 else
Nico Huber6a4dfc82016-11-04 15:50:58 +0100328 Setup_Hires_Plane (Controller, Framebuffer);
Nico Huber3675db52016-11-04 16:27:29 +0100329 end if;
330
331 Registers.Write
332 (Register => Controller.PIPESRC,
333 Value => Encode
Nico Huber9b479412017-08-27 11:55:56 +0200334 (Rotated_Height (Framebuffer), Rotated_Width (Framebuffer)));
Nico Huber83693c82016-10-08 22:17:55 +0200335
Nico Huber113a14b2016-12-06 21:59:15 +0100336 if Config.Has_Pipeconf_Misc then
337 Registers.Write
338 (Register => Controller.PIPEMISC,
Nico Huber7ad2d652016-12-07 15:19:32 +0100339 Value => Transcoder.BPC_Conf (Dither_BPC, Dither));
Nico Huber113a14b2016-12-06 21:59:15 +0100340 end if;
Nico Huber83693c82016-10-08 22:17:55 +0200341 end Setup_Display;
342
343 ----------------------------------------------------------------------------
344
Nico Huber4dc4c612018-01-10 15:55:09 +0100345 procedure Update_Cursor
346 (Pipe : Pipe_Index;
347 FB : Framebuffer_Type;
348 Cursor : Cursor_Type)
349 is
350 begin
351 -- on some platforms writing CUR_CTL disables self-arming of CUR_POS
352 -- so keep it first
353 Registers.Write
Nico Huber75a707f2018-06-18 16:28:33 +0200354 (Register => Cursors (Pipe).CTL,
Nico Huber4dc4c612018-01-10 15:55:09 +0100355 Value => CUR_CTL_PIPE_SELECT (Pipe) or
356 CUR_CTL_MODE (Cursor.Mode, Cursor.Size));
357 Place_Cursor (Pipe, FB, Cursor);
358 end Update_Cursor;
359
360 procedure Place_Cursor
361 (Pipe : Pipe_Index;
362 FB : Framebuffer_Type;
363 Cursor : Cursor_Type)
364 is
365 Width : constant Width_Type := Cursor_Width (Cursor.Size);
366 X : Int32 := Cursor.Center_X - Width / 2;
367 Y : Int32 := Cursor.Center_Y - Width / 2;
368 begin
369 -- off-screen cursor needs special care
370 if X <= -Width or Y <= -Width or
Nico Huberc5c767a2018-06-03 01:09:04 +0200371 X >= Rotated_Width (FB) or Y >= Rotated_Height (FB) or
Nico Huber4dc4c612018-01-10 15:55:09 +0100372 X > Config.Maximum_Cursor_X or Y > Config.Maximum_Cursor_Y
373 then
374 X := -Width;
375 Y := -Width;
376 end if;
377 Registers.Write
Nico Huber75a707f2018-06-18 16:28:33 +0200378 (Register => Cursors (Pipe).POS,
Nico Huber4dc4c612018-01-10 15:55:09 +0100379 Value => CUR_POS_Y (Y) or CUR_POS_X (X));
380 -- write to CUR_BASE always arms other CUR_* registers
381 Registers.Write
Nico Huber75a707f2018-06-18 16:28:33 +0200382 (Register => Cursors (Pipe).BASE,
Nico Huber4dc4c612018-01-10 15:55:09 +0100383 Value => Shift_Left (Word32 (Cursor.GTT_Offset), 12));
384 end Place_Cursor;
385
386 ----------------------------------------------------------------------------
387
Nico Huberc5c767a2018-06-03 01:09:04 +0200388 function Scale (Val, Max, Num, Denom : Width_Type)
389 return Width_Type is ((Val * Num) / Denom)
Nico Huberda1185e2018-06-03 01:07:46 +0200390 with
Nico Huberc5c767a2018-06-03 01:09:04 +0200391 Pre => Denom <= Num and Val * Num < Max * Denom,
Nico Huberda1185e2018-06-03 01:07:46 +0200392 Post => Scale'Result < Max;
393
Nico Huber4916e342016-11-04 14:37:53 +0100394 procedure Scale_Keep_Aspect
Nico Huberc5c767a2018-06-03 01:09:04 +0200395 (Width : out Width_Type;
396 Height : out Height_Type;
397 Max_Width : in Width_Type;
398 Max_Height : in Height_Type;
Nico Huber4916e342016-11-04 14:37:53 +0100399 Framebuffer : in Framebuffer_Type)
400 with
401 Pre =>
Nico Huberc5c767a2018-06-03 01:09:04 +0200402 Rotated_Width (Framebuffer) <= Max_Width and
403 Rotated_Height (Framebuffer) <= Max_Height,
Nico Huber4916e342016-11-04 14:37:53 +0100404 Post =>
405 Width <= Max_Width and Height <= Max_Height
406 is
Nico Huberc5c767a2018-06-03 01:09:04 +0200407 Src_Width : constant Width_Type := Rotated_Width (Framebuffer);
408 Src_Height : constant Height_Type := Rotated_Height (Framebuffer);
Nico Huber4916e342016-11-04 14:37:53 +0100409 begin
Nico Huberda1185e2018-06-03 01:07:46 +0200410 case Scaling_Type (Src_Width, Src_Height, Max_Width, Max_Height) is
411 when Letterbox =>
412 Width := Max_Width;
413 Height := Scale (Src_Height, Max_Height, Max_Width, Src_Width);
414 when Pillarbox =>
415 Width := Scale (Src_Width, Max_Width, Max_Height, Src_Height);
416 Height := Max_Height;
417 when Uniform =>
418 Width := Max_Width;
419 Height := Max_Height;
420 end case;
Nico Huber4916e342016-11-04 14:37:53 +0100421 end Scale_Keep_Aspect;
422
423 procedure Setup_Skylake_Pipe_Scaler
424 (Controller : in Controller_Type;
425 Mode : in HW.GFX.Mode_Type;
426 Framebuffer : in HW.GFX.Framebuffer_Type)
427 with
428 Pre =>
Nico Huber9b479412017-08-27 11:55:56 +0200429 Rotated_Width (Framebuffer) <= Mode.H_Visible and
430 Rotated_Height (Framebuffer) <= Mode.V_Visible
Nico Huber4916e342016-11-04 14:37:53 +0100431 is
Nico Huber7ad2d652016-12-07 15:19:32 +0100432 use type Registers.Registers_Invalid_Index;
433
Nico Huber4916e342016-11-04 14:37:53 +0100434 -- Enable 7x5 extended mode where possible:
435 Scaler_Mode : constant Word32 :=
436 (if Controller.PS_CTRL_2 /= Registers.Invalid_Register then
437 PS_CTRL_SCALER_MODE_7X5_EXTENDED else 0);
438
Nico Huberc5c767a2018-06-03 01:09:04 +0200439 Width_In : constant Width_Type := Rotated_Width (Framebuffer);
440 Height_In : constant Height_Type := Rotated_Height (Framebuffer);
Nico Huber9b479412017-08-27 11:55:56 +0200441
Nico Huber4916e342016-11-04 14:37:53 +0100442 -- We can scale up to 2.99x horizontally:
Nico Huber9b479412017-08-27 11:55:56 +0200443 Horizontal_Limit : constant Pos32 := (Width_In * 299) / 100;
Nico Huber4916e342016-11-04 14:37:53 +0100444 -- The third scaler is limited to 1.99x
445 -- vertical scaling for source widths > 2048:
446 Vertical_Limit : constant Pos32 :=
Nico Huber9b479412017-08-27 11:55:56 +0200447 (Height_In *
Nico Huber4916e342016-11-04 14:37:53 +0100448 (if Controller.PS_CTRL_2 = Registers.Invalid_Register and
Nico Huber9b479412017-08-27 11:55:56 +0200449 Width_In > 2048
Nico Huber4916e342016-11-04 14:37:53 +0100450 then
451 199
452 else
453 299)) / 100;
454
Nico Huberc5c767a2018-06-03 01:09:04 +0200455 Width : Width_Type;
456 Height : Height_Type;
Nico Huber4916e342016-11-04 14:37:53 +0100457 begin
458 -- Writes to WIN_SZ arm the PS registers.
459
460 Scale_Keep_Aspect
461 (Width => Width,
462 Height => Height,
Nico Huberc5c767a2018-06-03 01:09:04 +0200463 Max_Width => Pos32'Min (Horizontal_Limit, Mode.H_Visible),
464 Max_Height => Pos32'Min (Vertical_Limit, Mode.V_Visible),
Nico Huber4916e342016-11-04 14:37:53 +0100465 Framebuffer => Framebuffer);
466
467 Registers.Write
468 (Register => Controller.PS_CTRL_1,
469 Value => PS_CTRL_ENABLE_SCALER or Scaler_Mode);
470 Registers.Write
471 (Register => Controller.PS_WIN_POS_1,
472 Value =>
Nico Huberc5c767a2018-06-03 01:09:04 +0200473 Shift_Left (Word32 (Mode.H_Visible - Width) / 2, 16) or
474 Word32 (Mode.V_Visible - Height) / 2);
Nico Huber4916e342016-11-04 14:37:53 +0100475 Registers.Write
476 (Register => Controller.PS_WIN_SZ_1,
477 Value => Shift_Left (Word32 (Width), 16) or Word32 (Height));
478 end Setup_Skylake_Pipe_Scaler;
479
480 procedure Setup_Ironlake_Panel_Fitter
481 (Controller : in Controller_Type;
482 Mode : in HW.GFX.Mode_Type;
483 Framebuffer : in HW.GFX.Framebuffer_Type)
484 with
485 Pre =>
Nico Huber9b479412017-08-27 11:55:56 +0200486 Rotated_Width (Framebuffer) <= Mode.H_Visible and
487 Rotated_Height (Framebuffer) <= Mode.V_Visible
Nico Huber4916e342016-11-04 14:37:53 +0100488 is
489 -- Force 1:1 mapping of panel fitter:pipe
490 PF_Ctrl_Pipe_Sel : constant Word32 :=
491 (if Config.Has_PF_Pipe_Select then
492 (case Controller.PF_CTRL is
493 when Registers.PFA_CTL_1 => 0 * 2 ** 29,
494 when Registers.PFB_CTL_1 => 1 * 2 ** 29,
495 when Registers.PFC_CTL_1 => 2 * 2 ** 29,
496 when others => 0) else 0);
497
Nico Huberc5c767a2018-06-03 01:09:04 +0200498 Width : Width_Type;
499 Height : Height_Type;
Nico Huberfdb0df12018-02-07 14:30:34 +0100500 X, Y : Int32;
Nico Huber4916e342016-11-04 14:37:53 +0100501 begin
502 -- Writes to WIN_SZ arm the PF registers.
503
504 Scale_Keep_Aspect
505 (Width => Width,
506 Height => Height,
Nico Huberc5c767a2018-06-03 01:09:04 +0200507 Max_Width => Mode.H_Visible,
508 Max_Height => Mode.V_Visible,
Nico Huber4916e342016-11-04 14:37:53 +0100509 Framebuffer => Framebuffer);
510
Nico Huberfdb0df12018-02-07 14:30:34 +0100511 -- Do not scale to odd width (at least Haswell has trouble with this).
Nico Huberc5c767a2018-06-03 01:09:04 +0200512 if Width < Mode.H_Visible and Width mod 2 = 1 then
Nico Huberfdb0df12018-02-07 14:30:34 +0100513 Width := Width + 1;
514 end if;
Nico Huberb3b9fa32018-06-18 16:16:41 +0200515 -- Do not scale to odd height (at least Sandy Bridge makes trouble).
516 if Height < Mode.V_Visible and Height mod 2 = 1 then
517 Height := Height + 1;
518 end if;
Nico Huberfdb0df12018-02-07 14:30:34 +0100519
Nico Huberc5c767a2018-06-03 01:09:04 +0200520 X := (Mode.H_Visible - Width) / 2;
521 Y := (Mode.V_Visible - Height) / 2;
Nico Huberfdb0df12018-02-07 14:30:34 +0100522
523 -- Hardware is picky about minimal horizontal gaps.
Nico Huberc5c767a2018-06-03 01:09:04 +0200524 if Mode.H_Visible - Width <= 3 then
525 Width := Mode.H_Visible;
Nico Huberfdb0df12018-02-07 14:30:34 +0100526 X := 0;
527 end if;
528
Nico Huber4916e342016-11-04 14:37:53 +0100529 Registers.Write
530 (Register => Controller.PF_CTRL,
531 Value => PF_CTRL_ENABLE or PF_Ctrl_Pipe_Sel or PF_CTRL_FILTER_MED);
532 Registers.Write
533 (Register => Controller.PF_WIN_POS,
Nico Huberfdb0df12018-02-07 14:30:34 +0100534 Value => Shift_Left (Word32 (X), 16) or Word32 (Y));
Nico Huber4916e342016-11-04 14:37:53 +0100535 Registers.Write
536 (Register => Controller.PF_WIN_SZ,
537 Value => Shift_Left (Word32 (Width), 16) or Word32 (Height));
538 end Setup_Ironlake_Panel_Fitter;
539
Arthur Heymansd5198442018-03-28 17:05:12 +0200540 procedure Setup_Gmch_Panel_Fitter
Nico Huber958c5642018-06-02 16:59:31 +0200541 (Controller : in Controller_Type;
542 Mode : in HW.GFX.Mode_Type;
543 Framebuffer : in HW.GFX.Framebuffer_Type)
Arthur Heymansd5198442018-03-28 17:05:12 +0200544 is
545 PF_Ctrl_Pipe_Sel : constant Word32 :=
546 (case Controller.Pipe is
547 when Primary => GMCH_PFIT_CONTROL_SELECT_PIPE_A,
548 when Secondary => GMCH_PFIT_CONTROL_SELECT_PIPE_B,
549 when others => 0);
Nico Huber958c5642018-06-02 16:59:31 +0200550
Arthur Heymansf70edda2018-08-21 18:37:00 +0200551 -- Work around a quirk:
552 -- In legacy VGA mode Pillarbox fails to display anything so just force
553 -- 'auto' mode on all displays, which will the output stretched to
554 -- fullscreen .
Nico Huber958c5642018-06-02 16:59:31 +0200555 PF_Ctrl_Scaling : constant Word32 :=
Arthur Heymansf70edda2018-08-21 18:37:00 +0200556 (if Framebuffer.Offset = VGA_PLANE_FRAMEBUFFER_OFFSET then
557 GMCH_PFIT_CONTROL_SCALING (Uniform)
558 else
559 GMCH_PFIT_CONTROL_SCALING (Scaling_Type (Framebuffer, Mode)));
Nico Huber958c5642018-06-02 16:59:31 +0200560
Arthur Heymansd5198442018-03-28 17:05:12 +0200561 In_Use : Boolean;
562 begin
563 Registers.Is_Set_Mask
564 (Register => Registers.GMCH_PFIT_CONTROL,
565 Mask => PF_CTRL_ENABLE,
566 Result => In_Use);
567
568 if not In_Use then
569 Registers.Write
570 (Register => Registers.GMCH_PFIT_CONTROL,
Nico Huber958c5642018-06-02 16:59:31 +0200571 Value => PF_CTRL_ENABLE or PF_Ctrl_Pipe_Sel or PF_Ctrl_Scaling);
Arthur Heymansd5198442018-03-28 17:05:12 +0200572 else
Nico Huber7ba7bd62018-06-06 12:27:09 +0200573 pragma Debug (Debug.Put_Line
574 ("GMCH Pannel fitter already in use, skipping..."));
Arthur Heymansd5198442018-03-28 17:05:12 +0200575 end if;
576 end Setup_Gmch_Panel_Fitter;
577
Nico Huberf361ec82018-06-02 18:01:45 +0200578 procedure Gmch_Panel_Fitter_Pipe (Pipe : out Pipe_Index)
579 is
580 Used_For_Secondary : Boolean;
581 begin
582 Registers.Is_Set_Mask
583 (Register => Registers.GMCH_PFIT_CONTROL,
584 Mask => GMCH_PFIT_CONTROL_SELECT_PIPE_B,
585 Result => Used_For_Secondary);
586 Pipe := (if Used_For_Secondary then Secondary else Primary);
587 end;
588
Nico Huberb4b72792018-01-02 13:45:41 +0100589 procedure Panel_Fitter_Off (Controller : Controller_Type)
590 is
591 use type HW.GFX.GMA.Registers.Registers_Invalid_Index;
Nico Huberf361ec82018-06-02 18:01:45 +0200592 Pipe_Using_PF : Pipe_Index;
Nico Huberb4b72792018-01-02 13:45:41 +0100593 begin
594 -- Writes to WIN_SZ arm the PS/PF registers.
595 if Config.Has_Plane_Control then
596 Registers.Unset_Mask (Controller.PS_CTRL_1, PS_CTRL_ENABLE_SCALER);
597 Registers.Write (Controller.PS_WIN_SZ_1, 16#0000_0000#);
598 if Controller.PS_CTRL_2 /= Registers.Invalid_Register and
599 Controller.PS_WIN_SZ_2 /= Registers.Invalid_Register
600 then
601 Registers.Unset_Mask (Controller.PS_CTRL_2, PS_CTRL_ENABLE_SCALER);
602 Registers.Write (Controller.PS_WIN_SZ_2, 16#0000_0000#);
603 end if;
Arthur Heymansd5198442018-03-28 17:05:12 +0200604 elsif Config.Has_GMCH_PFIT_CONTROL then
Nico Huberf361ec82018-06-02 18:01:45 +0200605 Gmch_Panel_Fitter_Pipe (Pipe_Using_PF);
606 if Pipe_Using_PF = Controller.Pipe then
607 Registers.Unset_Mask (Registers.GMCH_PFIT_CONTROL, PF_CTRL_ENABLE);
Arthur Heymansd5198442018-03-28 17:05:12 +0200608 end if;
Nico Huberb4b72792018-01-02 13:45:41 +0100609 else
610 Registers.Unset_Mask (Controller.PF_CTRL, PF_CTRL_ENABLE);
611 Registers.Write (Controller.PF_WIN_SZ, 16#0000_0000#);
612 end if;
613 end Panel_Fitter_Off;
614
Nico Huber4916e342016-11-04 14:37:53 +0100615 procedure Setup_Scaling
616 (Controller : in Controller_Type;
617 Mode : in HW.GFX.Mode_Type;
618 Framebuffer : in HW.GFX.Framebuffer_Type)
619 with
620 Pre =>
Nico Huber9b479412017-08-27 11:55:56 +0200621 Rotated_Width (Framebuffer) <= Mode.H_Visible and
622 Rotated_Height (Framebuffer) <= Mode.V_Visible
Nico Huber4916e342016-11-04 14:37:53 +0100623 is
624 begin
Nico Huber3d06de82018-05-29 01:35:04 +0200625 if Requires_Scaling (Framebuffer, Mode) then
Nico Huber4916e342016-11-04 14:37:53 +0100626 if Config.Has_Plane_Control then
627 Setup_Skylake_Pipe_Scaler (Controller, Mode, Framebuffer);
Arthur Heymansd5198442018-03-28 17:05:12 +0200628 elsif Config.Has_GMCH_PFIT_CONTROL then
Nico Huber958c5642018-06-02 16:59:31 +0200629 Setup_Gmch_Panel_Fitter (Controller, Mode, Framebuffer);
Nico Huber4916e342016-11-04 14:37:53 +0100630 else
631 Setup_Ironlake_Panel_Fitter (Controller, Mode, Framebuffer);
632 end if;
Nico Huberb4b72792018-01-02 13:45:41 +0100633 else
634 Panel_Fitter_Off (Controller);
Nico Huber4916e342016-11-04 14:37:53 +0100635 end if;
636 end Setup_Scaling;
637
Nico Huber9a4c4c32019-09-16 22:05:11 +0200638 procedure Reserve_Scaler
639 (Success : out Boolean;
640 Reservation : in out Scaler_Reservation;
641 Pipe : in Pipe_Index)
Nico Huberf361ec82018-06-02 18:01:45 +0200642 is
643 Pipe_Using_PF : Pipe_Index := Pipe_Index'First;
644 PF_Enabled : Boolean;
645 begin
646 if Config.Has_GMCH_PFIT_CONTROL then
Nico Huber9a4c4c32019-09-16 22:05:11 +0200647 if Reservation.Reserved then
648 Success := Reservation.Pipe = Pipe;
649 return;
650 end if;
651
Nico Huberf361ec82018-06-02 18:01:45 +0200652 Registers.Is_Set_Mask
653 (Register => Registers.GMCH_PFIT_CONTROL,
654 Mask => PF_CTRL_ENABLE,
655 Result => PF_Enabled);
656 if PF_Enabled then
657 Gmch_Panel_Fitter_Pipe (Pipe_Using_PF);
658 end if;
659
Nico Huber9a4c4c32019-09-16 22:05:11 +0200660 Success := not PF_Enabled or Pipe_Using_PF = Pipe;
661 if Success then
662 Reservation.Reserved := True;
663 Reservation.Pipe := Pipe;
664 end if;
Nico Huberf361ec82018-06-02 18:01:45 +0200665 else
Nico Huber9a4c4c32019-09-16 22:05:11 +0200666 Success := True;
Nico Huberf361ec82018-06-02 18:01:45 +0200667 end if;
Nico Huber9a4c4c32019-09-16 22:05:11 +0200668 end Reserve_Scaler;
Nico Huberf361ec82018-06-02 18:01:45 +0200669
Nico Huber4916e342016-11-04 14:37:53 +0100670 ----------------------------------------------------------------------------
671
Nico Huberf7f537e2018-01-02 14:15:43 +0100672 procedure Setup_FB
673 (Pipe : Pipe_Index;
674 Mode : Mode_Type;
675 Framebuffer : Framebuffer_Type)
676 is
677 -- Enable dithering if framebuffer BPC differs from port BPC,
678 -- as smooth gradients look really bad without.
679 Dither : constant Boolean := Framebuffer.BPC /= Mode.BPC;
680 begin
681 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
682
Nico Huber4dc4c612018-01-10 15:55:09 +0100683 -- Disable the cursor first.
684 Update_Cursor (Pipe, Framebuffer, Default_Cursor);
685
Nico Huberf7f537e2018-01-02 14:15:43 +0100686 Setup_Display (Controllers (Pipe), Framebuffer, Mode.BPC, Dither);
687 Setup_Scaling (Controllers (Pipe), Mode, Framebuffer);
688 end Setup_FB;
689
Nico Huber83693c82016-10-08 22:17:55 +0200690 procedure On
Nico Huberf3e23662016-12-05 21:33:03 +0100691 (Pipe : Pipe_Index;
Nico Huber83693c82016-10-08 22:17:55 +0200692 Port_Cfg : Port_Config;
Nico Huber4dc4c612018-01-10 15:55:09 +0100693 Framebuffer : Framebuffer_Type;
694 Cursor : Cursor_Type)
Nico Huber83693c82016-10-08 22:17:55 +0200695 is
696 begin
697 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
698
Nico Huber7ad2d652016-12-07 15:19:32 +0100699 Transcoder.Setup (Pipe, Port_Cfg);
Nico Huber83693c82016-10-08 22:17:55 +0200700
Nico Huberf7f537e2018-01-02 14:15:43 +0100701 Setup_FB (Pipe, Port_Cfg.Mode, Framebuffer);
Nico Huber4dc4c612018-01-10 15:55:09 +0100702 Update_Cursor (Pipe, Framebuffer, Cursor);
Nico Huber83693c82016-10-08 22:17:55 +0200703
Nico Huberabb16d92018-05-29 01:44:26 +0200704 Transcoder.On
705 (Pipe => Pipe,
706 Port_Cfg => Port_Cfg,
707 Dither => Framebuffer.BPC /= Port_Cfg.Mode.BPC,
708 Scale => Requires_Scaling (Framebuffer, Port_Cfg.Mode));
Nico Huber83693c82016-10-08 22:17:55 +0200709 end On;
710
711 ----------------------------------------------------------------------------
712
Nico Huber75a707f2018-06-18 16:28:33 +0200713 procedure Planes_Off (Controller : Controller_Type; CUR : Cursor_Regs)
714 is
715 use type Registers.Registers_Invalid_Index;
Nico Huber83693c82016-10-08 22:17:55 +0200716 begin
Nico Huber75a707f2018-06-18 16:28:33 +0200717 Registers.Write (CUR.CTL, 16#0000_0000#);
718 if CUR.FBC_CTL /= Registers.Invalid_Register then
719 Registers.Write (CUR.FBC_CTL, 16#0000_0000#);
Nico Huber4dc4c612018-01-10 15:55:09 +0100720 end if;
Nico Huber7ad2d652016-12-07 15:19:32 +0100721 Registers.Unset_Mask (Controller.SPCNTR, DSPCNTR_ENABLE);
Nico Huber83693c82016-10-08 22:17:55 +0200722 if Config.Has_Plane_Control then
723 Clear_Watermarks (Controller);
724 Registers.Unset_Mask (Controller.PLANE_CTL, PLANE_CTL_PLANE_ENABLE);
725 Registers.Write (Controller.PLANE_SURF, 16#0000_0000#);
726 else
727 Registers.Unset_Mask (Controller.DSPCNTR, DSPCNTR_ENABLE);
728 end if;
729 end Planes_Off;
730
Nico Huber7ad2d652016-12-07 15:19:32 +0100731 procedure Off (Pipe : Pipe_Index)
Nico Huberf3e23662016-12-05 21:33:03 +0100732 is
Nico Huber83693c82016-10-08 22:17:55 +0200733 begin
734 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
735
Nico Huber75a707f2018-06-18 16:28:33 +0200736 Planes_Off (Controllers (Pipe), Cursors (Pipe));
Nico Huber7ad2d652016-12-07 15:19:32 +0100737 Transcoder.Off (Pipe);
Nico Huberf3e23662016-12-05 21:33:03 +0100738 Panel_Fitter_Off (Controllers (Pipe));
Nico Huber7ad2d652016-12-07 15:19:32 +0100739 Transcoder.Clk_Off (Pipe);
Nico Huber83693c82016-10-08 22:17:55 +0200740 end Off;
741
Nico Huber33912aa2016-12-06 20:36:23 +0100742 procedure Legacy_VGA_Off
743 is
744 use type HW.Word8;
745 Reg8 : Word8;
746 begin
747 Port_IO.OutB (VGA_SR_INDEX, VGA_SR01);
748 Port_IO.InB (Reg8, VGA_SR_DATA);
749 Port_IO.OutB (VGA_SR_DATA, Reg8 or VGA_SR01_SCREEN_OFF);
750 Time.U_Delay (100); -- PRM says 100us, Linux does 300
Arthur Heymansdfcdd772018-03-28 16:42:50 +0200751 Registers.Set_Mask (VGACNTRL_REG, VGA_CONTROL_VGA_DISPLAY_DISABLE);
Nico Huber33912aa2016-12-06 20:36:23 +0100752 end Legacy_VGA_Off;
753
Nico Huber83693c82016-10-08 22:17:55 +0200754 procedure All_Off
755 is
Nico Huber83693c82016-10-08 22:17:55 +0200756 begin
757 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
758
Nico Huber33912aa2016-12-06 20:36:23 +0100759 Legacy_VGA_Off;
760
Nico Huberf3e23662016-12-05 21:33:03 +0100761 for Pipe in Pipe_Index loop
Nico Huber75a707f2018-06-18 16:28:33 +0200762 Planes_Off (Controllers (Pipe), Cursors (Pipe));
Nico Huber7ad2d652016-12-07 15:19:32 +0100763 Transcoder.Off (Pipe);
Nico Huberf3e23662016-12-05 21:33:03 +0100764 Panel_Fitter_Off (Controllers (Pipe));
Nico Huber7ad2d652016-12-07 15:19:32 +0100765 Transcoder.Clk_Off (Pipe);
Nico Huber83693c82016-10-08 22:17:55 +0200766 end loop;
Nico Huber83693c82016-10-08 22:17:55 +0200767 end All_Off;
768
Nico Huber83693c82016-10-08 22:17:55 +0200769end HW.GFX.GMA.Pipe_Setup;