gma: Configure cursor plane

Programming the cursor plane registers is straight forward.

On newer hardware, we also have to account for the cursor in GPU
internal buffer allocation. Fortunately, we have enough resources
for a static configuration that always accounts for a cursor.

Cursors with a location that is off limits are placed off-screen
in the top-left corner, hence, are invisible.

Change-Id: I08ffd81d524e14e464af6e6f6fb5effbd4890d8a
Signed-off-by: Nico Huber <nico.huber@secunet.com>
Reviewed-on: https://review.coreboot.org/23204
Tested-by: Nico Huber <nico.h@gmx.de>
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
This commit is contained in:
Nico Huber
2018-01-10 15:55:09 +01:00
committed by Nico Huber
parent a02b2c699b
commit 4dc4c61a4a
5 changed files with 248 additions and 22 deletions

View File

@@ -56,6 +56,7 @@ is
Has_Plane_Control : constant Boolean := CPU >= Broxton;
Has_DSP_Linoff : constant Boolean := CPU <= Ivybridge;
Has_PF_Pipe_Select : constant Boolean := CPU in Ivybridge .. Haswell;
Has_Cursor_FBC_Control : constant Boolean := CPU >= Ivybridge;
VGA_Plane_Workaround : constant Boolean := CPU = Ivybridge;
Has_GMCH_DP_Transcoder : constant Boolean := CPU = G45;
Has_GMCH_VGACNTRL : constant Boolean := CPU = G45;

View File

