blob: e1ff83575c686e4e8668e54a12bc415f2617e8d1 [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
92 ---------------------------------------------------------------------------
93
Nico Huber83693c82016-10-08 22:17:55 +020094 function PLANE_WM_LINES (Lines : Natural) return Word32 is
95 begin
96 return Shift_Left (Word32 (Lines), PLANE_WM_LINES_SHIFT)
97 and PLANE_WM_LINES_MASK;
98 end PLANE_WM_LINES;
99
100 function PLANE_WM_BLOCKS (Blocks : Natural) return Word32 is
101 begin
102 return Word32 (Blocks) and PLANE_WM_BLOCKS_MASK;
103 end PLANE_WM_BLOCKS;
104
105 ---------------------------------------------------------------------------
106
107 function Encode (LSW, MSW : Pos16) return Word32 is
108 begin
Nico Huber7ad2d652016-12-07 15:19:32 +0100109 return Shift_Left (Word32 (MSW) - 1, 16) or (Word32 (LSW) - 1);
Nico Huber83693c82016-10-08 22:17:55 +0200110 end Encode;
111
112 ----------------------------------------------------------------------------
113
Nico Huber83693c82016-10-08 22:17:55 +0200114 procedure Clear_Watermarks (Controller : Controller_Type) is
115 begin
116 Registers.Write
117 (Register => Controller.PLANE_BUF_CFG,
118 Value => 16#0000_0000#);
119 for Level in WM_Levels range 0 .. WM_Levels'Last loop
120 Registers.Write
121 (Register => Controller.PLANE_WM (Level),
122 Value => 16#0000_0000#);
123 end loop;
124 Registers.Write
125 (Register => Controller.WM_LINETIME,
126 Value => 16#0000_0000#);
127 end Clear_Watermarks;
128
129 procedure Setup_Watermarks (Controller : Controller_Type)
130 is
Nico Huberf3e23662016-12-05 21:33:03 +0100131 type Per_Plane_Buffer_Range is array (Pipe_Index) of Word32;
132 Buffer_Range : constant Per_Plane_Buffer_Range :=
133 (Primary => Shift_Left (159, 16) or 0,
134 Secondary => Shift_Left (319, 16) or 160,
135 Tertiary => Shift_Left (479, 16) or 320);
Nico Huber83693c82016-10-08 22:17:55 +0200136 begin
137 Registers.Write
138 (Register => Controller.PLANE_BUF_CFG,
Nico Huberf3e23662016-12-05 21:33:03 +0100139 Value => Buffer_Range (Controller.Pipe));
Nico Huber83693c82016-10-08 22:17:55 +0200140 Registers.Write
141 (Register => Controller.PLANE_WM (0),
142 Value => PLANE_WM_ENABLE or
143 PLANE_WM_LINES (2) or
144 PLANE_WM_BLOCKS (160));
145 end Setup_Watermarks;
146
147 ----------------------------------------------------------------------------
148
Nico Huber3675db52016-11-04 16:27:29 +0100149 procedure Setup_Hires_Plane
Nico Huber6a4dfc82016-11-04 15:50:58 +0100150 (Controller : Controller_Type;
Nico Huber0164b022017-08-24 15:12:51 +0200151 FB : HW.GFX.Framebuffer_Type)
Nico Huber83693c82016-10-08 22:17:55 +0200152 with
153 Global => (In_Out => Registers.Register_State),
154 Depends =>
155 (Registers.Register_State
156 =>+
157 (Registers.Register_State,
158 Controller,
Nico Huber9b479412017-08-27 11:55:56 +0200159 FB)),
160 Pre => FB.Height <= FB.V_Stride
Nico Huber83693c82016-10-08 22:17:55 +0200161 is
162 -- FIXME: setup correct format, based on framebuffer RGB format
163 Format : constant Word32 := 6 * 2 ** 26;
164 PRI : Word32 := DSPCNTR_ENABLE or Format;
Nico Huber83693c82016-10-08 22:17:55 +0200165 begin
166 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
167
Nico Huber83693c82016-10-08 22:17:55 +0200168 if Config.Has_Plane_Control then
Nico Huber9b479412017-08-27 11:55:56 +0200169 declare
170 Stride, Offset, GTT_Addr : Word32;
171 Width : constant Pos16 := Rotated_Width (FB);
172 Height : constant Pos16 := Rotated_Height (FB);
173 begin
174 if Rotation_90 (FB) then
175 Stride := Word32 (FB_Pitch (FB.V_Stride, FB));
176 Offset := Word32 (FB.V_Stride - FB.Height);
177 GTT_Addr :=
178 FB.Offset + Word32 (GTT_Rotation_Offset) * GTT_Page_Size;
179 else
180 Stride := Word32 (FB_Pitch (FB.Stride, FB));
181 Offset := 0;
182 GTT_Addr := FB.Offset;
183 end if;
184 Registers.Write
185 (Register => Controller.PLANE_CTL,
186 Value => PLANE_CTL_PLANE_ENABLE or
187 PLANE_CTL_SRC_PIX_FMT_RGB_32B_8888 or
188 PLANE_CTL_PLANE_GAMMA_DISABLE or
189 PLANE_CTL_TILED_SURFACE (FB.Tiling) or
190 PLANE_CTL_PLANE_ROTATION (FB.Rotation));
191 Registers.Write (Controller.PLANE_OFFSET, Offset);
192 Registers.Write (Controller.PLANE_SIZE, Encode (Width, Height));
193 Registers.Write (Controller.PLANE_STRIDE, Stride);
194 Registers.Write (Controller.PLANE_POS, 16#0000_0000#);
195 Registers.Write (Controller.PLANE_SURF, GTT_Addr and 16#ffff_f000#);
196 end;
Nico Huber83693c82016-10-08 22:17:55 +0200197 else
198 if Config.Disable_Trickle_Feed then
199 PRI := PRI or DSPCNTR_DISABLE_TRICKLE_FEED;
200 end if;
201 -- for now, just disable gamma LUT (can't do anything
202 -- useful without colorimetry information from display)
203 Registers.Unset_And_Set_Mask
204 (Register => Controller.DSPCNTR,
205 Mask_Unset => DSPCNTR_MASK,
206 Mask_Set => PRI);
207
Nico Huber0164b022017-08-24 15:12:51 +0200208 Registers.Write
209 (Controller.DSPSTRIDE, Word32 (Pixel_To_Bytes (FB.Stride, FB)));
210 Registers.Write (Controller.DSPSURF, FB.Offset and 16#ffff_f000#);
Nico Huber83693c82016-10-08 22:17:55 +0200211 if Config.Has_DSP_Linoff then
212 Registers.Write (Controller.DSPLINOFF, 0);
213 end if;
214 Registers.Write (Controller.DSPTILEOFF, 0);
215 end if;
Nico Huber3675db52016-11-04 16:27:29 +0100216 end Setup_Hires_Plane;
217
218 procedure Setup_Display
Nico Huber113a14b2016-12-06 21:59:15 +0100219 (Controller : Controller_Type;
220 Framebuffer : Framebuffer_Type;
221 Dither_BPC : BPC_Type;
222 Dither : Boolean)
Nico Huber3675db52016-11-04 16:27:29 +0100223 with
224 Global => (In_Out => (Registers.Register_State, Port_IO.State)),
225 Depends =>
226 (Registers.Register_State
227 =>+
228 (Registers.Register_State,
229 Controller,
Nico Huber113a14b2016-12-06 21:59:15 +0100230 Framebuffer,
231 Dither_BPC,
232 Dither),
Nico Huber3675db52016-11-04 16:27:29 +0100233 Port_IO.State
234 =>+
Nico Huber9b479412017-08-27 11:55:56 +0200235 (Framebuffer)),
236 Pre =>
237 Framebuffer.Offset = VGA_PLANE_FRAMEBUFFER_OFFSET or
238 Framebuffer.Height <= Framebuffer.V_Stride
Nico Huber3675db52016-11-04 16:27:29 +0100239 is
240 use type Word8;
241
242 Reg8 : Word8;
243 begin
244 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
245
246 if Config.Has_Plane_Control then
247 Setup_Watermarks (Controller);
248 end if;
249
250 if Framebuffer.Offset = VGA_PLANE_FRAMEBUFFER_OFFSET then
Nico Huberfbb42202016-11-07 15:08:26 +0100251 if Config.VGA_Plane_Workaround then
252 Registers.Unset_And_Set_Mask
253 (Register => Registers.ILK_DISPLAY_CHICKEN1,
254 Mask_Unset => ILK_DISPLAY_CHICKEN1_VGA_MASK,
255 Mask_Set => ILK_DISPLAY_CHICKEN1_VGA_ENABLE);
256 Registers.Unset_And_Set_Mask
257 (Register => Registers.ILK_DISPLAY_CHICKEN2,
258 Mask_Unset => ILK_DISPLAY_CHICKEN2_VGA_MASK,
259 Mask_Set => ILK_DISPLAY_CHICKEN2_VGA_ENABLE);
260 end if;
261
Nico Huber3675db52016-11-04 16:27:29 +0100262 Registers.Unset_And_Set_Mask
263 (Register => Registers.VGACNTRL,
264 Mask_Unset => VGA_CONTROL_VGA_DISPLAY_DISABLE or
265 VGA_CONTROL_BLINK_DUTY_CYCLE_MASK or
266 VGA_CONTROL_VSYNC_BLINK_RATE_MASK,
267 Mask_Set => VGA_CONTROL_BLINK_DUTY_CYCLE_50 or
268 VGA_CONTROL_VSYNC_BLINK_RATE (30));
269
270 Port_IO.OutB (VGA_SR_INDEX, VGA_SR01);
271 Port_IO.InB (Reg8, VGA_SR_DATA);
272 Port_IO.OutB (VGA_SR_DATA, Reg8 and not (VGA_SR01_SCREEN_OFF));
273 else
Nico Huber6a4dfc82016-11-04 15:50:58 +0100274 Setup_Hires_Plane (Controller, Framebuffer);
Nico Huber3675db52016-11-04 16:27:29 +0100275 end if;
276
277 Registers.Write
278 (Register => Controller.PIPESRC,
279 Value => Encode
Nico Huber9b479412017-08-27 11:55:56 +0200280 (Rotated_Height (Framebuffer), Rotated_Width (Framebuffer)));
Nico Huber83693c82016-10-08 22:17:55 +0200281
Nico Huber113a14b2016-12-06 21:59:15 +0100282 if Config.Has_Pipeconf_Misc then
283 Registers.Write
284 (Register => Controller.PIPEMISC,
Nico Huber7ad2d652016-12-07 15:19:32 +0100285 Value => Transcoder.BPC_Conf (Dither_BPC, Dither));
Nico Huber113a14b2016-12-06 21:59:15 +0100286 end if;
Nico Huber83693c82016-10-08 22:17:55 +0200287 end Setup_Display;
288
289 ----------------------------------------------------------------------------
290
Nico Huber4916e342016-11-04 14:37:53 +0100291 procedure Scale_Keep_Aspect
292 (Width : out Pos32;
293 Height : out Pos32;
294 Max_Width : in Pos32;
295 Max_Height : in Pos32;
296 Framebuffer : in Framebuffer_Type)
297 with
298 Pre =>
299 Max_Width <= Pos32 (Pos16'Last) and
300 Max_Height <= Pos32 (Pos16'Last) and
Nico Huber9b479412017-08-27 11:55:56 +0200301 Pos32 (Rotated_Width (Framebuffer)) <= Max_Width and
302 Pos32 (Rotated_Height (Framebuffer)) <= Max_Height,
Nico Huber4916e342016-11-04 14:37:53 +0100303 Post =>
304 Width <= Max_Width and Height <= Max_Height
305 is
Nico Huber9b479412017-08-27 11:55:56 +0200306 Src_Width : constant Pos32 := Pos32 (Rotated_Width (Framebuffer));
307 Src_Height : constant Pos32 := Pos32 (Rotated_Height (Framebuffer));
Nico Huber4916e342016-11-04 14:37:53 +0100308 begin
Nico Huber9b479412017-08-27 11:55:56 +0200309 if (Max_Width * Src_Height) / Src_Width <= Max_Height then
Nico Huber4916e342016-11-04 14:37:53 +0100310 Width := Max_Width;
Nico Huber9b479412017-08-27 11:55:56 +0200311 Height := (Max_Width * Src_Height) / Src_Width;
Nico Huber4916e342016-11-04 14:37:53 +0100312 else
313 Height := Max_Height;
314 Width := Pos32'Min (Max_Width, -- could prove, it's <= Max_Width
Nico Huber9b479412017-08-27 11:55:56 +0200315 (Max_Height * Src_Width) / Src_Height);
Nico Huber4916e342016-11-04 14:37:53 +0100316 end if;
317 end Scale_Keep_Aspect;
318
319 procedure Setup_Skylake_Pipe_Scaler
320 (Controller : in Controller_Type;
321 Mode : in HW.GFX.Mode_Type;
322 Framebuffer : in HW.GFX.Framebuffer_Type)
323 with
324 Pre =>
Nico Huber9b479412017-08-27 11:55:56 +0200325 Rotated_Width (Framebuffer) <= Mode.H_Visible and
326 Rotated_Height (Framebuffer) <= Mode.V_Visible
Nico Huber4916e342016-11-04 14:37:53 +0100327 is
Nico Huber7ad2d652016-12-07 15:19:32 +0100328 use type Registers.Registers_Invalid_Index;
329
Nico Huber4916e342016-11-04 14:37:53 +0100330 -- Enable 7x5 extended mode where possible:
331 Scaler_Mode : constant Word32 :=
332 (if Controller.PS_CTRL_2 /= Registers.Invalid_Register then
333 PS_CTRL_SCALER_MODE_7X5_EXTENDED else 0);
334
Nico Huber9b479412017-08-27 11:55:56 +0200335 Width_In : constant Pos32 := Pos32 (Rotated_Width (Framebuffer));
336 Height_In : constant Pos32 := Pos32 (Rotated_Height (Framebuffer));
337
Nico Huber4916e342016-11-04 14:37:53 +0100338 -- We can scale up to 2.99x horizontally:
Nico Huber9b479412017-08-27 11:55:56 +0200339 Horizontal_Limit : constant Pos32 := (Width_In * 299) / 100;
Nico Huber4916e342016-11-04 14:37:53 +0100340 -- The third scaler is limited to 1.99x
341 -- vertical scaling for source widths > 2048:
342 Vertical_Limit : constant Pos32 :=
Nico Huber9b479412017-08-27 11:55:56 +0200343 (Height_In *
Nico Huber4916e342016-11-04 14:37:53 +0100344 (if Controller.PS_CTRL_2 = Registers.Invalid_Register and
Nico Huber9b479412017-08-27 11:55:56 +0200345 Width_In > 2048
Nico Huber4916e342016-11-04 14:37:53 +0100346 then
347 199
348 else
349 299)) / 100;
350
351 Width, Height : Pos32;
352 begin
353 -- Writes to WIN_SZ arm the PS registers.
354
355 Scale_Keep_Aspect
356 (Width => Width,
357 Height => Height,
358 Max_Width => Pos32'Min (Horizontal_Limit, Pos32 (Mode.H_Visible)),
359 Max_Height => Pos32'Min (Vertical_Limit, Pos32 (Mode.V_Visible)),
360 Framebuffer => Framebuffer);
361
362 Registers.Write
363 (Register => Controller.PS_CTRL_1,
364 Value => PS_CTRL_ENABLE_SCALER or Scaler_Mode);
365 Registers.Write
366 (Register => Controller.PS_WIN_POS_1,
367 Value =>
368 Shift_Left (Word32 (Pos32 (Mode.H_Visible) - Width) / 2, 16) or
369 Word32 (Pos32 (Mode.V_Visible) - Height) / 2);
370 Registers.Write
371 (Register => Controller.PS_WIN_SZ_1,
372 Value => Shift_Left (Word32 (Width), 16) or Word32 (Height));
373 end Setup_Skylake_Pipe_Scaler;
374
375 procedure Setup_Ironlake_Panel_Fitter
376 (Controller : in Controller_Type;
377 Mode : in HW.GFX.Mode_Type;
378 Framebuffer : in HW.GFX.Framebuffer_Type)
379 with
380 Pre =>
Nico Huber9b479412017-08-27 11:55:56 +0200381 Rotated_Width (Framebuffer) <= Mode.H_Visible and
382 Rotated_Height (Framebuffer) <= Mode.V_Visible
Nico Huber4916e342016-11-04 14:37:53 +0100383 is
384 -- Force 1:1 mapping of panel fitter:pipe
385 PF_Ctrl_Pipe_Sel : constant Word32 :=
386 (if Config.Has_PF_Pipe_Select then
387 (case Controller.PF_CTRL is
388 when Registers.PFA_CTL_1 => 0 * 2 ** 29,
389 when Registers.PFB_CTL_1 => 1 * 2 ** 29,
390 when Registers.PFC_CTL_1 => 2 * 2 ** 29,
391 when others => 0) else 0);
392
393 Width, Height : Pos32;
394 begin
395 -- Writes to WIN_SZ arm the PF registers.
396
397 Scale_Keep_Aspect
398 (Width => Width,
399 Height => Height,
400 Max_Width => Pos32 (Mode.H_Visible),
401 Max_Height => Pos32 (Mode.V_Visible),
402 Framebuffer => Framebuffer);
403
404 Registers.Write
405 (Register => Controller.PF_CTRL,
406 Value => PF_CTRL_ENABLE or PF_Ctrl_Pipe_Sel or PF_CTRL_FILTER_MED);
407 Registers.Write
408 (Register => Controller.PF_WIN_POS,
409 Value =>
410 Shift_Left (Word32 (Pos32 (Mode.H_Visible) - Width) / 2, 16) or
411 Word32 (Pos32 (Mode.V_Visible) - Height) / 2);
412 Registers.Write
413 (Register => Controller.PF_WIN_SZ,
414 Value => Shift_Left (Word32 (Width), 16) or Word32 (Height));
415 end Setup_Ironlake_Panel_Fitter;
416
417 procedure Setup_Scaling
418 (Controller : in Controller_Type;
419 Mode : in HW.GFX.Mode_Type;
420 Framebuffer : in HW.GFX.Framebuffer_Type)
421 with
422 Pre =>
Nico Huber9b479412017-08-27 11:55:56 +0200423 Rotated_Width (Framebuffer) <= Mode.H_Visible and
424 Rotated_Height (Framebuffer) <= Mode.V_Visible
Nico Huber4916e342016-11-04 14:37:53 +0100425 is
426 begin
Nico Huber9b479412017-08-27 11:55:56 +0200427 if Rotated_Width (Framebuffer) /= Mode.H_Visible or
428 Rotated_Height (Framebuffer) /= Mode.V_Visible
Nico Huber4916e342016-11-04 14:37:53 +0100429 then
430 if Config.Has_Plane_Control then
431 Setup_Skylake_Pipe_Scaler (Controller, Mode, Framebuffer);
432 else
433 Setup_Ironlake_Panel_Fitter (Controller, Mode, Framebuffer);
434 end if;
435 end if;
436 end Setup_Scaling;
437
438 ----------------------------------------------------------------------------
439
Nico Huber83693c82016-10-08 22:17:55 +0200440 procedure On
Nico Huberf3e23662016-12-05 21:33:03 +0100441 (Pipe : Pipe_Index;
Nico Huber83693c82016-10-08 22:17:55 +0200442 Port_Cfg : Port_Config;
443 Framebuffer : Framebuffer_Type)
444 is
Nico Huber113a14b2016-12-06 21:59:15 +0100445 -- Enable dithering if framebuffer BPC differs from port BPC,
446 -- as smooth gradients look really bad without.
447 Dither : constant Boolean := Framebuffer.BPC /= Port_Cfg.Mode.BPC;
Nico Huber83693c82016-10-08 22:17:55 +0200448 begin
449 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
450
Nico Huber7ad2d652016-12-07 15:19:32 +0100451 Transcoder.Setup (Pipe, Port_Cfg);
Nico Huber83693c82016-10-08 22:17:55 +0200452
Nico Huberf3e23662016-12-05 21:33:03 +0100453 Setup_Display
Nico Huber113a14b2016-12-06 21:59:15 +0100454 (Controllers (Pipe), Framebuffer, Port_Cfg.Mode.BPC, Dither);
Nico Huber83693c82016-10-08 22:17:55 +0200455
Nico Huberf3e23662016-12-05 21:33:03 +0100456 Setup_Scaling (Controllers (Pipe), Port_Cfg.Mode, Framebuffer);
Nico Huber4916e342016-11-04 14:37:53 +0100457
Nico Huber7ad2d652016-12-07 15:19:32 +0100458 Transcoder.On (Pipe, Port_Cfg, Dither);
Nico Huber83693c82016-10-08 22:17:55 +0200459 end On;
460
461 ----------------------------------------------------------------------------
462
463 procedure Planes_Off (Controller : Controller_Type) is
464 begin
Nico Huber7ad2d652016-12-07 15:19:32 +0100465 Registers.Unset_Mask (Controller.SPCNTR, DSPCNTR_ENABLE);
Nico Huber83693c82016-10-08 22:17:55 +0200466 if Config.Has_Plane_Control then
467 Clear_Watermarks (Controller);
468 Registers.Unset_Mask (Controller.PLANE_CTL, PLANE_CTL_PLANE_ENABLE);
469 Registers.Write (Controller.PLANE_SURF, 16#0000_0000#);
470 else
471 Registers.Unset_Mask (Controller.DSPCNTR, DSPCNTR_ENABLE);
472 end if;
473 end Planes_Off;
474
Nico Huber7ad2d652016-12-07 15:19:32 +0100475 procedure Panel_Fitter_Off (Controller : Controller_Type)
Nico Huber83693c82016-10-08 22:17:55 +0200476 is
Nico Huber7ad2d652016-12-07 15:19:32 +0100477 use type HW.GFX.GMA.Registers.Registers_Invalid_Index;
Nico Huber83693c82016-10-08 22:17:55 +0200478 begin
479 -- Writes to WIN_SZ arm the PS/PF registers.
480 if Config.Has_Plane_Control then
481 Registers.Unset_Mask (Controller.PS_CTRL_1, PS_CTRL_ENABLE_SCALER);
482 Registers.Write (Controller.PS_WIN_SZ_1, 16#0000_0000#);
483 if Controller.PS_CTRL_2 /= Registers.Invalid_Register and
484 Controller.PS_WIN_SZ_2 /= Registers.Invalid_Register
485 then
486 Registers.Unset_Mask (Controller.PS_CTRL_2, PS_CTRL_ENABLE_SCALER);
487 Registers.Write (Controller.PS_WIN_SZ_2, 16#0000_0000#);
488 end if;
489 else
Nico Huber4916e342016-11-04 14:37:53 +0100490 Registers.Unset_Mask (Controller.PF_CTRL, PF_CTRL_ENABLE);
Nico Huber83693c82016-10-08 22:17:55 +0200491 Registers.Write (Controller.PF_WIN_SZ, 16#0000_0000#);
492 end if;
493 end Panel_Fitter_Off;
494
Nico Huber7ad2d652016-12-07 15:19:32 +0100495 procedure Off (Pipe : Pipe_Index)
Nico Huberf3e23662016-12-05 21:33:03 +0100496 is
Nico Huber83693c82016-10-08 22:17:55 +0200497 begin
498 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
499
Nico Huberf3e23662016-12-05 21:33:03 +0100500 Planes_Off (Controllers (Pipe));
Nico Huber7ad2d652016-12-07 15:19:32 +0100501 Transcoder.Off (Pipe);
Nico Huberf3e23662016-12-05 21:33:03 +0100502 Panel_Fitter_Off (Controllers (Pipe));
Nico Huber7ad2d652016-12-07 15:19:32 +0100503 Transcoder.Clk_Off (Pipe);
Nico Huber83693c82016-10-08 22:17:55 +0200504 end Off;
505
Nico Huber33912aa2016-12-06 20:36:23 +0100506 procedure Legacy_VGA_Off
507 is
508 use type HW.Word8;
509 Reg8 : Word8;
510 begin
511 Port_IO.OutB (VGA_SR_INDEX, VGA_SR01);
512 Port_IO.InB (Reg8, VGA_SR_DATA);
513 Port_IO.OutB (VGA_SR_DATA, Reg8 or VGA_SR01_SCREEN_OFF);
514 Time.U_Delay (100); -- PRM says 100us, Linux does 300
515 Registers.Set_Mask (Registers.VGACNTRL, VGA_CONTROL_VGA_DISPLAY_DISABLE);
516 end Legacy_VGA_Off;
517
Nico Huber83693c82016-10-08 22:17:55 +0200518 procedure All_Off
519 is
Nico Huber83693c82016-10-08 22:17:55 +0200520 begin
521 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
522
Nico Huber33912aa2016-12-06 20:36:23 +0100523 Legacy_VGA_Off;
524
Nico Huberf3e23662016-12-05 21:33:03 +0100525 for Pipe in Pipe_Index loop
526 Planes_Off (Controllers (Pipe));
Nico Huber7ad2d652016-12-07 15:19:32 +0100527 Transcoder.Off (Pipe);
Nico Huberf3e23662016-12-05 21:33:03 +0100528 Panel_Fitter_Off (Controllers (Pipe));
Nico Huber7ad2d652016-12-07 15:19:32 +0100529 Transcoder.Clk_Off (Pipe);
Nico Huber83693c82016-10-08 22:17:55 +0200530 end loop;
Nico Huber83693c82016-10-08 22:17:55 +0200531 end All_Off;
532
533 ----------------------------------------------------------------------------
534
Nico Huberf3e23662016-12-05 21:33:03 +0100535 procedure Update_Offset (Pipe : Pipe_Index; Framebuffer : Framebuffer_Type)
536 is
Nico Huber83693c82016-10-08 22:17:55 +0200537 begin
538 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
539
Nico Huberf3e23662016-12-05 21:33:03 +0100540 Registers.Write
541 (Controllers (Pipe).DSPSURF, Framebuffer.Offset and 16#ffff_f000#);
Nico Huber83693c82016-10-08 22:17:55 +0200542 end Update_Offset;
543
Nico Huber83693c82016-10-08 22:17:55 +0200544end HW.GFX.GMA.Pipe_Setup;