blob: 215b4dee57451aed496e691ae903372951e93dc7 [file] [log] [blame]
Nico Huber83693c82016-10-08 22:17:55 +02001--
2-- Copyright (C) 2015-2016 secunet Security Networks AG
3--
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
18with HW.GFX.GMA.Config;
Nico Huber7ad2d652016-12-07 15:19:32 +010019with HW.GFX.GMA.Transcoder;
Nico Huber83693c82016-10-08 22:17:55 +020020
21package body HW.GFX.GMA.Pipe_Setup is
22
Nico Huberfbb42202016-11-07 15:08:26 +010023 ILK_DISPLAY_CHICKEN1_VGA_MASK : constant := 7 * 2 ** 29;
24 ILK_DISPLAY_CHICKEN1_VGA_ENABLE : constant := 5 * 2 ** 29;
25 ILK_DISPLAY_CHICKEN2_VGA_MASK : constant := 1 * 2 ** 25;
26 ILK_DISPLAY_CHICKEN2_VGA_ENABLE : constant := 0 * 2 ** 25;
27
Nico Huber7ad2d652016-12-07 15:19:32 +010028 DSPCNTR_ENABLE : constant := 1 * 2 ** 31;
29 DSPCNTR_GAMMA_CORRECTION : constant := 1 * 2 ** 30;
30 DSPCNTR_DISABLE_TRICKLE_FEED : constant := 1 * 2 ** 14;
31 DSPCNTR_FORMAT_MASK : constant := 15 * 2 ** 26;
Nico Huber83693c82016-10-08 22:17:55 +020032
33 DSPCNTR_MASK : constant Word32 :=
34 DSPCNTR_ENABLE or
35 DSPCNTR_GAMMA_CORRECTION or
36 DSPCNTR_FORMAT_MASK or
37 DSPCNTR_DISABLE_TRICKLE_FEED;
38
39 PLANE_CTL_PLANE_ENABLE : constant := 1 * 2 ** 31;
40 PLANE_CTL_SRC_PIX_FMT_RGB_32B_8888 : constant := 4 * 2 ** 24;
41 PLANE_CTL_PLANE_GAMMA_DISABLE : constant := 1 * 2 ** 13;
Nico Huber0164b022017-08-24 15:12:51 +020042 PLANE_CTL_TILED_SURFACE_MASK : constant := 7 * 2 ** 10;
43 PLANE_CTL_TILED_SURFACE_LINEAR : constant := 0 * 2 ** 10;
44 PLANE_CTL_TILED_SURFACE_X_TILED : constant := 1 * 2 ** 10;
45 PLANE_CTL_TILED_SURFACE_Y_TILED : constant := 4 * 2 ** 10;
46 PLANE_CTL_TILED_SURFACE_YF_TILED : constant := 5 * 2 ** 10;
47
48 PLANE_CTL_TILED_SURFACE : constant array (Tiling_Type) of Word32 :=
49 (Linear => PLANE_CTL_TILED_SURFACE_LINEAR,
50 X_Tiled => PLANE_CTL_TILED_SURFACE_X_TILED,
51 Y_Tiled => PLANE_CTL_TILED_SURFACE_Y_TILED);
Nico Huber83693c82016-10-08 22:17:55 +020052
53 PLANE_WM_ENABLE : constant := 1 * 2 ** 31;
54 PLANE_WM_LINES_SHIFT : constant := 14;
55 PLANE_WM_LINES_MASK : constant := 16#001f# * 2 ** 14;
56 PLANE_WM_BLOCKS_MASK : constant := 16#03ff# * 2 ** 0;
57
Nico Huber33912aa2016-12-06 20:36:23 +010058 VGA_SR_INDEX : constant := 16#03c4#;
59 VGA_SR_DATA : constant := 16#03c5#;
60 VGA_SR01 : constant := 16#01#;
61 VGA_SR01_SCREEN_OFF : constant := 1 * 2 ** 5;
Nico Huber3675db52016-11-04 16:27:29 +010062
63 VGA_CONTROL_VGA_DISPLAY_DISABLE : constant := 1 * 2 ** 31;
64 VGA_CONTROL_BLINK_DUTY_CYCLE_MASK : constant := 16#0003# * 2 ** 6;
65 VGA_CONTROL_BLINK_DUTY_CYCLE_50 : constant := 2 * 2 ** 6;
66 VGA_CONTROL_VSYNC_BLINK_RATE_MASK : constant := 16#003f# * 2 ** 0;
67
68 subtype VGA_Cycle_Count is Pos32 range 2 .. 128;
69 function VGA_CONTROL_VSYNC_BLINK_RATE
70 (Cycles : VGA_Cycle_Count)
71 return Word32
72 is
73 begin
74 return Word32 (Cycles) / 2 - 1;
75 end VGA_CONTROL_VSYNC_BLINK_RATE;
76
Nico Huber7ad2d652016-12-07 15:19:32 +010077 PF_CTRL_ENABLE : constant := 1 * 2 ** 31;
78 PF_CTRL_PIPE_SELECT_MASK : constant := 3 * 2 ** 29;
79 PF_CTRL_FILTER_MED : constant := 1 * 2 ** 23;
Nico Huber83693c82016-10-08 22:17:55 +020080
Nico Huber7ad2d652016-12-07 15:19:32 +010081 PS_CTRL_ENABLE_SCALER : constant := 1 * 2 ** 31;
82 PS_CTRL_SCALER_MODE_7X5_EXTENDED : constant := 1 * 2 ** 28;
83 PS_CTRL_FILTER_SELECT_MEDIUM_2 : constant := 1 * 2 ** 23;
Nico Huber83693c82016-10-08 22:17:55 +020084
85 ---------------------------------------------------------------------------
86
Nico Huber83693c82016-10-08 22:17:55 +020087 function PLANE_WM_LINES (Lines : Natural) return Word32 is
88 begin
89 return Shift_Left (Word32 (Lines), PLANE_WM_LINES_SHIFT)
90 and PLANE_WM_LINES_MASK;
91 end PLANE_WM_LINES;
92
93 function PLANE_WM_BLOCKS (Blocks : Natural) return Word32 is
94 begin
95 return Word32 (Blocks) and PLANE_WM_BLOCKS_MASK;
96 end PLANE_WM_BLOCKS;
97
98 ---------------------------------------------------------------------------
99
100 function Encode (LSW, MSW : Pos16) return Word32 is
101 begin
Nico Huber7ad2d652016-12-07 15:19:32 +0100102 return Shift_Left (Word32 (MSW) - 1, 16) or (Word32 (LSW) - 1);
Nico Huber83693c82016-10-08 22:17:55 +0200103 end Encode;
104
105 ----------------------------------------------------------------------------
106
Nico Huber83693c82016-10-08 22:17:55 +0200107 procedure Clear_Watermarks (Controller : Controller_Type) is
108 begin
109 Registers.Write
110 (Register => Controller.PLANE_BUF_CFG,
111 Value => 16#0000_0000#);
112 for Level in WM_Levels range 0 .. WM_Levels'Last loop
113 Registers.Write
114 (Register => Controller.PLANE_WM (Level),
115 Value => 16#0000_0000#);
116 end loop;
117 Registers.Write
118 (Register => Controller.WM_LINETIME,
119 Value => 16#0000_0000#);
120 end Clear_Watermarks;
121
122 procedure Setup_Watermarks (Controller : Controller_Type)
123 is
Nico Huberf3e23662016-12-05 21:33:03 +0100124 type Per_Plane_Buffer_Range is array (Pipe_Index) of Word32;
125 Buffer_Range : constant Per_Plane_Buffer_Range :=
126 (Primary => Shift_Left (159, 16) or 0,
127 Secondary => Shift_Left (319, 16) or 160,
128 Tertiary => Shift_Left (479, 16) or 320);
Nico Huber83693c82016-10-08 22:17:55 +0200129 begin
130 Registers.Write
131 (Register => Controller.PLANE_BUF_CFG,
Nico Huberf3e23662016-12-05 21:33:03 +0100132 Value => Buffer_Range (Controller.Pipe));
Nico Huber83693c82016-10-08 22:17:55 +0200133 Registers.Write
134 (Register => Controller.PLANE_WM (0),
135 Value => PLANE_WM_ENABLE or
136 PLANE_WM_LINES (2) or
137 PLANE_WM_BLOCKS (160));
138 end Setup_Watermarks;
139
140 ----------------------------------------------------------------------------
141
Nico Huber3675db52016-11-04 16:27:29 +0100142 procedure Setup_Hires_Plane
Nico Huber6a4dfc82016-11-04 15:50:58 +0100143 (Controller : Controller_Type;
Nico Huber0164b022017-08-24 15:12:51 +0200144 FB : HW.GFX.Framebuffer_Type)
Nico Huber83693c82016-10-08 22:17:55 +0200145 with
146 Global => (In_Out => Registers.Register_State),
147 Depends =>
148 (Registers.Register_State
149 =>+
150 (Registers.Register_State,
151 Controller,
Nico Huber0164b022017-08-24 15:12:51 +0200152 FB))
Nico Huber83693c82016-10-08 22:17:55 +0200153 is
154 -- FIXME: setup correct format, based on framebuffer RGB format
155 Format : constant Word32 := 6 * 2 ** 26;
156 PRI : Word32 := DSPCNTR_ENABLE or Format;
Nico Huber83693c82016-10-08 22:17:55 +0200157 begin
158 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
159
Nico Huber83693c82016-10-08 22:17:55 +0200160 if Config.Has_Plane_Control then
Nico Huber83693c82016-10-08 22:17:55 +0200161 Registers.Write
162 (Register => Controller.PLANE_CTL,
163 Value => PLANE_CTL_PLANE_ENABLE or
164 PLANE_CTL_SRC_PIX_FMT_RGB_32B_8888 or
Nico Huber0164b022017-08-24 15:12:51 +0200165 PLANE_CTL_PLANE_GAMMA_DISABLE or
166 PLANE_CTL_TILED_SURFACE (FB.Tiling));
Nico Huber83693c82016-10-08 22:17:55 +0200167 Registers.Write (Controller.PLANE_OFFSET, 16#0000_0000#);
Nico Huber6a4dfc82016-11-04 15:50:58 +0100168 Registers.Write
169 (Controller.PLANE_SIZE,
Nico Huber0164b022017-08-24 15:12:51 +0200170 Encode (Pos16 (FB.Width), Pos16 (FB.Height)));
171 Registers.Write
172 (Controller.PLANE_STRIDE, Word32 (FB_Pitch (FB.Stride, FB)));
Nico Huber83693c82016-10-08 22:17:55 +0200173 Registers.Write (Controller.PLANE_POS, 16#0000_0000#);
Nico Huber0164b022017-08-24 15:12:51 +0200174 Registers.Write (Controller.PLANE_SURF, FB.Offset and 16#ffff_f000#);
Nico Huber83693c82016-10-08 22:17:55 +0200175 else
176 if Config.Disable_Trickle_Feed then
177 PRI := PRI or DSPCNTR_DISABLE_TRICKLE_FEED;
178 end if;
179 -- for now, just disable gamma LUT (can't do anything
180 -- useful without colorimetry information from display)
181 Registers.Unset_And_Set_Mask
182 (Register => Controller.DSPCNTR,
183 Mask_Unset => DSPCNTR_MASK,
184 Mask_Set => PRI);
185
Nico Huber0164b022017-08-24 15:12:51 +0200186 Registers.Write
187 (Controller.DSPSTRIDE, Word32 (Pixel_To_Bytes (FB.Stride, FB)));
188 Registers.Write (Controller.DSPSURF, FB.Offset and 16#ffff_f000#);
Nico Huber83693c82016-10-08 22:17:55 +0200189 if Config.Has_DSP_Linoff then
190 Registers.Write (Controller.DSPLINOFF, 0);
191 end if;
192 Registers.Write (Controller.DSPTILEOFF, 0);
193 end if;
Nico Huber3675db52016-11-04 16:27:29 +0100194 end Setup_Hires_Plane;
195
196 procedure Setup_Display
Nico Huber113a14b2016-12-06 21:59:15 +0100197 (Controller : Controller_Type;
198 Framebuffer : Framebuffer_Type;
199 Dither_BPC : BPC_Type;
200 Dither : Boolean)
Nico Huber3675db52016-11-04 16:27:29 +0100201 with
202 Global => (In_Out => (Registers.Register_State, Port_IO.State)),
203 Depends =>
204 (Registers.Register_State
205 =>+
206 (Registers.Register_State,
207 Controller,
Nico Huber113a14b2016-12-06 21:59:15 +0100208 Framebuffer,
209 Dither_BPC,
210 Dither),
Nico Huber3675db52016-11-04 16:27:29 +0100211 Port_IO.State
212 =>+
213 (Framebuffer))
214 is
215 use type Word8;
216
217 Reg8 : Word8;
218 begin
219 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
220
221 if Config.Has_Plane_Control then
222 Setup_Watermarks (Controller);
223 end if;
224
225 if Framebuffer.Offset = VGA_PLANE_FRAMEBUFFER_OFFSET then
Nico Huberfbb42202016-11-07 15:08:26 +0100226 if Config.VGA_Plane_Workaround then
227 Registers.Unset_And_Set_Mask
228 (Register => Registers.ILK_DISPLAY_CHICKEN1,
229 Mask_Unset => ILK_DISPLAY_CHICKEN1_VGA_MASK,
230 Mask_Set => ILK_DISPLAY_CHICKEN1_VGA_ENABLE);
231 Registers.Unset_And_Set_Mask
232 (Register => Registers.ILK_DISPLAY_CHICKEN2,
233 Mask_Unset => ILK_DISPLAY_CHICKEN2_VGA_MASK,
234 Mask_Set => ILK_DISPLAY_CHICKEN2_VGA_ENABLE);
235 end if;
236
Nico Huber3675db52016-11-04 16:27:29 +0100237 Registers.Unset_And_Set_Mask
238 (Register => Registers.VGACNTRL,
239 Mask_Unset => VGA_CONTROL_VGA_DISPLAY_DISABLE or
240 VGA_CONTROL_BLINK_DUTY_CYCLE_MASK or
241 VGA_CONTROL_VSYNC_BLINK_RATE_MASK,
242 Mask_Set => VGA_CONTROL_BLINK_DUTY_CYCLE_50 or
243 VGA_CONTROL_VSYNC_BLINK_RATE (30));
244
245 Port_IO.OutB (VGA_SR_INDEX, VGA_SR01);
246 Port_IO.InB (Reg8, VGA_SR_DATA);
247 Port_IO.OutB (VGA_SR_DATA, Reg8 and not (VGA_SR01_SCREEN_OFF));
248 else
Nico Huber6a4dfc82016-11-04 15:50:58 +0100249 Setup_Hires_Plane (Controller, Framebuffer);
Nico Huber3675db52016-11-04 16:27:29 +0100250 end if;
251
252 Registers.Write
253 (Register => Controller.PIPESRC,
254 Value => Encode
255 (Pos16 (Framebuffer.Height), Pos16 (Framebuffer.Width)));
Nico Huber83693c82016-10-08 22:17:55 +0200256
Nico Huber113a14b2016-12-06 21:59:15 +0100257 if Config.Has_Pipeconf_Misc then
258 Registers.Write
259 (Register => Controller.PIPEMISC,
Nico Huber7ad2d652016-12-07 15:19:32 +0100260 Value => Transcoder.BPC_Conf (Dither_BPC, Dither));
Nico Huber113a14b2016-12-06 21:59:15 +0100261 end if;
Nico Huber83693c82016-10-08 22:17:55 +0200262 end Setup_Display;
263
264 ----------------------------------------------------------------------------
265
Nico Huber4916e342016-11-04 14:37:53 +0100266 procedure Scale_Keep_Aspect
267 (Width : out Pos32;
268 Height : out Pos32;
269 Max_Width : in Pos32;
270 Max_Height : in Pos32;
271 Framebuffer : in Framebuffer_Type)
272 with
273 Pre =>
274 Max_Width <= Pos32 (Pos16'Last) and
275 Max_Height <= Pos32 (Pos16'Last) and
276 Framebuffer.Width <= Max_Width and
277 Framebuffer.Height <= Max_Height,
278 Post =>
279 Width <= Max_Width and Height <= Max_Height
280 is
281 begin
282 if (Max_Width * Framebuffer.Height) / Framebuffer.Width <= Max_Height then
283 Width := Max_Width;
284 Height := (Max_Width * Framebuffer.Height) / Framebuffer.Width;
285 else
286 Height := Max_Height;
287 Width := Pos32'Min (Max_Width, -- could prove, it's <= Max_Width
288 (Max_Height * Framebuffer.Width) / Framebuffer.Height);
289 end if;
290 end Scale_Keep_Aspect;
291
292 procedure Setup_Skylake_Pipe_Scaler
293 (Controller : in Controller_Type;
294 Mode : in HW.GFX.Mode_Type;
295 Framebuffer : in HW.GFX.Framebuffer_Type)
296 with
297 Pre =>
298 Framebuffer.Width <= Pos32 (Mode.H_Visible) and
299 Framebuffer.Height <= Pos32 (Mode.V_Visible)
300 is
Nico Huber7ad2d652016-12-07 15:19:32 +0100301 use type Registers.Registers_Invalid_Index;
302
Nico Huber4916e342016-11-04 14:37:53 +0100303 -- Enable 7x5 extended mode where possible:
304 Scaler_Mode : constant Word32 :=
305 (if Controller.PS_CTRL_2 /= Registers.Invalid_Register then
306 PS_CTRL_SCALER_MODE_7X5_EXTENDED else 0);
307
308 -- We can scale up to 2.99x horizontally:
309 Horizontal_Limit : constant Pos32 := ((Framebuffer.Width * 299) / 100);
310 -- The third scaler is limited to 1.99x
311 -- vertical scaling for source widths > 2048:
312 Vertical_Limit : constant Pos32 :=
313 (Framebuffer.Height *
314 (if Controller.PS_CTRL_2 = Registers.Invalid_Register and
315 Framebuffer.Width > 2048
316 then
317 199
318 else
319 299)) / 100;
320
321 Width, Height : Pos32;
322 begin
323 -- Writes to WIN_SZ arm the PS registers.
324
325 Scale_Keep_Aspect
326 (Width => Width,
327 Height => Height,
328 Max_Width => Pos32'Min (Horizontal_Limit, Pos32 (Mode.H_Visible)),
329 Max_Height => Pos32'Min (Vertical_Limit, Pos32 (Mode.V_Visible)),
330 Framebuffer => Framebuffer);
331
332 Registers.Write
333 (Register => Controller.PS_CTRL_1,
334 Value => PS_CTRL_ENABLE_SCALER or Scaler_Mode);
335 Registers.Write
336 (Register => Controller.PS_WIN_POS_1,
337 Value =>
338 Shift_Left (Word32 (Pos32 (Mode.H_Visible) - Width) / 2, 16) or
339 Word32 (Pos32 (Mode.V_Visible) - Height) / 2);
340 Registers.Write
341 (Register => Controller.PS_WIN_SZ_1,
342 Value => Shift_Left (Word32 (Width), 16) or Word32 (Height));
343 end Setup_Skylake_Pipe_Scaler;
344
345 procedure Setup_Ironlake_Panel_Fitter
346 (Controller : in Controller_Type;
347 Mode : in HW.GFX.Mode_Type;
348 Framebuffer : in HW.GFX.Framebuffer_Type)
349 with
350 Pre =>
351 Framebuffer.Width <= Pos32 (Mode.H_Visible) and
352 Framebuffer.Height <= Pos32 (Mode.V_Visible)
353 is
354 -- Force 1:1 mapping of panel fitter:pipe
355 PF_Ctrl_Pipe_Sel : constant Word32 :=
356 (if Config.Has_PF_Pipe_Select then
357 (case Controller.PF_CTRL is
358 when Registers.PFA_CTL_1 => 0 * 2 ** 29,
359 when Registers.PFB_CTL_1 => 1 * 2 ** 29,
360 when Registers.PFC_CTL_1 => 2 * 2 ** 29,
361 when others => 0) else 0);
362
363 Width, Height : Pos32;
364 begin
365 -- Writes to WIN_SZ arm the PF registers.
366
367 Scale_Keep_Aspect
368 (Width => Width,
369 Height => Height,
370 Max_Width => Pos32 (Mode.H_Visible),
371 Max_Height => Pos32 (Mode.V_Visible),
372 Framebuffer => Framebuffer);
373
374 Registers.Write
375 (Register => Controller.PF_CTRL,
376 Value => PF_CTRL_ENABLE or PF_Ctrl_Pipe_Sel or PF_CTRL_FILTER_MED);
377 Registers.Write
378 (Register => Controller.PF_WIN_POS,
379 Value =>
380 Shift_Left (Word32 (Pos32 (Mode.H_Visible) - Width) / 2, 16) or
381 Word32 (Pos32 (Mode.V_Visible) - Height) / 2);
382 Registers.Write
383 (Register => Controller.PF_WIN_SZ,
384 Value => Shift_Left (Word32 (Width), 16) or Word32 (Height));
385 end Setup_Ironlake_Panel_Fitter;
386
387 procedure Setup_Scaling
388 (Controller : in Controller_Type;
389 Mode : in HW.GFX.Mode_Type;
390 Framebuffer : in HW.GFX.Framebuffer_Type)
391 with
392 Pre =>
393 Framebuffer.Width <= Pos32 (Mode.H_Visible) and
394 Framebuffer.Height <= Pos32 (Mode.V_Visible)
395 is
396 begin
397 if Framebuffer.Width /= Pos32 (Mode.H_Visible) or
398 Framebuffer.Height /= Pos32 (Mode.V_Visible)
399 then
400 if Config.Has_Plane_Control then
401 Setup_Skylake_Pipe_Scaler (Controller, Mode, Framebuffer);
402 else
403 Setup_Ironlake_Panel_Fitter (Controller, Mode, Framebuffer);
404 end if;
405 end if;
406 end Setup_Scaling;
407
408 ----------------------------------------------------------------------------
409
Nico Huber83693c82016-10-08 22:17:55 +0200410 procedure On
Nico Huberf3e23662016-12-05 21:33:03 +0100411 (Pipe : Pipe_Index;
Nico Huber83693c82016-10-08 22:17:55 +0200412 Port_Cfg : Port_Config;
413 Framebuffer : Framebuffer_Type)
414 is
Nico Huber113a14b2016-12-06 21:59:15 +0100415 -- Enable dithering if framebuffer BPC differs from port BPC,
416 -- as smooth gradients look really bad without.
417 Dither : constant Boolean := Framebuffer.BPC /= Port_Cfg.Mode.BPC;
Nico Huber83693c82016-10-08 22:17:55 +0200418 begin
419 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
420
Nico Huber7ad2d652016-12-07 15:19:32 +0100421 Transcoder.Setup (Pipe, Port_Cfg);
Nico Huber83693c82016-10-08 22:17:55 +0200422
Nico Huberf3e23662016-12-05 21:33:03 +0100423 Setup_Display
Nico Huber113a14b2016-12-06 21:59:15 +0100424 (Controllers (Pipe), Framebuffer, Port_Cfg.Mode.BPC, Dither);
Nico Huber83693c82016-10-08 22:17:55 +0200425
Nico Huberf3e23662016-12-05 21:33:03 +0100426 Setup_Scaling (Controllers (Pipe), Port_Cfg.Mode, Framebuffer);
Nico Huber4916e342016-11-04 14:37:53 +0100427
Nico Huber7ad2d652016-12-07 15:19:32 +0100428 Transcoder.On (Pipe, Port_Cfg, Dither);
Nico Huber83693c82016-10-08 22:17:55 +0200429 end On;
430
431 ----------------------------------------------------------------------------
432
433 procedure Planes_Off (Controller : Controller_Type) is
434 begin
Nico Huber7ad2d652016-12-07 15:19:32 +0100435 Registers.Unset_Mask (Controller.SPCNTR, DSPCNTR_ENABLE);
Nico Huber83693c82016-10-08 22:17:55 +0200436 if Config.Has_Plane_Control then
437 Clear_Watermarks (Controller);
438 Registers.Unset_Mask (Controller.PLANE_CTL, PLANE_CTL_PLANE_ENABLE);
439 Registers.Write (Controller.PLANE_SURF, 16#0000_0000#);
440 else
441 Registers.Unset_Mask (Controller.DSPCNTR, DSPCNTR_ENABLE);
442 end if;
443 end Planes_Off;
444
Nico Huber7ad2d652016-12-07 15:19:32 +0100445 procedure Panel_Fitter_Off (Controller : Controller_Type)
Nico Huber83693c82016-10-08 22:17:55 +0200446 is
Nico Huber7ad2d652016-12-07 15:19:32 +0100447 use type HW.GFX.GMA.Registers.Registers_Invalid_Index;
Nico Huber83693c82016-10-08 22:17:55 +0200448 begin
449 -- Writes to WIN_SZ arm the PS/PF registers.
450 if Config.Has_Plane_Control then
451 Registers.Unset_Mask (Controller.PS_CTRL_1, PS_CTRL_ENABLE_SCALER);
452 Registers.Write (Controller.PS_WIN_SZ_1, 16#0000_0000#);
453 if Controller.PS_CTRL_2 /= Registers.Invalid_Register and
454 Controller.PS_WIN_SZ_2 /= Registers.Invalid_Register
455 then
456 Registers.Unset_Mask (Controller.PS_CTRL_2, PS_CTRL_ENABLE_SCALER);
457 Registers.Write (Controller.PS_WIN_SZ_2, 16#0000_0000#);
458 end if;
459 else
Nico Huber4916e342016-11-04 14:37:53 +0100460 Registers.Unset_Mask (Controller.PF_CTRL, PF_CTRL_ENABLE);
Nico Huber83693c82016-10-08 22:17:55 +0200461 Registers.Write (Controller.PF_WIN_SZ, 16#0000_0000#);
462 end if;
463 end Panel_Fitter_Off;
464
Nico Huber7ad2d652016-12-07 15:19:32 +0100465 procedure Off (Pipe : Pipe_Index)
Nico Huberf3e23662016-12-05 21:33:03 +0100466 is
Nico Huber83693c82016-10-08 22:17:55 +0200467 begin
468 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
469
Nico Huberf3e23662016-12-05 21:33:03 +0100470 Planes_Off (Controllers (Pipe));
Nico Huber7ad2d652016-12-07 15:19:32 +0100471 Transcoder.Off (Pipe);
Nico Huberf3e23662016-12-05 21:33:03 +0100472 Panel_Fitter_Off (Controllers (Pipe));
Nico Huber7ad2d652016-12-07 15:19:32 +0100473 Transcoder.Clk_Off (Pipe);
Nico Huber83693c82016-10-08 22:17:55 +0200474 end Off;
475
Nico Huber33912aa2016-12-06 20:36:23 +0100476 procedure Legacy_VGA_Off
477 is
478 use type HW.Word8;
479 Reg8 : Word8;
480 begin
481 Port_IO.OutB (VGA_SR_INDEX, VGA_SR01);
482 Port_IO.InB (Reg8, VGA_SR_DATA);
483 Port_IO.OutB (VGA_SR_DATA, Reg8 or VGA_SR01_SCREEN_OFF);
484 Time.U_Delay (100); -- PRM says 100us, Linux does 300
485 Registers.Set_Mask (Registers.VGACNTRL, VGA_CONTROL_VGA_DISPLAY_DISABLE);
486 end Legacy_VGA_Off;
487
Nico Huber83693c82016-10-08 22:17:55 +0200488 procedure All_Off
489 is
Nico Huber83693c82016-10-08 22:17:55 +0200490 begin
491 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
492
Nico Huber33912aa2016-12-06 20:36:23 +0100493 Legacy_VGA_Off;
494
Nico Huberf3e23662016-12-05 21:33:03 +0100495 for Pipe in Pipe_Index loop
496 Planes_Off (Controllers (Pipe));
Nico Huber7ad2d652016-12-07 15:19:32 +0100497 Transcoder.Off (Pipe);
Nico Huberf3e23662016-12-05 21:33:03 +0100498 Panel_Fitter_Off (Controllers (Pipe));
Nico Huber7ad2d652016-12-07 15:19:32 +0100499 Transcoder.Clk_Off (Pipe);
Nico Huber83693c82016-10-08 22:17:55 +0200500 end loop;
Nico Huber83693c82016-10-08 22:17:55 +0200501 end All_Off;
502
503 ----------------------------------------------------------------------------
504
Nico Huberf3e23662016-12-05 21:33:03 +0100505 procedure Update_Offset (Pipe : Pipe_Index; Framebuffer : Framebuffer_Type)
506 is
Nico Huber83693c82016-10-08 22:17:55 +0200507 begin
508 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
509
Nico Huberf3e23662016-12-05 21:33:03 +0100510 Registers.Write
511 (Controllers (Pipe).DSPSURF, Framebuffer.Offset and 16#ffff_f000#);
Nico Huber83693c82016-10-08 22:17:55 +0200512 end Update_Offset;
513
Nico Huber83693c82016-10-08 22:17:55 +0200514end HW.GFX.GMA.Pipe_Setup;