@@ -72,6 +72,26 @@ package body HW.GFX.GMA.Pipe_Setup is
VGA_CONTROL_BLINK_DUTY_CYCLE_50 : constant := 2 * 2 ** 6;
VGA_CONTROL_VSYNC_BLINK_RATE_MASK : constant := 16#003f# * 2 ** 0;
CUR_CTL_PIPE_SELECT : constant array (Pipe_Index) of Word32 :=
(Primary => 0 * 2 ** 28,
Secondary => 1 * 2 ** 28,
Tertiary => 2 * 2 ** 28);
CUR_CTL_MODE : constant array (Cursor_Mode, Cursor_Size) of Word32 :=
(No_Cursor => (others => 16#00#),
ARGB_Cursor =>
(Cursor_64x64 => 16#27#,
Cursor_128x128 => 16#22#,
Cursor_256x256 => 16#23#));
function CUR_POS_Y (Y : Int32) return Word32 is
((if Y >= 0 then 0 else 1 * 2 ** 31) or Shift_Left (Word32 (abs Y), 16))
with
Pre => Y > Int32'First;
function CUR_POS_X (X : Int32) return Word32 is
((if X >= 0 then 0 else 1 * 2 ** 15) or Word32 (abs X))
with
Pre => X > Int32'First;
subtype VGA_Cycle_Count is Pos32 range 2 .. 128;
function VGA_CONTROL_VSYNC_BLINK_RATE
(Cycles : VGA_Cycle_Count)
@@ -122,35 +142,45 @@ package body HW.GFX.GMA.Pipe_Setup is
procedure Clear_Watermarks (Controller : Controller_Type) is
begin
Registers.Write
(Register => Controller.PLANE_BUF_CFG,
Value => 16#0000_0000#);
for Level in WM_Levels range 0 .. WM_Levels'Last loop
Registers.Write
(Register => Controller.PLANE_WM (Level),
Value => 16#0000_0000#);
Registers.Write (Controller.CUR_BUF_CFG, 16#0000_0000#);
for Level in WM_Levels loop
Registers.Write (Controller.CUR_WM (Level), 16#0000_0000#);
end loop;
Registers.Write
(Register => Controller.WM_LINETIME,
Value => 16#0000_0000#);
Registers.Write (Controller.PLANE_BUF_CFG, 16#0000_0000#);
for Level in WM_Levels loop
Registers.Write (Controller.PLANE_WM (Level), 16#0000_0000#);
end loop;
Registers.Write (Controller.WM_LINETIME, 16#0000_0000#);
end Clear_Watermarks;
procedure Setup_Watermarks (Controller : Controller_Type)
is
type Per_Plane_Buffer_Range is array (Pipe_Index) of Word32;
Buffer_Range : constant Per_Plane_Buffer_Range :=
(Primary => Shift_Left (159, 16) or 0,
Secondary => Shift_Left (319, 16) or 160,
Tertiary => Shift_Left (479, 16) or 320);
Cur_Buffer_Range : constant Per_Plane_Buffer_Range :=
(Primary => Shift_Left ( 7, 16) or 0,
Secondary => Shift_Left (167, 16) or 160,
Tertiary => Shift_Left (327, 16) or 320);
Plane_Buffer_Range : constant Per_Plane_Buffer_Range :=
(Primary => Shift_Left (159, 16) or 8,
Secondary => Shift_Left (319, 16) or 168,
Tertiary => Shift_Left (479, 16) or 328);
begin
Registers.Write
(Register => Controller.PLANE_BUF_CFG,
Value => Buffer_Range (Controller.Pipe));
Value => Plane_Buffer_Range (Controller.Pipe));
Registers.Write
(Register => Controller.PLANE_WM (0),
Value => PLANE_WM_ENABLE or
PLANE_WM_LINES (2) or
PLANE_WM_BLOCKS (160));
PLANE_WM_BLOCKS (152));
Registers.Write
(Register => Controller.CUR_BUF_CFG,
Value => Cur_Buffer_Range (Controller.Pipe));
Registers.Write
(Register => Controller.CUR_WM (0),
Value => PLANE_WM_ENABLE or
PLANE_WM_LINES (2) or
PLANE_WM_BLOCKS (8));
end Setup_Watermarks;
----------------------------------------------------------------------------
@@ -304,6 +334,49 @@ package body HW.GFX.GMA.Pipe_Setup is
----------------------------------------------------------------------------
procedure Update_Cursor
(Pipe : Pipe_Index;
FB : Framebuffer_Type;
Cursor : Cursor_Type)
is
begin
-- on some platforms writing CUR_CTL disables self-arming of CUR_POS
-- so keep it first
Registers.Write
(Register => Controllers (Pipe).CUR_CTL,
Value => CUR_CTL_PIPE_SELECT (Pipe) or
CUR_CTL_MODE (Cursor.Mode, Cursor.Size));
Place_Cursor (Pipe, FB, Cursor);
end Update_Cursor;
procedure Place_Cursor
(Pipe : Pipe_Index;
FB : Framebuffer_Type;
Cursor : Cursor_Type)
is
Width : constant Width_Type := Cursor_Width (Cursor.Size);
X : Int32 := Cursor.Center_X - Width / 2;
Y : Int32 := Cursor.Center_Y - Width / 2;
begin
-- off-screen cursor needs special care
if X <= -Width or Y <= -Width or
X >= Int32 (Rotated_Width (FB)) or Y >= Int32 (Rotated_Height (FB)) or
X > Config.Maximum_Cursor_X or Y > Config.Maximum_Cursor_Y
then
X := -Width;
Y := -Width;
end if;
Registers.Write
(Register => Controllers (Pipe).CUR_POS,
Value => CUR_POS_Y (Y) or CUR_POS_X (X));
-- write to CUR_BASE always arms other CUR_* registers
Registers.Write
(Register => Controllers (Pipe).CUR_BASE,
Value => Shift_Left (Word32 (Cursor.GTT_Offset), 12));
end Place_Cursor;
----------------------------------------------------------------------------
procedure Scale_Keep_Aspect
(Width : out Pos32;
Height : out Pos32;
@@ -540,6 +613,9 @@ package body HW.GFX.GMA.Pipe_Setup is
begin
pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
-- Disable the cursor first.
Update_Cursor (Pipe, Framebuffer, Default_Cursor);
Setup_Display (Controllers (Pipe), Framebuffer, Mode.BPC, Dither);
Setup_Scaling (Controllers (Pipe), Mode, Framebuffer);
end Setup_FB;
@@ -547,7 +623,8 @@ package body HW.GFX.GMA.Pipe_Setup is
procedure On
(Pipe : Pipe_Index;
Port_Cfg : Port_Config;
Framebuffer : Framebuffer_Type)
Framebuffer : Framebuffer_Type;
Cursor : Cursor_Type)
is
begin
pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
@@ -555,6 +632,7 @@ package body HW.GFX.GMA.Pipe_Setup is
Transcoder.Setup (Pipe, Port_Cfg);
Setup_FB (Pipe, Port_Cfg.Mode, Framebuffer);
Update_Cursor (Pipe, Framebuffer, Cursor);
Transcoder.On
(Pipe => Pipe,
@@ -567,6 +645,10 @@ package body HW.GFX.GMA.Pipe_Setup is
procedure Planes_Off (Controller : Controller_Type) is
begin
Registers.Write (Controller.CUR_CTL, 16#0000_0000#);
if Config.Has_Cursor_FBC_Control then
Registers.Write (Controller.CUR_FBC_CTL, 16#0000_0000#);
end if;
Registers.Unset_Mask (Controller.SPCNTR, DSPCNTR_ENABLE);
if Config.Has_Plane_Control then
Clear_Watermarks (Controller);

View File

@@ -22,7 +22,8 @@ is
procedure On
(Pipe : Pipe_Index;
Port_Cfg : Port_Config;
Framebuffer : Framebuffer_Type)
Framebuffer : Framebuffer_Type;
Cursor : Cursor_Type)
with
Pre =>
Rotated_Width (Framebuffer) <= Port_Cfg.Mode.H_Visible and
@@ -47,6 +48,15 @@ is
(Framebuffer.Offset = VGA_PLANE_FRAMEBUFFER_OFFSET or
Framebuffer.Height + Framebuffer.Start_Y <= Framebuffer.V_Stride);
procedure Update_Cursor
(Pipe : Pipe_Index;
FB : Framebuffer_Type;
Cursor : Cursor_Type);
procedure Place_Cursor
(Pipe : Pipe_Index;
FB : Framebuffer_Type;
Cursor : Cursor_Type);
private
subtype WM_Levels is Natural range 0 .. 7;
@@ -66,6 +76,10 @@ private
DSPSURF : Registers.Registers_Index;
DSPTILEOFF : Registers.Registers_Index;
SPCNTR : Registers.Registers_Index;
CUR_CTL : Registers.Registers_Index;
CUR_BASE : Registers.Registers_Index;
CUR_POS : Registers.Registers_Index;
CUR_FBC_CTL : Registers.Registers_Index;
-- Skylake registers (partially aliased)
PLANE_CTL : Registers.Registers_Index;
PLANE_OFFSET : Registers.Registers_Index;
@@ -81,6 +95,8 @@ private
WM_LINETIME : Registers.Registers_Index;
PLANE_BUF_CFG : Registers.Registers_Index;
PLANE_WM : PLANE_WM_Type;
CUR_BUF_CFG : Registers.Registers_Index;
CUR_WM : PLANE_WM_Type;
end record;
type Controller_Array is array (Pipe_Index) of Controller_Type;
@@ -99,6 +115,10 @@ private
DSPSURF => Registers.DSPASURF,
DSPTILEOFF => Registers.DSPATILEOFF,
SPCNTR => Registers.SPACNTR,
CUR_CTL => Registers.CUR_CTL_A,
CUR_BASE => Registers.CUR_BASE_A,
CUR_POS => Registers.CUR_POS_A,
CUR_FBC_CTL => Registers.CUR_FBC_CTL_A,
PLANE_CTL => Registers.DSPACNTR,
PLANE_OFFSET => Registers.DSPATILEOFF,
PLANE_POS => Registers.PLANE_POS_1_A,
@@ -120,7 +140,17 @@ private
Registers.PLANE_WM_1_A_4,
Registers.PLANE_WM_1_A_5,
Registers.PLANE_WM_1_A_6,
Registers.PLANE_WM_1_A_7)),
Registers.PLANE_WM_1_A_7),
CUR_BUF_CFG => Registers.CUR_BUF_CFG_A,
CUR_WM => PLANE_WM_Type'(
Registers.CUR_WM_A_0,
Registers.CUR_WM_A_1,
Registers.CUR_WM_A_2,
Registers.CUR_WM_A_3,
Registers.CUR_WM_A_4,
Registers.CUR_WM_A_5,
Registers.CUR_WM_A_6,
Registers.CUR_WM_A_7)),
Secondary => Controller_Type'
(Pipe => Secondary,
PIPESRC => Registers.PIPEBSRC,
@@ -134,6 +164,10 @@ private
DSPSURF => Registers.DSPBSURF,
DSPTILEOFF => Registers.DSPBTILEOFF,
SPCNTR => Registers.SPBCNTR,
CUR_CTL => Registers.CUR_CTL_B,
CUR_BASE => Registers.CUR_BASE_B,
CUR_POS => Registers.CUR_POS_B,
CUR_FBC_CTL => Registers.CUR_FBC_CTL_B,
PLANE_CTL => Registers.DSPBCNTR,
PLANE_OFFSET => Registers.DSPBTILEOFF,
PLANE_POS => Registers.PLANE_POS_1_B,
@@ -155,7 +189,17 @@ private
Registers.PLANE_WM_1_B_4,
Registers.PLANE_WM_1_B_5,
Registers.PLANE_WM_1_B_6,
Registers.PLANE_WM_1_B_7)),
Registers.PLANE_WM_1_B_7),
CUR_BUF_CFG => Registers.CUR_BUF_CFG_B,
CUR_WM => PLANE_WM_Type'(
Registers.CUR_WM_B_0,
Registers.CUR_WM_B_1,
Registers.CUR_WM_B_2,
Registers.CUR_WM_B_3,
Registers.CUR_WM_B_4,
Registers.CUR_WM_B_5,
Registers.CUR_WM_B_6,
Registers.CUR_WM_B_7)),
Tertiary => Controller_Type'
(Pipe => Tertiary,
PIPESRC => Registers.PIPECSRC,
@@ -169,6 +213,10 @@ private
DSPSURF => Registers.DSPCSURF,
DSPTILEOFF => Registers.DSPCTILEOFF,
SPCNTR => Registers.SPCCNTR,
CUR_CTL => Registers.CUR_CTL_C,
CUR_BASE => Registers.CUR_BASE_C,
CUR_POS => Registers.CUR_POS_C,
CUR_FBC_CTL => Registers.CUR_FBC_CTL_C,
PLANE_CTL => Registers.DSPCCNTR,
PLANE_OFFSET => Registers.DSPCTILEOFF,
PLANE_POS => Registers.PLANE_POS_1_C,
@@ -190,6 +238,16 @@ private
Registers.PLANE_WM_1_C_4,
Registers.PLANE_WM_1_C_5,
Registers.PLANE_WM_1_C_6,
Registers.PLANE_WM_1_C_7)));
Registers.PLANE_WM_1_C_7),
CUR_BUF_CFG => Registers.CUR_BUF_CFG_C,
CUR_WM => PLANE_WM_Type'(
Registers.CUR_WM_C_0,
Registers.CUR_WM_C_1,
Registers.CUR_WM_C_2,
Registers.CUR_WM_C_3,
Registers.CUR_WM_C_4,
Registers.CUR_WM_C_5,
Registers.CUR_WM_C_6,
Registers.CUR_WM_C_7)));
end HW.GFX.GMA.Pipe_Setup;

