blob: e2d2567d072a36dead317a53ef5a4342e520954a [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
Nico Huber9b479412017-08-27 11:55:56 +020053 PLANE_CTL_PLANE_ROTATION_MASK : constant := 3 * 2 ** 0;
54 PLANE_CTL_PLANE_ROTATION : constant array (Rotation_Type) of Word32 :=
55 (No_Rotation => 0 * 2 ** 0,
56 Rotated_90 => 1 * 2 ** 0,
57 Rotated_180 => 2 * 2 ** 0,
58 Rotated_270 => 3 * 2 ** 0);
59
Nico Huber83693c82016-10-08 22:17:55 +020060 PLANE_WM_ENABLE : constant := 1 * 2 ** 31;
61 PLANE_WM_LINES_SHIFT : constant := 14;
62 PLANE_WM_LINES_MASK : constant := 16#001f# * 2 ** 14;
63 PLANE_WM_BLOCKS_MASK : constant := 16#03ff# * 2 ** 0;
64
Nico Huber33912aa2016-12-06 20:36:23 +010065 VGA_SR_INDEX : constant := 16#03c4#;
66 VGA_SR_DATA : constant := 16#03c5#;
67 VGA_SR01 : constant := 16#01#;
68 VGA_SR01_SCREEN_OFF : constant := 1 * 2 ** 5;
Nico Huber3675db52016-11-04 16:27:29 +010069
70 VGA_CONTROL_VGA_DISPLAY_DISABLE : constant := 1 * 2 ** 31;
71 VGA_CONTROL_BLINK_DUTY_CYCLE_MASK : constant := 16#0003# * 2 ** 6;
72 VGA_CONTROL_BLINK_DUTY_CYCLE_50 : constant := 2 * 2 ** 6;
73 VGA_CONTROL_VSYNC_BLINK_RATE_MASK : constant := 16#003f# * 2 ** 0;
74
75 subtype VGA_Cycle_Count is Pos32 range 2 .. 128;
76 function VGA_CONTROL_VSYNC_BLINK_RATE
77 (Cycles : VGA_Cycle_Count)
78 return Word32
79 is
80 begin
81 return Word32 (Cycles) / 2 - 1;
82 end VGA_CONTROL_VSYNC_BLINK_RATE;
83
Nico Huber7ad2d652016-12-07 15:19:32 +010084 PF_CTRL_ENABLE : constant := 1 * 2 ** 31;
85 PF_CTRL_PIPE_SELECT_MASK : constant := 3 * 2 ** 29;
86 PF_CTRL_FILTER_MED : constant := 1 * 2 ** 23;
Nico Huber83693c82016-10-08 22:17:55 +020087
Nico Huber7ad2d652016-12-07 15:19:32 +010088 PS_CTRL_ENABLE_SCALER : constant := 1 * 2 ** 31;
89 PS_CTRL_SCALER_MODE_7X5_EXTENDED : constant := 1 * 2 ** 28;
90 PS_CTRL_FILTER_SELECT_MEDIUM_2 : constant := 1 * 2 ** 23;
Nico Huber83693c82016-10-08 22:17:55 +020091
Arthur Heymansdfcdd772018-03-28 16:42:50 +020092 VGACNTRL_REG : constant Registers.Registers_Index :=
93 (if Config.Has_GMCH_VGACNTRL then
94 Registers.GMCH_VGACNTRL
95 else Registers.CPU_VGACNTRL);
96
Nico Huber83693c82016-10-08 22:17:55 +020097 ---------------------------------------------------------------------------
98
Nico Huber83693c82016-10-08 22:17:55 +020099 function PLANE_WM_LINES (Lines : Natural) return Word32 is
100 begin
101 return Shift_Left (Word32 (Lines), PLANE_WM_LINES_SHIFT)
102 and PLANE_WM_LINES_MASK;
103 end PLANE_WM_LINES;
104
105 function PLANE_WM_BLOCKS (Blocks : Natural) return Word32 is
106 begin
107 return Word32 (Blocks) and PLANE_WM_BLOCKS_MASK;
108 end PLANE_WM_BLOCKS;
109
110 ---------------------------------------------------------------------------
111
112 function Encode (LSW, MSW : Pos16) return Word32 is
113 begin
Nico Huber7ad2d652016-12-07 15:19:32 +0100114 return Shift_Left (Word32 (MSW) - 1, 16) or (Word32 (LSW) - 1);
Nico Huber83693c82016-10-08 22:17:55 +0200115 end Encode;
116
117 ----------------------------------------------------------------------------
118
Nico Huber83693c82016-10-08 22:17:55 +0200119 procedure Clear_Watermarks (Controller : Controller_Type) is
120 begin
121 Registers.Write
122 (Register => Controller.PLANE_BUF_CFG,
123 Value => 16#0000_0000#);
124 for Level in WM_Levels range 0 .. WM_Levels'Last loop
125 Registers.Write
126 (Register => Controller.PLANE_WM (Level),
127 Value => 16#0000_0000#);
128 end loop;
129 Registers.Write
130 (Register => Controller.WM_LINETIME,
131 Value => 16#0000_0000#);
132 end Clear_Watermarks;
133
134 procedure Setup_Watermarks (Controller : Controller_Type)
135 is
Nico Huberf3e23662016-12-05 21:33:03 +0100136 type Per_Plane_Buffer_Range is array (Pipe_Index) of Word32;
137 Buffer_Range : constant Per_Plane_Buffer_Range :=
138 (Primary => Shift_Left (159, 16) or 0,
139 Secondary => Shift_Left (319, 16) or 160,
140 Tertiary => Shift_Left (479, 16) or 320);
Nico Huber83693c82016-10-08 22:17:55 +0200141 begin
142 Registers.Write
143 (Register => Controller.PLANE_BUF_CFG,
Nico Huberf3e23662016-12-05 21:33:03 +0100144 Value => Buffer_Range (Controller.Pipe));
Nico Huber83693c82016-10-08 22:17:55 +0200145 Registers.Write
146 (Register => Controller.PLANE_WM (0),
147 Value => PLANE_WM_ENABLE or
148 PLANE_WM_LINES (2) or
149 PLANE_WM_BLOCKS (160));
150 end Setup_Watermarks;
151
152 ----------------------------------------------------------------------------
153
Nico Huber3675db52016-11-04 16:27:29 +0100154 procedure Setup_Hires_Plane
Nico Huber6a4dfc82016-11-04 15:50:58 +0100155 (Controller : Controller_Type;
Nico Huber0164b022017-08-24 15:12:51 +0200156 FB : HW.GFX.Framebuffer_Type)
Nico Huber83693c82016-10-08 22:17:55 +0200157 with
158 Global => (In_Out => Registers.Register_State),
159 Depends =>
160 (Registers.Register_State
161 =>+
162 (Registers.Register_State,
163 Controller,
Nico Huber9b479412017-08-27 11:55:56 +0200164 FB)),
165 Pre => FB.Height <= FB.V_Stride
Nico Huber83693c82016-10-08 22:17:55 +0200166 is
167 -- FIXME: setup correct format, based on framebuffer RGB format
168 Format : constant Word32 := 6 * 2 ** 26;
169 PRI : Word32 := DSPCNTR_ENABLE or Format;
Nico Huber83693c82016-10-08 22:17:55 +0200170 begin
171 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
172
Nico Huber83693c82016-10-08 22:17:55 +0200173 if Config.Has_Plane_Control then
Nico Huber9b479412017-08-27 11:55:56 +0200174 declare
Nico Huber34be6542017-12-13 09:26:24 +0100175 Stride, Offset : Word32;
Nico Huber9b479412017-08-27 11:55:56 +0200176 Width : constant Pos16 := Rotated_Width (FB);
177 Height : constant Pos16 := Rotated_Height (FB);
178 begin
179 if Rotation_90 (FB) then
180 Stride := Word32 (FB_Pitch (FB.V_Stride, FB));
181 Offset := Word32 (FB.V_Stride - FB.Height);
Nico Huber9b479412017-08-27 11:55:56 +0200182 else
183 Stride := Word32 (FB_Pitch (FB.Stride, FB));
184 Offset := 0;
Nico Huber9b479412017-08-27 11:55:56 +0200185 end if;
186 Registers.Write
187 (Register => Controller.PLANE_CTL,
188 Value => PLANE_CTL_PLANE_ENABLE or
189 PLANE_CTL_SRC_PIX_FMT_RGB_32B_8888 or
190 PLANE_CTL_PLANE_GAMMA_DISABLE or
191 PLANE_CTL_TILED_SURFACE (FB.Tiling) or
192 PLANE_CTL_PLANE_ROTATION (FB.Rotation));
193 Registers.Write (Controller.PLANE_OFFSET, Offset);
194 Registers.Write (Controller.PLANE_SIZE, Encode (Width, Height));
195 Registers.Write (Controller.PLANE_STRIDE, Stride);
196 Registers.Write (Controller.PLANE_POS, 16#0000_0000#);
Nico Huber34be6542017-12-13 09:26:24 +0100197 Registers.Write (Controller.PLANE_SURF, FB.Offset and 16#ffff_f000#);
Nico Huber9b479412017-08-27 11:55:56 +0200198 end;
Nico Huber83693c82016-10-08 22:17:55 +0200199 else
200 if Config.Disable_Trickle_Feed then
201 PRI := PRI or DSPCNTR_DISABLE_TRICKLE_FEED;
202 end if;
203 -- for now, just disable gamma LUT (can't do anything
204 -- useful without colorimetry information from display)
205 Registers.Unset_And_Set_Mask
206 (Register => Controller.DSPCNTR,
207 Mask_Unset => DSPCNTR_MASK,
208 Mask_Set => PRI);
209
Nico Huber0164b022017-08-24 15:12:51 +0200210 Registers.Write
211 (Controller.DSPSTRIDE, Word32 (Pixel_To_Bytes (FB.Stride, FB)));
212 Registers.Write (Controller.DSPSURF, FB.Offset and 16#ffff_f000#);
Nico Huber83693c82016-10-08 22:17:55 +0200213 if Config.Has_DSP_Linoff then
214 Registers.Write (Controller.DSPLINOFF, 0);
215 end if;
216 Registers.Write (Controller.DSPTILEOFF, 0);
217 end if;
Nico Huber3675db52016-11-04 16:27:29 +0100218 end Setup_Hires_Plane;
219
220 procedure Setup_Display
Nico Huber113a14b2016-12-06 21:59:15 +0100221 (Controller : Controller_Type;
222 Framebuffer : Framebuffer_Type;
223 Dither_BPC : BPC_Type;
224 Dither : Boolean)
Nico Huber3675db52016-11-04 16:27:29 +0100225 with
226 Global => (In_Out => (Registers.Register_State, Port_IO.State)),
227 Depends =>
228 (Registers.Register_State
229 =>+
230 (Registers.Register_State,
231 Controller,
Nico Huber113a14b2016-12-06 21:59:15 +0100232 Framebuffer,
233 Dither_BPC,
234 Dither),
Nico Huber3675db52016-11-04 16:27:29 +0100235 Port_IO.State
236 =>+
Nico Huber9b479412017-08-27 11:55:56 +0200237 (Framebuffer)),
238 Pre =>
239 Framebuffer.Offset = VGA_PLANE_FRAMEBUFFER_OFFSET or
240 Framebuffer.Height <= Framebuffer.V_Stride
Nico Huber3675db52016-11-04 16:27:29 +0100241 is
242 use type Word8;
243
244 Reg8 : Word8;
245 begin
246 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
247
248 if Config.Has_Plane_Control then
249 Setup_Watermarks (Controller);
250 end if;
251
252 if Framebuffer.Offset = VGA_PLANE_FRAMEBUFFER_OFFSET then
Nico Huberfbb42202016-11-07 15:08:26 +0100253 if Config.VGA_Plane_Workaround then
254 Registers.Unset_And_Set_Mask
255 (Register => Registers.ILK_DISPLAY_CHICKEN1,
256 Mask_Unset => ILK_DISPLAY_CHICKEN1_VGA_MASK,
257 Mask_Set => ILK_DISPLAY_CHICKEN1_VGA_ENABLE);
258 Registers.Unset_And_Set_Mask
259 (Register => Registers.ILK_DISPLAY_CHICKEN2,
260 Mask_Unset => ILK_DISPLAY_CHICKEN2_VGA_MASK,
261 Mask_Set => ILK_DISPLAY_CHICKEN2_VGA_ENABLE);
262 end if;
263
Nico Huber3675db52016-11-04 16:27:29 +0100264 Registers.Unset_And_Set_Mask
Arthur Heymansdfcdd772018-03-28 16:42:50 +0200265 (Register => VGACNTRL_REG,
Nico Huber3675db52016-11-04 16:27:29 +0100266 Mask_Unset => VGA_CONTROL_VGA_DISPLAY_DISABLE or
267 VGA_CONTROL_BLINK_DUTY_CYCLE_MASK or
268 VGA_CONTROL_VSYNC_BLINK_RATE_MASK,
269 Mask_Set => VGA_CONTROL_BLINK_DUTY_CYCLE_50 or
270 VGA_CONTROL_VSYNC_BLINK_RATE (30));
271
272 Port_IO.OutB (VGA_SR_INDEX, VGA_SR01);
273 Port_IO.InB (Reg8, VGA_SR_DATA);
274 Port_IO.OutB (VGA_SR_DATA, Reg8 and not (VGA_SR01_SCREEN_OFF));
275 else
Nico Huber6a4dfc82016-11-04 15:50:58 +0100276 Setup_Hires_Plane (Controller, Framebuffer);
Nico Huber3675db52016-11-04 16:27:29 +0100277 end if;
278
279 Registers.Write
280 (Register => Controller.PIPESRC,
281 Value => Encode
Nico Huber9b479412017-08-27 11:55:56 +0200282 (Rotated_Height (Framebuffer), Rotated_Width (Framebuffer)));
Nico Huber83693c82016-10-08 22:17:55 +0200283
Nico Huber113a14b2016-12-06 21:59:15 +0100284 if Config.Has_Pipeconf_Misc then
285 Registers.Write
286 (Register => Controller.PIPEMISC,
Nico Huber7ad2d652016-12-07 15:19:32 +0100287 Value => Transcoder.BPC_Conf (Dither_BPC, Dither));
Nico Huber113a14b2016-12-06 21:59:15 +0100288 end if;
Nico Huber83693c82016-10-08 22:17:55 +0200289 end Setup_Display;
290
291 ----------------------------------------------------------------------------
292
Nico Huber4916e342016-11-04 14:37:53 +0100293 procedure Scale_Keep_Aspect
294 (Width : out Pos32;
295 Height : out Pos32;
296 Max_Width : in Pos32;
297 Max_Height : in Pos32;
298 Framebuffer : in Framebuffer_Type)
299 with
300 Pre =>
301 Max_Width <= Pos32 (Pos16'Last) and
302 Max_Height <= Pos32 (Pos16'Last) and
Nico Huber9b479412017-08-27 11:55:56 +0200303 Pos32 (Rotated_Width (Framebuffer)) <= Max_Width and
304 Pos32 (Rotated_Height (Framebuffer)) <= Max_Height,
Nico Huber4916e342016-11-04 14:37:53 +0100305 Post =>
306 Width <= Max_Width and Height <= Max_Height
307 is
Nico Huber9b479412017-08-27 11:55:56 +0200308 Src_Width : constant Pos32 := Pos32 (Rotated_Width (Framebuffer));
309 Src_Height : constant Pos32 := Pos32 (Rotated_Height (Framebuffer));
Nico Huber4916e342016-11-04 14:37:53 +0100310 begin
Nico Huber9b479412017-08-27 11:55:56 +0200311 if (Max_Width * Src_Height) / Src_Width <= Max_Height then
Nico Huber4916e342016-11-04 14:37:53 +0100312 Width := Max_Width;
Nico Huber9b479412017-08-27 11:55:56 +0200313 Height := (Max_Width * Src_Height) / Src_Width;
Nico Huber4916e342016-11-04 14:37:53 +0100314 else
315 Height := Max_Height;
316 Width := Pos32'Min (Max_Width, -- could prove, it's <= Max_Width
Nico Huber9b479412017-08-27 11:55:56 +0200317 (Max_Height * Src_Width) / Src_Height);
Nico Huber4916e342016-11-04 14:37:53 +0100318 end if;
319 end Scale_Keep_Aspect;
320
321 procedure Setup_Skylake_Pipe_Scaler
322 (Controller : in Controller_Type;
323 Mode : in HW.GFX.Mode_Type;
324 Framebuffer : in HW.GFX.Framebuffer_Type)
325 with
326 Pre =>
Nico Huber9b479412017-08-27 11:55:56 +0200327 Rotated_Width (Framebuffer) <= Mode.H_Visible and
328 Rotated_Height (Framebuffer) <= Mode.V_Visible
Nico Huber4916e342016-11-04 14:37:53 +0100329 is
Nico Huber7ad2d652016-12-07 15:19:32 +0100330 use type Registers.Registers_Invalid_Index;
331
Nico Huber4916e342016-11-04 14:37:53 +0100332 -- Enable 7x5 extended mode where possible:
333 Scaler_Mode : constant Word32 :=
334 (if Controller.PS_CTRL_2 /= Registers.Invalid_Register then
335 PS_CTRL_SCALER_MODE_7X5_EXTENDED else 0);
336
Nico Huber9b479412017-08-27 11:55:56 +0200337 Width_In : constant Pos32 := Pos32 (Rotated_Width (Framebuffer));
338 Height_In : constant Pos32 := Pos32 (Rotated_Height (Framebuffer));
339
Nico Huber4916e342016-11-04 14:37:53 +0100340 -- We can scale up to 2.99x horizontally:
Nico Huber9b479412017-08-27 11:55:56 +0200341 Horizontal_Limit : constant Pos32 := (Width_In * 299) / 100;
Nico Huber4916e342016-11-04 14:37:53 +0100342 -- The third scaler is limited to 1.99x
343 -- vertical scaling for source widths > 2048:
344 Vertical_Limit : constant Pos32 :=
Nico Huber9b479412017-08-27 11:55:56 +0200345 (Height_In *
Nico Huber4916e342016-11-04 14:37:53 +0100346 (if Controller.PS_CTRL_2 = Registers.Invalid_Register and
Nico Huber9b479412017-08-27 11:55:56 +0200347 Width_In > 2048
Nico Huber4916e342016-11-04 14:37:53 +0100348 then
349 199
350 else
351 299)) / 100;
352
353 Width, Height : Pos32;
354 begin
355 -- Writes to WIN_SZ arm the PS registers.
356
357 Scale_Keep_Aspect
358 (Width => Width,
359 Height => Height,
360 Max_Width => Pos32'Min (Horizontal_Limit, Pos32 (Mode.H_Visible)),
361 Max_Height => Pos32'Min (Vertical_Limit, Pos32 (Mode.V_Visible)),
362 Framebuffer => Framebuffer);
363
364 Registers.Write
365 (Register => Controller.PS_CTRL_1,
366 Value => PS_CTRL_ENABLE_SCALER or Scaler_Mode);
367 Registers.Write
368 (Register => Controller.PS_WIN_POS_1,
369 Value =>
370 Shift_Left (Word32 (Pos32 (Mode.H_Visible) - Width) / 2, 16) or
371 Word32 (Pos32 (Mode.V_Visible) - Height) / 2);
372 Registers.Write
373 (Register => Controller.PS_WIN_SZ_1,
374 Value => Shift_Left (Word32 (Width), 16) or Word32 (Height));
375 end Setup_Skylake_Pipe_Scaler;
376
377 procedure Setup_Ironlake_Panel_Fitter
378 (Controller : in Controller_Type;
379 Mode : in HW.GFX.Mode_Type;
380 Framebuffer : in HW.GFX.Framebuffer_Type)
381 with
382 Pre =>
Nico Huber9b479412017-08-27 11:55:56 +0200383 Rotated_Width (Framebuffer) <= Mode.H_Visible and
384 Rotated_Height (Framebuffer) <= Mode.V_Visible
Nico Huber4916e342016-11-04 14:37:53 +0100385 is
386 -- Force 1:1 mapping of panel fitter:pipe
387 PF_Ctrl_Pipe_Sel : constant Word32 :=
388 (if Config.Has_PF_Pipe_Select then
389 (case Controller.PF_CTRL is
390 when Registers.PFA_CTL_1 => 0 * 2 ** 29,
391 when Registers.PFB_CTL_1 => 1 * 2 ** 29,
392 when Registers.PFC_CTL_1 => 2 * 2 ** 29,
393 when others => 0) else 0);
394
395 Width, Height : Pos32;
396 begin
397 -- Writes to WIN_SZ arm the PF registers.
398
399 Scale_Keep_Aspect
400 (Width => Width,
401 Height => Height,
402 Max_Width => Pos32 (Mode.H_Visible),
403 Max_Height => Pos32 (Mode.V_Visible),
404 Framebuffer => Framebuffer);
405
406 Registers.Write
407 (Register => Controller.PF_CTRL,
408 Value => PF_CTRL_ENABLE or PF_Ctrl_Pipe_Sel or PF_CTRL_FILTER_MED);
409 Registers.Write
410 (Register => Controller.PF_WIN_POS,
411 Value =>
412 Shift_Left (Word32 (Pos32 (Mode.H_Visible) - Width) / 2, 16) or
413 Word32 (Pos32 (Mode.V_Visible) - Height) / 2);
414 Registers.Write
415 (Register => Controller.PF_WIN_SZ,
416 Value => Shift_Left (Word32 (Width), 16) or Word32 (Height));
417 end Setup_Ironlake_Panel_Fitter;
418
419 procedure Setup_Scaling
420 (Controller : in Controller_Type;
421 Mode : in HW.GFX.Mode_Type;
422 Framebuffer : in HW.GFX.Framebuffer_Type)
423 with
424 Pre =>
Nico Huber9b479412017-08-27 11:55:56 +0200425 Rotated_Width (Framebuffer) <= Mode.H_Visible and
426 Rotated_Height (Framebuffer) <= Mode.V_Visible
Nico Huber4916e342016-11-04 14:37:53 +0100427 is
428 begin
Nico Huber9b479412017-08-27 11:55:56 +0200429 if Rotated_Width (Framebuffer) /= Mode.H_Visible or
430 Rotated_Height (Framebuffer) /= Mode.V_Visible
Nico Huber4916e342016-11-04 14:37:53 +0100431 then
432 if Config.Has_Plane_Control then
433 Setup_Skylake_Pipe_Scaler (Controller, Mode, Framebuffer);
434 else
435 Setup_Ironlake_Panel_Fitter (Controller, Mode, Framebuffer);
436 end if;
437 end if;
438 end Setup_Scaling;
439
440 ----------------------------------------------------------------------------
441
Nico Huber83693c82016-10-08 22:17:55 +0200442 procedure On
Nico Huberf3e23662016-12-05 21:33:03 +0100443 (Pipe : Pipe_Index;
Nico Huber83693c82016-10-08 22:17:55 +0200444 Port_Cfg : Port_Config;
445 Framebuffer : Framebuffer_Type)
446 is
Nico Huber113a14b2016-12-06 21:59:15 +0100447 -- Enable dithering if framebuffer BPC differs from port BPC,
448 -- as smooth gradients look really bad without.
449 Dither : constant Boolean := Framebuffer.BPC /= Port_Cfg.Mode.BPC;
Nico Huber83693c82016-10-08 22:17:55 +0200450 begin
451 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
452
Nico Huber7ad2d652016-12-07 15:19:32 +0100453 Transcoder.Setup (Pipe, Port_Cfg);
Nico Huber83693c82016-10-08 22:17:55 +0200454
Nico Huberf3e23662016-12-05 21:33:03 +0100455 Setup_Display
Nico Huber113a14b2016-12-06 21:59:15 +0100456 (Controllers (Pipe), Framebuffer, Port_Cfg.Mode.BPC, Dither);
Nico Huber83693c82016-10-08 22:17:55 +0200457
Nico Huberf3e23662016-12-05 21:33:03 +0100458 Setup_Scaling (Controllers (Pipe), Port_Cfg.Mode, Framebuffer);
Nico Huber4916e342016-11-04 14:37:53 +0100459
Nico Huber7ad2d652016-12-07 15:19:32 +0100460 Transcoder.On (Pipe, Port_Cfg, Dither);
Nico Huber83693c82016-10-08 22:17:55 +0200461 end On;
462
463 ----------------------------------------------------------------------------
464
465 procedure Planes_Off (Controller : Controller_Type) is
466 begin
Nico Huber7ad2d652016-12-07 15:19:32 +0100467 Registers.Unset_Mask (Controller.SPCNTR, DSPCNTR_ENABLE);
Nico Huber83693c82016-10-08 22:17:55 +0200468 if Config.Has_Plane_Control then
469 Clear_Watermarks (Controller);
470 Registers.Unset_Mask (Controller.PLANE_CTL, PLANE_CTL_PLANE_ENABLE);
471 Registers.Write (Controller.PLANE_SURF, 16#0000_0000#);
472 else
473 Registers.Unset_Mask (Controller.DSPCNTR, DSPCNTR_ENABLE);
474 end if;
475 end Planes_Off;
476
Nico Huber7ad2d652016-12-07 15:19:32 +0100477 procedure Panel_Fitter_Off (Controller : Controller_Type)
Nico Huber83693c82016-10-08 22:17:55 +0200478 is
Nico Huber7ad2d652016-12-07 15:19:32 +0100479 use type HW.GFX.GMA.Registers.Registers_Invalid_Index;
Nico Huber83693c82016-10-08 22:17:55 +0200480 begin
481 -- Writes to WIN_SZ arm the PS/PF registers.
482 if Config.Has_Plane_Control then
483 Registers.Unset_Mask (Controller.PS_CTRL_1, PS_CTRL_ENABLE_SCALER);
484 Registers.Write (Controller.PS_WIN_SZ_1, 16#0000_0000#);
485 if Controller.PS_CTRL_2 /= Registers.Invalid_Register and
486 Controller.PS_WIN_SZ_2 /= Registers.Invalid_Register
487 then
488 Registers.Unset_Mask (Controller.PS_CTRL_2, PS_CTRL_ENABLE_SCALER);
489 Registers.Write (Controller.PS_WIN_SZ_2, 16#0000_0000#);
490 end if;
491 else
Nico Huber4916e342016-11-04 14:37:53 +0100492 Registers.Unset_Mask (Controller.PF_CTRL, PF_CTRL_ENABLE);
Nico Huber83693c82016-10-08 22:17:55 +0200493 Registers.Write (Controller.PF_WIN_SZ, 16#0000_0000#);
494 end if;
495 end Panel_Fitter_Off;
496
Nico Huber7ad2d652016-12-07 15:19:32 +0100497 procedure Off (Pipe : Pipe_Index)
Nico Huberf3e23662016-12-05 21:33:03 +0100498 is
Nico Huber83693c82016-10-08 22:17:55 +0200499 begin
500 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
501
Nico Huberf3e23662016-12-05 21:33:03 +0100502 Planes_Off (Controllers (Pipe));
Nico Huber7ad2d652016-12-07 15:19:32 +0100503 Transcoder.Off (Pipe);
Nico Huberf3e23662016-12-05 21:33:03 +0100504 Panel_Fitter_Off (Controllers (Pipe));
Nico Huber7ad2d652016-12-07 15:19:32 +0100505 Transcoder.Clk_Off (Pipe);
Nico Huber83693c82016-10-08 22:17:55 +0200506 end Off;
507
Nico Huber33912aa2016-12-06 20:36:23 +0100508 procedure Legacy_VGA_Off
509 is
510 use type HW.Word8;
511 Reg8 : Word8;
512 begin
513 Port_IO.OutB (VGA_SR_INDEX, VGA_SR01);
514 Port_IO.InB (Reg8, VGA_SR_DATA);
515 Port_IO.OutB (VGA_SR_DATA, Reg8 or VGA_SR01_SCREEN_OFF);
516 Time.U_Delay (100); -- PRM says 100us, Linux does 300
Arthur Heymansdfcdd772018-03-28 16:42:50 +0200517 Registers.Set_Mask (VGACNTRL_REG, VGA_CONTROL_VGA_DISPLAY_DISABLE);
Nico Huber33912aa2016-12-06 20:36:23 +0100518 end Legacy_VGA_Off;
519
Nico Huber83693c82016-10-08 22:17:55 +0200520 procedure All_Off
521 is
Nico Huber83693c82016-10-08 22:17:55 +0200522 begin
523 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
524
Nico Huber33912aa2016-12-06 20:36:23 +0100525 Legacy_VGA_Off;
526
Nico Huberf3e23662016-12-05 21:33:03 +0100527 for Pipe in Pipe_Index loop
528 Planes_Off (Controllers (Pipe));
Nico Huber7ad2d652016-12-07 15:19:32 +0100529 Transcoder.Off (Pipe);
Nico Huberf3e23662016-12-05 21:33:03 +0100530 Panel_Fitter_Off (Controllers (Pipe));
Nico Huber7ad2d652016-12-07 15:19:32 +0100531 Transcoder.Clk_Off (Pipe);
Nico Huber83693c82016-10-08 22:17:55 +0200532 end loop;
Nico Huber83693c82016-10-08 22:17:55 +0200533 end All_Off;
534
535 ----------------------------------------------------------------------------
536
Nico Huberf3e23662016-12-05 21:33:03 +0100537 procedure Update_Offset (Pipe : Pipe_Index; Framebuffer : Framebuffer_Type)
538 is
Nico Huber83693c82016-10-08 22:17:55 +0200539 begin
540 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
541
Nico Huberf3e23662016-12-05 21:33:03 +0100542 Registers.Write
543 (Controllers (Pipe).DSPSURF, Framebuffer.Offset and 16#ffff_f000#);
Nico Huber83693c82016-10-08 22:17:55 +0200544 end Update_Offset;
545
Nico Huber83693c82016-10-08 22:17:55 +0200546end HW.GFX.GMA.Pipe_Setup;