From f361ec81e075b3ece15fcb910ec4c96758ce33c2 Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Sat, 2 Jun 2018 18:01:45 +0200 Subject: [PATCH] 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 Reviewed-on: https://review.coreboot.org/26768 Reviewed-by: Arthur Heymans --- common/hw-gfx-gma-config_helpers.adb | 10 +++--- common/hw-gfx-gma-config_helpers.ads | 7 ++-- common/hw-gfx-gma-pipe_setup.adb | 50 +++++++++++++++++++--------- common/hw-gfx-gma-pipe_setup.ads | 2 ++ common/hw-gfx-gma.adb | 25 +++++++++----- 5 files changed, 63 insertions(+), 31 deletions(-) diff --git a/common/hw-gfx-gma-config_helpers.adb b/common/hw-gfx-gma-config_helpers.adb index 128b52beb5..b7f48332b9 100644 --- a/common/hw-gfx-gma-config_helpers.adb +++ b/common/hw-gfx-gma-config_helpers.adb @@ -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 diff --git a/common/hw-gfx-gma-config_helpers.ads b/common/hw-gfx-gma-config_helpers.ads index 48536343c2..d56be5e706 100644 --- a/common/hw-gfx-gma-config_helpers.ads +++ b/common/hw-gfx-gma-config_helpers.ads @@ -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 => diff --git a/common/hw-gfx-gma-pipe_setup.adb b/common/hw-gfx-gma-pipe_setup.adb index f0f0d864fb..a45dfb2b5b 100644 --- a/common/hw-gfx-gma-pipe_setup.adb +++ b/common/hw-gfx-gma-pipe_setup.adb @@ -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 diff --git a/common/hw-gfx-gma-pipe_setup.ads b/common/hw-gfx-gma-pipe_setup.ads index a61ff001f4..fe877adf71 100644 --- a/common/hw-gfx-gma-pipe_setup.ads +++ b/common/hw-gfx-gma-pipe_setup.ads @@ -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; diff --git a/common/hw-gfx-gma.adb b/common/hw-gfx-gma.adb index 7e9a959ecd..a5e9dbe08d 100644 --- a/common/hw-gfx-gma.adb +++ b/common/hw-gfx-gma.adb @@ -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;