View File

@@ -459,6 +459,19 @@ is
PIPEA_GMCH_DATA_N,
PIPEA_GMCH_LINK_M,
PIPEA_GMCH_LINK_N,
CUR_CTL_A,
CUR_BASE_A,
CUR_POS_A,
CUR_FBC_CTL_A,
CUR_WM_A_0,
CUR_WM_A_1,
CUR_WM_A_2,
CUR_WM_A_3,
CUR_WM_A_4,
CUR_WM_A_5,
CUR_WM_A_6,
CUR_WM_A_7,
CUR_BUF_CFG_A,
DSPACNTR,
DSPALINOFF,
DSPASTRIDE,
@@ -484,6 +497,19 @@ is
PIPEB_GMCH_DATA_N,
PIPEB_GMCH_LINK_M,
PIPEB_GMCH_LINK_N,
CUR_CTL_B,
CUR_BASE_B,
CUR_POS_B,
CUR_FBC_CTL_B,
CUR_WM_B_0,
CUR_WM_B_1,
CUR_WM_B_2,
CUR_WM_B_3,
CUR_WM_B_4,
CUR_WM_B_5,
CUR_WM_B_6,
CUR_WM_B_7,
CUR_BUF_CFG_B,
DSPBCNTR,
DSPBLINOFF,
DSPBSTRIDE,
@@ -506,6 +532,19 @@ is
PIPECCONF,
PIPECMISC,
PIPE_FRMCNT_C,
CUR_CTL_C,
CUR_BASE_C,
CUR_POS_C,
CUR_FBC_CTL_C,
CUR_WM_C_0,
CUR_WM_C_1,
CUR_WM_C_2,
CUR_WM_C_3,
CUR_WM_C_4,
CUR_WM_C_5,
CUR_WM_C_6,
CUR_WM_C_7,
CUR_BUF_CFG_C,
DSPCCNTR,
DSPCLINOFF,
DSPCSTRIDE,
@@ -768,6 +807,12 @@ is
PS_WIN_SZ_2_A => 16#06_8274# / Register_Width,
PS_CTRL_2_A => 16#06_8280# / Register_Width,
-- cursor control
CUR_CTL_A => 16#07_0080# / Register_Width,
CUR_BASE_A => 16#07_0084# / Register_Width,
CUR_POS_A => 16#07_0088# / Register_Width,
CUR_FBC_CTL_A => 16#07_00a0# / Register_Width,
-- display control
DSPACNTR => 16#07_0180# / Register_Width,
DSPALINOFF => 16#07_0184# / Register_Width,
@@ -801,6 +846,15 @@ is
PLANE_WM_1_A_6 => 16#07_0258# / Register_Width,
PLANE_WM_1_A_7 => 16#07_025c# / Register_Width,
PLANE_BUF_CFG_1_A => 16#07_027c# / Register_Width,
CUR_WM_A_0 => 16#07_0140# / Register_Width,
CUR_WM_A_1 => 16#07_0144# / Register_Width,
CUR_WM_A_2 => 16#07_0148# / Register_Width,
CUR_WM_A_3 => 16#07_014c# / Register_Width,
CUR_WM_A_4 => 16#07_0150# / Register_Width,
CUR_WM_A_5 => 16#07_0154# / Register_Width,
CUR_WM_A_6 => 16#07_0158# / Register_Width,
CUR_WM_A_7 => 16#07_015c# / Register_Width,
CUR_BUF_CFG_A => 16#07_017c# / Register_Width,
-- CPU transcoder clock select
TRANSA_CLK_SEL => 16#04_6140# / Register_Width,
@@ -862,6 +916,12 @@ is
PS_WIN_SZ_2_B => 16#06_8a74# / Register_Width,
PS_CTRL_2_B => 16#06_8a80# / Register_Width,
-- cursor control
CUR_CTL_B => 16#07_1080# / Register_Width,
CUR_BASE_B => 16#07_1084# / Register_Width,
CUR_POS_B => 16#07_1088# / Register_Width,
CUR_FBC_CTL_B => 16#07_10a0# / Register_Width,
-- display control
DSPBCNTR => 16#07_1180# / Register_Width,
DSPBLINOFF => 16#07_1184# / Register_Width,
@@ -895,6 +955,15 @@ is
PLANE_WM_1_B_6 => 16#07_1258# / Register_Width,
PLANE_WM_1_B_7 => 16#07_125c# / Register_Width,
PLANE_BUF_CFG_1_B => 16#07_127c# / Register_Width,
CUR_WM_B_0 => 16#07_1140# / Register_Width,
CUR_WM_B_1 => 16#07_1144# / Register_Width,
CUR_WM_B_2 => 16#07_1148# / Register_Width,
CUR_WM_B_3 => 16#07_114c# / Register_Width,
CUR_WM_B_4 => 16#07_1150# / Register_Width,
CUR_WM_B_5 => 16#07_1154# / Register_Width,
CUR_WM_B_6 => 16#07_1158# / Register_Width,
CUR_WM_B_7 => 16#07_115c# / Register_Width,
CUR_BUF_CFG_B => 16#07_117c# / Register_Width,
-- CPU transcoder clock select
TRANSB_CLK_SEL => 16#04_6144# / Register_Width,
@@ -939,6 +1008,12 @@ is
PS_WIN_SZ_1_C => 16#06_9174# / Register_Width,
PS_CTRL_1_C => 16#06_9180# / Register_Width,
-- cursor control
CUR_CTL_C => 16#07_2080# / Register_Width,
CUR_BASE_C => 16#07_2084# / Register_Width,
CUR_POS_C => 16#07_2088# / Register_Width,
CUR_FBC_CTL_C => 16#07_20a0# / Register_Width,
-- display control
DSPCCNTR => 16#07_2180# / Register_Width,
DSPCLINOFF => 16#07_2184# / Register_Width,
@@ -972,6 +1047,15 @@ is
PLANE_WM_1_C_6 => 16#07_2258# / Register_Width,
PLANE_WM_1_C_7 => 16#07_225c# / Register_Width,
PLANE_BUF_CFG_1_C => 16#07_227c# / Register_Width,
CUR_WM_C_0 => 16#07_2140# / Register_Width,
CUR_WM_C_1 => 16#07_2144# / Register_Width,
CUR_WM_C_2 => 16#07_2148# / Register_Width,
CUR_WM_C_3 => 16#07_214c# / Register_Width,
CUR_WM_C_4 => 16#07_2150# / Register_Width,
CUR_WM_C_5 => 16#07_2154# / Register_Width,
CUR_WM_C_6 => 16#07_2158# / Register_Width,
CUR_WM_C_7 => 16#07_215c# / Register_Width,
CUR_BUF_CFG_C => 16#07_217c# / Register_Width,
-- CPU transcoder clock select
TRANSC_CLK_SEL => 16#04_6148# / Register_Width,

View File

@@ -147,7 +147,8 @@ is
Display_Controller.On
(Pipe => Pipe,
Port_Cfg => Port_Cfg,
Framebuffer => Pipe_Cfg.Framebuffer);
Framebuffer => Pipe_Cfg.Framebuffer,
Cursor => Pipe_Cfg.Cursor);
Connectors.Post_On
(Pipe => Pipe,