gma: Introduce Pipe_Config.Scaler_Available()

G45 provides only a single panel fitter. Therefore, we can only enable
a single pipe that requires scaling. Scaler_Available() tells us if a
panel fitter is available for a given pipe. We use the result to filter
invalid configurations early.

Change-Id: Ie05bfb58318e79edc8ab81598458e620ffdcb2ab
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.coreboot.org/26768
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
This commit is contained in:
Nico Huber
2018-06-02 18:01:45 +02:00
parent 958c564045
commit f361ec81e0
5 changed files with 63 additions and 31 deletions

View File

@@ -188,9 +188,10 @@ is
-- Validates that a given configuration should work with
-- a given framebuffer.
function Validate_Config
(FB : Framebuffer_Type;
Mode : Mode_Type;
Pipe : Pipe_Index)
(FB : Framebuffer_Type;
Mode : Mode_Type;
Pipe : Pipe_Index;
Scaler_Available : Boolean)
return Boolean
is
begin
@@ -206,7 +207,8 @@ is
return
((Rotated_Width (FB) = Mode.H_Visible and
Rotated_Height (FB) = Mode.V_Visible) or
(Rotated_Width (FB) <= Config.Maximum_Scalable_Width (Pipe) and
(Scaler_Available and
Rotated_Width (FB) <= Config.Maximum_Scalable_Width (Pipe) and
Rotated_Width (FB) <= Mode.H_Visible and
Rotated_Height (FB) <= Mode.V_Visible)) and
(FB.Offset /= VGA_PLANE_FRAMEBUFFER_OFFSET or Pipe = Primary) and

View File

@@ -40,9 +40,10 @@ is
use type HW.Pos32;
pragma Warnings (GNAT, On, """Integer_32"" is already use-visible *");
function Validate_Config
(FB : Framebuffer_Type;
Mode : Mode_Type;
Pipe : Pipe_Index)
(FB : Framebuffer_Type;
Mode : Mode_Type;
Pipe : Pipe_Index;
Scaler_Available : Boolean)
return Boolean
with
Post =>

View File

@@ -532,10 +532,6 @@ package body HW.GFX.GMA.Pipe_Setup is
Value => Shift_Left (Word32 (Width), 16) or Word32 (Height));
end Setup_Ironlake_Panel_Fitter;
-- TODO the panel fitter can only be set for one pipe
-- If this causes problems:
-- Check in Enable_Output if panel fitter has already been enabled
-- Pass this information to Validate_Config
procedure Setup_Gmch_Panel_Fitter
(Controller : in Controller_Type;
Mode : in HW.GFX.Mode_Type;
@@ -566,10 +562,21 @@ package body HW.GFX.GMA.Pipe_Setup is
end if;
end Setup_Gmch_Panel_Fitter;
procedure Gmch_Panel_Fitter_Pipe (Pipe : out Pipe_Index)
is
Used_For_Secondary : Boolean;
begin
Registers.Is_Set_Mask
(Register => Registers.GMCH_PFIT_CONTROL,
Mask => GMCH_PFIT_CONTROL_SELECT_PIPE_B,
Result => Used_For_Secondary);
Pipe := (if Used_For_Secondary then Secondary else Primary);
end;
procedure Panel_Fitter_Off (Controller : Controller_Type)
is
use type HW.GFX.GMA.Registers.Registers_Invalid_Index;
Used_For_Secondary : Boolean;
Pipe_Using_PF : Pipe_Index;
begin
-- Writes to WIN_SZ arm the PS/PF registers.
if Config.Has_Plane_Control then
@@ -582,16 +589,9 @@ package body HW.GFX.GMA.Pipe_Setup is
Registers.Write (Controller.PS_WIN_SZ_2, 16#0000_0000#);
end if;
elsif Config.Has_GMCH_PFIT_CONTROL then
Registers.Is_Set_Mask
(Register => Registers.GMCH_PFIT_CONTROL,
Mask => GMCH_PFIT_CONTROL_SELECT_PIPE_B,
Result => Used_For_Secondary);
if (Controller.Pipe = Primary and not Used_For_Secondary) or
(Controller.Pipe = Secondary and Used_For_Secondary)
then
Registers.Unset_Mask
(Register => Registers.GMCH_PFIT_CONTROL,
Mask => PF_CTRL_ENABLE);
Gmch_Panel_Fitter_Pipe (Pipe_Using_PF);
if Pipe_Using_PF = Controller.Pipe then
Registers.Unset_Mask (Registers.GMCH_PFIT_CONTROL, PF_CTRL_ENABLE);
end if;
else
Registers.Unset_Mask (Controller.PF_CTRL, PF_CTRL_ENABLE);
@@ -622,6 +622,26 @@ package body HW.GFX.GMA.Pipe_Setup is
end if;
end Setup_Scaling;
procedure Scaler_Available (Available : out Boolean; Pipe : Pipe_Index)
is
Pipe_Using_PF : Pipe_Index := Pipe_Index'First;
PF_Enabled : Boolean;
begin
if Config.Has_GMCH_PFIT_CONTROL then
Registers.Is_Set_Mask
(Register => Registers.GMCH_PFIT_CONTROL,
Mask => PF_CTRL_ENABLE,
Result => PF_Enabled);
if PF_Enabled then
Gmch_Panel_Fitter_Pipe (Pipe_Using_PF);
end if;
Available := not PF_Enabled or Pipe_Using_PF = Pipe;
else
Available := True;
end if;
end Scaler_Available;
----------------------------------------------------------------------------
procedure Setup_FB

View File

@@ -57,6 +57,8 @@ is
FB : Framebuffer_Type;
Cursor : Cursor_Type);
procedure Scaler_Available (Available : out Boolean; Pipe : Pipe_Index);
private
subtype WM_Levels is Natural range 0 .. 7;

View File

@@ -99,6 +99,7 @@ is
Success : out Boolean)
is
Port_Cfg : Port_Config;
Scaler_Available : Boolean;
begin
pragma Debug (Debug.New_Line);
pragma Debug (Debug.Put_Line
@@ -108,8 +109,9 @@ is
(Port_Cfg, Pipe, Pipe_Cfg.Port, Pipe_Cfg.Mode, Success);
if Success then
Display_Controller.Scaler_Available (Scaler_Available, Pipe);
Success := Config_Helpers.Validate_Config
(Pipe_Cfg.Framebuffer, Port_Cfg.Mode, Pipe);
(Pipe_Cfg.Framebuffer, Port_Cfg.Mode, Pipe, Scaler_Available);
end if;
if Success then
@@ -275,6 +277,7 @@ is
for Pipe in Pipe_Index loop
declare
Success : Boolean;
Scaler_Available : Boolean;
Cur_Config : Pipe_Config renames Cur_Configs (Pipe);
New_Config : Pipe_Config renames Configs (Pipe);
begin
@@ -299,15 +302,19 @@ is
-- update framebuffer offset only
elsif New_Config.Port /= Disabled and
Cur_Config.Framebuffer /= New_Config.Framebuffer and
Config_Helpers.Validate_Config
(New_Config.Framebuffer, New_Config.Mode, Pipe)
Cur_Config.Framebuffer /= New_Config.Framebuffer
then
Display_Controller.Setup_FB
(Pipe, New_Config.Mode, New_Config.Framebuffer);
Display_Controller.Update_Cursor
(Pipe, New_Config.Framebuffer, New_Config.Cursor);
Cur_Config := New_Config;
Display_Controller.Scaler_Available (Scaler_Available, Pipe);
if Config_Helpers.Validate_Config
(New_Config.Framebuffer, New_Config.Mode,
Pipe, Scaler_Available)
then
Display_Controller.Setup_FB
(Pipe, New_Config.Mode, New_Config.Framebuffer);
Display_Controller.Update_Cursor
(Pipe, New_Config.Framebuffer, New_Config.Cursor);
Cur_Config := New_Config;
end if;
end if;
end;
end loop;