From 3675db58aa729bfb565b61389d3b2568360095af Mon Sep 17 00:00:00 2001 From: Nico Huber Date: Fri, 4 Nov 2016 16:27:29 +0100 Subject: [PATCH] gma: Add option for VGA plane on the primary pipe Add special VGA_PLANE_FRAMEBUFFER_OFFSET that, if set on the primary pipe, toggles the use of the legacy VGA plane instead of the `hires` plane. The caller is responsible for the configuration of the VGA plane and has to specify the framebuffer width and height accordingly. Change-Id: I9f678fe033d835c9183fbb2d2b05b6585eb545ca Signed-off-by: Nico Huber Reviewed-on: https://review.coreboot.org/17276 Tested-by: Nico Huber Reviewed-by: Ronald G. Minnich --- common/hw-gfx-gma-pipe_setup.adb | 77 ++++++++++++++++++++++++++++---- common/hw-gfx-gma.adb | 11 +++-- common/hw-gfx-gma.ads | 4 ++ 3 files changed, 79 insertions(+), 13 deletions(-) diff --git a/common/hw-gfx-gma-pipe_setup.adb b/common/hw-gfx-gma-pipe_setup.adb index b902b77465..1f13c86f7a 100644 --- a/common/hw-gfx-gma-pipe_setup.adb +++ b/common/hw-gfx-gma-pipe_setup.adb @@ -47,6 +47,22 @@ package body HW.GFX.GMA.Pipe_Setup is SPCNTR_ENABLE : constant := 1 * 2 ** 31; + VGA_SR01_SCREEN_OFF : constant := 1 * 2 ** 5; + + VGA_CONTROL_VGA_DISPLAY_DISABLE : constant := 1 * 2 ** 31; + VGA_CONTROL_BLINK_DUTY_CYCLE_MASK : constant := 16#0003# * 2 ** 6; + VGA_CONTROL_BLINK_DUTY_CYCLE_50 : constant := 2 * 2 ** 6; + VGA_CONTROL_VSYNC_BLINK_RATE_MASK : constant := 16#003f# * 2 ** 0; + + subtype VGA_Cycle_Count is Pos32 range 2 .. 128; + function VGA_CONTROL_VSYNC_BLINK_RATE + (Cycles : VGA_Cycle_Count) + return Word32 + is + begin + return Word32 (Cycles) / 2 - 1; + end VGA_CONTROL_VSYNC_BLINK_RATE; + TRANS_CLK_SEL_PORT_NONE : constant := 0 * 2 ** 29; type TRANS_CLK_SEL_PORT_Array is @@ -311,9 +327,8 @@ package body HW.GFX.GMA.Pipe_Setup is ---------------------------------------------------------------------------- - procedure Setup_Display + procedure Setup_Hires_Plane (Controller : in Controller_Type; - Head : in Head_Type; Mode : in HW.GFX.Mode_Type; Framebuffer : in HW.GFX.Framebuffer_Type) with @@ -323,7 +338,6 @@ package body HW.GFX.GMA.Pipe_Setup is =>+ (Registers.Register_State, Controller, - Head, Mode, Framebuffer)) is @@ -341,13 +355,7 @@ package body HW.GFX.GMA.Pipe_Setup is begin pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); - Registers.Write - (Register => Controller.PIPESRC, - Value => Encode - (Pos16 (Framebuffer.Height), Pos16 (Framebuffer.Width))); - if Config.Has_Plane_Control then - Setup_Watermarks (Controller); Registers.Write (Register => Controller.PLANE_CTL, Value => PLANE_CTL_PLANE_ENABLE or @@ -376,6 +384,57 @@ package body HW.GFX.GMA.Pipe_Setup is end if; Registers.Write (Controller.DSPTILEOFF, 0); end if; + end Setup_Hires_Plane; + + procedure Setup_Display + (Controller : in Controller_Type; + Head : in Head_Type; + Mode : in HW.GFX.Mode_Type; + Framebuffer : in HW.GFX.Framebuffer_Type) + with + Global => (In_Out => (Registers.Register_State, Port_IO.State)), + Depends => + (Registers.Register_State + =>+ + (Registers.Register_State, + Controller, + Head, + Mode, + Framebuffer), + Port_IO.State + =>+ + (Framebuffer)) + is + use type Word8; + + Reg8 : Word8; + begin + pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity)); + + if Config.Has_Plane_Control then + Setup_Watermarks (Controller); + end if; + + if Framebuffer.Offset = VGA_PLANE_FRAMEBUFFER_OFFSET then + Registers.Unset_And_Set_Mask + (Register => Registers.VGACNTRL, + Mask_Unset => VGA_CONTROL_VGA_DISPLAY_DISABLE or + VGA_CONTROL_BLINK_DUTY_CYCLE_MASK or + VGA_CONTROL_VSYNC_BLINK_RATE_MASK, + Mask_Set => VGA_CONTROL_BLINK_DUTY_CYCLE_50 or + VGA_CONTROL_VSYNC_BLINK_RATE (30)); + + Port_IO.OutB (VGA_SR_INDEX, VGA_SR01); + Port_IO.InB (Reg8, VGA_SR_DATA); + Port_IO.OutB (VGA_SR_DATA, Reg8 and not (VGA_SR01_SCREEN_OFF)); + else + Setup_Hires_Plane (Controller, Mode, Framebuffer); + end if; + + Registers.Write + (Register => Controller.PIPESRC, + Value => Encode + (Pos16 (Framebuffer.Height), Pos16 (Framebuffer.Width))); Registers.Write (Head.HTOTAL, Encode (Mode.H_Visible, Mode.H_Total)); Registers.Write (Head.HBLANK, Encode (Mode.H_Visible, Mode.H_Total)); diff --git a/common/hw-gfx-gma.adb b/common/hw-gfx-gma.adb index f8b0e7be08..c50d943309 100644 --- a/common/hw-gfx-gma.adb +++ b/common/hw-gfx-gma.adb @@ -192,16 +192,19 @@ is begin -- No downscaling -- Respect maximum scalable width - -- Only 32bpp RGB - -- Stride must be a multiple of 64 + -- VGA plane is only allowed on the primary pipe + -- Only 32bpp RGB (ignored for VGA plane) + -- Stride must be a multiple of 64 (ignored for VGA plane) return ((Framebuffer.Width = Pos32 (Port_Cfg.Mode.H_Visible) and Framebuffer.Height = Pos32 (Port_Cfg.Mode.V_Visible)) or (Framebuffer.Width <= Config.Maximum_Scalable_Width (I) and Framebuffer.Width <= Pos32 (Port_Cfg.Mode.H_Visible) and Framebuffer.Height <= Pos32 (Port_Cfg.Mode.V_Visible))) and - Framebuffer.BPC = 8 and - Framebuffer.Stride mod 64 = 0; + (Framebuffer.Offset /= VGA_PLANE_FRAMEBUFFER_OFFSET or I = Primary) and + (Framebuffer.Offset = VGA_PLANE_FRAMEBUFFER_OFFSET or + (Framebuffer.BPC = 8 and + Framebuffer.Stride mod 64 = 0)); end Validate_Config; procedure Fill_Port_Config diff --git a/common/hw-gfx-gma.ads b/common/hw-gfx-gma.ads index 1e64cb4f38..ed240ca642 100644 --- a/common/hw-gfx-gma.ads +++ b/common/hw-gfx-gma.ads @@ -58,6 +58,10 @@ is type Config_Index is (Primary, Secondary, Tertiary); type Configs_Type is array (Config_Index) of Config_Type; + -- Special framebuffer offset to indicate legacy VGA plane. + -- Only valid on primary pipe. + VGA_PLANE_FRAMEBUFFER_OFFSET : constant := 16#ffff_ffff#; + procedure Initialize (MMIO_Base : in Word64 := 0; Write_Delay : in Word64 := 0;