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 <nico.huber@secunet.com>
Reviewed-on: https://review.coreboot.org/17276
Tested-by: Nico Huber <nico.h@gmx.de>
Reviewed-by: Ronald G. Minnich <rminnich@gmail.com>
diff --git a/common/hw-gfx-gma-pipe_setup.adb b/common/hw-gfx-gma-pipe_setup.adb
index b902b77..1f13c86 100644
--- a/common/hw-gfx-gma-pipe_setup.adb
+++ b/common/hw-gfx-gma-pipe_setup.adb
@@ -47,6 +47,22 @@
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 @@
----------------------------------------------------------------------------
- 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 @@
=>+
(Registers.Register_State,
Controller,
- Head,
Mode,
Framebuffer))
is
@@ -341,13 +355,7 @@
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 @@
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));